Earlier quoted context omitted.
Reflection is usually not available in AoT compiled languages. The prevalent Rust coding styles rely heavily on monomorphic data types and functions, meaning there's nothing left to reflect at runtime. But if you want to deal with trait objects and need to access the underlying type, you need to use Any::downcast or rely on annotations on every type you want to reflect on. Or now, leverage DWARF info on Linux with de…
What are monomorphic data types? What should be my first read on the subject?
Native Reflection in Rust
11–20 of 68 posts
Re: Native Reflection in Rust
#12Does using DWARF info imply that this will break when you strip the resulting executable? I often strip my Rust binaries because it practically halves the application size, which can become quite a lot in a language where you're statically linking everything. Regardless, quite an ingenious use of standard ELF features, I didn't think this would be possible in Rust without adding some kind of VM around reflection code…
Re: Native Reflection in Rust
#13Earlier quoted context omitted.
What are monomorphic data types? What should be my first read on the subject?
It's a fancy way of saying "every time this type is used, replace all the generic type params with what was used and generate code for it". It's how generics are implemented in Rust. If you have struct Foo (T); And you create Foo(42i32) and Foo(0.0f64), the compiler will create the equivalent to struct Fooi32(i32); struct Foof64(f64); In other languages like Java, generics are implemented the way that Rust does "trai…
Re: Native Reflection in Rust
#14Earlier quoted context omitted.
Reflection is typically provided by a runtime, and languages that don't have runtimes usually don't have it. You shouldn't expect a low-level systems language to have reflection. There is no zero-cost way of implementing it.
Except Rust has runtime: [0]. And so, usually, does C (in hosted implementations). [0] https://doc.rust-lang.org/reference/runtime.html
Rust has no run-time type information except limited downcasts via `dyn Any` or explicitly derived traits on per-type basis, and these features compile to type-specific monomorphic code rather than calling some run-time reflection.
Re: Native Reflection in Rust
#15Earlier quoted context omitted.
What are monomorphic data types? What should be my first read on the subject?
It's a fancy way of saying "every time this type is used, replace all the generic type params with what was used and generate code for it". It's how generics are implemented in Rust. If you have struct Foo (T); And you create Foo(42i32) and Foo(0.0f64), the compiler will create the equivalent to struct Fooi32(i32); struct Foof64(f64); In other languages like Java, generics are implemented the way that Rust does "trai…
Re: Native Reflection in Rust
#16Earlier quoted context omitted.
What are monomorphic data types? What should be my first read on the subject?
It's a fancy way of saying "every time this type is used, replace all the generic type params with what was used and generate code for it". It's how generics are implemented in Rust. If you have struct Foo (T); And you create Foo(42i32) and Foo(0.0f64), the compiler will create the equivalent to struct Fooi32(i32); struct Foof64(f64); In other languages like Java, generics are implemented the way that Rust does "trai…
Re: Native Reflection in Rust
#17Earlier quoted context omitted.
What are monomorphic data types? What should be my first read on the subject?
It's a fancy way of saying "every time this type is used, replace all the generic type params with what was used and generate code for it". It's how generics are implemented in Rust. If you have struct Foo (T); And you create Foo(42i32) and Foo(0.0f64), the compiler will create the equivalent to struct Fooi32(i32); struct Foof64(f64); In other languages like Java, generics are implemented the way that Rust does "trai…
Re: Native Reflection in Rust
#18Earlier quoted context omitted.
What are monomorphic data types? What should be my first read on the subject?
It's a fancy way of saying "every time this type is used, replace all the generic type params with what was used and generate code for it". It's how generics are implemented in Rust. If you have struct Foo (T); And you create Foo(42i32) and Foo(0.0f64), the compiler will create the equivalent to struct Fooi32(i32); struct Foof64(f64); In other languages like Java, generics are implemented the way that Rust does "trai…
package main
import (
"fmt"
)
type wrapper[T any] struct {
Value T
}
func (w wrapper[T]) String() string {
return fmt.Sprintf("{%v}", w.Value)
}
func stringWrapped[T any](n int, v T) string {
if n == 0 {
return fmt.Sprintf("%v", v)
}
return stringWrapped(n-1, wrapper[T]{Value: v})
}
func main() {
n := 0
fmt.Scanf("%d", &n)
result := stringWrapped(n, "test")
fmt.Println(result)
}
Go refuses to compile because it can't possibly generate all instances of wrapper[T] that this program may use: wrapper[string], wrapper[wrapper[string]], wrapper[wrapper[wrapper[string]]], etc.Re: Native Reflection in Rust
#19Earlier quoted context omitted.
It's a fancy way of saying "every time this type is used, replace all the generic type params with what was used and generate code for it". It's how generics are implemented in Rust. If you have struct Foo (T); And you create Foo(42i32) and Foo(0.0f64), the compiler will create the equivalent to struct Fooi32(i32); struct Foof64(f64); In other languages like Java, generics are implemented the way that Rust does "trai…
To add to this, even the Foo-wrapper is gone, just the i32 remains. Rust values are amorphous data blobs at runtime.
Re: Native Reflection in Rust
#20Earlier quoted context omitted.
Reflection is typically provided by a runtime, and languages that don't have runtimes usually don't have it. You shouldn't expect a low-level systems language to have reflection. There is no zero-cost way of implementing it.
Except Rust has runtime: [0]. And so, usually, does C (in hosted implementations). [0] https://doc.rust-lang.org/reference/runtime.html