Live data from Hacker News

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

old.reddit.com

71–80 of 193 posts

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

#71

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 still haven't fully figured out how lifetimes work.

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

#72
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 confuses the hell out of people that just need the "Hello World" version.

If you want, I will volunteer to be the test subject "dumb" Rust programmer to vet the quality of future examples.

Tangentially related - here's a WASM example that goes from "Hello World" to Conway's Game of Life (I shit you not, that's actually how the tutorial progresses):

https://rustwasm.github.io/docs/book/

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

#74
post #35

Earlier quoted context omitted.

You mention that you use Rust. In that case, you're almost certainly familiar with generics, and you're likely familiar with associated types. If you've ever found yourself struggling to write an associated type that needed a generic parameter, this feature is for you. And if you haven't ever needed to do such a thing, that's totally fine, and you can happily ignore it and content yourself with benefiting from librar…

I've yet to figure out why to use associated types instead of generic parameters, and every time I've seen an explanation I nod my head in confusion and carry on.

You can view generic parameters as "inputs", they are controlled by the consumer of the type/trait (you construct a `Vec` because you want to store a bunch of `String` values).

Associated types are "outputs", they are controlled by the impl (` as IntoIterator>::into_iter()` will always return a `std::vec::IntoIter`, because that is how the trait is implemented for `Vec`).

You can often use generic parameters for "outputs" as well (you could have a world where you had `impl IntoIterator> for Vec`). However, this prevents the compiler from inferring the "output" type since there is no longer a guarantee that it is unique for a given set of "inputs".

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

#75

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…

Explicit knowledge if variable is copy/clone or reference is useful also in GC context if the variable is mutable.

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

#76

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 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 generic, the same way you can make a type alias generic when its not in a trait. The whole point of specifying GATs and not a more general "HKT" is that it's an obvious extension of the existing language.

There are lots of useful traits that you can't define if you can't make an associated type generic, so people are excited to have this feature.

It turned out that implementing this in rustc took a very long time, because refactoring the typechecker of rustc to support this was challenging. But that doesn't mean the feature itself is complicated or difficult to use. The whole point of GATs is that it shouldn't really feel like a feature once it's done: naturally, if you are writing a trait with a method that returns `Self::Foo`, but you need it to be `Self::Foo` or `Self::Foo`, you can just do that, rather than the compiler telling you that it's not supported.

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

#77
post #35

Earlier quoted context omitted.

You mention that you use Rust. In that case, you're almost certainly familiar with generics, and you're likely familiar with associated types. If you've ever found yourself struggling to write an associated type that needed a generic parameter, this feature is for you. And if you haven't ever needed to do such a thing, that's totally fine, and you can happily ignore it and content yourself with benefiting from librar…

I've yet to figure out why to use associated types instead of generic parameters, and every time I've seen an explanation I nod my head in confusion and carry on.

Associated types serve much the same role as generic parameters in the context of traits, but with the crucial distinction that associated types are specified by the person implementing the trait for their type, whereas generic parameters are specified by the person calling the methods defined by the trait.

In practice you could basically just have generic parameters and not bother with associated types, but it would be much less nice to use these APIs.

Here's an example of how an API would change if Rust didn't have associated types:

    let x = [1,2,3]; // an array of i32
    let mut y = x.iter(); // an iterator over it
    y.next(); // pull an item from the iterator
If Rust didn't have associated types, then that last line would have to look like this:

    y.next::(); // if Rust didn't have associated types

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

#78

I'm not familiar with Rust, but this seems pretty similar to how C# handles generics. Am I misunderstanding?

C# does already allow you to create interfaces whose methods are generic, yes. The way they are implemented is entirely different: Rust monomorphises all generically-typed functions (I believe this remains true for GATs), whereas the CLR monomorphises only struct-generics (and it uses the JIT to do so, unless you're using the fairly new AOT compilation).

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

#79
post #35

Earlier quoted context omitted.

You mention that you use Rust. In that case, you're almost certainly familiar with generics, and you're likely familiar with associated types. If you've ever found yourself struggling to write an associated type that needed a generic parameter, this feature is for you. And if you haven't ever needed to do such a thing, that's totally fine, and you can happily ignore it and content yourself with benefiting from librar…

I've yet to figure out why to use associated types instead of generic parameters, and every time I've seen an explanation I nod my head in confusion and carry on.

The Rust book has a pretty good explanation of the difference. https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

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

#80
post #26

Earlier quoted context omitted.

Actually I find C++ concepts much easier to grasp than GATs. Zig still has to win the love of the giants that ship C++, and increasingly Rust, in their products.

Aren't GATs equivalent to nested template classes? I.e. they are really orthogonal to concepts.

Might be a bit of job deformation, knowing C++ since 1993, and I still need to get myself used to those patterns.

Maybe I should delve again into GADTs in OCaml, before having a second look.

Post reply on HN