11 Jan 2024 · Software Engineering

    Gleam Language, Types for the BEAM

    9 min read
    Contents

    Every platform that achieves acknowledgment from its users and starts receiving admiration from different communities is growing in different aspects. We can see that .NET and JVM have different languages on top of them and even JavaScript lets us transpile different languages for it. Did you know that Whatsapp runs on BEAM? It’s built-in support for high load management and scalability provides the dedicated base platform for popular languages like Elixir and Erlang. I’d like to introduce you to another great language which runs on BEAM: Gleam.

    The Gleam language gives us the possibility to develop in the ML way (Meta-language like OCaml, not Machine Learning related). The language is evolving very fast, is close to version 1.0 and has an excellent, active community worth getting to know. So, let’s go for a tour.

    Another new language?!?

    Yes. I know. I think that maybe we have news about a new language appearing very often but in some way, it’s great because a new language means that people aren’t happy with the current languages and they are exploring and creating in the way they consider the languages should be. Every new language is trying to fix a different pain, like medicine. If you are unhappy because the system is taking longer to be compiled, maybe you can use Go, if you are unhappy because your Java isn’t functional enough you have Kotlin, and so on.

    In this case, Louis Pilfold an enthusiastic Erlang developer who fell in love with the BEAM, the Erlang Virtual Machine, and liked ML kind of languages. Louis considered that BEAM is great but it could be even greater if a kind of ML language could be available for developing. Most of the languages these days are moving to get static typing in some way, even Elixir, PHP, and Python. The advantage is undeniable for scaling the way we write code and avoiding different errors in compiling time that we could find in running time.

    Where did Gleam come from?

    Despite the compiler being written in Rust, most of the influences for Gleam came from Elm, even though there’s a very active community that knew both Elm and Gleam and they are contributing very actively making the language grow very fast.

    Gleam got it’s name because Louis was searching for something like Beam in the dictionary, reading until he found Gleam which was perfect because it means something similar and rhymes.

    In the beginning, Gleam was a beautiful way to write Erlang code. The Gleam compiler transpiled the code to Erlang and we could create an Erlang project to include some Gleam modules which will be compiled into the Erlang project. After that, the following versions let us include the Gleam code even for Elixir projects and lately, the Gleam compiler became the Gleam utility for creating projects, compiling and running our projects, even the change that drove Gleam to the next level was the possibility to transpile to JavaScript as well.

    We have the possibility to write our code in Gleam but obtain the compilation for BEAM or JavaScript, in other words, you have the same language and the possibility to write code for the backend and frontend.

    Why Gleam is good for us?

    One of the main problems when we want to start a project from scratch is what tools we can choose. If our team use always the same tools and the same kind of environments it’s not easy changing to a completely different environment. For example, if people work using Java, it’s easier to change to a language like Kotlin or Scala, because they share the same environment, than changing completely to another language like Python or Ruby.

    In the same way, projects that started using Erlang from the beginning are more inclined to change to Elixir or could be interested in Gleam, because they share still the same ecosystem and environment. The way for releasing and the way the system is behaving in production isn’t changing.

    According to the environment, using Erlang these days isn’t a popular option. Most people could prefer using Elixir, but people who like the way an ML language is handling the information in the compilation time, instead of keeping that for the running time were pushing hard in the Elixir community for a change and most of them are grateful for having a more mature solution like Gleam these days.

    How do we develop using Gleam?

    Gleam is still transpiled to Erlang when we choose to compile for the BEAM. But it does not mean that Gleam is more similar to Erlang like others. We can see a typical Hello World example as follows:

    import gleam/io
    
    pub fn main() {
      io.println("Hello world")
    }

    As you can see, we have to import the packages we want to use inside of the module. We are not defining the module, it’s intended the module is the name of the file. We are defining a public function called main that has no parameters and its return isn’t important for us but because the last function used was io.println and its return is Nil, the return of our function is inferred to be Nil as well.

    The types are compulsory only when they cannot be inferred or if we want to indicate them explicitly.

    We can try creating a project using the following command:

    $ gleam new greetings
    Your Gleam project greetings have been successfully created.
    The project can be compiled and tested by running these commands:
    
    	cd greetings
    	gleam test

    We created the project, and now we can go inside the directory and run the tests:

    $ gleam test
      Resolving versions
    Downloading packages
     Downloaded 2 packages in 0.11s
      Compiling gleam_stdlib
      Compiling gleeunit
      Compiling greetings
       Compiled in 4.12s
        Running greetings_test.main
    .
    Finished in 0.028 seconds
    1 tests, 0 failures

    The directory is pretty neat, we can find a file called gleam.toml where all of the configuration for the project is placed: name, version, description, and dependencies. You can find the directories for the code (src) and the directory for the tests (test), inside both directories you can find only one file and it’s pretty similar to the one I wrote above.

    Because the module has only the main function we could run it:

    $ gleam run
      Compiling gleam_stdlib
      Compiling gleeunit
      Compiling greetings
       Compiled in 0.03s
        Running greetings.main
    Hello from greetings!

    And we are going to add a dependency called birl. This is going to give us the possibility to work with dates, you know, you don’t know how hard is a language until you have to struggle with dates and times on it.

    We are going to add the usage for birl/time at the top of the module:

    import birl/time

    And then, we are going to rewrite the main function:

    pub fn main() {
      let num = time.to_unix(time.utc_now())
      io.println("Hello " <> name(num) <> "!")
    }

    As you can see we are using another function for getting a name, we are choosing the name based on the current time as an integer. We write the name function as follows:

    pub fn name(num: Int) {
      case num % 7 {
        0 -> "Dopey"
        1 -> "Doc"
        2 -> "Bashful"
        3 -> "Sneezy"
        4 -> "Happy"
        5 -> "Grumpy"
        6 -> "Sleepy"
      }
    }
    

    This way we ensure the input we receive is an integer number and using the remanent (modulo or %) we ensure the number is always between 0 and 6. Now if we run the code we can find the output depends on the time, you can run it several times to see how it’s changing.

    Now, let’s add the birl/time lib -> gleam add birl and give a try: gleam run. It works! We can go to the tour of the language documentation to continue and learn more about the language.

    BEAM or JavaScript, your call

    The Gleam language could generate both: JavaScript and Erlang. Some projects use specifically Erlang libraries and others use specifically JavaScript libraries, but Louis was working on getting most of the libraries available for both. The project we just created is generating the code for the BEAM, we can see that in the build/dev/erlang/greetings/ebin but we can just change the gleam.toml configuration and try again:

    target = "javascript"

    Note that when we choose erlang target, we need to have Erlang installed in the same way that when we choose javascript we need to have installed NodeJs.

    And we can just run again gleam run. It’s generating the same output but now, we can see in the path build/dev/javascript/greetings the code is JavaScript.

    If you are interested in developing using Gleam, maybe you could check the packages available for Gleam these days, and even you can use Erlang dependencies and even some of the Elixir dependencies, so there’s a lot you can do with the language. In my case, I’m building a database based on CQRS/ES, you can get some Gleam code examples regarding file usage, processes, and more.

    The future of Gleam

    Louis Pilfold is working full-time to improve the language. Thanks to the sponsors Louis can dedicate his time to performing the improvements and advances in the language and the Gleam ecosystem needs to be a great choice when the companies want to build a new project on top of the BEAM or if they want to use Node.js or Deno, or even if they want to use this kind of language for frontend.

    At the moment, the new features are released very frequently, the community is working hard and helping others to grasp the specifics of the language. The changes introduced that are affecting the code can run gleam fix and refactor automatically most of them. It’s a great advantage for avoiding accumulating technical debt.

    Note that gleam fix is only available for versions that have something to fix regarding the changes it introduces from previous versions. In that sense, v0.29 has available the command because there was a big change regarding the interoperability between Gleam and Erlang and/or JavaScript but it is not available for versions like 0.30 or 0.31.

    If you are interested in giving it a try, I recommend you start saying hello in the Discord server and checking out the language tour to limit the number of duplicated questions that could arise.

    And finally, if you enjoy the language as much as we do, give them support to continue growing.

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    Avatar
    Writen by:
    Manuel has been a developer since he was 12 years old he started with Basic, like others, but later also with Modula-2, Pascal, C, Assembler, and these before he was 20 years old. In his professional career, he has used Perl, PHP, Python, Ruby, Java, and JavaScript, and since 2009 he was more on Erlang and since 2016 he started with Elixir and Go. He can be considered a polyglot programmer and he loves to teach and mentor others.
    Avatar
    Reviewed by:
    I picked up most of my soft/hardware troubleshooting skills in the US Army. A decade of Java development drove me to operations, scaling infrastructure to cope with the thundering herd. Engineering coach and CTO of Teleclinic.