Getting Started, Types, and Values

Hello, World

i
name = "basics"
version = "1.0.0"
target = "erlang"

[dependencies]
gleam_stdlib = ">= 0.34.0 and < 2.0.0"

[dev-dependencies]
gleeunit = ">= 1.0.0 and < 2.0.0"
i
import gleam/io

pub fn main() {
  let name = "Gleam"
  io.println("Hello from " <> name <> "!")
}
i
Hello from Gleam!

Arithmetic

i
pub fn main() {
  let sum = 2 + 2
  io.println(string.inspect(sum))

  let product = 6 * 7
  io.println(string.inspect(product))

  let float_div = int.to_float(10) /. int.to_float(3)
  io.println(string.inspect(float_div))
}
i
4
42
3.3333333333333335

Built-in Types

Custom Types

i
pub type Color {
  Red
  Green
  Blue
}

type Shape {
  Circle(Float)
  Rectangle(Float, Float)
}
i
fn area(shape: Shape) -> Float {
  case shape {
    Circle(r) -> 3.14159 *. r *. r
    Rectangle(w, h) -> w *. h
  }
}
i
red is Red
circle is Circle(3.0)
rectangle is Rectangle(4.0, 5.0)
circle area is 28.274309999999996
rectangle area is 20.0

Records with Named Fields

i
type Flavor {
  Chocolate
  Vanilla
  Strawberry
}

type Container {
  Cone
  Cup
}

type IceCream {
  IceCream(flavor: Flavor, container: Container)
}
i
fn display(item: IceCream) -> String {
  flavor_string(item.flavor) <> " in a " <> container_string(item.container)
}
i
chocolate cone is Chocolate in a cone
vanilla cone is Vanilla in a cup
strawberry cone is Strawberry in a cone

Tuples

i
  let t = #(1, "hello", True)
  io.println(string.inspect(t))
i
  let #(a, b, c) = t
  io.println("a from tuple is " <> string.inspect(a))
  io.println("b from tuple is " <> string.inspect(b))
  io.println("c from tuple is " <> string.inspect(c))
i
#(1, "hello", True)
a from tuple is 1
b from tuple is "hello"
c from tuple is True

Type Inference

let x: Int = 42
let name: String = "Gleam"

Check Understanding

What is the difference between + in Python and Gleam?

Python uses a single + for both integers and floats and silently coerces between them, and uses + to concatenate strings as well. Gleam requires you to be explicit: + for integers, +. for floats, and <> for strings. This makes mixed-type arithmetic a compile error rather than a runtime surprise. The practical consequence is that you must call int.to_float before combining an integer with a float.

What happens if you forget to handle a variant in a case expression?

The compiler produces an error before the program runs. Every case expression in Gleam must be exhaustive, i.e., it must handle every variant of the type being matched. This is one of the most practical benefits of the type system: you cannot accidentally omit a case and discover the gap in production. Python has no equivalent guarantee: a missing elif or isinstance branch fails silently until the code runs.

Exercises

Hello with arithmetic (5 minutes)

Create a new Gleam project. In main, bind your name to a variable and print a greeting that includes it. Also print the result of 10 * 10 - 1 and the result of dividing 22.0 by 7.0.

Echo

Look up what echo does in Gleam, then convert one of the examples in this lesson to use it instead of io.println. How much do you miss Python's print function?

Ice cream order (10 minutes)

Using the IceCream type from icecream_demo.gleam, write describe(item: IceCream) -> String that returns a sentence like "Chocolate ice cream in a cone". Create three orders and print their descriptions.

Shape functions (10 minutes)

Write perimeter(shape: Shape) -> Float that returns 2 * pi * r for a circle and 2 * (w + h) for a rectangle. Also write describe(shape: Shape) -> String that returns a human-readable description like "circle with radius 3.0".

Tuple swap (5 minutes)

Write swap(pair: #(a, b)) -> #(b, a) that returns a new tuple with the two elements reversed. Gleam will infer the generic types a and b automatically. Test it with #(1, "one") and #(True, 42).

Public vs. private types (5 minutes)

In src/types.gleam, the Color type is declared pub type Color. Remove the pub keyword so it reads type Color, then run gleam run --module types. What warning does the compiler produce, and why?