DEV Community

loading...

5 notable things I learned from reading Elm's syntax documentation

dwayne profile image Dwayne Crooks ・2 min read

5. A neat trick for toggling comments

{--}
add x y = x + y
--}
Enter fullscreen mode Exit fullscreen mode

Just delete or insert the } on the first line to comment or uncomment the add function.

4. Multi-line strings

They are useful for holding JSON or other content that has quotation marks.

quotes : String
quotes =
  """
  {
    "quotes": [
      { "content": "A language that doesn't affect the way you think about programming is not worth knowing.", "author": "Alan J. Perlis" },
      { "content": "You don't understand anything until you learn it more than one way.", "author": "Marvin Minsky" }
    ]
  }
  """
Enter fullscreen mode Exit fullscreen mode

3. Field access functions

alan = { name = "Alan Turing", age = 41 }
alonzo = { name = "Alonzo Church", age = 92 }

.name alan == "Alan Turing"

-- > .name
-- <function> : { a | name : String } -> String

.age alonzo == 92

-- > .age
-- <function> : { a | age : Int } -> Int
Enter fullscreen mode Exit fullscreen mode

Notice that .name and .age take extensible records as arguments. .name accepts any record with a name field and .age accepts any record with an age field.

2. Extensible record definitions

type alias Named a =
  { a | name : String }

type alias Positioned a =
  { a | x : Float, y : Float }

alan : Named { age: Int }
alan =
  { name = "Alan Turing"
  , age = 41
  }

origin : Named (Positioned {})
origin =
  { name = "origin"
  , x = 0
  , y = 0
  }

getName : Named a -> String
getName { name } =
  name

getPos : Positioned a -> (Float, Float)
getPos { x, y } =
  (x, y)

names : List String
names =
  [ getName alan
  , getName origin
  ]
Enter fullscreen mode Exit fullscreen mode

It allows you to write small orthogonal functions that work with a wide variety of records. You get much of the freedom of a dynamically typed language while the type checker keeps you safe.

1. Typeclasses

When Evan released extensible records he made a few interesting remarks:

Polymorphic extensible records give some of the power of first-class modules in OCaml and SML.

...

These records also make it possible to create a more labor intensive version of typeclasses.

...

Part of why I am dragging my feet on adding typeclasses to Elm is because records, first-class modules, and typeclasses do a lot of the same things (records and modules and modules and typeclasses). There have been one or two proposals to unify first-class modules and typeclasses as well. I want to make sure Elm is getting the best of all of these features, so I have been doing a lot of research to make sure I do not make the wrong choices here.

type alias Eq a =
  { eq : a -> a -> Bool
  , neq : a -> a -> Bool
  }

type alias Comparison a =
  { compare : a -> a -> Order
  , lt : a -> a -> Bool
  , lte : a -> a -> Bool
  , gt : a -> a -> Bool
  , gte : a -> a -> Bool
  , min : a -> a -> a
  , max : a -> a -> a
  }
Enter fullscreen mode Exit fullscreen mode

Nikita Volkov has rediscovered this idea and in his write-up he highlights the limitations.

References

Discussion

pic
Editor guide