Live data from Hacker News

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

old.reddit.com

171–180 of 193 posts

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

#171

Earlier quoted context omitted.

I did want to say Rust was complicated, I meant to say it was complicated to learn. You never need to learn the Java syntax finalize, it is invisible until you have a problem where that is the solution. Similar to Java templates or overloading they dont exist until they are the solution to a problem you are having. My critique is that Rust appears (and I am probably wrong) to have a problem where syntax for complicat…

> syntax for complicated language features appear in the simplest code IDK, I hear you but I'm of two minds. 1. I think a lot of this is familiarity. `public static void main(string[] args)` That's a lot of stuff that I don't actually really need to care about but is in every single Java program. It even has 'static', which is honestly something I found very very confusing when I first learned Java (technically my fi…

Highly agree with #1. I think it really does come down to familiarity. I've learned all the languages you listed and every time there was something that was confusing only to then be cleared up the more I use it.

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

#172
post #87

Earlier quoted context omitted.

> you want to abstract over it. What does that mean? Any example you could point to?

Are you familiar with flat_map? It's the ability to take, for example, an iterator, then map over each element which itself can return an iterator. Similarly, you have Option::and_then, which takes a callback that takes T and returns an Option . Or Result::and_then. "Monad" is simply the umbrella term for all flat_maps, and things like it, in existence. Why would you want to abstract over it? For one, it's a surprisi…

By the way, as a simple example of what I mean when I say that monads are the least constrained form of sequencing: flat_map is strictly more general than map. In Rust, if an iterator I implements ExactSizeIterator, then Map implements ExactSizeIterator:

https://doc.rust-lang.org/std/iter/struct.Map.html#impl-Exac...

However, there is no such implementation for FlatMap:

https://doc.rust-lang.org/std/iter/struct.FlatMap.html

This intuitively makes sense! If a single input can generate zero, one or more than one outputs, then there's no way to know the exact size of it.

The simple map is more constrained -- it has to generate exactly one value -- which means that it can support more operations. The monad-like flat_map is less constrained, and it can do more, which means that it can't support as many operations. There's a catchphrase in the programming language community to describe this sort of thing: "constraints liberate, liberties constrain".

This can make a huge difference in production systems. For example, if you have a distributed system that walks over an execution graph, and nodes in the graph can create new nodes (flat_map/monad-like), the properties of your system are very different from if nodes can't do that.

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

#173

Earlier quoted context omitted.

`&` and `'` do mean something: `&` indicates something that's borrowed, and `'` indicates a lifetime. (`static` is a specifically blessed identifier given to a certain lifetime.) This is explained in https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#... , and the static lifetime is explained in https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#... .

It looks like I will just have to bite the bullet and actually read the rust book back to front. I find static particularly confusing because of the seemingly contradictory meanings that are all jumbled up in my head. The English meaning of immutable, the Java meaning of instance agnostic, and this Rust meaning of immortal lifetime.

> It looks like I will just have to bite the bullet and actually read the rust book back to front.

I mean, there you have it, right? Not a diss on you specifically, but I've often noticed that some people will complain about something, but then it comes out that they actually haven't learned it deeply enough, they're just going on what they either learned so far, learned that something in a haphazard way, or didn't learn it at all.

I used to do the same, so no shame, starting off writing programs as practice and googling things along the way because everyone on any programming thread says "the best way to learn is by building, not doing tutorials" but that's not necessarily true. Sure, I have learned a lot by building, but I've often spent longer simply running around googling and learning bits and pieces than the time I'd spend actually learning something top to bottom, front to back, from scratch. So I actually like and see the value of tutorials now.

Once I read The Rust Book front to back like you said, I understood a lot more of the language than my previous attempts to learn it a few years ago. Doing Rustlings at the same time was great too.

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

#174

Earlier quoted context omitted.

Basically, before this you couldn't have generic types in traits, like this: trait X { type Y ; } You couldn't express "a thing that contains another thing" in one of those type expressions before, and also use the contained type. It's needed for Mappable, because it's an abstraction over the concept of modifying a value inside a container. IMO the implementation that they have is a bit obtuse, but I don't know if yo…

I really wonder about the usefulness of implementing a language feature to reduce the need to copy paste in an editor.

Isn't that basically all language features? I could also write

    print("Hello")

    print("Hello2")

    print("Hello3")

    print("Hello4")

    print("Hello5")
(which I partially copy-pasted above) but I use a for-loop instead.

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

#175

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…

Before writing a completely asinine comment like this, you might consider that I, having been paid real American dollars to design this language, might know more than you about the relationship between GATs and HKTs and the design of Rust as a whole. Your comment evinces a total ignorance of the type theoretical issues that actually informed our decision on this issue.

Fortunately, Niko Matsakis blogged about our design discussions at the time. You can read more here and in the linked predecessor posts (at the time we were calling GATs "ATCs") https://smallcultfollowing.com/babysteps/blog/2016/11/04/ass...

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

#176

Earlier quoted context omitted.

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

Before writing a completely asinine comment like this, you might consider that I, having been paid real American dollars to design this language, might know more than you about the relationship between GATs and HKTs and the design of Rust as a whole. Your comment evinces a total ignorance of the type theoretical issues that actually informed our decision on this issue. Fortunately, Niko Matsakis blogged about our des…

Yes, your attitude (shall we say) was apparent from the start.

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

#177
post #2

As a beginner (having finished the book and not much more) the example in the top comment is very difficult to parse and hold in my head. At a glance I have no idea what we're doing and why.

It is totally ok to not understand stuff, and it's totally ok to not want to learn it as long as you don't need it.

Rust is a language with plenty of things to learn, some of which take some time to get used to. And often, having a concrete need for something makes it easier to learn the associated technique.

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

#178

Earlier quoted context omitted.

Basically, before this you couldn't have generic types in traits, like this: trait X { type Y ; } You couldn't express "a thing that contains another thing" in one of those type expressions before, and also use the contained type. It's needed for Mappable, because it's an abstraction over the concept of modifying a value inside a container. IMO the implementation that they have is a bit obtuse, but I don't know if yo…

I really wonder about the usefulness of implementing a language feature to reduce the need to copy paste in an editor.

As a library maintainer, you can't copy-paste a line for a type that isn't written yet.

As a library user, you can't copy-paste a line for a type you just created in a library you don't maintain.

Being able to do what you describe lets a maintainer create an interface for all the future types that satisfy given requirements.

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

#179

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…

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 the whole thing. Use it if it's useful to you.

If you've never needed to write a trait that incorporated an associated type (.AT) which needed to be generic (G..), then this won't mean much to you and that's fine. But you might be using libraries that could be somewhat more ergonomic if they were able to use this feature. The good news is that now that it's been released to stable, a future version of that library can be written more ergonomically.

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

#180
post #52

Earlier quoted context omitted.

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 or something more abstract.

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

> 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.

Post reply on HN