Live data from Hacker News

Native Reflection in Rust

jack.wrenn.fyi

41–50 of 68 posts

Re: Native Reflection in Rust

#42
post #32

Earlier quoted context omitted.

> This is a rather strange thing to bolt onto a language. It can just be an extremely fun and cute demo, without practical application.

how about adding this to debuggers for better object-views? (could it be possible to provide near-js/python/java level of obj view?)

Thus is already using DWARF debug infos. Using this for debugging would be a long way around to arrive where you started

You can already script gdb to provide rich views of any data structure.

Re: Native Reflection in Rust

#44
post #9

Earlier 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…

Pretty sure that some usage patterns of polymorphic types can not be completely monomorphized. Here's example in Golang: 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…

I think this is called polymorphic recursion in Haskell circles.

In C++ you can monomorphize as long as you can somehow prove the recursion terminates at compile time (for example by threading a static recursion counter).

Re: Native Reflection in Rust

#45
post #3

Today I learn that Rust does not have reflection.

Rust has very little influence from reflection-heavy languages like Java and C#. On their list of influences (https://doc.rust-lang.org/reference/influences.html), Java is not even mentioned, and C# is only mentioned for its attributes. There is very little overlap between the design philosophies that influenced Rust and Java/C#.

Ruts does not support inheritance either. But I have never missed either feature in a Rust program.

Re: Native Reflection in Rust

#46
post #33
post #5

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…

That's runtime reflection. Compile time reflection AFAIK is available in D and Zig, and is planned for C++.

That's right. Nim does as well. It's amazing. Once you get used to having CTTI and being able to use it, it's hard to program without it. Bonus points if you can do basic dependent types too.

In C++ with SFINAE you can effectively do CTTI-style programming in C++. C++ has long had runtime type reflection as well (RTTI), though it needs to be compiled in. Looks like there's a boost library for CTTI.

Re: Native Reflection in Rust

#47
post #3

Today I learn that Rust does not have reflection.

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.

This is of course only true for runtime reflection. And which language does not have a runtime?

Re: Native Reflection in Rust

#48
post #33
post #5

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…

That's runtime reflection. Compile time reflection AFAIK is available in D and Zig, and is planned for C++.

Yup. I consider runtime reflection an antifeature, which has negative performance effects, is unsafe (see e.g. log4j) and leads to fragile code.

I would however welcome static reflection with open arms. In Rust in particular, I’d prefer it if derive was implemented using static reflection, rather than proc macros.

Re: Native Reflection in Rust

#49
post #43

Can’t we rely more on Rust’s Pattern Matching and it’s strong type system? Reflection seems more helpful when the programming language is little unsounded.

Absolutely! That's the approach that frunk [0] takes. Frunk (and other reflection libraries like it) are suitable for most use cases, and make better use of Rust's affordances.

My crate is suitable for cases where you cannot know (or control) the set of types you might need to reflect on in advance. It's primary use-cases are related to debugging.

[0]: https://docs.rs/frunk

Re: Native Reflection in Rust

#50
post #49
post #43

Can’t we rely more on Rust’s Pattern Matching and it’s strong type system? Reflection seems more helpful when the programming language is little unsounded.

Absolutely! That's the approach that frunk [0] takes. Frunk (and other reflection libraries like it) are suitable for most use cases, and make better use of Rust's affordances. My crate is suitable for cases where you cannot know (or control) the set of types you might need to reflect on in advance. It's primary use-cases are related to debugging. [0]: https://docs.rs/frunk

Is Frunk Rust's Shapeless (from Scala)?
Post reply on HN