News for hackers. Stuff that matters.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by nicoburns on Monday November 07, 2022 @08:58AM (#33505810)
I think the easiest way to understand it is this:

Suppose you have a concrete type like

    Vec<i32>
Regular generics enable you to make the contained type generic, so you have:

    Vec<T>
where T can be i32, u32, String, etc. GATs allow you to make the container generic. So you can have:

    T<i32>
where T might be Vec, Option, Box, etc.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by brap on Monday November 07, 2022 @09:24AM (#33506108)
Thanks, this was much easier to understand than the original article. What will I use this for? Usually for the “T” to be useful it needs to have some interface. In Java I’d just use Collection<Integer> or something more abstract.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by mrkeen on Monday November 07, 2022 @10:14AM (#33506834)
T keeps its type info statically. So if you put a Set in, you can get a Set out.

Casting to Collection loses the static type info, so you couldn't write foo(bar(set)) if bar returned a Collection but foo accepted a Set.

Re:Rust: “Explain GATs Like I'm 5 Years Old” by orblivion on Monday November 07, 2022 @10:32AM (#33507080)
I forget what exactly a GADT is (even though I've used Haskell a bit before). But just going by the linked example from Reddit, you could make a generic `map` function that worked on any container type. You'd have to implement the map function separately for each type. But then you could make a bunch of utility functions that you'd implement once that use the generic `map` under the hood, and all of those container types would be able to use those utility functions.

Not a Rust guy but I think that's the idea.

Re:Rust: “Explain GATs Like I'm 5 Years Old” by kibwen on Monday November 07, 2022 @10:45AM (#33507292)
Just so that we're clear on acronyms for everyone out there, "GADT" is a computer science term for "generalized algebraic data type", which has no relation to "GAT", which is just Rust terminology for generics in associated types (even in Rust, I doubt that anyone will bother to refer to "GAT" in the coming years, rather than just lumping them in with the concept of associated types in general; there's really no need to teach them separately).
Re:Rust: “Explain GATs Like I'm 5 Years Old” by ghostwriter on Monday November 07, 2022 @06:11PM (#33513852)
> you could make a generic `map` function that worked on any container type.

not only container types, it can be any type that has a consistent context of evaluation for the final value being calculated: "doing async IO", "doing optional presence", "doing potentially erroneous extraction", and so on. In that sense, "doing multiplicity of values" is the context expressing a container type you mentioned as an example.

Re:Rust: “Explain GATs Like I'm 5 Years Old” by philzook on Monday November 07, 2022 @09:22AM (#33506082)
What you're describing sounds to me like higher kinded types, which are of some relationship to GATs (GATs enable a better encoding of higher kinded types as I understand it), but are not GATs. https://docs.rs/higher/latest/higher/
Re:Rust: “Explain GATs Like I'm 5 Years Old” by gunapologist99 on Monday November 07, 2022 @09:32AM (#33506222)
> as I understand it

You could be 100% right (I have no idea, but it sounds reasonable), but this entire question really hits home that Rust has tons of basically incomprehensible design features.

The worst part about features like this are that a few smart people will actually use them (whether because they're powerful features, or just because they feel powerful when using them), and then render their code incomprehensible to the mere mortals who have to support their code in the future.

The KISS principle (https://en.wikipedia.org//wiki/KISS_principle) is sometimes ignored because people don't want to be stupid, and why wouldn't you want to use a new toy(tool) once you've figured it out?

Re:Rust: “Explain GATs Like I'm 5 Years Old” by kibwen on Monday November 07, 2022 @09:46AM (#33506410)
This is quite uncharitable. Rust's features aren't there for no reason, they're there to address the hard problems of how to achieve C++-level performance while providing the level of abstraction that modern developers expect and remaining totally type-safe.

Furthermore, the amount of hand-wringing over this feature is disproportionate to its actual impact. It feels like people see "Haskell" mentioned in the same breath and immediately lose all sense of reason. This feature is not basically incomprehensible, it's a straightforward addition that allows generics to be used with associated types, both of which are features that already exist in the language.

If you're asking yourself, "when would I ever need to use these?", this answer is that you may never find call to use these. Traits are mechanisms for creating abstractions, which are mostly relevant to library authors. If you're not a library author, you may never have a good reason to write a trait. Even for people who are writing traits, they may have no reason to ever use associated types. And even for people who are writing traits with associated types, they may have no reason to ever want to use generics with those associated types.

However, all of these features are extremely useful for the people consuming libraries, and far from making Rust code more complicated, from what I've seen so far it makes Rust code in the wild less complicated.

Re:Rust: “Explain GATs Like I'm 5 Years Old” by soggybutter on Monday November 07, 2022 @09:47AM (#33506428)
Things like GATs also allow those smart people to add sorely needed features, like async traits, which the rest of us plebeians can benefit greatly from
Re:Rust: “Explain GATs Like I'm 5 Years Old” by philzook on Monday November 07, 2022 @10:45AM (#33507294)
The problem is people who are smart enough to use fancy features, but not wise enough to show restraint.

The question is do we inhibit the wise to protect us from the unwise? The answer might be yes. I enjoy learning about power features so I hope not.

Re:Rust: “Explain GATs Like I'm 5 Years Old” by inatreecrown2 on Monday November 07, 2022 @09:26AM (#33506142)
this sounds almost too easy to understand, will have to check with the documentation. (thank you!)
Re:Rust: “Explain GATs Like I'm 5 Years Old” by insanitybit on Monday November 07, 2022 @11:23AM (#33507884)
I think 90% of the reason why people have a hard time with GAT is because there aren't a ton of use cases. From what I can tell, GAT is quite simple - it is just like all other Rust generics except that now the generic can be in a new place.

Rust has made it years without needing this (granted, a few things have been less than ideal because of it) because, for the most part, people have not needed to reach for this type of abstraction. But it's really just "Generics in a new place".

Personally, I've accidentally written the GAT syntax years before I ever heard the term GAT because I thought a generic could go there.

Re:Rust: “Explain GATs Like I'm 5 Years Old” by Jweb_Guru on Monday November 07, 2022 @12:02PM (#33508580)
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 Rust code. Also, in a lot of cases where people would otherwise use GATs, people instead work around them by making traits generic and have super complicated towers of generic types, you've probably seen interfaces like this when using hyper for instance. GATs would simplify most of those interfaces.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by insanitybit on Monday November 07, 2022 @01:41PM (#33510182)
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". 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 Hyper, which prioritize being extremely generic (it's split into a ton of reusable crates), which aims to serve as a very low level set of generic primitives for HTTP, yes it will come up.

Hyper is a great example of a use case that 99.99% of developers are not going to be able to relate to because they aren't building a set of completely generic http primitives. It's an important use case, it's just not relatable.

Re:Rust: “Explain GATs Like I'm 5 Years Old” by Jweb_Guru on Tuesday November 08, 2022 @01:09AM (#33516362)
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” by fallat on Monday November 07, 2022 @09:22AM (#33506078)
THIS is literally the best explanation. My god people have forgotten how to explain anything anymore. Thank you.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by agluszak on Monday November 07, 2022 @09:28AM (#33506163)
It is easy to understand because it is an oversimplification :)
Re:Rust: “Explain GATs Like I'm 5 Years Old” by jstx1 on Monday November 07, 2022 @09:35AM (#33506259)
Which part is inaccurate/incomplete?
Re:Rust: “Explain GATs Like I'm 5 Years Old” by GolDDranks on Monday November 07, 2022 @10:14AM (#33506836)
The part that says `T<i32>`. GATs don't allow you to do that, not directly. GATs allow you, as said by Boats in https://news.ycombinator.com/item?id=33506540, have a generic type as an associated type, nothing less, nothing more. If you want to express `T<i32>`, GATs _enables_ you to do that as a kind of a distorted encoding, but it's not as simple as https://news.ycombinator.com/item?id=33505810 makes it seem.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by howinteresting on Monday November 07, 2022 @10:54AM (#33507437)
Bring able to abstract over Rc/RefCell and Arc/Mutex with marker types seems pretty useful. It's not directly HKT but it enables use cases that would otherwise be supported by HKT.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by dllthomas on Monday November 07, 2022 @12:03PM (#33508603)
Yes, but that doesn't make it somehow accurate to explain HKT and pretend you're explaining GAT...
Re:Rust: “Explain GATs Like I'm 5 Years Old” by howinteresting on Monday November 07, 2022 @12:16PM (#33508811)
That is definitely true.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by gpderetta on Monday November 07, 2022 @10:16AM (#33506857)
The Associated bit of GAT I guess.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by aarobot on Monday November 07, 2022 @09:20AM (#33506049)
Awesome example.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by howinteresting on Monday November 07, 2022 @10:56AM (#33507474)
Note that this isn't directly what GATs are, but you can use marker types to achieve this effect.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by dllthomas on Monday November 07, 2022 @01:12PM (#33509691)
The ability to just use T for Vec, Box, etc, anywhere you might want to is "higher kinded types" - GATs only allow it specifically for "associated types" on a trait.
Re:Rust: “Explain GATs Like I'm 5 Years Old” by johnmc408 on Tuesday November 08, 2022 @11:54AM (#33521202)
awesome and simple!!!