Picture it logo Blog Create

Tech: Why I chose Elixir and Elm for Picture it

by Rogerio Chaves
published: 17-09-2022

(this post cover image was generated using Picture it pictureit.art/p/17b616d0-a-purple-water-drop-and-some)

Across the years I built many side projects, I learned a lot and could discover my favorite tech, but one thing in common with those projects is that they were small, and did not connect many of my tastes

So, the idea to build Picture it came to mind, as a product that would allow me to use a lot of ML, something I’ve been learning and playing with for years, plus something that has a big scope and I can pour all my knowledge on, to keep building and building

Since it’s was my project, I got to choose the tech stack, so I wanted to be hipster and have fun, of course, but at the same time, AI art is at all the rage right now, and I wanted to build a successful product too, not just a fun project. So, it had to be a cool stack that also allows me to move fast: Elm, Elixir and Python

It may sound weird, such a hipster tech for someone that wants to move fast, why not just python and javascript? Slap some code together from the interwebs and the MVP is done right?

Well, hear me out, first of all, there is Python, but that’s because when dealing with ML there is no escaping that, you have to use Python, but I don’t feel Python allows me to move fast as some people feel, and definitively not as safe, so I use Python but as a separate small service with an API, just to provide the ML model execution, nowadays with Nx I could try to convert the model to run in Elixir as well, but I don’t think it’s worth the effort yet

Then, the bulk of the backend is in Elixir. Elixir is a functional programming language built on top of ErlangVM, which means it’s FAST by nature, but also, it has a Ruby (❤️) inspired syntax, which together with its web framework Phoenix, makes me feel very much at home as Ruby on Rails used to on the old days, and allow me to move super fast to build things, as Rails did. The main difference is that, being Elixir, I don’t need to worry about performance, at all, it’s just fast, but also, being functional and having some compiler type hints, makes it way harder for me to shoot myself in the foot, I feel it allows me to move faster (both in dev and performance speed) while also with good enough safety

Now, it’s not that safe either, being a dynamically typed language means I can easily have many runtime errors, still, I feel in the server this is a very good trade off to make compared to the boilerplate something like Rust or Haskell would add (if I really wanted type safety) for my project

Additionally, performance is not really important in my case, although it’s very nice not having to worry about it, the biggest bottleneck is actually in the GPU, on the Python AI model generating the art, but, Elixir is great at concurrency with its actor model, and allowed me to quickly build a priority queue the way I wanted to organize the requests before they reach the GPU for a better user experience

Now on the frontend I do go for a very strongly typed language: Elm, famously know for having no runtime exceptions, at all, might seem weird choice for wanting to move fast, since I can’t just hack and slash with it, but it does allow me to move fast enough, with a LOT of safety. For every situation I get annoyed I need to write a lot of Elm boilerplate for a simple thing, there is another situation where I need to do a big change and move everything around and at the end everything just works, as if by magic, there are usually no bugs

I do think this kind of guarantee is even more important in the frontend, since in the backend, most things that explode are captured by the error tracking tool, Sentry warns me, I fix it quickly, and move on, but on the frontend, a lot of times bugs just result in terrible user experience, where nothing explodes for the dev to become aware of it, the user just gets annoyed and leave, and you have no clue why

So once my UI is working, I want it to keep working, even if I move fast and break things, I want them to break… less.

Now, one big issue is that there is A LOT out there built and ready to use for React, or even plain javascript, but not for Elm, meaning a simple carousel would take me ages to build, and I certainly wouldn’t get it right. In this situations I don’t shy away from injecting some JS in the middle of my Elm, I don’t think twice about throwing the safety away in exchange for a pre-built complicated component, communicating from JS to Elm back-and-forth. But yeah, for the very few lines of JS I have I already added a typescript compiler, because I can’t stand the complete unsafety anymore

As a side note, both of those languages have a learning curve, that may or may not be steep depending if you have any FP and strongly-typed background, I already had years of experience in Elm and some in Elixir, so it might not be as productive for you on the early days

This was the first tech post in this blog, about the rationality behind the tech stack choices, I hope you enjoyed. I’m sharing this because I believe in #buildintheopen, and I want to continue to share our challenges and solutions as Picture it evolves

See ya!


More posts

Introducing Guide the Drawing

Read more

Picture it Just Launched!

Read more
See all ›