Found languages: Inko and Gleam

Today, some quick notes on two relatively young languages I came across recently that I found interesting. Both combine things I like in Rust (an advanced type system) and Erlang (nice concurrency primitives).

Inko

Inko is about five years old. Why I like it:

  • Rust’s single-ownership semantics (with a super-charged borrow checker).
  • Option and Result style null and error handling. I’ve enjoyed this in Rust.
  • Erlang’s actors, but with type-checked messages.

I found Inko’s combination of these features compelling.

Results and error handling:

import std.fs.file.ReadOnlyFile
import std.stdio.STDOUT

class async Main {
  fn async main {
    let size =
      ReadOnlyFile
        .new('README.md')             # => Result[ReadOnlyFile, Error]
        .then fn (file) { file.size } # => Result[Int, Error]
        .unwrap_or(0)                 # => Int

    STDOUT.new.print(size.to_string) # => 1099
  }
}

Concurrency:

class async Counter {
  let @value: Int

  fn async mut increment {
    @value += 1
  }

  fn async send_to(channel: Channel[Int]) {
    channel.send(@value)
  }
}

class async Main {
  fn async main {
    let counter = Counter { @value = 0 }
    let output = Channel.new(size: 1)

    counter.increment
    counter.increment
    counter.send_to(output)
    output.receive # => 2
  }
}

Read more about Inko.

Gleam

Gleam was introduced in 2019, so it’s about four years old. I like Gleam because it adds strong typing to Erlang’s advanced concurrency model and VM. It describes itself like this:

The power of a type system, the expressiveness of functional programming, and the reliability of the highly concurrent, fault-tolerant Erlang runtime, with a familiar and modern syntax.

Using pipelines and actors to parallelise processing:

fn spawn_task(i) {
  task.async(fn() {
    let n = int.to_string(i)
    io.println("Hello from " <> n)
  })
}

pub fn main() {
  // Run loads of threads, no problem
  list.range(0, 200_000)
  |> list.map(spawn_task)
  |> list.each(task.await_forever)
}

Defining types:

import gleam/io

pub type SchoolPerson {
  Teacher(name: String, subject: String)
  Student(String)
}

pub fn main() {
  let teacher1 = Teacher("Mr Schofield", "Physics")
  let student1 = Student("Koushiar")
  let student2 = Student("Naomi")

  let school = [teacher1, student1, student2]
  io.debug(school)

  io.debug(teacher1.name)
  io.debug(teacher1.subject)
}

There’s more at Gleam’s homepage.

← Older
Rust: using `String` and `&str` in your APIs
→ Newer
I ported my toy database index to Rust and I liked it