5 notable things I learned from reading Elm's syntax documentation
Tags: elm, beginners
Published: 2019-07-22 16:36:35

---
title: 5 notable things I learned from reading Elm's syntax documentation
published: true
description: 
tags: elm, beginner
---

## 5. A neat trick for toggling comments

```elm
{--}
add x y = x + y
--}
```

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.

```elm
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" }
    ]
  }
  """
```

## 3. Field access functions

```elm
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
```

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

```elm
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
  ]
```

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](https://elm-lang.org/news/0.7) 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](http://research.microsoft.com/pubs/65409/scopedlabels.pdf) and modules and typeclasses). There have been one or two proposals to [unify first-class modules and typeclasses](http://www.mpi-sws.org/~dreyer/papers/mtc/main-long.pdf) 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.

```elm
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
  }
```

Nikita Volkov has [rediscovered](https://github.com/nikita-volkov/typeclasses) this idea and in his write-up he highlights the [limitations](https://github.com/nikita-volkov/typeclasses/tree/9eac16c6bb85c037b6eac889043b11e526d46aa9#why-no-functors-monads-and-alike).

## References

- [Elm Syntax](https://elm-lang.org/docs/syntax)
- [Records](https://elm-lang.org/docs/records)
- [Elm 0.7](https://elm-lang.org/news/0.7)