DEV Community

Alex Spinov
Alex Spinov

Posted on

Gleam Has a Free Type-Safe Language for the BEAM VM — Here's Why Elixir Developers Are Curious

What if you could write Elixir-like code but with Rust-like type safety? Gleam gives you exactly that.

What is Gleam?

Gleam is a friendly language for building type-safe, scalable systems. It compiles to Erlang (for BEAM VM) and JavaScript, giving you the best of both ecosystems.

Quick Start

# Install
brew install gleam

# Create a project
gleam new my_app
cd my_app
gleam run
Enter fullscreen mode Exit fullscreen mode

Basic Syntax

import gleam/io
import gleam/int
import gleam/list
import gleam/string

pub fn main() {
  io.println("Hello from Gleam!")

  // Variables are immutable
  let name = "Alice"
  let age = 30

  io.println(name <> " is " <> int.to_string(age) <> " years old")
}
Enter fullscreen mode Exit fullscreen mode

Custom Types (Pattern Matching)

pub type Shape {
  Circle(radius: Float)
  Rectangle(width: Float, height: Float)
  Triangle(base: Float, height: Float)
}

pub fn area(shape: Shape) -> Float {
  case shape {
    Circle(r) -> 3.14159 *. r *. r
    Rectangle(w, h) -> w *. h
    Triangle(b, h) -> 0.5 *. b *. h
  }
}

pub fn describe(shape: Shape) -> String {
  case shape {
    Circle(..) -> "A circle"
    Rectangle(width: w, height: h) if w == h -> "A square"
    Rectangle(..) -> "A rectangle"
    Triangle(..) -> "A triangle"
  }
}
Enter fullscreen mode Exit fullscreen mode

Result Type (No Exceptions!)

import gleam/result

pub type AppError {
  NotFound
  Unauthorized
  DatabaseError(message: String)
}

pub fn find_user(id: String) -> Result(User, AppError) {
  case id {
    "" -> Error(NotFound)
    _ -> Ok(User(id: id, name: "Alice"))
  }
}

pub fn get_user_name(id: String) -> Result(String, AppError) {
  find_user(id)
  |> result.map(fn(user) { user.name })
}
Enter fullscreen mode Exit fullscreen mode

Pipe Operator (Beautiful Data Transformation)

pub fn process_names(names: List(String)) -> List(String) {
  names
  |> list.map(string.trim)
  |> list.filter(fn(name) { name != "" })
  |> list.map(string.capitalise)
  |> list.sort(string.compare)
  |> list.unique
}
Enter fullscreen mode Exit fullscreen mode

Web Server (with Wisp)

import wisp.{type Request, type Response}
import gleam/http

pub fn handle_request(req: Request) -> Response {
  case req.method, wisp.path_segments(req) {
    http.Get, [] -> wisp.ok() |> wisp.string_body("Hello!")
    http.Get, ["users", id] -> get_user(id)
    http.Post, ["users"] -> create_user(req)
    _, _ -> wisp.not_found()
  }
}
Enter fullscreen mode Exit fullscreen mode

Gleam vs Elixir

Feature Gleam Elixir
Type System Static, exhaustive Dynamic
Compile Target BEAM + JS BEAM
Null Safety Built-in (Option/Result) Runtime checks
Pattern Matching Exhaustive Non-exhaustive
Interop Erlang/Elixir/JS Erlang
Learning Curve Easy Medium
Ecosystem Growing Mature

Need reliable data extraction? Check out my web scraping actors on Apify Store — fault-tolerant like BEAM. For custom solutions, email spinov001@gmail.com.

Top comments (0)