Live data from Hacker News

Rust: “Explain GATs Like I'm 5 Years Old”

old.reddit.com

181–190 of 193 posts

Re: Rust: “Explain GATs Like I'm 5 Years Old”

#181

Is there any way to use GATs to achieve a particular use case of ah-hoc/anonymous enums[0]? Say if library L1 returns enum A|B, L2 operates on enum A|B, and main wants to pass enum A|B from L1 to L2, with the kicker being A, B are concrete in main. I'm not interested in distinguishing between multiple appearances of the same type as in the RFC example, so rather like: let foo: (~str|int) = (_|666); match foo { (s: st…

You might be interested in Rust's either crate (not built-in): https://docs.rs/either/latest/either/

Yes, thank you that should work since both libs L1, L2 and main can all refer to Either.

This parallels a similar solution to the nominal sum types I ended up making for Java (Either, Option3, etc) with these generic types in a common shared library and other libraries and consumers of both accessing the shared type.

One more question: In Rust is Either type-erased, specializations generated, or something else?

Re: Rust: “Explain GATs Like I'm 5 Years Old”

#182

The top Reddit example is tremendous. I'm passed being a Rust beginner, but I have a note to the Rust community: Your official examples are overcomplicated and bad and you should also feel a little bad. Stick to things like apple, orange, pear and you'll see much easier adoption than if you go with something like LendingIterator! Through the GAT process all I have seen is the same hyper-specific example used that con…

Android devs are having flashbacks to Thermosiphons

Re: Rust: “Explain GATs Like I'm 5 Years Old”

#183

Earlier quoted context omitted.

It's needed for a lot of features people desperately want. Async functions in traits, closures that return futures where you need to run the future in a loop, and array indexing that doesn't necessarily return a reference, are three examples of things that essentially need GATs in order to be implemented without allocating. You may not feel like you missed it but not having that leads to a ton of ugly workarounds in…

The vast majority of users do not desperately want async functions in traits, they just use async_trait and go "it'll be cool when GATs are done". Besides, no one is going to use GAT for async traits, that will be done for them by the compiler. Obviously there are use cases for GAT, what I'm saying is that they're going to be in very generic library code, which I don't think most users are writing. For libraries like…

I know people who refuse to use async_trait for documentation reasons alone. The macro-based solutions aren't always pleasant to use and often come with a lot of weird tradeoffs. And yeah, I agree that most users don't need to write theme explicitly--I'm arguing that users are currently significantly impacted by the lack of them, even if they are never in a position where they'd consider writing them themselves, because it prevents library authors from writing precise APIs. For example, you might not be wanting to write GATs like the Hyper authors, but anyone using Hyper for anything nontrivial (and that's surprisingly common, IME) is certainly negatively impacted by the massive complexity caused by needing to work around their absence.

Re: Rust: “Explain GATs Like I'm 5 Years Old”

#184

I feel like they are making languages too complicated. Most projects should just be garbage collected, most don't need to deal with pointers or anything advanced. We need variables, functions, conditionals, loops, exception handling, struts, and a library with a bunch of standard utilities (including simple I/O and string managment). Everything else should be optional and kept out of sight unless you are looking for…

Garbage Collection is extremely complicated. It is a whole other program running to manage your memory using extremely complex, hyper optimized algorithms that have lots of best and worst case scenarios depending on which one you use. GC implementations can very easily make code confusing. Consider `finalize` in Java - a destructor that gets called at a completely indeterminate period of time, making it a very confus…

That is why finalize is deprecated for removal, and will eventually be dropped from Java.

https://openjdk.org/jeps/421

One is supposed to use try-with-resources, determinist resource management, or cleaner types.

Re: Rust: “Explain GATs Like I'm 5 Years Old”

#185

Earlier quoted context omitted.

Not trying to make you feel like you have failed, but whenever I encounter language features on this level - aka not comprehensible for a mortal like myself - I do tend to want to shamefully turn away from this profession entirely. The good news is that I am most likely a total dunce. I wish I could become reasonable with rust because I do like the concepts that I think I grasp.

You're begging the question when you say that GATs are "not comprehensible for a mortal like myself." My entire point is that they were designed not to be incomprehensible. What is "not comprehensible for a mortal" in this situation is why adding a generic to an associated type is a long-anticipated feature that took years of development to support. This is related to the "incomprehensible" discussion that occurs aro…

To be super clear I'm not trying to disparage you at all. I am just saying that I might not be cut out for understanding these complexities and ... honestly it deeply frustrates me, but I don't know how to overcome it.

Re: Rust: “Explain GATs Like I'm 5 Years Old”

#186

Earlier quoted context omitted.

Not trying to make you feel like you have failed, but whenever I encounter language features on this level - aka not comprehensible for a mortal like myself - I do tend to want to shamefully turn away from this profession entirely. The good news is that I am most likely a total dunce. I wish I could become reasonable with rust because I do like the concepts that I think I grasp.

Traits can have associated types. trait Foo { type Bar; } Until now, those types had to be concrete, as in the above example. You can implement Foo with `Bar = u32` and `Bar = String` and even `Bar = Vec `. trait Foo { type Bar ; } That `Bar` type above can now be generic over some other type `T` so you can implement it for `Bar = Vec `, `Bar = Result `, `Bar = Option `, and any other generic type. That's it. That's…

Is that what this is all about? I feel like the examples people give are nowhere near this simple.

Re: Rust: “Explain GATs Like I'm 5 Years Old”

#187

Earlier quoted context omitted.

I hope you don't. To establish my credentials for this comment - GATs were my idea. The entire point of GATs was to carve out a design space that solved peoples' problems without being so high-minded as monads and HKT and so on. Unfortunately, a lot of people who like monads like to talk about GATs in the same way. But its really as simple as this: when you add an associated type to a trait, you can make that type ge…

> The entire point of GATs was to carve out a design space that solved peoples' problems without being so high-minded as monads and HKT and so on. High-minded or snobbish or whatever other deragotory words that one wants to use: the benefit of something like HKT is that it encompasses one thing that Rust now currently ends up catching up to by implementing dozens of “X with Y” (“generic const in associated lifetimes…

> Meanwhile a Haskell programmer might go years and never think about HKT as a feature. It’s just “kinds” without artificial-looking limitations.

And yet, at the same time, Haskell has many, many extensions to enable certain features that would come for free in a dependently typed language, for example. I find Idris's type system easier to fit in my head, for example.

There's always a next level of generality in which previously complicated concepts can be expressed more simply, but there are also sometimes reasons not to want to reach that level of abstraction, for various reasons.

(Although in principle, I agree. I don't find the concept of HKTs particularly complicated per se.)

Re: Rust: “Explain GATs Like I'm 5 Years Old”

#189

Earlier quoted context omitted.

Traits can have associated types. trait Foo { type Bar; } Until now, those types had to be concrete, as in the above example. You can implement Foo with `Bar = u32` and `Bar = String` and even `Bar = Vec `. trait Foo { type Bar ; } That `Bar` type above can now be generic over some other type `T` so you can implement it for `Bar = Vec `, `Bar = Result `, `Bar = Option `, and any other generic type. That's it. That's…

Is that what this is all about? I feel like the examples people give are nowhere near this simple.

Yep.

People are trying to show how you might use it in practice, which is useful. But I think people should start with the above.

If you’ve ever used associated types, this is the sort of thing you would probably expect would be possible even if you never needed to do it. Now it’s possible.

Re: Rust: “Explain GATs Like I'm 5 Years Old”

#190

I'm filing this one along with Monads and Haskell as programming concepts that I'll never understand. Rust is my favorite language, but that explanation, lauded directly below it as This is personally the easiest to understand example I've seen of GATs. , was incomprehensible.

I think the easiest way to understand it is this: Suppose you have a concrete type like Vec Regular generics enable you to make the contained type generic, so you have: Vec where T can be i32, u32, String, etc. GATs allow you to make the container generic. So you can have: T where T might be Vec, Option, Box, etc.

awesome and simple!!!
Post reply on HN