Proposal: chain access field functions

tl;dr: allow .info.age as a derived form/syntactic sugar for (\r -> r.info.age) in the same way that already works for simply .age.

I find an accessor function a pretty useful shortcut, obviously not because it’s fewer characters but just because it gets rid of noise that isn’t helpful to comprehension:

    combinedAge =
         List.map .age people

Seems nicer to me than

    combinedAge =
         List.map (\p -> p.age) people

Unfortunately if the value required is nested this doesn’t work, you have to write the noisy lambda way:

    combinedAge =
          List.map (\p -> p.info.age) people

or

   getAge person =
        person.info.age
   combinedAge =
        List.map getAge people

So I suggest that this shortcut should just be allowed regardless of how long the chain is:

    combinedAge =
         List.map .info.age people

I realise that Elm tends to discourage nested records in favour of just having larger records and using extensible record type syntax to restrict/hide information where necessary. But this seems still a reasonable extension of the shortcut nonetheless.

Obviously it’s probably something of a code smell if you saw something like List.map .one.two.three.four.five, I’d respond with

  1. I’m not sure this proposed syntax really encourages deeply nested record structures rather than just makes them slightly less unpleasant to work with.
  2. If the alternative is List.map (\r -> r.one.two.three.four.five) at least the shortcut makes it clearer at first glance that the function really does nothing other than accessing a nested record.
  3. If you’re really worried about that you could restrict it to whatever length you wanted, but I believe 1 is not the correct length to restrict it to.

However, if you suggest that forcing someone to name the getAge function is better that’s a much more convincing argument (to me anyway). In fact I’m not sure I haven’t just talked myself out of this altogether. I suppose it isn’t forcing you to write the getAge because you can write the lambda (am I now proposing to ban lambdas? I at least think lambdas are useful in teaching to demonstrate that functions are values just as ints and strings are)

Mostly irrelevant side issue

Currently if you try to write this, the error message you get is:

> .info.age
-- TYPE MISMATCH ---------------------------------------------------------- REPL

The 1st argument to this function is not what I expect:

3|   .info.age
          ^^^^
This .age field access function has type:

    { b | age : a } -> a

But this function needs the 1st argument to be:

    { b | info : a }

So it’s basically saying that you’re trying to apply the function .info to the value (which happens to be a function) .age, which of course does not have the correct type. But I guess that’s almost certainly not what the user was trying to do, they where either assuming .info.age would work in the way I propose or they have simply mis-typed something like person.info.age as person .info.age

1 Like

You can also combine accessors functions like this.

combinedAge =
  List.map (.info >> .age) people

I think this solves your problem quite nicely, even if it’s slightly more verbose than the syntactic sugar that you proposed.

10 Likes

That does at least make it clear that the function doesn’t do anything other than access nested records. I guess I’d suggest that this needs to be a little ‘learnt’ whereas .info.age is probably accessible even on day 1 of Elm.

Your way is arguably more flexible since you could also write .age << .info if you care about having the punchline first, as in “I’m getting the age, the details of how I get that aren’t as important”.

(I just realised I forgot to do |> List.sum in my example, haha).

As a side note regardless of any merits of this proposal:

The only substantive changes in the Elm syntax in the last 4 years have been:

  • Removes the ability to define custom operators
  • Tuples limited to a max of 3 elements
  • Variable shadowing removed
  • No top level destructuring

(i.e. no syntax added, only a bunch of syntax removed/limited)

The previous release was similar:

  • Remove backtick function calls
  • Remove the ability to define 'a
  • Remove [1..5]

TL;DR: it has been a loooong time since Elm added any syntax. I suggest to take that explicitly into consideration when making syntax proposals - a proposal should come with justification why this particular thing should reverse that trend.

4 Likes

Yeah, I think probably “Proposal” was the wrong word, I should have said “Discussion”, but that always seems rather redundant on what is ultimately discussion forum software :wink:

Agreed, that it is difficult to get any syntactic additions into Elm, and also agreed that that’s largely been a good trend.

Agreed that if there were some formal means of proposing anything, that that proposal should come with justification etc.

We should be careful however not to always shut down discussion with high barriers to entry. A formal proposal would indeed require such justification, but let’s not stop conversations before they get started. It doesn’t have to be the original poster that comes up with the solid justification. Or more over just the process of failing to come up with a solid justification can be enlightening. I mean I half talked myself out of the proposal before I got through it. The process of writing was useful to me, and who knows the process of reading it might be useful to someone else. Lastly the outcome might look nothing like the original proposal, half way down I asked “am I now proposing to ban lambdas?” So the original suggestion to add syntax contained some germ of removing syntax. That would be a discussion worth having. Someone else may well ask “hey, yeah if I had chained access field functions I pretty much wouldn’t need lambdas anymore”, someone else may disagree.

I guess what I’m saying is, I would rather people felt more free to make any proposal they thought merited consideration particularly in this informal setting. If the proposal is unmerited let’s discuss why that is. If is merited, then let’s figure that out together.

To be clear, I understood from your answer that you wished to discourage people from making half-backed proposals/ideas/suggestions on this forum. I am disagreeing with that, because I don’t feel this is a formal enough setting to require such a high barrier, and may discourage useful discussion. In particular you said “a proposal should come with justification why this particular thing should reverse that trend”, perhaps you meant “any successful proposal would ultimately have to …”, but that’s not what I understood.

Best wishes.

1 Like

I am not trying to shut down any discussion and apologies if that was how it came off. My only aim was to make sure everyone participating in the discussion goes in with correct expectations: even if we all agree this is a fantastic idea, nothing will likely come of it.

(This is an experiment from my side based on some discussion about why people get frustrated with attempting to contribute to Elm. One of the hypotheses is that they assume they might succeed or that the barrier is reasonably low. So one idea to mitigate this issue is simply to make it explicit pretty early on what to expect.)

2 Likes

Okay thanks for clarifying. It was probably my fault for using the word ‘Proposal’.
As it happens I have suitably low expectations, ie. I’ve been here before. I just enjoy the discussion.

A laudable experiment, just for some feedback, to me I was worried it came off (to others rather than me), as “don’t bother making proposals” rather than “expect failure, the barrier for language modifications is high”.

3 Likes

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