Gleam is a statically typed language for the Erlang VM (BEAM). It is designed to be a productive and fun language to work with. Gleam is a compiled language, which means that it is compiled to BEAM bytecode and runs on the Erlang VM. It is a functional programming language with a strong type system that helps catch errors at compile time.

Few things I like about Gleam are:

  • Gleam ships with all language tooling just like Go. This makes it easy to get started with Gleam.
  • Gleam’s async support is very good. It is easy to write concurrent code in Gleam.
  • No nulls representation in Gleam. This makes it easier to write safe code.

Few things I dislike about Gleam are:

  • Gleam is a new language and the community is still growing. This means that there are fewer libraries available compared to other languages.

Variables

In Gleam, variables are declared by specifying the type after the variable name. Gleam also supports type inference using the = syntax.

Syntax and Example:

let a: Int = 10 // Explicit type declaration
let b, c: Int = 20, 30 // Multiple variables

const pi: Float = 3.14 // Constants
const world = "Hello, World"

let x = 42 // type inferred as Int
let y = "Hello, Gleam" // type inferred as String

Control Statements

Control statements in Gleam direct the flow of execution. They include if, else, case, and looping constructs like for.

Syntax and Example:

// If statement
if x > 0 {
    io.println("x is positive")
}

// For loop
for i in list(1, 2, 3) {
    io.println(i)
}

// Case statement
case x {
    0 -> io.println("x is zero")
    _ -> io.println("x is not zero")
}

// Case statement with guards
case x {
    x if x > 0 -> io.println("x is positive")
    x if x < 0 -> io.println("x is negative")
    _ -> io.println("x is zero")
}

// List pattern matching
case list(1, 2, 3) {
    [1, 2, 3] -> io.println("List matches")
    _ -> io.println("List does not match")
}

Functions

Functions in gleam are defined using the fn keyword. They can take zero or more arguments and return zero or more results.

There are public and private functions in Gleam. Public functions can be called from other modules, while private functions are only accessible within the module (file).

Syntax and Example:

// Function declaration
fn add(x: Int, y: Int) -> Int {
    x + y
}

// Function call
io.println(add(42, 13))

// Anonymous Functions
fn main() {
    let add = fn(x, y) { x + y }
    io.println(add(1, 1))
}

// Function with multiple return values
fn vals() -> (Int, Int) {
    (3, 7)
}

// Pipe operator to chain functions together
fn add_one(x: Int) -> Int { x + 1 }
fn add_two(x: Int) -> Int { x + 2 }

4
|> add_one
|> add_two
|> io.debug

Data Structures

Gleam supports custom types using type keyword

Syntax and Example:

type Person {
    name: String,
    age: Int,
}

let person = Person("Alice", 30)

Collection Manipulation

Gleam provides a set of functions to manipulate collections like lists, tuples, and maps.

Syntax and Example:

// List
let numbers = [1, 2, 3, 4, 5]

// Record
Teacher(name: "Alice", age: 30)

// Tuple
let person = ("Alice", 30)

Error Handling

Gleam has a Result type to handle errors. It is similar to Rust’s Result type.

Syntax and Example:

pub type DivideError {
    DivisionByZero
}

fn divide(x: Int, y: Int) -> Result(Int, DivideError) {
    if y == 0 {
        DivisionByZero
    } else {
        Ok(x / y)
    }
}

case divide(10, 0) {
    Ok(result) -> io.println("Result: #{result}")
    Error(error) -> io.println("Error: #{error}") // DivisionByZero
}

Concurrency

Gleam has built-in support for concurrency using the spawn keyword. It allows you to run multiple tasks concurrently.

Syntax and Example:

// Define an async task
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) // Wait for all tasks to finish
}

Eco-system

Gleam language comes with all the required tools for the language. We won’t need to install any additional tools to get started with Gleam.

Installation

To install Gleam, you can use the following command:

brew install gleam

Erlang will be installed as a dependency when you install Gleam.

Hello World

io.println("Hello, World!")

Build and Run

To run a Gleam program, you can use the following command:

gleam run hello.gleam

This will compile and run the program.