Click here to play! Set is a fun puzzle game that challenges your thinking skills.
In the Winter of 2015, I took Functional Programming at the University of Chicago. The course focused on topics in functional programming, specifically purely functional data structures, and used the Elm Programming Language, which compiles to JavaScript, for implementations. Elm, though still in development, is a superb way to write applications for the browser: it is a strongly and statically typed, functionally reactive language that is remarkably easy to use. As one of my projects for the course, I implemented what is essentially a training tool for the popular card game Set.
Though Elm is still in its infancy, it is a promising language. Functional reactive programming is very powerful, and the functional programming paradigm generally brings a pleasant elegance and assured type-safety to web development. This makes it not only easy, but also enjoyable to write, read, and debug Elm code. I think the design philosophy behind Elm is very well-considered — it straddles a good balance among power, expressiveness, and ease of use. I expect Elm to become increasingly popular as time progresses.
That being said, there are of course parts of Elm that could be improved or are otherwise controversial. I could nit-pick the presence of a few bugs in the Graphics libraries (e.g. textures and links seem to not work properly), but those sorts of minor issues are to be expected of a language-in-development. More seriously, I'm concerned that the functional programming paradigm can occasionally be too restrictive, coercing the user into writing a solution in a very particular way, constrained by the syntax of the language. The current absence of straight-forward iteration, or the impossibility of converting a Signal into a constant value might be frustrating to some users. I think there are effectively three ways of handling such issues:
- Abstraction: devise more abstract internal wrappers to hide potentially frustrating or confusing issues from the programmer. As an example, I had to make significant use of the Random library for generating random values. Elm currently requires
the programmer to keep track of the Seed for generating random values, which can be tedious. I think that the programmer's experience would be improved if all Seed-handling was
abstracted away from the user and done automatically (perhaps directly in JavaScript).
- Superficially compromise the functional purity of elm: incorporate features that, to the programmer, look like imperative alternatives, but are simply imperative-style wrappers on functional methods.
- Actually compromise the functional purity of Elm, and incorporate some imperative features, moving Elm closer to languages like OCaml in terms of programming paradigm.
Finally, I think that it was a good choice to use a language-in-development to teach a class. It was interesting to be exposed to the front lines of programming language development — to occasionally encounter bugs, check out the source code, report issues, create packages, etc. Moreover, because Elm is not yet mainstream, resources like StackOverflow threads, tutorials, etc. aren't really available, which forced me to spend more time thinking about problem-solving, digging through source code, reading the documentation, and simply experimenting. (I note that I spent a lot of time fiddling with the Elm Examples, the educational value of which is top-notch.) As such, I think that made for a good learning experience.
The GitHub repository is available here. Note that I wrote this application in Elm 0.14.1, and Elm is undergoing rapid iterative development, so the .elm files will likely need to be adjusted in the future. Please contact me if you find any bugs/errors, or use my work for any interesting derivative work — I'd like to see what you come up with.
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.