Full-stack developer happiness

György Balázsi
DAML Masterclass
Published in
7 min readJan 5, 2021

How to marry a delightful UI language (Elm) with a delightful smart contract platform (DAML)

TLDR: you can use any UI framework with your DAML driven application. But if you love DAML for its elegance, safety and business friendliness, I’m almost certain you will love Elm for the same reasons. And vice versa.

DAML is advertised, and rightly so, in this way: “Build full-stack, distributed applications for DLT, Blockchain, or databases in days”.

Elm is advertised, and rightly so, as “A delightful language” <> {“for reliable webapps.”, “with no runtime exceptions.” , “for data visualization.” , “with friendly error messages.” , “for 3D graphics.”}. (See the source code of the text animation in this file.)

How I came to the idea of connecting DAML with Elm

I told the story of how I became a DAML and Haskell aficionado in my introduction on the DAML Forum.

I first heard about Elm in Richard Feldman’s video Why Isn’t Functional Programming the Norm?. I guess the video was offered by YouTube because I was watching videos about Haskell, like Haskell is useless by Simon Payton Jones or Hitler reacts to functional programming (“What is a monad anyway? — A monad is just a monoid in the category of endofunctors”).

I learnt that the unofficial HQ of Elm is NoRedInk, where Richard Feldman and Elm creator Evan Czaplicki works. (For me it’s an added piece of fun fact that before NoRedInk, Evan was working for a few years with Prezi and traveled to Budapest several times a year, too bad I didn’t know about Elm at that time.)

I was fascinated how Evan talks about designing Elm like a cool radio which is easy to use because you don’t have to think about how to use the buttons:

http://www.youtube.com/watch?v=uGlzRt-FYto&t=20m10s

I was also fascinated by the fact that at a Canadian university, MacMaster, professor Anand teaches kids coding and maths using Elm.

Both DAML and Elm are functional, somewhat similar to Haskell, so I figured they might be a good fit.

I have to admit that I didn’t put much effort into learning JavaScript and React, because I belong to the crowd which “loves to hate” JavaScript because of its lack of type safety, and I don’t think TypeScript helps much. (As Richard Feldman explains in an interview, TypeScript gives you a false sense of safety. “Elm does not have the type any. The type any is sort of an escape hatch that is important to facilitate TypeScript interoperability with JavaScript. It may however lead to runtime type mismatches. The TypeScript type system is intentionally unsound. That may lead to crashes and worse things.”)

So i’m personally grateful to the creators of Elm for providing an alternative to the JavaScript ecosystem. But all this is personal to me: if you love JavaScript and React, it’s a perfectly good toolset to be used with DAML driven applications (like any other UI toolset for that matter).

My first ELM <> DAML application: create-daml-app

In December I embarked on my Elm journey.

First, I completed in ten days the Elm track on Exercism. Then I read (again) the Elm introduction written by Evan, and the first few chapters of Richard’s book Elm in Action. Then I started to write my first application in Elm, which is a skeleton version of the UI, written in React by the DAML people, for the create-daml-app demo application in the DAML docs.

The app is a simple social networking application, in which users can follow other users, and can write messages to users, who are following them. (In this context, “following” means something like “listening to”, not like following people publishing posts on Twitter.)

The DAML smart contract package consists of two templates, the User template and the Message template. The User contract instance stores the owner’s name, and the list of users they are following. When the owner starts to follow another user, they modify their own User contract by making the other user, whom they follow, an observer on it. So the list of followed users is identical to the list of observers on the User contract. A choice on the User contract makes it possible to the followed users / observers to write a message to the owner of the User contract. Exercising the choice creates a Message contract instance, which contains the sender, the receiver, and the content of the message, and is signed by both sender and receiver. (This is a nice example of the “propose / accept” pattern, which is a key feature of DAML. When I start following someone, I quasi make an offer to them to write messages to me, and the message is quasi a contract between us, signed by both of us. No spamming is possible.)

The professionally written React UI is much nicer than my skeleton:

I’m still at the beginning of my UI developer journey, so I concentrated on implementing the mechanics of the UI. The next step will be to learn the Grid CSS, and other nice things necessary to produce beautiful UI.

This is how my demo login page looks like:

I didn’t hide the fact, that for http communication you need a JWT token for all users. With the Sandbox, which doesn’t check the signature on the JWT token, you could use on the fly JWT generation in the background based on user name and ledger id. In a production grade application you need to hook up your app to a JWT service provider. Here is a blog post describing how it’s done: Easy authentication for your distributed app with DAML and Auth0.

After logging in, you can see this screen:

I modified the app mechanics a little bit. I only allow you to follow those users, who are already signed up for the site. The official React version creates a user in the background when you want to follow a new user. In order for that to work, I guess, you need to use on-the-fly JWT generation in the background, which wouldn’t work in a real-life application. So I display to the user those other users, who are signed up, but are not followed by them.

What cool things Elm can do for you

Elm is like React and Redux put together, minus the need to write JavaScript code. (The last part is not entirely true. You might need to write JavaScript if you want to integrate your Elm code with JavaScript code, for say using a websocket API or an external UI library. Currently Elm compiles to JavaScript, but in the future hopefully will compile to WebAssembly. It’s similar to React in that it uses virtual DOM, and similar to Redux in that it handles application state. Actually, Redux was inspired by Elm.)

It has a bunch of cool features which make developing and debugging a breeze.

The first and foremost is the Elm Architecture. This is an interface which structures the message and command flow of your application, as well as the rendering of the UI on the screen.

This is a simplified representation of the Elm Architecture, leaving out commands and subscriptions:

The essence of it is that the main component of your Elm code are the following ones:

The Model is a data structure which stores the application state. It gets initialized by the init function, and gets updated by the update function.

The UI gets rendered by the view function, using as input the contents of Model, whenever Model changes. (In Elm, rendering is extremely fast, because in the background, it uses a virtual DOM, so that only the changing DOM nodes are updated. Additionally, further optimization are possible, like keying list elements for tracking reordering, or lazy evaluation. )

In the view function, HTML nodes are represented by function values. The node generating functions take two arguments: a list of style elements, and a list of child nodes.

The update function gets triggered whenever a message is fired in the application. This can happen either by UI events, like modifying a text input or pushing a button, or getting back the result of a command, like a clock tick, a random number, or the answer to an http request.

For http communication, Elm uses JSON composable decoders and encoders. The decoders also typecheck the incoming JSON messages, based on what type your application is expecting.

https://guide.elm-lang.org/effects/json.html

With subscriptions you can use websocket API’s. I started out in that direction, but DAML currently doesn’t expose the streaming version of the parties endpoint, so I switched to polling the REST API for the list of signed up users and the active contract set visible for the logged in user. For polling, I also need a subscription, which is a clock tick, triggering the API request.

You can find further useful details about how ELM works in the two resources I have mentioned before: the Elm introduction written by Evan Czaplicki, and the book Elm in Action, written by Richard Feldman.

Here are some snippets from my code. You can find the whole code in this repo.

--

--