1. 22
  1. 3

    What’s the rationale for wanting HKTs in Rust? I see a lot of people wanting to drag Rust closer to Haskell, but I don’t understand why.

    My personal opinion is that adding HKTs to Rust would further complexify Rust — which is already nearly busting its strangeness budget with the ownership system — and offer little practical value in return. The only place where we might want such flexibility is with arrays, and this is being addressed with const generics.

    1. 4

      I think HKT are one of the things that shouldn’t be missing in modern languages – it’s one of the few features where I gladly pay the complexity cost (alongside turbo-charged if-expressions to get rid of separate pattern matching constructs).

      I don’t think you can blame HKT’s for blowing up Rust’s complexity budget – they could have easily avoided earlier mistakes to not push their complexity budget to the current point. (Hello ::<>!)

      1. 4

        Turbofish is just a small syntax-level quirk. I don’t think it’s even in top 20 of complexity in Rust.

        There are much worse things, like patterns trying to be dual of expressions, which made & mean either reference or dereference depending on context (and in function and closure args, that context is hard to notice). Or the very subtle meaning of implied 'static bounds. Especially when the compiler says something has to live for a 'static lifetime, which isn’t the same thing as lifetime of a &'static reference.

        1. 0

          Turbofish is just a small syntax-level quirk.

          I like the ::<> example because it fits the “easily avoided” descriptor best.

          (Rust got it right in the beginning, then changed it to current worse “design”.)

          I don’t think it’s even in top 20 of complexity in Rust.

          Yep, but if “getting these trivial-to-get-right things wrong” gets a pass, the floodgates are pretty much open.

          A language community either decides “yes, we have a quality standard, and we enforce it” or it doesn’t; there is little in between.

          There are much worse things, like patterns trying to be dual of expressions, which made & mean either reference or dereference depending on context (and in function and closure args, that context is hard to notice). Or the very subtle meaning of implied ’static bounds. Especially when the compiler says something has to live for a ’static lifetime, which isn’t the same thing as lifetime of a &’static reference.

          Are there any write-ups that document “and this is how we should have done it properly, if we were allowed to”, because otherwise the mistake will be repeated over and over.

          1. 1

            You’ve got Turbofish entirely backwards. It is an intentional design that fixed a parsing ambiguity. C++ doesn’t have such disambiguator, and has well-documented problems with parsing < in templates vs comparisons & shifts. Rust avoided having such mistake, and it was a conscious design decision. It fixed a fundamental problem in the grammar at cost of a quirk that is just an aesthetic thing.

            Putting “design” is scare quotes makes you sound like a troll.

            1. 3

              And the turbo-fish operator does not significantly affect how people interact with the language — HKTs would.

              I used to be into Haskell and I always wanted to abstract my code more and more (for what reason, I do not know). As I’ve gotten older, I’ve gotten grumpier and more conservative in what I want out of a programming languages: I now put more value in simplicity and solutions that solve an actual problem rather than a generalization of a problem.

              My worry is that Rust will become too complex if we say yes to every proposition for a new way to create abstractions. My 27 year-old self would probably be ecstatic, but my 37 year-old self is dubious that this is desirable.

              Rust is already taking quite a gamble that programmers will accept to change the way they work with memory in exchange for safety; I would hate for that gamble to become riskier by introducing every GHC extension into Rust.

              1. 1

                I’m not sure what you are trying to argue against.

                Picking a design that does not require working around parsing ambiguities as Rust did in the beginning is vastly superior to having 4 different syntax variations for generics and pretending that’s a good thing.

        2. 1

          I like that ‘strangeness budget’ idea. I think we agree on why it would be dubious to add higher-kinded types to Rust.

          I see a lot of people wanting to drag Rust closer to Haskell, but I don’t understand why.

          I’m not advocating to make Rust more like Hakell, but the reason why I want a language “like Rust, with higher-kinded types” is because I think such a language is strictly better for building robust, maintainable software. To me, Rust is strictly better than C in the same way. I find it hard to believe that we have this all figured out after only ~70yrs of innovation.

        3. 1

          This is awesome @lightandlight!

          1. 1

            I haven’t finished the article yet, and I suspect it may end up going over my head, but I appreciate the clear explanation of the terminology in the first half of the post. I really feel like I’ve learned something. Thanks!

            1. 2

              You’re welcome, I’m glad you feel that way :)

            2. 0

              Thanks for sharing!