Laziness would be good for Time.Extra.posixToParts

In this post I’m going to show a good example of where laziness would work well. This is of course not an argument that lazy programming languages are somehow better than strictly evaluated programming languages. Rather what I wish to do here is answer the question, what is laziness good for? My example here comes from the justinmimbs/time-extra Elm package. The main purpose of this library is to provide a means for working with the standard library’s Time.Posix values. Functions are provided to calculate the difference between two time values, and also to add/minus a given interval from a given time value. So for example it provides a convenient way to take a given time value and add one day, or two hours, or six months. ...

October 27, 2022

No more imports

Imports in most languages always seem like a bit of an add-on, a separate language to the actual language. Today’s post is a thought experiment regarding removing imports from Elm/Gren. Ultimately I think it’s probably worthwhile having the import statements there, but this is an interesting (and quick) thought experiment. If we remove import statements from the head of a module file the first thing to note is that a file then becaomes one module declaration line followed by simply a list of top level declarations. However, we would obviously need someway to refer to values and types defined in another module. ...

October 6, 2022

Structural Custom Types

There have been a few proposals for extensible custom types in Elm, the idea is that they are somewhat analogous to extensible record types. In this post I wish to give a proposal for how to make custom types ’extensible’ that could play well with opaque types. The key point is that we need not focus on extensibility so much as the distinction between structural and nominal types. The slightly longer summary is to say that we can make custom union types structural types. This means that custom union type declarations are actually type aliases, just as record type definitions are in Elm. Two record types can share the same field, and thus it is trivial to make two record types one of which is a sub-type of the other. Similarly if custom union types are structural, and their associated definitions type aliases, two such custom union types can share a constructor, and again it is trivial to create two custom union type definitions one of which is a sub-type of the other. With this apparatus we can implement opaque types by choosing to expose a type either nominally or structurally, this gives us opaque types in which the underlying type can be a primitive type, a function type, a record type or a custom union type. ...

June 29, 2022

SimulatedHttp, functors and sed

In this post I’m going to describe an awkwardness encountered when using elm-program-test to simulate HTTP events in the program being tested. I will then describe ML functors, a feature of the SML/Ocaml module system and show how these would solve the awkwardness. I’ll then show how it’s pretty simple to hack together a “poor-person’s-functor” and use that to solve the aforementioned awkwardness. An awkwardness when simulating HTTP for testing If you haven’t used elm-program-test to test an entire Elm program I recommend trying it out. I’ve found that it not only does the obvious part of helping to build robust tests for Elm programs, but also helps me structure the Elm program in a way that is better for testing, but also just generally better. ...

March 11, 2022

Let signatures

A throw-away comment on the elm-radio episode debugging in elm led me to re-evaluate one of my Elm practices. The comment concerned writing a type signature for values/names defined in a let-in scope. I’ve always done this in what seemed to be a traditional accepted practice. That is omitting pretty much any and all signatures on names defined within a let-in scope. If you look at most Elm code you can find on the web, in particular in the elm-lang guide, and in documentation for elm libraries, you will find the same style. ...

May 29, 2021

Immutability bugs again

Previously I’ve written about immutability bugs which are bugs that are more likely in an immutable language than a mutable one. I think these are relatively rare, but they do exist. A good example has come up on the Elm discourse. The person asking the question wants to create new unique identifiers for items in their model. To do this you can simply keep a count of the number of identifiers you have thus far created. So you can do something like the following: ...

April 7, 2021

Templating HTML and String interpolation

When I first started writing web applications I was using Python, and pretty much by default I started using a templating language to actually render the HTML. There are quite a number of templating languages (or frameworks) for Python, I tried a few and found them to be mostly much of a muchness, that is to say I couldn’t quite work out why so many existed since the difference between them seemed minimal to me. ...

April 6, 2021

Overusing Right Pizza

Programmers are good at following rules. Rules make for reducing the number of decisions you have to make. That’s why we like rules such as “do not have functions that are longer than 300 lines of code” much better than “try not to have your functions too long, but sometimes you need it, so it’s a judgement call”. You might think that kind of rule gives you more flexibility, but just means you have to make more decisions. Should I really refactor this function it seems fine? That is easy to answer with the first rule, much more difficult with the second rule. ...

April 5, 2021

Case for if-then-else

I mostly do not use if-then-else. Part of this is just a common Elm feeling of desiring to keep the language small, and since we have case expressions we do not really need if-then-else. But there is another part to it, I can order the branches anyway I like, I do not have to have the True branch first. Why would I wish to do this? My feeling is that as you’re reading code, there is only so much you can keep on your “stack”. So if you have a large branch of an if-then-else and a small trivial one, I tend to place the small trivial one first. ...

April 4, 2021

Uses and definitions

Sometime in the early part of the century, think about 2004, I saw a talk which analysed source code for defects. They had used, what was at the time fairly new, online source code repositories for open source programs. They determined that a piece of code was buggy if it was changed in a commit which fixed a bug. The authors analysed the code (which was all written in Haskell) to see if they could determine differences between ‘buggy’ code and ’non-buggy code’. I wish I could remember the authors or the title, but I cannot. ...

April 3, 2021

Another polymorphism blind spot

Yesterday I detailed a simple fragment of code that is untyped in traditional Hindley-Milner type systems (such as that employed by Elm), but which is a perfectly reasonable bit of code. I think of this as a minor irritation and quite easy to live with. I term it a blind-spot of polymorphism, because in general I find that polymorphic Hindley-Milner style type systems map pretty well on to the types of programs that I wish to write. Aside from the issue of meta-programming, but that’s quite a separate issue. ...

April 2, 2021

Polymorphism blind spot

I am a huge fan of polymorphism and of accompanying static type checking. I find that, meta-programming aside, I mostly do not wish to write the kinds of things that are allowed by dynamic typing but disallowed by static typing. There are two exceptions, or blind spots to this and I thought I would detail the first one. Suppose you have a data structure with several Maybe fields: type alias Preferences = { favouriteFood : Maybe Food , favouriteBand : Maybe Band , favouriteColor : Maybe Color , favouriteNumber : Maybe Int , favouriteName : Maybe String } Now suppose you want to count how many of these are set: ...

April 1, 2021

Elm missing features #1033

Global variables have a bad name, mostly for good reason, but as with most things which are considered harmful some have uses, whilst others are symptoms of specific needs. Elm of course, being a purely functional language (by which I mean it is devoid of any side-effects), does not have global variables. It does have global constants. I feel like there is a missing feature in between these two. A global constant that is initialised on startup, perhaps by the program flags. ...

March 31, 2021

Elm input states

A small design decision has come up whilst developing with Elm on both the front-end and the back-end. The issue concerns an input that has some UI state, that doesn’t need to be transfered from front-end to the back-end (or vice versa). So I’m going first explain an example of an input that might have some associated UI state that you need to keep track of. Then I’m going to explain how you might represent this has part of a larger entity that needs to be encoded into JSON, and decoded from JSON to send to and from the front-end and back-end. ...

March 30, 2021

Elm-format features

I’ve spoken before about how great and liberating elm-format is. Once you cede control of the formatting of your source code, other possible features arise. Some of these could potentially take the burden away from the code editor tools. An obvious example would be the formatting of multi-line comments. When you change a multi-line comment, you often have to do a bit of formatting if you wish to keep the lines under a given character count. ...

March 28, 2021

Tailwind so far

I’ve started using Tailwind in anger now, and whilst I cannot say I’ve fully completed a project I have some thoughts on it. The first thing is, I do not hate it. I can see how for a certain kind of development team, in particular single developers who are going to do the styling themselves anyway, doing the styling in whatever language you’re using to generate your HTML is quite liberating. In particular I do not have quite the same fear I have of changing the styling. In large projects I find they get to the point where I start adding more and more class names to the elements so that I do not have to modify the current CSS but rather add more. That way I’m more confident of not breaking anything that is currently working. However, of course that’s not a sustainable path forward. So I’m pretty pleased that the tailwind approach is seeing me more willing to change the current styling. ...

March 27, 2021

Elm paradox

As Paul Graham’s blog has been replaying some pretty old posts so have I been reading them. A recent one was the python paradox. I think this applies pretty well to Elm at the moment. The Python Paradox was written in 2004 when Python, was still what one might call an esoteric language, that is, it wasn’t particularly popular. Whereby popular, we mean, used by many people, rather than liked by those that used it. Even at the time Python was very much loved by its users. Anyway the basic idea in the Python Paradox, is that programmers at the time did not learn Python because it was good for their resume, or it was good to find a job, because there were no python jobs. Because of this, it means that they were learning Python purely for the love of programming, and perhaps because Python seemed a bit different. Such programmers are nearly always good programmers, at the very least programmers with potential. Therefore companies should use Python in order to attract such developers, or at least require Python experience. ...

March 20, 2021

Response to a Tailwind Critique

Sometimes it’s possible to make a kind of judgement of a technology without trying it out, and that’s useful. In this sense you’re judging a book by its cover, see Paul Graham’s pre-critique of Java. Because of the recent release of Tailwind modules for Elm I’ve been trying to judge the cover of Tailwind before I jump in and start using it. One way of judging a technology without trying it, is to look at critiques of that technology. Do those comments hit home for you? A prominent critique of Tailwind came up on my feed. I think the author of this critique just doesn’t share similar problems to the ones I typically face, and, I think are typically faced by Elm developers. So I’m going to go through most of the points in the critique article and roughly state why I don’t think they really apply for Elm developers. ...

March 17, 2021

Elm-review as an optimiser

I’ve written before about the prospect of compile-time laziness and using elm-review to act as an elm-to-elm compiler pass. Obviously one way to implement compile-time laziness would be to fork the compiler. As I said previously the use of elm-review to do this instead is something of a low-risk route into this. If this works out particularly well it could be translated fairly easily into an internal compiler pass. An internal compiler pass would have the benefit that the output of the pass might not necessarily have to be valid Elm. It might also be faster because it would not involve the expensive operations of unparsing and re-parsing the Elm code. ...

March 16, 2021

Clients as a pitfall

Back looking Paul Graham’s old posts from 20 years ago, and back to the language design one. There is a section on pitfalls and the first pitfall is about clients: This is just a guess, but my guess is that the winning model for most applications will be purely server-based. Designing software that works on the assumption that everyone will have your client is like designing a society on the assumption that everyone will just be honest. It would certainly be convenient, but you have to assume it will never happen. ...

March 11, 2021

Is Elm faking work

It’s always worth examining the things you love for the reasons why. Could something you think is improving your productivity actually be harming it? Perhaps in a way that makes it feel like you’re being productive. Continuing the look at some of Paul Graham’s older posts, this one regarding object-oriented programming languages popped up on my feed. I think it stands up pretty well over the previous two decades. I wouldn’t say object-oriented programming has been debunked, but it has certainly lost some of its hype. I thought about Elm when reading the following third point: ...

March 10, 2021

Paul Grahams's Programming Language Questions

I’m not sure if it is intentional or something to do with the RSS configuration on his site but Paul Graham’s RSS feed is going through a redux of posts from 2001. Some of these are interesting to read with the 20 years worth of perspective. Back in 2001 he thought that Java didn’t smell great, a point he made without trying the language. I think for the most part this post has stood up well to time other than the frequent use of Perl as a counter-balance. ...

March 9, 2021

Impossible states and stale messages

There are two quite common pieces of advice for Elm programmers: Make impossible states impossible Avoid carrying state state in your messages Impossible states impossible The first is a call to carefully consider the types, mostly in your model and messages. So do not have a Maybe User type used anywhere where you consider it impossible for the value to be Nothing. So for example, you might have a message, such as the liking of a post, that requires a logged in user, because the request takes in the authorisation token: ...

March 8, 2021

Html.Lazy and extensible records

I really like using Elm’s extensible records. There is a little debate about how best to utilise them. It seems clear they should be used for narrowing the types of function arguments. Narrowing the type of an argument to a function often makes it significantly more general. Here’s a quick example, suppose you have a User type in your application, you might have only a few of them, say a list of friends of the current user or something. So you might write a function to find a particular user in a list: ...

March 7, 2021

Let-in Let-in

I noticed a sort of surprising syntax thing in Elm yesterday. When you think about it, it’s not all that surprising, but the question is, can it be made of use? So what I noticed is that the in expression of a let-in expression can itself be a let-in expression. So the following is valid syntax: ... let x = 1 in let y = 2 in x + y That’s because the syntax of let-in is let <def-list> in <expr> and let-in is itself a valid <expr>. So you can have as many let-in blocks chained as you see fit. Clearly, you can just delete the middle two in-let lines and you still have a valid expression. The question then is, what is this useful for? ...

March 3, 2021

Restricted text input in Elm

A little tip for restricted text input in Elm. I’ve coded up the general idea in an ellie. This is really a general HTML tip, that I didn’t know existed, but for some reason I feel it works pretty well in Elm. The sitation is that you wish to restrict a text input to one of several possibilities, but there are many possibilities, so a select element is probably not correct. You may or may not wish to prevent any output not in the list of suggestions. What I didn’t know is that you can define a datalist element that has all the suggestions and the browser will interpret that appropriately provided you set the list attribute on the input element. As for invalidating it, you could use a pattern attribute, but I think in Elm you’re probably doing your own invalidation anyway. ...

March 2, 2021

Unrelated bar usages

This post is pure, unadulterated bike-shedding, on the use of the | operator for extending a record type. As I’ve said many times before, one of the big draws of Elm is the clean, and very slim syntax. This has numerous benefits. One thing I never noticed before but has just been pointed out on the Elm discouse is that the bar operator | is used for two different, unrelated record-type meanings in Elm. The first is within a record type to indicate that the record is an extensible one: ...

February 27, 2021

Pattern matching records

A blog post popped up on my feed, which has the main point that tagged union types (called custom types in Elm) are overrated for implementing intermediate representations. To be clear the author is not saying that tagged union types are in general overrated, but their suitability for intermediate representations within compilers is just not that big of a win. It’s easy to see why tagged union types are thought of as perfect for internal representations of code in compilers. The grammar of a language kind of looks like a tagged union type already. You might represent the grammar of an elm expression in Elm’s custom types something like the following: ...

February 19, 2021

Missing language feature - Remove from scope

Today I’m going to talk about a language feature that I think is missing from most languages. I know of at least one in which it exists, I do not know of any functional langauges in which it exists. The language feature I’m talking about is the removal of a name from the scope. Let me first talk about a situation that is ripe for bugs, and then introduce the idea of removing a name from the scope so that you do not use it mistakenly. ...

February 17, 2021

Stale Messages in Elm

Coury Ditch reported on the trickiest Elm bug he’s ever seen. It’s a good read and a good caution against holding stateful information into your Elm messages. When I was very new to Elm one of the first things I had to do at a new company was figure out a bug that basically had the ‘Stale message’ anti-pattern as main reason behind it. So I’m going to described the bug and the solution. ...

February 16, 2021

Embedding HTML into an Elm program

Someone asked on the Elm discourse how to embed HTML into an Elm app. There are basically two approaches, which I will try to describe along with advantages and disadvantages. Translate the HTML to Elm Either by hand, or you can use an online tool. As the original poster seemed to find, there is a limit to how sophisticated such a tool is, but it’s probably worth a shot. However, this is only going to work if the HTML you are trying to display is not going to change. In the discourse posts, the HTML was what was presented to them from a legal website drafting a set of Terms and Conditions. But if say that HTML was being produced by some wysiwyg HTML editor, then unless you can automate the translation of the HTML to Elm this isn’t going to work. It obviously will definitely not be able to display dynamically generated HTML. ...

February 15, 2021

Surprising Elm

Popping up on my feed was an article on learning Python by looking through the gotchas and unexpected things that happen in Python. It’s a nice enough article, and clearly a lot of time has been spent polishing it off and even publishing a package to accompany it. What is a little disconcerting though is the sheer number of surprising snippets. A pretty reasonable goal for a language would be to have as few surprising parts as possible. That’s another advantage of having a very small language, there are fewer things that could have been designed in a surprising way, and perhaps more importantly, there are fewer moving pieces that can combine to produce strange or surprising behaviours. ...

February 13, 2021

Re-implement the browser

Single page applications are a good way to write responsive websites. Non-single page applications have to do a lot of re-getting of the same information, so they are often quite slow to move around. A single page application on the other hand tends to get most of what it needs up front, and then when you move around it only has to get the new data it needs for the new route that you’re on. This can make it seem very fast, in particular things like searching and sorting can be near instantaneous whilst on a non-single-page application they can take a lot more time. Even when you do need to go get more data, your app can feel more responsive because you only show a ‘working’ indicator in the part of the app waiting to display the new data. There are other advantages, such as lessening the load on your server since all the rendering is done on the client rather than the server. ...

February 12, 2021

Foldl and foldr

This is a pretty entry level post on functional programming. It concerns the folding patterns in functional programming. I’ll be using Elm as an example language, but the ideas are broadly similar in other functional languages. So I’m talking about the fold functions List.foldl and List.foldr. I’ll talk about a strict/eager language, though one of the interesting things about folds is that in strict languages the foldl is the ‘good’ one, whilst in lazy languages the foldr function is the ‘good’ one. I’m going to try to explain why the foldl is the good one in strict languages, I’ll leave why ‘foldr’ is the good one for lazy languages for another day. ...

February 11, 2021

Laziness again

I wrote recently about laziness, I was trying to convey a sense of how useful laziness can be. I pointed out that it does have some disadvantages. I have been reading Michael Snoyman’s series of posts on the bad parts of Haskell (part 2, and part 3). It’s part 1, that I’m interested in. He talks about the sum and product functions over lists, here is what he says: The sum and product functions are implemented in terms of foldr. Well, actually foldMap, but list’s foldMap is implemented in terms of foldr, and lists are the only data structure that exist in Haskell. “Oh, but foldr is the good function, right?” Only if you’re folding a function which is lazy in its second argument. + and * are both strict in both of their arguments. ...

February 10, 2021

Promises and Elm

For pole-prediction I’m experimenting with writing server-side Elm code. Alex Korban’s Elm-weekly newsletter alerted me to a nice article which suggests using Javascript promises. The stated benefit of this is that it: decouples the Elm code and ports from Express itself I’m not sure I understand the benefit of using Promises here. So I’m going to describe in a bit more detail the current solution in pole-prediction which doesn’t use promises and then re-show Eber Freitas Dias’s promise-using code. ...

February 9, 2021

Generating from types

I actually managed to do a little bit of work on the pole-prediction backend last night. There is a part where we store messages in the “database” (it’s not really a database, it’s really just persistent storage). So the messages are a variant type, and as such we need to write code to both encode each message into JSON, and decode each message from JSON. type DatabaseMessage = AddDriver Year Driver | AddTeam Year Team | AddEntrant Driver.Id Team encodeDatabaseMessage : DatabaseMessage -> Encode.Value encodeDatabaseMessage dMsg = case dMsg of AddDriver year driver -> [ ( "tag", "AddDriver" |> Encode.string ) , ( "arg1", year |> Encode.int ) , ( "arg2", driver |> Driver.encode ) ] |> Encode.object AddTeam year team -> [ ( "tag", "AddTeam" |> Encode.string ) , ( "arg1", year |> Encode.int ) , ( "arg2", team |> Team.encode ) ] |> Encode.object AddEntrant year driverId team -> [ ( "tag", "AddEntant" |> Encode.string ) , ( "arg1", driverId |> Encode.string ) , ( "arg2", team |> Team.encode ) ] |> Encode.object databaseMessageDecoder : Decoder DatabaseMessage databaseMessageDecoder = let interpret s = case s of "AddDriver" -> Decode.succeed AddDriver |> Decode.andField "arg1" Decode.int |> Decode.andField "arg2" Driver.decoder "AddTeam" -> Decode.succeed AddTeam |> Decode.andField "arg1" Decode.int |> Decode.andField "arg2" Team.decoder "AddEntrant" -> Decode.succeed AddEntrant |> Decode.andField "arg1" Decode.string |> Decode.andField "arg2" Decode.string _ -> Decode.fail (String.append "Unknown message string: " s) in Decode.field "tag" Decode.string |> Decode.andThen interpret As you can see all of this is very repetitive and lends itself well to being automatically generated. You can easily imagine some meta-code that, given a type definition, can automatically generate an encoder and decoder (there is also the elm-codec library but if you’re auto-generating these anyway then that’s less useful). ...

February 8, 2021

Laziness

I have spoken recently about compile-time laziness as well here and here. Both Elm and Purescript are pure languages that in theory could be compiled as a lazy language. Because there are no side-effects laziness wouldn’t change the behaviour of most programs and those that it does, it is because of infinite loops that do not need to be calculated. However both have chosen to compile in eager (or strict) fashion, partly to reduce the complexity of the compiler, and partly to allow easier interop with Javascript which is the target of compilation in both cases. ...

February 7, 2021

Typed meta-programming

This post is some vague, not-well-thought-out rambling on meta-programming in statically typed languages. As I have said dynamically typed languages tend to have meta-programming already baked in. This is because changing the program itself, doesn’t need to be re-type checked. However, the whole point of a statically typed language is that the program is type-checked before it is run. So you cannot then change the program at run-time because in that case the new program would not be typed. In theory of course you could allow this, but you would have to do one of three things: ...

February 6, 2021

Nested records and defensive programming

A fairly common problem for an Elm developer to encounter after around 6 months is that nested record update is a little painful. Suppose you have a form on your model, like this: type alias CommentForm = { content : String , subject : String , visibleToAll : Bool } type alias Model = { route : Route , commentForm : CommentForm , ... } So now you want to handle the message for updating the comment form. So you might have a handler like this: ...

February 5, 2021

Unit type and empty records

An interesting thread came up on the Elm discourse today. It concerned the point of the unit type () (which is also the only value of type unit). The question was do we really need this? Couldn’t we use the empty record {}. This then provoked the question of whether we even need tuple types at all, why not just always insist on record types? I find it quite interesting that even in Elm a language that is far more frugal with its syntax than most, you can still find parts of the grammar that have questionable use. I think getting rid of both the unit type and more generally tuples would be perfectly doable, though I doubt it will happen since it would be somewhat inconvenient for most since tuples are even used as the results of both the init and update functions. Hence all programs and probably a large proportion of libraries would need to be updated for the change. Nonetheless it’s pretty fun to imagine the language without tuple types. ...

February 4, 2021

Splitting Elm messages

Elm apps, require that we define a single type, usually called Msg, to host the type of messages that form a major part of the ‘The Elm Architecture’. This single type is usually a custom/variant type, and because it must host all of the messages that the app may consume, it can get rather large. This leads to a large update function. I do not think this necessarily a bad thing, but many beginners to Elm baulk at the idea of large functions, and so they seek solutions to break up their Msg type. The basic idea is to make your messages hierarchical, so you have a variant that itself contains a variant. The question is how best to split this up. I’m going to explain why the first instinct in this is usually wrong, suggest a slightly better way, and end up by claiming that the main thing is to remain fluid in your datatypes so that you can best represent whatever the current situation is, rather than cling to an old design for earlier requirements. ...

February 3, 2021

Type classes are meta-programming

A feature that is semi-regularly requested in Elm, or at least discussed is the issue of type-classes. Type classes are a means in Haskell of restricting polymorphism, which then allows you to write more generic functions that you would otherwise be able to. In fancy words that means that type classes support ad-hoc polymorphism, but you can forget about that. I’ll start off with a simple example, then show how you could acheive a similar result without the type classes. Finally I’ll use this to argue that therefore type-classes are a limited form of meta-programming. ...

February 2, 2021

Lambdas again

Just after I wrote about lambdas in Elm suggesting that they were not particularly useful and if we had a mind to we could remove them from the Elm language (very unlikely to happen since I think it would cause too much anger within the Elm community), I read on the awesome Python newsletter a post regarding lambdas in Python, specifically 5 uses of lambda expressions. The author doesn’t quite have a main point, but it seems to be that lambda expressions are useful and you should use them in your Python code. ...

January 30, 2021

Safe dead code removal and compile-time laziness

Jeroen Engels of elm-review and elm-radio fame has written an excellent blog post regarding the safe removal of dead code in a purely functional language. The main take-away is that because there are no side-effects, all code dependencies are explicit. Because of this it’s relatively easy to determine that code does not depend on other code, and therefore some code is dead (ie. unused), and can be safely removed. You can extend this idea, and say the order that code is executed in, is only dependent on the explicit dependencies between code. Two days ago I wrote about compile-time laziness, I showed that the following code: ...

January 28, 2021

Frugal syntax formatter

As I’ve mentioned many times on this blog Elm has a famously pretty frugal syntax. There are obviously positives and negatives from this. A potential negative is that you simply cannot write the code the way you would wish to, which presumably might mean that the code you do write is inferior, since you obviously had some reason for wishing to write it another way. Still, in general I think the positives outweight the negatives, and have even argued in the pass that Elm could consider removing some syntax, specifically lambda expressions and if-then-else expressions. Though it must be said I’ve also argued for the inclusion of the odd bit of new syntax. ...

January 27, 2021

More compile time laziness

Following on from yesterday I think there are various other ways in which a compile-time elm-to-elm optimiser could improve the performance of Javascript code output by the Elm compiler. It goes without saying that this does not necessarily have to be done as a separate tool, it could easily be incorporated into the Elm compiler itself. It is just potentially a lower barrier for entry to do it the separate tool way. It’s also a little easier to describe. ...

January 26, 2021

Elm's Maybe.withDefault

In certain circles in the Elm community it is seen as more ‘Elmish’, that is more idiomatic, or more desirable to write code using functions to combine/inspect common datatypes. So this code: Maybe.withDefault 0 mInt is more desirable than the following code which uses a case expression to achieve the same end: case mInt of Nothing -> 0 Just x -> x One question that arises, is does one compile to more efficient code? Let’s test this, we can easily write the following into an elm file and compile with optimisation turned on: ...

January 25, 2021

Elm and lambda expressions

I have remarked before that Elm is pretty frugal when it comes to syntax. Lambda expressions though are a sort of staple of functional languages. For no particularly good reason a language is not seen as functional if it doesn’t have lambda expressions. It’s even possible to see phrases attributing elements of functional programming that have found their way into mainstream imperative languges such as Python, and it often includes lambdas. So lambda expressions are somehow seen as a quintessentially functional feature. ...

January 24, 2021

Elm records and let declarations

Elm is pretty frugal when it comes to syntax. This has many benefits, one oft cited is that it helps beginners get started pretty quickly, in particular after learning the syntax for ten minutes or so a beginner can understand most Elm code out in the wild. I think a more compelling advantage is that the lack of syntax reduces the ways in which the same problem can be solved. It of course doesn’t eliminate this entirely, some people like to use |> and others much prefer <|, or even just to use parentheses. ...

January 22, 2021

Hungarian notation and Elm maybes.

There is an old but excellent post from Joel on Software which defends hungarian notation. Briefly hungarian notation was mis-applied in many places, and so something that wasn’t nearly as useful as hungarian notation was adopted and then (rightly) despised. That post is great and worth reading if you haven’t, but it is also quite long, so I’m going to first of all explain the correct hungarian notation that is useful, then the incorrect despised hungarian notation. Finally, I’m going to end by discussing how the old despised hungarian notation relates to Elm maybes. ...

January 21, 2021

Elm - Minor imports syntax tweak

I want to explain a minor tweak to Elm’s import syntax, that I cannot find justification for. Before that I’ll explain a syntax improvement that I at first thought was a no-brainer, but then came to realise was hard to justify, and certainly not a no-brainer. I’ll end by saying that despite the fact that I cannot find sufficient justification, I still think my minor syntax tweak should be adopted. ...

January 20, 2021

Terser error messages

I was reading a post found on Hackernews. Its main point is that shorter error messages are superior because the main problem is not obscured by other, mostly irrelevant details. I think it’s far from a universal truth, but some of their examples were pretty compelling. It got me thinking about Elm’s error messages. Elm’s compiler error messages are famously great. However, they are not typically short. This is a major boon for beginners. The compiler often explains in detail why it was not able to type check your entire program and possible fixes. So for beginners this is a major boon. For more experienced users however there is a lot of information being printed that is not helpful, mostly because we’ve seen it before. ...

January 18, 2021

Extensible custom types in Elm

There was a fairly long thread on the Elm discource regarding a proposal to add extensible custom (union) types to Elm. I thought I would try to summarise a little, the current status. In brief, I think currently the cons outweight the pros, but most of the cons are uncertainty rather than definite disadvantages so it is possible that some further work could tip the balance. I’ll describe here very briefly what an extenible custom type is, and then the pros and cons, why I think the cons outweight the pros at present, and finally a path towards overturning that. ...

January 17, 2021

Elm errors with filenames

Elm famously has excellent error messages, particularly for type errors. When the compiler detects errors in multiple files it outputs a little switch between which looks like this: `This `NeverEditable` value is a: Field.Editable But `withEditable` needs the 1st argument to be: Int Admin.Config.Orders.OrderTotals ↑ ====o======================================================================o==== ↓ Admin.Config.Basic -- TYPE MISMATCH ------------------------------------ src/Admin/Config/Basic.elm Although it’s a little redundant to repeat the filename (technically it’s a module name in the separator but since module names must line up to the filename it’s still redundant), I find this pretty helpful. Just one thing I would change, for the last error message, because you’re not at that point switching between error messages you don’t get a module or filename at the very bottom of the output: ...

January 16, 2021

Elm open source model

There was a thread on the Elm discourse regarding the communcation of expectations when contributing to Elm. It’s an interesting thread albeit mostly quite negative, but it’s still useful to hear people’s frustrations and view points. I wanted to focus in on one particular view point that seems pretty common. This is a direct quote from the thread: Thinking this a bit more, this actually sums up clearly the difference between Elm and other open source projects: ...

January 14, 2021

Elm and comma separated lists

In Elm comma separated lists (and records and tuples) are traditionally written with the comma on the next line preceding the next item like: elements : List (Html msg) elements = [ title , introduction , mainImage , mainContent , conclusion ] I’m quite used to this style from my Haskell days. Although the comma-at-the-start feels a bit unnatural at first, I think after a while you start to see the benefit of having a nice visual clue which distinguishes a contination of a previous item with the start of a new item. Another benefit in my mind is that it means the items naturally align even though each line has the same indentation. ...

January 13, 2021

Indent with two or four spaces

I’ve always indented Elm with four spaces. To my mind this looks nicer than two or eight spaces. It also seems to be about the default, relatively common in code seen in the wild. Recently I’ve found a really good reason to prefer two spaces, but I still cannot quite make myself accept it. I thought I would detail it here anyway. The ‘problem’ with four spaces comes when you want to indent nested comma separated entities. So a list of lists, or a list of record types. Suppose you have a list of people: ...

January 12, 2021

My opinionated import style

In Elm it’s possible to import a name from a module in two ways, you can either import the module and expose the name, or import the module, perhaps aliasing the module name, and then qualify the use of the target entity. This seems common in documentation, I’m not sure why it seems to be that having unqualified names “looks better”, and there is certainly a sense in particular for the elm/html library that the resulting code more resembles the HTML that is essentially being described. ...

January 10, 2021

Or patterns

Elm is famously pretty conservative when it comes to adding language features/syntax. In general I appreciate this, but or-patterns are something I have longed for for a long time. I feel they can drastically increase clarity. However I do understand that a ‘better’ solution may arrive and we will all be glad Elm held off on implementing or-patterns. Still I feel that in this case, it’s worth the risk, or-patterns are used in a few other languages and to good effect. ...

January 7, 2021

Defensive programming and validations

Defensive programming is generally defined using terms such as ‘impossible’, one definition on the c2 wiki has Defend against the impossible because the impossible will happen. In addition there is also the idea to do the right thing. Such a definition is obviously (and intentionally) vague. The question is, what is the right thing? That’s always situation specific and it can be a difficult part in programming. That’s what I find interesting here, the programmer can easily make happen whatever we want, but it’s difficult to decide what we should want. That’s difficult to follow so let’s try an example. ...

January 6, 2021

Elm extensible record syntax and warnings

Elm has extensible records, you can write a type like { a | x : Int } which means a record type that has at least a field named x of type Int but may have other fields as well. The general advice seems to be not to use these for data modelling but instead use them to narrow the type of function arguments. See this Richard Feldman talk and, for example, this Charlie Koster blog post. ...

January 5, 2021

Elm catalog

Alex Korban has released another version of his Elm Catalog. I think this is both very important work and very well done. This century it’s become popular for languages to include a package/library manager. I’m not quite sure when this started to become popular but certainly in the 90s such package managers were not common. This lead to many different ways to install libraries, and mostly including a new dependency was a chore at best. So the introduction of package managers as part of a language’s eco-system has been a major boon. ...

January 4, 2021

CLR, Purescript, and Elm

I’m going to talk about the common-language-runtime, and use this to contrast Purescript and Elm. Although I have in mind the .Net common-language-runtime, I’m more talking about the general concept. Specifically, it’s not just the common platform used as compilation target, but the idea of interoperability, in particular libraries that can be consumed by different languages so long as they adhere to the common-language runtime. Similarly whilst I’m contrasting Elm to Purescript, I’m more contrasting narrow versus broad scopes. ...

January 3, 2021

Builder pattern record update operator

The builder pattern seems to be prettty popular in Elm, here is an elm-radio episode dedicated to it. The builder pattern To be clear, the builder pattern is used where you have a data structure, usually a record, which allows for a reasonable default and can be customised by chaining modifier functions. A simple example is best to describe this. Suppose you have number inputs in your application. You might have some module tasked with rendering a number input, but the number inputs themselves can have various settings, so you have a NumberInputConfig type which controls both the view and update of a number input. ...

January 2, 2021