Files
hpr-knowledge-base/hpr_transcripts/hpr2633.txt

497 lines
22 KiB
Plaintext
Raw Normal View History

Episode: 2633
Title: HPR2633: Elm - First Impressions
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2633/hpr2633.mp3
Transcribed: 2025-10-19 06:49:30
---
This is HPR Episode 2633 entitled, Elm First Impression.
It is hosted by Tuku Toroto and is about 30 minutes long and can remain an explicit flag.
The summary is, my first impression on Elm Programming Language.
This episode of HPR is brought to you by an honesthost.com.
Get 15% discount on all shared hosting with the offer code HPR15, that's HPR15.
Better web hosting that's honest and fair, at An honesthost.com.
Good morning, listeners of the HAKA conference radio.
I'm Tuku Toroto, Tuku Toroto, and you can call me Tuka if that's any easy.
Today I'm going to talk to you about Elm, my first impressions on the language after playing around with it a little bit.
So how did I get started with Elm?
I have been working with some Haskell code with a project as a hobby and needed to make some clients scripting.
I wanted to do something else and JavaScript and chose Elm because it looked interesting.
Elm is a static with static type to function a language compiled to JavaScript.
So it means that you write your code in Elm and then you run a compiler and that compilator to Elm code into the JavaScript code that you can include on the web page.
It also checks that your type matches like you cannot accidentally use strings instead of indexes and things like that.
So it took a little bit of feeling to get things up and running with the Jesot mainly because I didn't know better.
But after I figured out how to include Elm scripts into Jesot website it was pretty smooth sailing.
And I must admit that I really, really like the Elm currently. It's a really exciting language for me.
So Elm architecture. So the architecture of the programs you write in Elm, the language architecture.
So it's pretty set to the stone how you are supposed to structure your programs.
I don't know any other ways to do that. But essentially you have an Elm group and you have handful of functions that are related to that Elm group.
So first is in it for setting up things that basically just returns you the state of the program.
This is the initial state and it might run one or more commands.
We'll get into those little bit later, but those are for example if you're loading some JSON data from the web server, this is where you do it today.
That's what you do with the commands.
And that state of the program that's just a single type, single or instance of that type.
I usually end up just being very unimade. You unimade, unimade.
They just call my model. That was my state as a model.
So this is what the init does. Initial state, zero or more commands.
Then there's an update. It's a function that takes two parameters. It takes the current state and it gets a message.
And based on those, it creates a new model, a new state for you.
And that's basically it. Oh, right. It also might again create zero or more commands.
And these messages that update handles this can be a result of commands.
Like if you send a HTTP get to the server, eventually it will come back as a message.
Hey, here's your data. So the upgrade function is basically a big, big case study.
If the message is this to do this to the state messages, this to this to the state and so on.
And the last important part is the view. This is what what is in charge of rendering things on the screen.
And it's just a function that takes one parameter, current state of the program.
And it's supposed to return you a HTML page or fragment.
Here you, here you, here you render your stuff on the screen based on the, based on the state of the program.
Or actually, you don't render it on the screen. You describe L that this is the XD HTML that I want to have.
And L behind the scenes will take that HTML, convert it to what's on screen already and update it.
Only on the parts that needs to be updated in the whole screen doesn't get updated every time there's a single event.
And a fourth part that not all of every program is a subscribe.
That is, for example, if you want to set up primers at the beginning of the, picking of the programs.
This is, this is a.
So this is the stuff that, okay, subscribe. I create a primer like this and subscribe to the, subscribe to that.
And it will start creating events to you on a, on a, even, even base.
And in it and the subscribe around once the start of the program, but the update and you are on constantly every time there's something happens update.
I mean, every time the new message comes update takes care of that.
And every time update has run L, I will take care of that you will do run and it will displayed your stuff on the screen.
So it's really, it's a thing that I liked about this is that it's so well organized.
There's no accidentally updating the screen while you are modifying the state of the program.
And you cannot modify state of the program when you're updating the screen.
Everything is put, put neatly in the boxes and those boxes are labeled.
So when you define those four functions, you can construct an program.
I don't even know what that function is called, but it's in a tutorial.
So I mentioned commands earlier.
So these are four things like HDV requests, random numbers, geolocation, such.
So because L means, L means idea behind of L, one of the ideas behind the L means that the data is immutable.
You can modify the data.
You can only create a new data.
So if you have a model for example, you cannot modify that, but you can create a new model.
And that, that, that existing one, same thing with the sort of sending in the corner,
accidentally somewhere in the program to something that has an effect on the, for example,
she doesn't accidentally trigger HDV request.
Very explicitly creating those commands, the update function, no way else.
And when you create a command, you, L doesn't execute it yet.
You just say that, hey, L, please, do, do HTTP get to this address.
And when the message comes, when the result comes back, wrap it into this message and give it to the update function.
And L will take that command of yours and execute it behind the scenes.
And at some point you will get message, but you're not, but yourself aren't executing anything.
You are just asking L to do that for you.
So I think all of the code you're writing in the L is really neat, neat and simple.
Because this is everything inside.
This parameters come in, this data comes out.
You may call other functions from your function, but those are again, this, this data comes in, this data comes out very explicitly typed.
Nobody's, nobody's going to trigger a HTTP get, for example, or HTTP post somewhere deep in your code.
You can be sure that if you call this function, nothing else will happen, but the, you pass in the data and you get the answer back.
And that makes the, at least in my opinion, programs easier to, easier to keep, keep in, keep together and easier to understand what's going on.
Okay, JSON decoding encoding.
This is something that I actually struggled initially, partly because of the whole language is completely new to me, partly because I think that the L's default JSON parser is somewhat, it's not that good as it could be.
But in the end, it ended up pretty nice.
So in my case, the JSON is a boundary between ESO and the LM.
So on the server side, there's all those nice little, nice neat data structures modeling the, my domain.
And then they get turned into the string that is cast over the internet.
L receives that string, hopefully in a, induct and turns, turns that string into a object.
And vice versa, of course, when the L's and my end programs and something on the server, all those beautiful data structures get encoded into the string that is tracked over the internet.
And this is the path where you, where I got quite a lot of errors and problems because you don't have type safety.
You have a string and then you are doing your best to pass it and the compiler, compiler can help you to somewhat, but compiler has no clue what to do.
So also about the structure of your string that you are passing.
Compile this idea about the code that is doing the passing, either coding or encoding, but it has no idea what's in the string or what should be in the string.
And I don't really know if it in any central way could even have that information.
So the, if you talk about the coding first, the L's pass, JSON pass, we space on the combining passes together.
There's a bunch of simple passes like it knows how to take a string and turn that into the index or take a string and then that to the string or take a list of something.
And as a string presentation, list of something and turn that into the real list of something.
And those are some preset that they are like legos.
They have a really, the tiny passes have a safe interface.
Everybody has the same interface and you can combine them together.
So if you are passing an object, you are just saying that create me an object of this type.
And search from the JSON, this field named this and pass it with this pass.
And then you fetch this field, fill them in practice and pass it with this pass and the whole thing wraps it up.
So L talks about encoders.
So the whole thing gets into the encoder.
And that encoder you can throw into a new, sorry, decoder, of course.
And the decoder you can use, it has the exact same interface as that humble takes string written in.
Now you have a decoder that take a JSON string and return your object.
And then if you want to, if you want to decode bunch of, you have a list of these in your JSON.
You can just say that, okay, take a decode list and combine that with your, your specific parser.
And now you have a parser that parses a list of your things.
And you can have some logic there.
If you have a JSON that is very complicated, very complex, you can have that things like, okay, try this parser.
If it doesn't work, try this and try third one as the last one.
Like you can have some logic there.
It tries those three and uses the value, uses the rest that sucks it.
But if nothing sucks it, the whole thing just fails.
So the thing that is not so nice here is that it relies on the order of constructor parameters.
So if you have an object that takes a 10 parameters, it has 10 fields.
You have to test those decoders onto that object in a correct order.
Types will help you to keep things not mixed up, but it's still less than ideal.
I don't really know how to write it better.
And like I said, the elements standard, original JSON decoder is a bit of a, not so nice.
Like if you are parsing an object that has two parameters, you're calling, I think it's called object two function.
And if you are parsing an object that has three parameters or three fields, you are calling object three.
And so on all the way up to the object eight.
And that's not really good.
But there's a couple libraries.
One is JSON extra and one is JSON pipeline and I'm very good at that.
And the package system and those will make things a lot easier and a lot nicer.
Personally, I'm using JSON extra because that's what I stumbled first.
And only later on I learned about JSON pipeline.
Pipeline is maybe a little bit nicer in the face.
You don't have to repeat something that you have to repeat in the JSON extra, but both of them are on my knowledge pretty good.
I'll include a link into that.
So now let's find this.
Funnily, encoding was much easier than decoding.
Like, on the, on a retrofactor, a retrofactor isn't that surprising because you're just turning an object into string.
Basically, I'm just saying to the JSON dot encode that takes this.
Create me a.
Indecker and keep put in put it in this.
Value this indecker and then it will turn that into JSON Indecker.
Basically, it will just put a.
What is the marks around it, same thing with the list and same thing with the.
At the, at the JSON data types and then you have the.
Object that takes just takes an array of.
First, first element of the bubble is a name of the name of the field and second one is the value.
Seven one is the passing.
The actual actual decoding part.
So here you put, for example, an encode in your Indecker or again, if you have a complex thing you can put the.
Your own encode.
So again, you are.
Building encodes for.
Simple things and then combining those simple things to more, more complex thing to have a.
Big complex passes that are relatively easy to maintain.
I mentioned earlier that L is.
L is data structures are in multiple.
So you, you cannot.
You cannot modify them.
You can just take out existing data structure and create a new one based on that.
So with the numbers, it's easy like.
You are given one and you want to add something to that.
You just say one plus.
You, you, you.
Object plus one and you get to.
But if you have a.
If you have a.
Has tables or this narrative or associative.
I raise whatever you want to call them that I'm basically just a key value appears that you have a key.
And then you have a value.
And if you want to.
Work with those things.
I'm getting a bit more complicated.
Reading is easy because if you are, if you have an object called.
And then you have.
And you know that that's a.
That's a record.
I'm using them records here.
And you know that it's a record.
That has a name.
Name field in it.
You can just say.
Sip.
Name.
And you get the name out of friendly few.
If you know that the name object is a.
Again, a record.
You can say.
Name to something else.
Maybe there.
I don't know.
First name.
That.
That doesn't really make sense in the case of Sip.
But you get the idea.
So reading is easy.
But if you want to modify things, then.
Then I'm not modified, but create new ones.
Then.
Then it might get a bit tricky with the record.
The L has that thing that you can create a new record and replace values inside of that.
I mean, you can create a new record based on the old one and replace some of the values.
That is easy to do on the L.
No problems there.
But if you have a nested record structure and you want to vetting you, you have a.
For example, you have a ship record and inside of the ship you record you have a.
What are engine record and instead of the engine record, you have a crankshaft record.
And there you have some value that you want to change.
For example.
How fast?
I don't know.
And.
Normally.
To change that, you would have to.
You would have to take that.
Trankshaft record.
Replace the value of it.
The basic value that you want.
No, now you have a new new crankshaft record.
And then you want to stuff that into the engine.
So you need to construct a new engine record and replace the.
Your crankshaft there with that new value that you created.
And then you have to take the ship.
And create a new ship from the old replacing the.
Engine with that new engine that you created that has the.
New crankshaft that you created.
And this gets really tedious over time.
But.
Elm had.
Sort of kind of lenses.
The.
Set us.
Father.
Lenses come.
I think.
I first encountered those on the Haskell site.
On the Elm site, they are quite a bit easier.
Simple.
Because.
Reading is reading of the things is so easy.
But.
And.
Trutically told.
I never really got the.
Lenses working that way.
But.
That's.
That's not here or there.
But these are little helpers.
That.
Are.
For.
For.
For modifying master data structures.
Because.
You can write up.
Lenses.
That.
In our example.
Modifies the.
Engine.
Sips engine.
Nothing else.
And then you can write up.
Lenses.
That.
Modifies.
Engines.
Crankshaft.
And then you can.
Write a lens.
That.
Modifies.
Crankshaft.
Whatever value.
That.
Rotation speed, for example.
And these.
These.
Descriptions are just one lines.
They are not.
They are not complicated.
They are.
Just one.
Lenses.
And these.
Lenses.
You can then.
Chain together.
To.
Mega.
You.
Mo.
Mo.
Mo.
Complex.
Lenses.
And it.
Give it to name.
Or you can just.
Combine them.
When you need them.
Without giving them to name.
And then you can.
Just take your.
Take your.
Ship.
And say that.
On this ship.
Crunchy.
Lenses.
And.
Stuff.
Change the.
Value to this.
And it will.
Automatically.
Estraxxer your whole.
Ship.
Engine.
Crunch.
Dingy.
Set that.
Value on the crunch of the accent.
We.
Together.
To.
To.
To.
Enging.
And to you.
This is all happening in the.
Behind the.
Behind the scenes.
You don't have to worry about this.
You just say that.
Please.
Please update.
My.
Sips.
This.
Value.
It.
This.
Value.
And.
If you also like.
If you want.
You can also.
There's another syntax that can be used to run a function to that.
Value that you.
Set.
Set from the down there.
And.
Use that to replace it.
So that makes.
Editing those.
Those.
Nested data structure.
Much.
Nice.
And.
There are couple ones of these again.
Please focus.
Is what I ended up using.
I like the.
I like the name.
Like you have a really complex.
Big thing.
And it's just a.
Hey, please focus on this.
Thing here.
So.
And again, I will include a link into the.
So notes.
Where to find this one.
So.
That's basically what I had to.
What I have been playing with the.
Elm so far.
Happy.
I'm.
I'm.
I have been building our little.
Spaceship.
Designer.
Just for fun.
Like where you can.
Big.
But another.
Cases you have.
And then you.
Start putting on the.
Various components.
Like.
Bridge and.
Fensors and motors.
And such.
And then the.
Then the program.
Keep.
I have some rules that.
You.
Certain.
You don't.
Exit them.
Maximum fade rate.
And you have.
It's.
It's.
It's.
It's.
It's.
It's.
It's.
It's.
It's.
But I think that.
Because.
It's.
Completely.
So.
Pretty much everything I need to ask.
Ask.
Do I do this.
So.
Summars.
Marum.
What I like.
I like that.
The compiler.
We'll catch.
Summary.
It.
It's.
I got sort of caught railing the keeping me in the correct track, not letting me to go into the funny places where you can add springs and indicators together.
And I think that it might be easier if you have a big project for new people come in if you have a statically dark language like Elm.
Of course, the compiler will say that this place accepts this kind of input and this place combines with some other stuff like this.
It's like a sort of like a legos that is specifically designed interfaces.
You don't accidentally end up combining things incorrectly.
I mean, you can combine things incorrectly, but compiler will catch some of those incorrectness.
Incorrectness, not all compiling Elm program is valid.
It's not a bug free Elm program, but every compiling Elm program for a public is much, I don't know.
I just like in this case that these are compiling to help me to keep things in track.
Which is funny because I don't know.
I don't know.
I don't know how you can work on a dynamic dynamic type language is like some disks and Python or the other real mouse.
Maybe I just like pretty much every language, but for different reasons.
I don't know.
JSON parsing and coding and decoding after the initial hurdles is pretty nice.
Like you get your magical strings coming from the internet turned into a data structure in a way that hopefully catches some errors.
And on the other hand, you can take your beautiful data structures and create a string and send them to the internet with some confidence.
Documentation on the Elm is good.
The official site has a nice amount of examples and the package repository seems to have decent documentation.
At least on the package list that I ended up using.
What I miss sometimes sometimes there's some cases where I missed that I missed that the Elm would have died classes.
This is a feature from the hostile side, but you can usually work around that.
It's not that big thing and I mean it's not that big deal that they aren't there.
They are huge thing to implement.
I think that's because I think that's why they aren't in the Elm.
I found some discussions online where they're talking about implementing those and sort of kind of saying that we look into this.
But nothing has surfaced and it's nothing big.
It's just something that I missed sometimes.
And what I really should learn is to how to debug properly and how to do testing of the Elm programs properly.
I don't really know anything about that.
I know that there's a bunch of testing libraries out there, but I just haven't had time to look into those and experiment with those.
Same with the debugging.
I have resolved.
I have used that age old printing out data debugging.
So when I have a piece of program that isn't working, I'm just printing out what's going in and what's going out and trying to figure out what's wrong with that.
But that's a really nice thing about Elm because every function is just data in data out.
It's easier to think what's wrong with this.
Why isn't this thing working?
You don't have to go hunting all over the program.
Like, is this flat set or is this thingy mode in a state AOPU?
Everything is just, this comes in, you do some processing, this comes out.
That's nice and clean and makes thinking about the program, how good it is.
But that's about it, what I have to say about Elm currently.
It's a really nice language.
I heard or recommend you to have a look at it if you are doing some client-side scripting on a web and want to try out some different type of languages.
Okay, talk to you next time.
Yes.
You've been listening to Hecropublic Radio at HecropublicRadio.org.
We are a community podcast network that releases shows every weekday Monday through Friday.
Today's show, like all our shows, was contributed by an HPR listener like yourself.
If you ever thought of recording a podcast, then click on our contributing to find out how easy it really is.
Hecropublic Radio was founded by the digital dog pound and the Infonomicon Computer Club.
And it's part of the binary revolution at binrev.com.
If you have comments on today's show, please email the host directly, leave a comment on the website or record a follow-up episode yourself.
Otherwise, status, today's show is released on the creative comments, attribution, share a life, 3.0 license.