I'm posting this here rather than in elm-dev because the discussion might 
get both long and broad.
Also, as much as I would like to help out, I understand that only Evan 
changes the compiler.

The matter has been discussed already, and it might be useful to get an 
idea of the prior thoughts:

This is a previous discussion that evaluated a few different proposals:
https://github.com/elm-lang/elm-compiler/issues/984

This is a very useful summary of the ideas considered:
https://gist.github.com/rtfeldman/f4b04468f3d865c4135153fea29d23f7

What follow is my personal experience; the TL;DR version is "Any proposed 
overhaul of record syntax should consider not only instance manipulation, 
but also record type manipulation".

-----------

The issues I personally encountered are:

1)
There is a common pattern where a library (ex, elm-markdown) will provide a 
default config, to be extended by the user.

import Slides

myCustomSlidesConfig =
 { Slides.defaultConfig | someAttribute = myCustomvalue }

The above does not work because the left side of the { record | attribute = 
value, ...} syntax does not accept expressions.
The current workarounds are either:

import Slides

slidesDefaultConfig =
  Slides.defaultConfig

myCustomSlidesConfig =
 { slidesDefaultConfig | someAttribute = myCustomvalue }

or

import Slides exposing (slidesDefaultConfig)

myCustomSlidesConfig =
 { slidesDefaultConfig | someAttribute = myCustomvalue }

Not a big deal TBH, but annoying.

2) 
Record type manipulation is limited.
It is normal for the front end to get some record from the database, 
display it, edit it or create a new one and push it back to the db.
The record types necessary for these operations are very similar but need 
to have very specific differences.
When the record comes from the db and is displayed, it has usually several 
definite values.
However when editing it, many (but not necessarily all) of those values 
could be "Maybe x" rather than "x".
If I am creating a new record in the front end, chances are that it will 
not have an "id" field.

However, the options that I have to define a record as function of another 
are very limited.
I can't remove fields but only add them, and even that is very limited.

In my current project, I need to edit a "Rule" record.
The app has already a "Rule" type, which *must* have an "id", because 
that's how the data arrives from the DB and is displayed to the user.
However, the form to edit a Rule will need a different type, because 
depending on whether I am creating a new rule or editing an existing one, 
it may or may not have an "id".
I have to duplicate every attribute of the "Rule" type but "id : String" 
into a "RuleContent" type.

3)
Then, unless I want to get crazy with updating nested record properties, I 
need to extend my form Model with RuleContent.
This is the best workaround I have found so far:

type alias RuleContentAnd a =
  {a |
    attributes...
  }

type alias RuleContent = RuleContentAnd {}




type alias Model =
  RuleContentAnd
    { someUiAttributes
    ,  ...
    }

This works, but currently it removes the ability to use "ResultContent" as 
a constructor (which is very useful when writing decoders).
If manipulating nested records was easier, this would be less of a problem 
because then the Model could just contain a "ruleContent : RuleContent" 
attribute.
As Elm is right now, nested records require me to write an updater helper 
"updateRuleContentAttributeX : TypeOfX -> Model -> Model" for every 
attribute in "RuleContent", leading to even more duplication.


I might be wrong, but I think that points 2) and 3) describe use cases 
(Display / Edit / Create something from/on a DB) that are probably the most 
common in web applications.
If this is the case, it might be worth to consider not only how to better 
manipulate record instances, but also record types.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to