(0) Here’s a summary of a useful private conversation with @Janiczek. I’ve made changes to what I said, when I think it’s an improvement.
(1) The starting point was a wish to have something like a list literal, but of variable length. And Html.fragment
was proposed as a way of achieving this. The two arguments to div
, button
and so on are both lists. So any syntactic sugar here might be widely used.
(2) Literals are one way to construct a List
. They are a convenient shortcut.
> 1 :: 2 :: 3 :: 4 :: (List.singleton 5)
[1,2,3,4,5] : List number
> [1, 2, 3, 4, 5]
[1,2,3,4,5] : List number
(2) By the way, constructing a record requires at least one literal for every record type, and another literal for every modification.
> type alias Rec = { a : Int , b : String }
> rec = Rec 2 "three"
{ a = 2, b = "three" } : Rec
> rec2 = { rec | a = 4 }
{ a = 4, b = "three" } : { a : Int, b : String }
(3) The semantics of Python’s
[ a , b, * c, d ]
when written in Elm is
[ a, b ] ++ c ++ [ d ]
or in other words * c, is equivalent to the admittedly odd
] ++ c ++ [
(4) An alternative approach is
> c = [ 3, 4 ]
[3,4] : List number
> List.concat [ [ 1, 2 ], c, [ 5 ] ]
[1,2,3,4,5] : List number
(5) Either way, something close to Python’s *
operator can be achieved in Elm via suitable literals.
(6) @Janiczek notes
*
as a language syntax would certainly be more general than Html.Fragment
. That can be its advantage and disadvantage (probably depending on who you ask).
(7) The Elm compiler does type implication. Also, every element in a list must have the same type. This would allow the compiler to imply the *
operator in most list literals.
(8) For example, if we have the *
operator then we would have
> b = [ 2, 3 ]
[2,3] : List number
> [ 1 , *b, 4 ]
[1,2,3,4] : List number
and implying the *
operator would allow
> [ 1 , b, 4 ]
[1,2,3,4] : List number
(9) In this situation a literals such as
[ [ ], [ ] ]
[ [ 1 ] ], [ [ [ 2 ] ] ] ]
would be ambiguous.
(10) Implying the *
operator doesn’t need a new ItemOrList
type, even if the starred identifier comes from outside of a function. I suggest that the compiler adds the stars only when there’s one way to produce type-valid code.
(11) If that is done, then the ambiguous examples in (9) would produce Type Error
. This is a lack of backwards compatibility. The code could be fixed by adding a type annotation.
(12) To conclude.
-
Something similar to Html.Fragment can already be achieved, via List
methods. Doing nothing is an option.
-
The *
operator might be a useful addition to List
literals.
-
The compiler implying the star is an alternative to adding the *
operator.
(13) Finally, suppose the compiler implies the *
operator. Then for example the value of
[0, 1, 2, aaa, 4]
could be any of
[0, 1, 2, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 7, 8, 9, 4]
depending on the value of aaa
. This language feature might at first confuse beginners. Perhaps, even if it can be implied, we’d benefit from an explicit *
operator.