Livecoding fun: Brooke updated her local installation of elm from 18 to 19 with:
npm install -g elm
I observed that she's using nvm
^^ I installed elm with the installer today.
and now we see:
$ elm repl
---- Elm 0.19.0 ----------------------------------------------------------------
Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
--------------------------------------------------------------------------------
> :exit
:exit
: to get out of the repl! a little different from other languages.
Why Elm?
https://elmbridge.github.io/curriculum/Why%20Elm.html
Several people mentioned that Elm is their first functional programming language.
Functional means that a function will always return the same output back given the same input.
Statically-typed means that the compiler checks the code to make sure it makes sense before running it in the wile.
* if you've used javascript before, you might have had some unexpected things happen where you try to multiply a string and a float and had different things happen like NaN
... Elm will notice that and point it out and tell you to fix it. If your Elm code compiles, it means it makes sense!
If your function say_hello
is supposed to take a string, but you feed it the number 2, it'll say "ahh! this doesn't make sense!" and give you a hint of how to fix it. That's one of the super-awesmoe things about Elm, and the volunteers will have storeis about how that's been helpful!
Have you had this happen?
- "I expected this function to return a number, but I got nil instead!"
- "This function returned a different value even though I gave it the same input as last time!"
- "Something's changing the value of this variable, and I'm not sure what's happening!" Elm is functional, so you won't have random side effects elsewhere in your code affecting what's running.
These errors can't happen in Elm because of the language's strictness. If you do write a bug, the compiler will tell you "this program doesn't
There are no runtime exceptions! Elm devs spend much less time in debugging tools.
I like this side note about "the experience of working in an alien environment, even if it's just for a little while, can be fruitful." And also the note that we're not claiming functional is better. I think that's a good thing to note because we'll run into other devs in the world who have attitudes and making it explicit that we aren't gonna be like that is friendly and helps me feel safe.
Brooke notes that she still writes a lot of Ruby, because of her org's backend, and learning Elm has changed the way she writes her Ruby.
ok, now we're playing around in the repl!
Getting Started
https://elmbridge.github.io/curriculum/Getting%20Started.html
Using the repl!
maybe we should explain what a repl is
> "Potato" + 7
-- TYPE MISMATCH ----------------------------------------------------------- elm
I cannot do addition with String values like this one:
4| "Potato" + 7
^^^^^^^^
The (+) operator only works with Int and Float values.
Hint: Switch to the (++) operator to append strings!
>
I cannot believe how friendly Elm's error messages are. I heard a volunteer talk about it just an hour ago and now I see what they mean ^^
You can see
String
number
Float
Q: why plus plus?
A: in Elm, every function expects a certain kind of output. + deals with numbers and ++ deals with strings.
Q: why is number
lowercase but String
is uppercase?
A: Something that's a number
does not know yet if it's an Integer
or a Float
until we do something that makes it be an Integer
or a Float
!
woah that's cool. Does this mean we can call both Float and Integer functions on numbers? What is number
????? A class?
We'll probably see a lot of error messages today. That's good! We'll get used to all the error messages Elm sends us.
Q: What if we wanted to use ++ with a string that's made up of digits? To make a number into a string, we use quotes?
A: yes, you can do "10" ++ "Betsy"
and end up with "10Betsy"
. There's also a function you can use to turn 10 from an Integer to a String.
What error message will we get if we forget the ++ ? Elm lets us know ^^
Functions
lol i discovered this is not the way to give Elm a float
> max -3342 .3
-- PARSE ERROR ------------------------------------------------------------- elm
Something went wrong while parsing repl_value_2's definition.
3| repl_value_2 =
4| max -3342 .3
^
I was expecting to see a lower-case variable, like `x` or `user`
this works tho:
> max -3342 0.3
0.3 : Float
We're going through the Strings now. I see String.fromInt so I'm going to try toInt too. hmmm
> String.toInt "10"
Just 10 : Maybe Int
> String.toInt "djsaf"
Nothing : Maybe Int
What is a Maybe?!??!?!?! I'm sure we'll find out soon!
Q: is that an array?
A: it's a List!
> String.join " " ["hey", "hello"]
"hey hello" : String
> String.split " " "hello how are you i'm doing a thing--yay"
["hello","how","are","you","i'm","doing","a","thing--yay"]
: List String
woah it tells you what a list is made of. on my own, I'm wondering if I can put different kinds of things in Lists? let's see...
> x = ["123", 456]
-- TYPE MISMATCH ----------------------------------------------------------- elm
The 2nd element of this list does not match all the previous elements:
3| x = ["123", 456]
^^^
The 2nd element is a number of type:
number
But all the previous elements in the list are:
String
Hint: Everything in the list needs to be the same type of value. This way you
never run into unexpected values partway through. To mix different types in a
single list, create a "union type" as described in:
<http://guide.elm-lang.org/types/union_types.html>
Hint: Try using String.fromInt to convert it to a string?
omg
what about a list of lists
> x = [["hello", "world"], [123, 567]]
-- TYPE MISMATCH ----------------------------------------------------------- elm
The 2nd element of this list does not match all the previous elements:
3| x = [["hello", "world"], [123, 567]]
^^^^^^^^^^
The 2nd element is a list of type:
List number
But all the previous elements in the list are:
List String
Hint: Everything in the list needs to be the same type of value. This way you
never run into unexpected values partway through. To mix different types in a
single list, create a "union type" as described in:
<http://guide.elm-lang.org/types/union_types.html>
Hint: Try using String.fromInt to convert it to a string?
ahaha wow lists of lists have to carry the same thing. fascinating.
11am
Modules
Q: what is a module?
A: today it can also be a file.
We're going to import Dict
this whole bit in parens is called a tuple: ("one", 1)
- the key is
"one"
- the value is
1
Q: can you have various types of Dicts depending on what you want? If you want different specific values per dictionary?
A: yes, you can mix. but they keys have to be the same type!
wow! That's kind of that Elm type safety kicking in.
You can get the keys... etc. Lots of functions! https://package.elm-lang.org/packages/elm/core/latest/Dict
11:11am
Functions
My own thoughts: it's confusing to me that the thing between parameters and the output are both ->
but it's probably fine because there's only ever one output. So we know which thing is the output... the last one.
Q: can you re-define a variable?
A: no, you cannot! but you can do :reset
in the Elm repl, and our curriculum does note that in the next paragraph =)
haha i wanted to test String.toInt combined with this, and got this:
> multiplyByFive (String.toInt "6.8")
-- TYPE MISMATCH ----------------------------------------------------------- elm
The 1st argument to `multiplyByFive` is not what I expect:
8| multiplyByFive (String.toInt "6.8")
^^^^^^^^^^^^^^^^^^
This `toInt` call produces:
Maybe Int
But `multiplyByFive` needs the 1st argument to be:
number
Hint: Use Maybe.withDefault to handle possible errors. Longer term, it is
usually better to write out the full `case` though!
Q: when you call :reset
, does it reset all variables?
A: yes!
Q: what if i just want to reset one?
A: well... you're not really in the repl a lot in practice. i think no, :reset
is just to clear your elm repl session; you probably won't need it. you're not going to be defining one-off variables very much.
Q: why did the creators choose not to allow that? in other languages, you can override variables.
A: in the last version of Elm, you actually could. and it opened up one of the only ways to cause a runtime exception in practice. i have done it (not in production, just locally) and it was really hard to debug it. i had reused a variable and it was calling a function when i didn't mean it to.
So not allowing shadowing is a way to help you not make that mistake. The goal is to help you, but at the time you're here in the repl like "oh! how irritating!"
done with repl time! ctrl-d
is also an option haha.
BONUS
all the types begin with a capital letter but variables are lowercase... except the type number
is lowercase! also maybes lol