Live data from Hacker News

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

old.reddit.com

161–170 of 193 posts

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

#161

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 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 positions”… to use a made up feature) that are just about lifting limitations, and that end up sounding “complicated” and “featureful” (kitchen sink accusations) to anyone who isn’t knee deep in building an async runtime library or whatever.

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

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

#162
post #158
post #146

Earlier quoted context omitted.

The only thing similar about them is the acronym: GATs are generic type aliases which are defined inside traits. GADTs are generic sum types with extra constraints on which variants may be used with which type arguments. There is no reasonable way in which they are "quite similar," nor do either of them have anything at all to do with affine types.

Where is the type theory for Rust's GATs for us to educate ourselves?

The RFC might be a good place to start: https://rust-lang.github.io/rfcs/1598-generic_associated_typ...

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

#163

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…

> I feel like they are making languages too complicated.

Perhaps. But this topic is not a natural springboard for that topic since GATs are about lifting a current restriction in Rust. So you have the same features as yesterday, but with one less (arbitrary-looking) restriction.

Maybe it makes the language more complicated to implement (?) but it doesn’t make it more complicated for the language user.

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

#164
post #155

Earlier quoted context omitted.

I will agree with you that most languages should just be gc. Rust is niche; targeted at applications where you need control over memory and layout. It is not a good general purpose language. That being said, most of things you pointed out as “no reason to be this complex” do have good reasons. String and &str could be renamed to StringBuf and StringSlice. The String type lets you manipulate the string value, but it i…

> without really adding complexity Pretty sure many relevant contributors have said it is the most complex language feature since async ..

certainly complex from a implementation standpoint, and some of the rough edges can be a footgun around lifetimes until those are ironed out. But being able to add generic arguments to associated types is just a natural extension of the language from a user standpoint. You could already add generic arguments to functions, structs, type aliases, enums, etc. This just allows it in one more place.

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

#165

Earlier quoted context omitted.

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…

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 first language since I took a course at a local community college).

Compare that to c, `int main()`

That's a lot less in my face for sure.

But if I were used to Python? I'd just write my code directly in the file and it would execute from top to bottom. WTF is this `int` and `main` ???

In Java you have int and Integer, and Integer can be this "null" thing? I just wanted to add 2 and 2 wtf??

Generics? `class Foo` ? WTF is ``?

The point is that what you have to learn when you first use the language is really going to depend on what you learned before it. I don't consider that complexity, it's just new.

The thing is that there is no language that you're likely to have used before that will prepare you for some bits of Rust.

2. Rust could be easier. It would be cool if there were a way for beginners to think less about the differences between String and &'a str and &'static str. At the same time, abstracting over those would have its own downsides - if you learn about strings in Rust in a way that abstracts that all out, will you understand the underlying components and how the abstraction works? It's tough.

I think the reality is that Rust is just not going to be as easy to learn as the same exact language but where lifetimes are managed at runtime. It probably shouldn't even try too hard to be that easy, because being that easy has costs, and there's a limit to how much you should optimize for newcomers. Rust has balanced things pretty well so far there - 2018 brought a lot of ergonomics wins that I frankly don't care for very much or even just forget about, but it helped tons of people pick the language up.

All this is to say, I think there's truth to what you're saying but I also think you may be attributing some issues to complexity where I believe it's an issue of familiarity.

I appreciate your opinion on this though, I do always find it so interesting to hear about how others view complexity and programming languages (when they're constructive about it).

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

#166

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.

Really? You don't see the problem with trying to maintain code that's been copy-pasted everywhere with slight differences? Doesn't it seem easier to maintain one implementation of something than N implementations?

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

#167
post #149

Earlier quoted context omitted.

Even if the use cases outside the standard library were weak, given that the work needs to be done anyway for the standard library, why wouldn't you expose them?

To be clear, there are not use cases in the std lib. The use case is as an intermediate representation for the compiler, and that is no motivation for inclusion in the language (in the same way that we don't have vtables or register allocation in the surface syntax)

Being able to have a generic "Mappable" trait seems like a good use case for the standard library. It's something I've wanted in the past, and was disappointed that it didn't exist.

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

#168
post #20

Earlier quoted context omitted.

Rust getting more of Haskell's type system features is a good thing. The stronger your type system is, the more mistakes you can discover as compiler errors instead of runtime bugs.

> The stronger your type system is... I used to think a stronger and stronger type system was a universal good, then I got experience with code written by architecture astronauts[1] armed with such type systems. Knowing exactly which kinds of things to make impossible at compile time and which not is absolutely an art form. Unfortunately, such type systems seem to result in so many nightmares. https://www.joelonsoftw…

An architecture astronauts in Java just use code generation and runtime reflection, which are bigger nightmares than type system features.

Architecture astronauts are going to be a problem regardless of language features.

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

#169
post #86

Earlier quoted context omitted.

It's also possible to have `&str`s with smaller lifetimes than `'static`, in which case you will have a different lifetime specifier there.

Ah, so this probably tells the compiler where to insert the free? If I gave it a local lifetime it would free the memory on function return for example, even if I tried to return a reference to it? Basically Rust just forces you to code in the memory freeing at the definition state of variable creation?

Not quite. Lifetime annotations prevent you from accidentally using references after the value they refer to has been freed. They track how long things will live, instead of defining how long they will live.

Basically they turn use-after-free errors into compile errors.

(I'm using 'free' here to mean cleaned up in general. Lifetimes can track stack values.)

Post reply on HN