5 ms·
I used to say that what is a library in Haskell is a language feature in most other languages. Now I see what is library in Haskell is a "Project Group" in Rust
by thesz 6y ago
I used to say that what is a library in Haskell is a language feature in most other languages. Now I see what is library in Haskell is a "Project Group" in Rust. Rust is much further than most other languages here.
Joking aside, why did Rust not adopted type constructors for a start?
Having "Error Exception Int" would not let you ignore the error when you try to get that Int. Having "TChan x -> STM x" would not let you perform channel reading outside of transaction with that channel. Monadic binding will not let you mix Error and STM computations easily while preserving sequentiality of code.
Even Kotlin got that, for all PL theory sake. The language that is very close to Java. I cannot see why Rust can't.
PS
And things from this comment [1] would be very much explainable through "follow the types".
[1] https://news.ycombinator.com/item?id=24526604 https://news.ycombinator.com/item?id=24526604
- steveklabnik 6y ago> Now I see what is library in Haskell is a "Project Group" in Rust. Sort of, a "project group" is a means for organizing people to help accomplish tasks in the language. (or other parts of the project in general, this group is under the libs team, which maintains the standard library) > Joking aside, why did Rust not adopted type constructors for a start? It is not trivial to adopt advanced type system features in a language like Rust, and we have been working on getting to this point. It just takes a lot of time. Associated type constructors are called "generic associated types" in Rust, and are desired, and being worked on, it takes non-trivial effort. Higher kinded types are less clear. Monadic binding even less clear than that.
- comex 6y agoIs the parent actually talking about associated type constructors? This: > Having "Error Exception Int" would not let you ignore the error when you try to get that Int. just sounds like a description of Result, which of course Rust already has.
- steveklabnik 6y agoNo, I believe that they are talking about higher kinded types, but I was trying to discuss all of our movement in this general direction. ATC gives you a certain amount of what you want out of HKT, in a Rust context, anyway. > just sounds like a description of Result, which of course Rust already has. That would be "Either Exception Int", I believe they were talking about Control.Monad.Error. But maybe you are right!
- thesz 6y agoNo, I was talking about type constructors. Haskell's Functor class sets typechecking constraints on something that can contain different types but not a realisable type in itself: class Functor f where fmap :: (a -> b) -> f a -> f b Here, "f a" is a type, for example, list or maybe or "Map key a". But constraint is on "f", a type constructor variable (an application of type "a" to a type constructor "f" gives you a type "f a": Int is a type, List is a type constructor and List Int is a list of integers). The same goes to monads - they are type constructors (can hold different types) with a class constraint (must implement two or three functions). I think you cannot write something like that in Rust: f :: Monad m => m Int -> m Int -> M String f getA getB = do { a <- getA; b <- getB; return (show (a+b))} this code will work over Result, Maybe, List, IO, STM and many other things.
- comex 6y agoSo you're talking about the ability to have type constructors as generic parameters, a feature usually referred to as "higher-kinded types". Indeed, Rust cannot do this yet, although it will be able to do something like it (but uglier) soon using associated type constructors (something like Haskell's type families). However, I doubt this will have much impact on error handling. For example, from your earlier post: > PS And things from this comment [1] would be very much explainable through "follow the types". > [1] https://news.ycombinator.com/item?id=24526604 https://news.ycombinator.com/item?id=24526604 They already are explainable that way. I went through and mapped the bullets there to the actual language/library features being explained in the corresponding blog post: - A method on Result - A method on Result - A method on Result - The ? operator - Existential (boxed) types - The Any trait - API design tips - How to create an ADT and implement some traits for it - The ? operator uses the From trait - Pattern matching on ADTs In short, most of it is explaining either standard library functionality, or general-purpose language features as applied to the error-handling use case. The exception is the one language feature specific to error handling, the ? operator.
- thesz 6y agoHave you tried to express what Rust has with Haskell type system? E.g., to embed Rust into Haskell? There were some attempts to do so, for example, [1] and associated code at [2]. [1] http://web.engr.oregonstate.edu/~walkiner/student-theses/mcgirr-18-ms-project.pdf http://web.engr.oregonstate.edu/~walkiner/student-theses/mcg... [2] https://github.com/lambda-land/OwnershipMonad https://github.com/lambda-land/OwnershipMonad I actually am slightly sad that Mozilla started Rust effort instead of embedding what they wanted/needed to do into some proof assistant or Haskell.
- Ericson2314 6y agoConsidering the state of "linear Haskell", and the difficulties in working on GHC (which didn't have CI at the time), I don't really blame them. I would actually like GHC be a Rust compiler too. I think that would force it to be more modular, and if it's more modular and has more incremental CI, we'll get a lot of productivity and such a thing would actually be practical. So just gotta find a way to unwind the causality loop they (probably modularity for modularity's sake.)
- thesz 6y agoI keep saying that one can embed his language of choice into Haskell and get whatever one needs. Including, but not limited to, LLVM and other backends. Linear Haskell is a disgrace, glad you asked. It can be implemented as a library, as usual [1], and the process of inputting that linear logic into compiler I see as political, not technical. [1] https://jpaykin.github.io/papers/pz_linearity_monad_2017.pdf https://jpaykin.github.io/papers/pz_linearity_monad_2017.pdf Compiler (ghc) can recognize what code that monad from [1] produces and apply transformations accordingly. The bonus here? That recognition process can accidentally optimize parts of program that do not use linear monad at all but happen to have same structure and same satisfied constraints. About fifteen-twenty years ago I tried to invent a linear programming language or add that to Haskell. And it was not pretty. Linearity pops where you clearly don't want it to be, preventing clear explanation of ideas and/or requiring several types for innocent expression (there's no possibility of most general type in some variants of linear logic).
- 6y ago
- Ericson2314 6y agoActually higher kinded types are easier than "generic associated types". All things associated type related play less nice with type inference, and in fact Haskell's associated types are seriously flawed and needs to overhauled. I don't know why Rust doesn't got for HKTs. It would be relatively easy, and they have often have much nicer error messages than associated types.
- steveklabnik 6y agoI didn't say one or the other was easier, just that extending a type system like Rust's with an attitude towards stability like Rust's is not simple. > I don't know why Rust doesn't got for HKTs. In my understanding, the benefits are less clear. You don't just get Monad for free because you have HKTs. ATC/GATs are much more clearly needed.
- Ericson2314 6y agoYou indeed don't get Monad for free, we're in agreement. To pick a use case dear to Rust, it's definitely the best way to e.g. write data structures that are parameterized over say Rc, Arc, or some Gc. Again, I say "the best" with pedagogy and productivity in mind: the error messages are better and intent clearer with this mechanism over the associated type alternatives.
- comex 6y ago> Actually higher kinded types are easier than "generic associated types". Rust leans heavily on associated types in general, and there are several concrete use cases where generic associated types are sorely missed (especially involving lifetimes). You might ask, why not both? Part of the reason is conservatism about language features, and wanting 'only one way to do it'. But another part is that Rust is starved for compiler implementation manpower. The current generic associated types RFC was proposed in 2016 and merged in 2017, and it's a highly prioritized feature. But implementation work didn't even start until sometime in 2019 (AFAIK), and it still has a ways to go. There's also another, somewhat more mundane problem... Higher-kinded types somewhat conflict with default type parameters. If you have struct Foo<T = i32> { t: T } then you can currently write Bar<Foo> and it's equivalent to Bar<Foo<i32>>. So how do you distinguish that from passing the Foo constructor itself? It may be possible to just distinguish based on context, but it's an issue.
- tome 6y agoI appreciate your sense of humour and generally agree with the thrust of what you are saying. Please bear in mind that we have just had a couple of large discussions about the "arrogance" of the Haskell community and that tone can easily be misconstrued in internet discussions such as these.
- thesz 6y agoWhere can I read these discussions?
- tome 6y ago* https://news.ycombinator.com/item?id=24401748 https://news.ycombinator.com/item?id=24401748 * https://news.ycombinator.com/item?id=24449927 https://news.ycombinator.com/item?id=24449927 * https://old.reddit.com/r/haskell/comments/io3c11/essay_found_in_2030_what_killed_haskell_could/ https://old.reddit.com/r/haskell/comments/io3c11/essay_found...
- thesz 6y agoThank you, these are at the very least amusingly entertaining, reaching to educating levels at times.