Pipe operator in extensible record type

I came across extensible record code like the following:

type alias Editable r
 = { r | author: String, created : Int }

I understand it’s saying "I’m creating a record type who can hold any fields so long as it has two particular fields author and created". However I have not seen the pipe operator being introduced in creating record type in the office document. It’s indeed explained as a way to update a record value though.

Is it some sort of hack or it has a general usage beyond the definition of extensible record?

1 Like

i don’t understand your question

Your understandment is correct - the | symbol is present on two different situations, meaning two different things. When defining a type alias it is used to represent an extensible record. But it can also mean “return this record with this update”. Those two usages are unrelated.

3 Likes

extensible records, like the one you’ve shown, exists as a tool for “narrowing” types - this video should start at 21:29, where it’s described :slight_smile:

I’d recommend watching the whole video though!

1 Like

Yes, I’ve already watched it and planed to watch it again. It’s awsome.

Sorry for my bad English expression. I mean how can a pipe operator be used in defining a record type? According to these well-known documents(e.g., offical guide, Beginning Elm), a pipe is used to updating a record value, not to compose a new record type.

So I’m wondering If I’ve missed some key concepts of Elm.

The syntax for extensible records and record update expressions have a similar meaning, but they do something different. It’s similar to how arguments exist for both types and functions.

1 Like

I’m surprised that the official language guide does not mention extensible record types. I’m sure that must have been where I first read about them years ago, but I don’t see any mention of them now.

It actually looks like it used to be on this page, but was removed.

1 Like

Really? It appeared and dispeared again? What happened? The extensible record seems an important concept when building large application. The Richard’s video has shown the importance in narrowing type. I love this concept.

Following Evan recommendation, I wouldn’t use them. The compiler has bugs dealing with them and it is recommended using record composition over extensible records. Also consider how you would reuse/compose decoders. For example:

type alias PersonalDetails a = 
    { a
        | name : String
        , age : Int
    }

type alias AccessData a =
    { a
        | isAdmin : Bool
        , isBanned : Bool
    }

type Profile =
    PersonalDetails (AccessData {})

VS

type alias PersonalDetails = 
    { name : String
    , age : Int
    }

type alias AccessData =
    { isAdmin : Bool
    , isBanned : Bool
    }

type Profile =
    { details : PersonalDetails
    , access : AccessData
    }

PS: I would be surprised that they are removed in future releases of Elm.

2 Likes

What you’re discussing is data-modeling, which is what they’re discouraged for.

Using extensible-records is definitely not discouraged, and I’m very confident they’re not going anywhere.

1 Like

Nothing wrong with using them in data modelling either - just don’t expect them to work like subtypes in the same way that extending objects in OO works.

“Extensible records are useful for restricting arguments, not data-modeling” - evancz, the video above.

I’m fairly certain this still holds true

Just because someone says (or writes) something does not make it true. You need some kind of logic to make a case. I would not use them in data modelling carelessly, but I think occasionally they can work nicely there. Mostly if you have some kind of linear pipeline process that builds up fields as processing works down the pipeline - it can be nice to model each stage as an extensible group of fields, with the final output made up of all the parts. The alternative of modelling each stage separately is that you might add a field to one stage but forget to add it to all the others further down the pipeline.

I used them once to define an extensible API with common base functions and multiple implementations - that was quite OO, but worked for the use case.

I think the advice should be “Extensible records are most useful for restricting arguments, not data-modeling”.

2 Likes

:confused:

I’m mean to pass on what I consider solid advice, as it has made things easier for me in the past. I don’t want to argue it’s merits in this thread :sunny:

EDIT: But I suppose it could be interesting to start a new thread to discuss the subject!

1 Like

As newbie of elm, I like to read the new thread if it’s created :wink: .

To me, “restricting arguments” is highly related to “data-modeling”. It seems an elm application is pretty much just a big(flat) data(model) surrounded by a lot of logic(functions). So “restricting arguments” is an important way to deal with that data. By what I’ve learned about elm so far(which is limited BTW), it’s one of the key concepts one must grasp to build serious application.

For myself, the distinction is whether we’re talking types of function-arguments, or types of application state.

I haven’t had any practical uses for extensible-records on types that live inside the “Model” :sunny:

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.