DEV Community

Harsha S
Harsha S

Posted on

Introduction to Gleam Programming Language

Introduction:

Welcome to this beginner-friendly tutorial on Gleam, a functional programming language designed to create fast, safe, and concurrent systems. Gleam is a statically typed language that compiles to both Erlang and JavaScript, making it ideal for building scalable, fault-tolerant applications. This tutorial will guide you through the basics of Gleam, helping you write your first Gleam program and understand its core features. In this blog post, we'll explore the fundamental concepts of Gleam and get you started on your journey with this exciting language.

What is Gleam?

Gleam is a statically typed functional programming language that compiles to both Erlang bytecode (for running on the BEAM) and JavaScript. This means you can use it for building robust backends and interactive frontends. Key characteristics include:

  • 😊 Functional: Emphasizes immutability and pure functions.
  • 🔍 Statically Typed: Catches errors at compile time.
  • đŸ’Ș Concurrent: Runs on the BEAM, inheriting its concurrency model.
  • 🚀 Interoperable: Works seamlessly with Erlang and Elixir code.
  • 🔧 Modern Syntax: Clean and expressive, inspired by languages like Elm and OCaml.

Why Learn Gleam?

Before diving into Gleam, let's look at why it’s worth learning:

  • Safety: Gleam’s strong, static type system catches errors at compile-time, ensuring your code is reliable.

  • Performance: Gleam leverages the Erlang virtual machine (BEAM), renowned for its low-latency and fault-tolerant properties.

  • Simplicity: Its concise syntax and focus on practicality make it easy for beginners and experts alike.

Setting Up Your Gleam Environment

Prerequisites

  • A code editor: Visual Studio Code is recommended.

  • Erlang/OTP: Install it from Erlang.org.

  • Gleam compiler: Install via your terminal, refer here:

brew install gleam
Enter fullscreen mode Exit fullscreen mode

Verifying Installation

Run the following command to check if Gleam is installed:

gleam --version
Enter fullscreen mode Exit fullscreen mode

You should see the version number if Gleam is installed correctly. Refer the image below

Gleam Version

Writing Your First Gleam Program

Step 1: Create a New Project

Open your terminal and create a new Gleam project:

gleam new hello_gleam
cd hello_gleam
Enter fullscreen mode Exit fullscreen mode

This generates a project structure with a src directory for your code.

Step 2: Write a Simple Program

Navigate to the src directory and open main.gleam. Replace its content with:

import gleam/io

pub fn main() {
  let greeting = "Hello, Gleam!"
  io.println(greeting)
}
Enter fullscreen mode Exit fullscreen mode

This program defines a function main that prints a greeting to the console.

Step 3: Run Your Program

Compile and run your program:

gleam build
gleam run
Enter fullscreen mode Exit fullscreen mode

You should see Hello, Gleam! printed to the console.

Basic Syntax

1. Variables and Data Types

  • Variables: In Gleam, variables are immutable (bindings). Once assigned, their value cannot be changed. Gleam uses let for variable binding.
import gleam/io
import gleam/int
import gleam/float
import gleam/bool

pub fn main() {
  let name = "Alice"
  let age = 30
  let height = 5.8
  let is_student = False

  io.println("Name: " <> name)
  io.println("Age: " <> int.to_string(age))
  io.println("Height: " <> float.to_string(height))
  io.println("Is student? " <> bool.to_string(is_student))
}
Enter fullscreen mode Exit fullscreen mode

Refer the below image for the output

Variables output snapshot

  • Data Types: Gleam has a rich type system. Some basic types:

    • String: Text (e.g., "Hello").
    • Int: Integers (e.g., 10, -5).
    • Float: Decimal numbers (e.g., 3.14).
    • Bool: True or False.

Gleam uses type inference, so you often don't need to explicitly declare types.

2. Functions

Functions are essential in Gleam. Here's how you define them

import gleam/io

pub fn greet(name: String) -> String {
  "Hello, " <> name <> "!"
}

pub fn main() {
  io.println(greet("Bob"))
}
Enter fullscreen mode Exit fullscreen mode
  • pub: Makes the function publicly accessible.
  • fn: Keyword for defining a function.
  • ->: Specifies the return type.
  • <>: String concatenation operator.
  • main: The entry point of your program.

functions output snapshot

3. Control Flow: Conditional Expressions

Gleam uses conditional expressions (which return a value) rather than statements:

import gleam/io

pub fn is_adult(age: Int) -> String {
  case age >= 18 {
    True -> "You are an adult."
    False -> "You are not an adult yet."
  }
}

pub fn main() {
    io.println(is_adult(20)) // Output: You are an adult.
    io.println(is_adult(10)) // Output: You are not an adult yet.
}
Enter fullscreen mode Exit fullscreen mode

The case expression checks a condition and returns a value based on the result. Refer the below image for the output.

control flow snapshot

4. Data Structures: Lists and Tuples

  • Lists: Ordered collections of elements of the same type:
let fruits = ["apple", "banana", "cherry"]
let numbers = [1, 2, 3, 4, 5]
Enter fullscreen mode Exit fullscreen mode
  • Tuples: Fixed-size collections of elements of potentially different types:
let person = #("Alice", 30)
let name = person.0 // Access the first element ("Alice")
let age = person.1  // Access the second element (30)
Enter fullscreen mode Exit fullscreen mode

Refer the below image for the example

data structures snapshot

Core Features of Gleam

Pattern Matching

Pattern matching is a powerful feature in Gleam for working with data structures. It simplifies conditional logic:

import gleam/io

pub fn describe_fruit(fruit: String) -> String {
  case fruit {
    "apple" -> "It's an apple!"
    "banana" -> "It's a banana!"
    other -> "It's something else: " <> other
  }
}

pub fn main() {
  io.println(describe_fruit("apple")) // Output: It's an apple!
  io.println(describe_fruit("orange")) // Output: It's something else: orange
}
Enter fullscreen mode Exit fullscreen mode

This concisely handles different cases based on the value of fruit. Refer the below image for output.

pattern matching output

Modules

Gleam uses modules to organize code into logical units. Every Gleam file is a module.

// my_module.gleam
pub fn my_function() -> Int {
  10
}

// main.gleam
import my_module
import gleam/io

pub fn main() {
    io.println(my_module.my_function())
}
Enter fullscreen mode Exit fullscreen mode

Refer the below image for the output.

module output

Concurrency

Gleam leverages Erlang’s concurrency model to build fault-tolerant systems.

import gleam/io

pub fn spawn_task() {
  io.println("Starting task")
}

pub fn main() {
  let _ = spawn(spawn_task)
  io.println("Task spawned")
}
Enter fullscreen mode Exit fullscreen mode

Practical Example: Building a Calculator

Let's build a simple calculator to demonstrate these concepts:

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

pub type Operation {
  Add
  Subtract
  Multiply
  Divide
}

pub fn calculate(operation: Operation, a: Int, b: Int) -> Result(Int, String) {
  case operation {
    Add -> Ok(a + b)
    Subtract -> Ok(a - b)
    Multiply -> Ok(a * b)
    Divide -> case b {
      0 -> Error("Division by zero!")
      _ -> Ok(a / b)
    }
  }
}

pub fn main() {
  case calculate(Add, 5, 3) {
    Ok(result) -> io.println("5 + 3 = " <> int.to_string(result))
    Error(msg) -> io.println("Error: " <> msg)
  }
}

Enter fullscreen mode Exit fullscreen mode

Refer the below image for the output.

calculator output

Best Practices & Tips

  1. Type First Development

    • Design your types before implementing functionality
    • Let the compiler guide your implementation
  2. Use Pattern Matching

    • Prefer pattern matching over if/else statements
    • Make your code more readable and maintainable
  3. Leverage the Type System

    • Use custom types to model your domain
    • Let the compiler catch errors early
  4. Testing

    • Write tests using Gleam's built-in test framework
    • Run tests with gleam test

Community Resources

Conclusion

Gleam offers a modern, type-safe approach to programming while leveraging the robust Erlang ecosystem. Its friendly compiler messages and clean syntax make it an excellent choice for both beginners and experienced developers. By following this tutorial, you’ve taken the first step in mastering Gleam. You've learned about variables, functions, data types, control flow, and pattern matching. This is a great foundation for exploring more advanced concepts.

Top comments (0)