top | item 26277295

(no title)

glittershark | 5 years ago

I think it probably falls more into the category of removing a restriction rather than a new feature, but I'm still waiting on HKTs - not for traits (as a former die-hard haskeller, I have been gradually converted to the side of "rust doesn't need a Monad trait") but for data types. There's a design pattern in haskell called "Higher-Kinded-Data"[0] where you parametrize a datatype on a type-constructor, and use that to generically define either partial or total versions of that data type- something like (in rust syntax):

    struct Person<F> {
        pub name: F<String>,
        pub age: F<u32>,
    }
where you can then have `Person<Option>` be a person that may or may not have all fields filled, and `Person<Box>` be a person with all fields definitely filled. This is something I find myself reaching for surprisingly frequently when writing rust, and I feel like it's a missed benefit of implementing higher-kinded types.

[0]: https://reasonablypolymorphic.com/blog/higher-kinded-data/

All that said, I'm really excited to have const generics land! Props to all the amazing work by withoutboats and the entire rust team.

discuss

order

meetups323|5 years ago

In TS this would be flipped:

    type Person = {
     name: string;
     age: number;
    }

    type SomeFieldsMissing = Partial<Person>;
    type AllFieldsRequired = Required<Person>; // No real change in this case
Where Partial and Required are defined like:

    type Partial<T> = { [P in keyof T]?: T[P] | undefined; }

    type Required<T> = { [P in keyof T]-?: T[P]; }
What would you think of something like this ("mapped types")? They can get fairly powerful: https://www.typescriptlang.org/docs/handbook/2/mapped-types....

glittershark|5 years ago

that seems like something that would only really work with a type system that's as structural as TS (vs rust, which is very nominal)

kazoomonger|5 years ago

What would happen if I wanted only some fields to be required? To borrow from the GP example, something like this:

    struct Person<F> {
        pub name: F<String>,
        pub age: Option<u32>,
    }
With `Person<Box>` still leaving `age` as optional.

a1369209993|5 years ago

That superficially looks horrible. How do you write `Person (Compose Maybe Maybe)`, even, never mind anything more sophisticated?

Edit, for that matter, how do you deal with a `Person f` that includes a `f (Maybe Something)` without confusing "the user didn't specify a `Maybe Something`" with "the user specified a `Maybe Something` with value `Nothing`" (or vice versa)?

steveklabnik|5 years ago

I like and enjoy HKTs in other languages, but don't feel a super strong need for them in Rust. I know some other people differ. It is very unclear when, if ever, Rust will get HKTs proper. GATs cover a lot of the same ground. We'll see :)

adamch|5 years ago

Wow, higher-kinded data. I've never heard of that, but it would absolutely be useful. E.g. for converting JSON inputs, where any field might be missing, into a version of the data which definitely has values for all the fields. Or a version of the struct where the values are actually read from a cache/database.

twic|5 years ago

I proposed using it to model lifecycles of entities:

https://github.com/tim-group/higher-kinded-lifecycle/blob/ma...

(in this code, "idea" is a domain concept from the firm i worked for at the time - basically a recommendation to buy a stock, which is 'opened' on a certain date, and 'closed' when it no longer seems like a good recommendation)

My collegues didn't like it, and stuck to using separate types for objects in different stages of the lifecycle!

IggleSniggle|5 years ago

TypeScript (as you might expect from a lang built for dealing with JS Objects), has really great tooling for this kind of type narrowing these days (including on string template matching now) and I miss it so much now that I’m writing Go.

glittershark|5 years ago

yes! once you use it you start wanting it everywhere, which is a big part of why I wish I could do it in Rust

viraptor|5 years ago

> where you can then have `Person<Option>` ... This is something I find myself reaching for surprisingly frequently

What's a practical use case for it? It's cool in theory, but I struggle to come up with something that doesn't use at most 2 implementations (just copy the struct then), or some API where the types don't mix and can be generated via a macro instead.