News for hackers. Stuff that matters.
Re:Ownership and Borrowing in D by pcwalton on Monday July 15, 2019 @11:50PM (#20447335)
> - Higher-kinded types (template template params): it's possible to implement Haskell-style monads etc. in D, if for some reason you felt the need.

Because the templates aren't typed at all. I'm not sure you can call untyped templates "Haskell-style".

Re:Ownership and Borrowing in D by logicchains on Tuesday July 16, 2019 @12:10AM (#20447397)
While the templates are technically untyped (in the sense that there are no type-classes or traits in D), you can use template constraints to achieve something similar: https://dlang.org/concepts.html. Essentially you'd write a compile time isMonad predicate that only returned true if certain functions were defined for a type.

Even without that, the key thing is it's still possible to implement monads in the C++ style (https://stackoverflow.com/a/2565191/2553416), whereas it's impossible to write code to do the same thing in current Rust. It just gives much worse compiler errors if you use it wrong compared to if the language had built in type-classes / traits.

Re:Ownership and Borrowing in D by pcwalton on Tuesday July 16, 2019 @12:52AM (#20447561)
Template constraints aren't the same thing as typed generics. The key issue is that typed generics influence the typechecker. For example, you can write "let x = Default::default(); f(x);" and the compiler can determine the type of x from the type of f.

Also, there is the "higher" crate for higher-kinded types if you need them, so it is possible to write a monad typeclass in Rust. It's not exactly something you'd want to use, though.

Re:Ownership and Borrowing in D by logicchains on Tuesday July 16, 2019 @01:11AM (#20447626)
>For example, you can write "let x = Default::default(); f(x);" and the compiler can determine the type of x from the type of f.

That would be less helpful in C++/D because their compilers don't do Hindley-Milner style bidirectional inference, so even if they had typed generics they wouldn't necessarily be able to do that inference. But I suppose that's an argument in favour of Rust, stronger type inference.

>It's not exactly something you'd want to use, though.

Ergonomic HKT can make writing various kinds of utilities easier. E.g. imagine I want to write a function Singleton that takes a collection C (vector, list, stream...) and an item of type T, and returns C<T>, a collection containing a single instance of that type. I can write that in Haskell, D or C++, but not in Rust. Or perhaps more usefully, a function Fill, that returns a container C containing n items of type T. For Rust it seems I'd need to write a separate implementation of Fill for each container type, I couldn't write one parameterised over any C?

Re:Ownership and Borrowing in D by paavohtl on Tuesday July 16, 2019 @03:48AM (#20448247)
You can do that without HKT, using FromIterator (which is also used by the widely used iterator method "collect").

Here is an implementation: https://play.rust-lang.org/?version=stable&mode=release&edit...

Fill is also possible, using the same trait and iterators.

Re:Ownership and Borrowing in D by logicchains on Tuesday July 16, 2019 @06:19AM (#20448810)
I stand corrected. Could the same technique also be used to have a struct parameterised by C and T that had a C as a member?
Re:Ownership and Borrowing in D by leshow on Tuesday July 16, 2019 @09:42AM (#20449911)
You can't partially apply type parameters in rust, that is HKT. But traits & associated types in traits get you pretty far.
Re:Ownership and Borrowing in D by awson on Tuesday July 16, 2019 @04:35AM (#20448438)
"wouldn't necessarily be able"

It goes completely against the most (perhaps) fundamental part of C++ philosophy of overloading functions on argument types.

Re:Ownership and Borrowing in D by tuukkah on Tuesday July 16, 2019 @05:24AM (#20448617)
Overloading does not conflict with type inference: it just means that type annotations are sometimes necessary to get down to concrete types for execution. From "f(x)" we can infer that the type of x is one of f's overloaded argument types.