Live data from Hacker News

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

old.reddit.com

61–70 of 193 posts

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

#61

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 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 is a bigger type than a slice (&str). &’static just indicates that the string slice will live for the entire program. As you continue to learn Rust, more of these distinctions will make sense to you.

GAT’s themselves are actually a great example of a feature that adds capabilities without really adding complexity. They feel like they should have always been there, and I feel like anyone who has worked with the language for a while has implicitly tried to do this and was surprised it didn’t work.

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

#63

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…

`&` 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#... .

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

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

As a non-beginner, I feel the same way. I'm not too worried about it at the moment, but it's early in the day (and week) and DST happened yesterday, sooo...

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

#65

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 can program in Scala and Haskell relatively easily. I still struggle with Rust's lifetime abstractions and things like this:

  impl LendingIterator for Map
  where
   I: LendingIterator,
   F: for Mapper>::Item>,
  {
   type Item = dyn for GivesItem>::Item>>::Output,
   >;

   fn next(&mut self) -> Option>::Item> {
    self.iter.next().map(&mut self.mapper)
   }
  }
Haskell is so much easier.

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

#66

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…

Most things don’t need to be written in Rust. But C/C++ exist for a reason, and Rust for effectively the same reasons.

Rust looks complicated but it’s a complicated problem that’s why the solution is complicated.

If you want zero cost (e.g no GC!) abstractions and some compile time guarantees about concurrency and memory safety well then you have a complex problem requiring a complex solution.

&str is a “slice” of a string, it doesn’t own any characters it just points to someone else’s characters. String is a heap allocated string so it has its own characters.

The ‘ indicates a lifetime and “static” just means “lives forever”.

In the end, lifetimes and multiple string types is the price we pay for performance and safety. There is no world where Rust just had ergonomic strings like Java and safety/performance unaffected.

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

#67

Earlier quoted context omitted.

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/

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

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”

#68

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

> I feel like anyone who has worked with the language for a while has implicitly tried to do this and was surprised it didn’t work.

Just to lend some extra evidence to your assertion, I hit the lack of GATs within two days of starting to learn Rust. In the natural course of trying to solve a problem, I tried to write `LendingInterator`, and discovered that I could not.

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

#69

Earlier quoted context omitted.

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/

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

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”

#70
post #20

Earlier quoted context omitted.

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

The linked article talks about abstraction, and that you could abstract so much that the concrete problem doesn't fit in your abstraction. I.e., your abstraction is broken. I think that is precisely why OOP started to disappoint (tbh: I also think many people did not understand OOP really well). Haskell pushes you to compose types instead of building inheritance hierarchies. Multiple inheritance turned out to be a ba…

As with anything, it all goes well until it doesn't. When you have a single bug (e.g. type error or dynamic error), the guts of whatever is in the box spill out. Case in point: all the implicit template parameters to std:: in C++ these days. The only way to add configuration options in a backwards-compatible way was to add default values for template arguments. That's all fine and good when you can't see them, but as soon as you have a nasty type error, the types that come spilling out in error messages have zillions of default arguments that get printed.

It's almost always the same with inference. I would be very, very wary of doing so much type sophistry that it requires heavy inference to be usable.

Post reply on HN