The three major ways to communicate with the outside world in the Elm
Sub a, and
Html a. This is a curious thing to say, because none of those
types do anything, in the imperative sense. Regardless, it’s tempting to think
Http.send as a function that kicks off an
XmlHttpRequest() in the browser
and you get the result as what you defined as your
It’s also tempting to think of that
Time.every 60000 subscription as starting
setTimeout. Then you just wait for the every-minute callbacks to roll in.
This is convenient to think about, but it’s wrong. It’s not very wrong, but
it’s wrong in some important ways that can hamper understanding. So, yes, the
end result of the
Http.send is that a request is fired off to the API you want
to hit. And the end result of
Time.every is that you get a callback every so
often. The difference, though, is that it’s not “your code” doing it. It’s the
I’m going to focus on
Cmd a here because that’s the most straightforward
case, but both
Sub a and
Html a deal with things in a similar manner.
The first important thing to note is that little
a. This makes
Cmd a a
parameterized type the same way that a
List a is a parameterized type. And
just like a
List String describes a
List that deals with
String describes a
Cmd that deals with a
Cmd part tells Elm
“This value represents a thing I want you to do” and the
String tells Elm “and
when it’s done, use this value to tell me about it.”
You might see (and probably will see) people using
Cmd Msg fairly often.
isn’t magical, it’s a union type that anyone can define for
themselves. Each tag in the union is a kind of response that
you’re looking for. The name “Msg” is just a convention as to what Elm
programmers should call this data type.
Imagine you have a personal assistant for a second. You give them a note that
says “Buy 2 apples and give them to me.” and they do. It’s their job, after all.
And they come back and say “I got you the apples you asked for”. The assistant
in this scenario is a metaphor for the Elm Runtime, which actually does the
Cmd as specify. The important thing to know is that you are not
doing the action. You’re telling the Elm Runtime to do the action (“Buy 2
apples”) and to let you know how you want to be told when it’s done (“Give me
OK, so that’s great. I can tell the Elm Runtime to do something for me, but I have a whole application here. I’m a busy developer. Stuff needs to get done! I have to do more than one thing at a time!
Cmd a is the equivalent of handing your assistant a note with instructions on
it. Fortunately, we can do more. With
Cmd.batch you can combine multiple
commands into one. How do you tell someone to buy multiple things? Same way: you
batch all the things you want up into one shopping list and hand them the list.
Voila! You cam have you assistant buy Apples, buy Cereal, make a request to an
API, and buy Potatoes all in the same trip.
The conceptual model that we’re talking about here is that you’re telling the Elm Runtime to handle something on your behalf and then waiting for it to be done. And then, because you told Elm how to tell you, it sends you the message you were expecting.
Like the wonderful Tell Me When It Closes, you offload the stress of having to worry about you actions to someone else.
It took me some time to really grok what was going on with the pattern of types
that deal with
Msg and how it fits into the architecture and my thinking. But
once it clicked for me, the whole way of “doing things” and the way it doesn’t
really involve doing things yourself finally came into focus.
and ports all operate on more or less this same style of getting things done.