Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
  • Elm is not a frontend framework.
  • Elm is neither V in MVC, nor MV in MVC, nor even MVC itself.
  • You don't assemble libraries and configure options to make Elm do what you want.

Elm is a language. You write programs with it.

But instead of providing a regular main function to run, Elm wants you to write at least 2 parts to run your program: init and update. This is my pseudo code for your init and update plugs into Elm runtime:

let [globalState, cmd] = init(optionFlags)

const messageBus = new EventEmitter()

messageBus.on('msg', function (msg) {
  const [newState, newCmd] = update(msg, globalState)
  globalState = newState                              // NOTE: globalState changes every update
  execAndEmitMsg(newCmd, messageBus)
})

execAndEmitMsg(cmd, messageBus)

NOTE: if you are unfamiliar with EventEmitter, it is a "message bus" that provide emit and on listeners alternatively, you may prefer the Go example

Backend web devs are very familiar with writing programs in an event-driven manner: each incoming http request is handled by a stateless function, reading and writing a global database. Imagine doing the same, but not just to handle incoming http requests.

Elm is just saying, that's how we write all Elm programs.

In addition, Elm is saying it is best if init and update functions cannot perform any actual commands like open a file, or http get. Instead just return plain values to tell the runtime what to execute next:

cmd = { type: "Http.get", url: "http://roll.diceapi.com/json/d6", msg: "RollDice" }

In the first pseudo code on top, these cmd values are handed off to a runtime function execAndEmitMsg that performs the real actions:

function execAndEmitMsg (cmd, messageBus) {
  switch (cmd.type) {
    case 'Http.get':
      fetchText(cmd.url).then((data) => messageBus.emit('msg', [cmd.msg, data]))
      break
  }
}

Notice that messageBus.emit('msg', ...)? That's how the result is passed back through messageBus.on('msg', ...) and handled by your update

And just like that, round and round we go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment