← Back to list

Exploring Programming Languages — Gleam

Let’s continue our exploration of programming languages with a new, interesting one: Gleam.

Blag aka Alvaro Tejada Galindo in Dev Genius · 2026-07-14 19:56 · 10 claps · 5.7 min read paywalled
#gleam #programming #programming-languages #functional-programming
Open on Medium ↗
Wiki topics: FT · Fine-tuning & Adaptation 💻 · Programming

Exploring Programming Languages — Gleam

Generated by Google’s Gemini

Generated by Google’s Gemini

Let’s continue our exploration of programming languages with a new, interesting one: Gleam.

Not a Medium subscriber? 😕 You can read this post for free here 🥳

Gleam is a relatively new language, only 9 years old. It was first published in 2016.

I started playing with Gleam almost as soon as it came out 🤓, though I gotta admit I left it on the back burner for a long time.

Fun fact: Gleam compiles to Erlang or JavaScript.

Second fun fact: Louis, Gleam's author, is pretty active on X and reached out to me when I first started playing with Gleam.

Ok, let’s jump into our main topic, which is creating an LED Numbers application.

The application should work like this: we input 1977, and it returns:

LED Numbers output

LED Numbers output

Keep in mind that we want to show this to newcomers to Gleam, not seasoned developers.

The first thing we’re going to do is create a Dictionary (Similar to a Hash or a Map in other languages) to hold all the components of the LED numbers:

import gleam/dict
import gleam/io

pub fn main() {
  let leds =
    dict.new()
    |> dict.insert("0", [" _  ", "| | ", "|_| "])
    |> dict.insert("1", ["    ", " |  ", " |  "])
    |> dict.insert("2", [" _  ", " _| ", "|_  "])
    |> dict.insert("3", [" _  ", " _| ", " _| "])
    |> dict.insert("4", ["    ", "|_| ", "  | "])
    |> dict.insert("5", [" _  ", "|_  ", " _| "])
    |> dict.insert("6", [" _  ", "|_  ", "|_| "])
    |> dict.insert("7", [" _  ", " |  ", " |  "])
    |> dict.insert("8", [" _  ", "|_| ", "|_| "])
    |> dict.insert("9", [" _  ", "|_| ", " _| "])
}

We create a new dictionary and insert all the key-value pairs.

We’re separating each number into three lines. So, for example, if we were to print the number 6, we could do it like this:

  case dict.get(leds, "6") {
    Ok(six)-> {
      let assert [s1, s2, s3] = six

      io.println(s1)
      io.println(s2)
      io.println(s3)
    }

    _ ->
      io.println("digit not found")

Let’s analyze what is going on here:

  • We’re going to use a case statement to determine the value of getting 6 from the leds dictionary.
  • It will either find a value and assign it to the variable six or fail to find one.
  • If the value is found and assigned to the variable six, we’re going to destruct the array elements into three variables: s1, s2, and s3.
  • We’re going to print each variable.

The result is going to be:

 _  
|_  
|_|

Of course, we would like to print more than one number, so the idea would be to concatenate each number’s line and then print them:

case dict.get(leds, "6"), dict.get(leds, "2") {
  Ok(six), Ok(two) -> {
    let assert [s1, s2, s3] = six
    let assert [t1, t2, t3] = two

    io.println(s1 <> "" <> t1)
    io.println(s2 <> "" <> t2)
    io.println(s3 <> "" <> t3)
  }

  _, _ ->
    io.println("digit not found")
}

The result is going to be:

 _   _  
|_   _|
|_| |_

Of course, we need a way to automate this, as we don’t want to keep reading each new value and then adding it to the println command.

Ok, we have then 3 lines that need to be printed. But an unknown number. It’s important to know at runtime how many digits our number has so that we act accordingly. Let’s say we want to print the number 1593, so we have 4 digits, and we need to print 3 lines, each line with sections of those 4 digits, so here’s our application code:

import gleam/dict.{type Dict, new, insert, get}
import gleam/string
import gleam/list
import gleam/io
import gleam/result

@external(erlang, "io", "get_line")
fn get_line(prompt: String) -> String

pub fn main() {
  let leds = led_map()

  let input =
    get_line("Enter a number: ")
    |> string.trim()

  render(input, leds)
}

fn led_map() -> Dict(String, List(String)) {
  new()
  |> insert("0", [" _ ", "| |", "|_|"])
  |> insert("1", ["   ", " | ", " | "])
  |> insert("2", [" _ ", " _|", "|_ "])
  |> insert("3", [" _ ", " _|", " _|"])
  |> insert("4", ["   ", "|_|", "  |"])
  |> insert("5", [" _ ", "|_ ", " _|"])
  |> insert("6", [" _ ", "|_ ", "|_|"])
  |> insert("7", [" _ ", "  |", "  |"])
  |> insert("8", [" _ ", "|_|", "|_|"])
  |> insert("9", [" _ ", "|_|", " _|"])
}

fn render(number: String, leds: Dict(String, List(String))) {
  let digits = string.to_graphemes(number)

  let rendered =
    digits
    |> list.map(fn(digit) {
      get(leds, digit)
      |> result.unwrap(["   ", "   ", "   "])
    })

  let line1 =
    rendered
    |> list.map(fn(parts) {
      case parts {
        [a, _, _] -> a
        _ -> "   "
      }
    })
    |> string.join(" ")

  let line2 =
    rendered
    |> list.map(fn(parts) {
      case parts {
        [_, b, _] -> b
        _ -> "   "
      }
    })
    |> string.join(" ")

  let line3 =
    rendered
    |> list.map(fn(parts) {
      case parts {
        [_, _, c] -> c
        _ -> "   "
      }
    })
    |> string.join(" ")

  io.println(line1)
  io.println(line2)
  io.println(line3)
}

Here, we’re importing several modules. One of the most important is the dict that will be used to create our leds map.

We also import string, list, io, and result to help us transform data and print the output.

We define a function named get_line that actually calls Erlang’s built-in function under the hood. This is how we read user input in Gleam.

We start in main.

First, we create our leds dictionary by calling led_map().

Then, we ask the user for a number.

The result of get_line includes a newline (\n), so we use string.trim() to clean it up.

Finally, we call render, passing the input and the leds map.

We split the input into individual characters by calling string.to_graphemes(number).

We use a map to loop through each digit and retrieve its value with get(leds, digit). If the digit exists, we retrieve its value; otherwise, we return a blank line. |> result.unwrap([“ “, “ “, “ “]).

We go line by line, extracting the values that we need.

To make things easier, let’s debug our application and see which values would be present on each iteration:

  • We’re going to use a loop going from 0 to the size of the input parameter minus 1.
  • For each digit, we’re going to read the leds variable content, extract the character we need, and assign it to a line variable.
  • Finally, we print all lines.
  • For the first digit, which is 1, we’re going to read the content of leds and extract the first element of the string. We’re going to concatenate this on line1 — the second element on line2, and the third element on line3.
  | 
  |
  • For the second digit, which is 5, we’re going to read the contents of led and extract the first element of the string. We’re going to concatenate this on line1 — the second element on line2, and the third element on line3.
      _ 
  |  |_ 
  |   _|
  • For the third digit, which is 5, we’re going to read the contents of led and extract the first element of the string. We’re going to concatenate this on line1 — the second element on line2, and the third element on line3.
      _   _ 
  |  |_  |_|
  |   _|  _|
  • For the fourth and last digit, which is 5, we’re going to read the contents of led and extract the first element of the string. We’re going to concatenate this on line1 — the second element on line2, and the third element on line3.
      _   _   _ 
  |  |_  |_|  _|
  |   _|  _|  _|

If we name our application lednumbers, we can call it the terminal like this :

gleam run

We input 1593, and get the LED Numbers printed

We input 1593, and get the LED Numbers printed

That’s it 🤓. I hope you liked it, and I will see you again in the next installment, which will feature Janet.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Follow me on X: @Blag Follow me on BlueSky: @blag.bsky.social Connect with me on LinkedIn: Blag aka Alvaro Tejada Galindo


메타데이터
post_id
5aa466d1028d
slug
exploring-programming-languages-gleam-5aa466d1028d
url
https://blog.devgenius.io/exploring-programming-languages-gleam-5aa466d1028d
canonical_url
https://blog.devgenius.io/exploring-programming-languages-gleam-5aa466d1028d
author_url
https://medium.com/@atejada
status
ok
fetched_at
2026-07-15 12:04:14