Master Sticker Shop in Gleam: Complete Learning Path

a computer with a keyboard and mouse

Master Sticker Shop in Gleam: The Complete Learning Path

The Sticker Shop module is a foundational project in the Gleam learning path that teaches you how to manage application state using custom types and pattern matching. You'll learn to build a robust, type-safe system for handling different kinds of sticker orders, ensuring correctness and preventing common runtime errors through Gleam's powerful compiler.


The Frustration of Fragile Code

Have you ever built a small application, maybe a simple e-commerce backend or an inventory tracker, only to have it crash because of an unexpected input? You might have passed a string where a number was expected, or tried to process an order type that you forgot to handle. These runtime errors are the bane of developers, especially those coming from dynamically-typed languages like Python or JavaScript. They are silent bugs that lie in wait, ready to break your application at the worst possible moment.

This is where the paradigm shift offered by Gleam truly shines. Imagine building a system where the compiler itself acts as your first line of defense, refusing to even build your code if there's a possibility of such an error. This isn't magic; it's the power of a strong, static type system. The Sticker Shop module on kodikra.com is your hands-on introduction to this world of confidence and reliability. It guides you through building a small but complete system, proving that type safety doesn't have to be complex or verbose—it can be elegant, expressive, and incredibly powerful.


What Exactly Is the Sticker Shop Module?

The Sticker Shop is a core module within the exclusive kodikra.com Gleam curriculum designed to be a practical, project-based introduction to some of the most important features of the language. It's not just an abstract exercise; it's a simulation of a real-world problem: managing inventory and processing customer orders for a sticker business.

At its heart, this module challenges you to create a system that can accurately calculate the total cost of a batch of stickers. The complexity arises from the various rules: different sizes have different prices, and ordering in bulk might grant a discount. You must represent these concepts—sticker sizes, order types, and potential errors—within Gleam's type system.

You will primarily work with custom types (also known as algebraic data types) and case expressions (pattern matching). These two features work in tandem to create code that is not only correct but also self-documenting. The compiler will enforce that you have handled every possible type of order, eliminating entire classes of bugs before you even run your program.

The Core Concepts You Will Master:

  • Custom Types: Learn to define your own data structures to perfectly model your application's domain. You'll create types for StickerSize, Order, and more.
  • Pattern Matching: Use case expressions to deconstruct your custom types and execute specific logic for each variant. This is the primary way control flow is handled in Gleam for complex data.
  • Functional State Management: Understand how to manage state (like inventory counts or order totals) in an immutable way, by passing data through functions and returning new, updated data.
  • Error Handling with `Result`: Implement robust error handling for scenarios like invalid orders using Gleam's built-in Result(value, error) type.

Why This Module is a Game-Changer for Learning Gleam

Moving to a language like Gleam, especially from a dynamically-typed background, requires a shift in thinking. You move from fixing bugs at runtime to satisfying the compiler at compile time. The Sticker Shop module is the perfect catalyst for this mental shift for several key reasons.

First, it provides a tangible, relatable problem. Everyone understands the basics of buying and selling products. This familiarity allows you to focus on the "how" (the Gleam implementation) rather than getting bogged down in an abstract, unfamiliar domain.

Second, it showcases the immediate payoff of type safety. As you build the logic, you'll inevitably forget to handle a specific sticker size or order type. The Gleam compiler will immediately point this out with a clear, helpful error message. This instant feedback loop is incredibly effective for learning. It feels less like fighting a strict machine and more like pairing with a very knowledgeable and thorough co-programmer.

Finally, it introduces the elegance of functional programming in a practical context. You'll see how composing small, pure functions leads to a system that is easy to reason about, test, and extend. There are no hidden side effects or mutable state to worry about; the logic is transparent and predictable.

● Start: Receive an Order
│
▼
┌──────────────────────────┐
│ Define Custom Types      │
│ e.g., Small, Medium, Large │
└────────────┬─────────────┘
             │
             ▼
◆ Use `case` to match order type
╱             |             ╲
Single     Package        Invalid
│             │             │
▼             ▼             ▼
┌─────────┐ ┌─────────┐   ┌─────────┐
│ Calc    │ │ Calc    │   │ Return  │
│ Price   │ │ Price + │   │ Error   │
│         │ │ Discount│   │         │
└─────────┘ └─────────┘   └─────────┘
      ╲         │         ╱
       └────────┬────────┘
                ▼
           ● End: Return Result(Cost, Error)

How to Implement the Sticker Shop Logic in Gleam

Let's break down the step-by-step process of building the Sticker Shop. This is a deep dive into the code and the logic, mirroring the experience you'll have in the kodikra module.

Step 1: Defining the Domain with Custom Types

The first and most crucial step is to model our problem domain using Gleam's type system. We need to represent the different sizes of stickers a customer can order. A custom type is perfect for this.

We'll create a file, perhaps named shop/sticker.gleam, and define our types.

// In shop/sticker.gleam
// We define a custom type to represent the possible sticker sizes.
// The compiler now knows that a `StickerSize` can only be one of these three variants.
pub type StickerSize {
  Small
  Medium
  Large
}

// We can also define a type for an order.
// An order can be a single sticker of a certain size,
// or a package containing a specific number of stickers.
pub type Order {
  Single(size: StickerSize)
  Package(count: Int)
}

With these few lines of code, we have created a powerful boundary in our program. It is now impossible for a function expecting a StickerSize to receive anything other than Small, Medium, or Large. Invalid string values like "small" or "extra-large" will be caught at compile time.

Step 2: Implementing the Core Logic with Pattern Matching

Now that we have our types, we need a function to calculate the price. Let's say small stickers are 2, medium are 3, and large are 4 currency units. We can use a case expression to handle each possibility.

// A function to get the price for a single sticker size.
// The compiler guarantees that we have handled all variants of `StickerSize`.
// If we were to add an `ExtraLarge` variant to our type, the compiler
// would tell us this function is incomplete until we add a case for it.
fn price_for_size(size: StickerSize) -> Int {
  case size {
    Small -> 2
    Medium -> 3
    Large -> 4
  }
}

Next, let's create the main function to calculate the total cost of an Order. Let's add a business rule: a package of 10 stickers gets a 10% discount. Here, we'll use a nested case expression, which is a common and powerful pattern.

import gleam/int

pub fn calculate_cost(order: Order) -> Int {
  case order {
    // If the order is for a single sticker...
    Single(size) -> {
      // ...we just get the price for its size.
      price_for_size(size)
    }

    // If the order is a package...
    Package(count) -> {
      // For this example, let's assume all package stickers are Medium.
      let base_price = price_for_size(Medium) * count
      
      // Apply a discount for bulk orders
      case count >= 10 {
        True -> base_price * 90 / 100 // 10% discount
        False -> base_price
      }
    }
  }
}

Step 3: Running and Testing Your Gleam Project

To test this logic, you would typically write unit tests using Gleam's built-in test runner. The workflow in your terminal would look something like this.

First, create a new Gleam project if you haven't already:

$ gleam new my_sticker_shop
$ cd my_sticker_shop

Then, you would add your code to the src directory and tests to the test directory. To run the tests and check your logic:

# This command compiles your project and runs all functions annotated with @test
$ gleam test

If all tests pass, it means your logic is correct according to your specifications. If there's a type error or a failing test, the compiler or test runner will give you precise feedback.


Where This Foundational Logic Can Be Applied

The concepts learned in the Sticker Shop module are not just for toy projects; they are the building blocks for large-scale, resilient systems. The pattern of modeling your domain with custom types and processing them with exhaustive case expressions is fundamental to writing reliable software.

  • E-commerce Backends: The most direct application. Instead of Order, you might have PaymentMethod (CreditCard, PayPal, Crypto) or ShippingStatus (Processing, Shipped, Delivered). Gleam's compiler ensures you handle every status update and payment type correctly.
  • API Design: When defining a JSON API, you can create Gleam types that exactly match the expected JSON structure. This allows you to parse incoming requests with confidence, knowing that any malformed data will be caught and handled gracefully.
  • - Compilers and Interpreters: The core of a compiler is an Abstract Syntax Tree (AST), which is a perfect fit for custom types. You can define types for Statement, Expression, VariableDeclaration, etc., and use pattern matching to walk the tree and generate code. - State Machines: Any system that moves between a finite number of states (like a user authentication flow or a document approval process) can be modeled perfectly with custom types. This makes it impossible to write code that attempts an invalid state transition.

Expanding the Shop: Concurrency with Actors

A simple function that calculates a price is great, but a real shop needs to handle multiple orders at once and manage a shared state, like the sticker inventory. This is where Gleam, running on the Erlang VM (BEAM), truly excels thanks to the Actor Model.

An actor is a lightweight, isolated process that communicates with other processes by sending and receiving messages. It has its own private state that no other actor can touch directly. This is the key to managing concurrency without the headaches of locks, mutexes, or race conditions.

We can model our entire Sticker Shop as an actor. This actor would hold the current inventory in its state. When a customer wants to place an order, they don't call a function directly; they send a message to the shop actor.

Here is a conceptual diagram of this actor-based workflow:

  ● Customer 1
   │
   │ sends message: {Order, Medium, 5}
   ▼
┌──────────────────┐
│                  │
│   Shop Actor     │
│  (Mailbox)       │
├──────────────────┤
│ {Order, Medium, 5} │ ⟵ Message from Customer 1
│ {Order, Small, 2}  │ ⟵ Message from Customer 2
│ {CheckInventory} │ ⟵ Message from Admin
└──────────────────┘
   │
   │ processes one message at a time
   ▼
┌──────────────────┐
│ Internal State:  │
│ {small: 50,      │
│  medium: 25,     │
│  large: 10}      │
└────────┬─────────┘
         │
         ▼
◆ Process {Order, Medium, 5}
         │
         ▼
┌──────────────────┐
│ New State:       │
│ {small: 50,      │
│  medium: 20,     │  // Inventory updated
│  large: 10}      │
└────────┬─────────┘
         │
         ▼
   ● Reply to Customer 1: {Success}

This model ensures that inventory updates are atomic and sequential. Even if thousands of orders arrive at the same time, the actor's mailbox queues them up and processes them one by one, preventing overselling and ensuring the inventory state is always consistent. While the basic Sticker Shop module doesn't require actors, it builds the perfect foundation for you to explore these more advanced, powerful concurrency patterns available in the Gleam ecosystem.

Pros and Cons of the Gleam Approach

This method of building software is incredibly powerful, but it's helpful to understand its trade-offs. Here's a balanced view based on the principles taught in the Sticker Shop module.

Pros (Advantages) Cons (Potential Challenges)
Extreme Reliability: The compiler catches a vast range of errors, from typos to unhandled logic paths, leading to fewer bugs in production. Steeper Initial Learning Curve: Developers new to static types and functional programming may need time to adjust their thinking.
Excellent Refactoring: Changing custom types will cause the compiler to show you every single place in your code that needs to be updated. This makes large-scale changes fearless. More Upfront Design: You need to think about your data structures and types more carefully at the beginning, which can feel slower than dynamic prototyping.
Self-Documenting Code: Well-defined types and exhaustive pattern matching make the code's intent clear without needing excessive comments. Verbosity for Simple Cases: For very simple, one-off scripts, defining custom types might feel like overkill compared to just using basic data structures.
High Performance Concurrency: The underlying actor model of the BEAM allows for massive, scalable, and fault-tolerant concurrent systems. Smaller Ecosystem: As a newer language, Gleam's library and tool ecosystem is smaller than that of giants like JavaScript or Python, though it is growing rapidly.

The Complete Sticker Shop Learning Path on Kodikra

This module is designed to be a focused, hands-on experience. The progression is straightforward: master the core concepts in this single, comprehensive challenge. It serves as a gateway to more complex problems in the Gleam learning path.

  • Module 1: The Foundation

    This is where you'll tackle the main challenge. You will apply your knowledge of Gleam's syntax, custom types, and pattern matching to build a working, tested solution.

    Start the Sticker Shop Challenge: Dive in and build the core logic for pricing and handling different sticker orders step by step.

After completing this module, you will be well-equipped to explore more advanced topics such as interacting with databases, building web servers, and managing concurrent state with actors. Consider this module your ticket to writing professional, production-grade Gleam code.


Frequently Asked Questions (FAQ)

Why use custom types instead of just strings or integers?

Using primitive types like strings (e.g., "small", "medium") opens the door to runtime errors. A typo like "smaal" would compile but crash your program when it's run. A custom type like Small is checked by the compiler, making such typos impossible. It creates a more constrained, correct, and self-documenting representation of your data.

What does it mean for pattern matching to be "exhaustive"?

Exhaustive pattern matching means the Gleam compiler checks your case expressions to ensure you have written a branch for every possible variant of a custom type. If you define a StickerSize with Small, Medium, and Large, and your case expression only handles Small and Medium, the compiler will refuse to build your code, forcing you to handle the Large case. This eliminates "forgotten case" bugs.

Is Gleam a purely functional language?

Gleam is a functional language that encourages immutability and pure functions, but it is also pragmatic. It runs on the Erlang VM, which is designed for side effects (like I/O and message passing). Gleam manages these side effects in a controlled way, giving you the benefits of functional programming for your core logic while allowing you to build real-world, stateful applications.

How does Gleam's `Result` type compare to exceptions in other languages?

In many languages, a function can throw an exception, which is an invisible control flow path. You might not know a function can fail unless you read its documentation. In Gleam, if a function can fail, its return type makes this explicit, e.g., Result(Int, String). This forces the programmer to handle both the success (Ok(Int)) and failure (Error(String)) cases, leading to more robust and predictable code.

Can I use the actor model without a library in Gleam?

Yes, Gleam has a standard library called gleam/otp which provides a friendly, type-safe API for working with the underlying OTP actor abstractions (like gen_server). You can create actors, manage their state, and handle messages using pure Gleam code, making it accessible and safe.

Where do I go after mastering the Sticker Shop module?

After this module, a great next step is to explore modules that involve external interactions. Look for challenges on the Gleam Learning Roadmap that involve parsing JSON, building a simple web server with the Wisp or Lustre libraries, or interacting with the file system. This will show you how to apply your type-safe domain modeling to real-world I/O.


Conclusion: From Sticker Shop to Unbreakable Systems

The Sticker Shop module is far more than a simple pricing calculator. It's a microcosm of the entire philosophy behind Gleam: building correct, readable, and resilient software by leveraging the power of a strong type system. The skills you build here—modeling domains with custom types, implementing logic with exhaustive pattern matching, and thinking functionally—are the bedrock of modern, reliable application development.

By completing this challenge, you are not just learning the syntax of a new language. You are adopting a new way of thinking about programming, one where the compiler is your partner in building quality software. You are preparing yourself to tackle complex, concurrent systems with a level of confidence that is often hard to achieve in other environments.

Technology Disclaimer: All code examples and concepts are based on Gleam v1.0.0+ and its standard library conventions. The Gleam ecosystem is active, so always consult the official documentation for the latest updates and best practices. Ready to build with confidence? Dive into the complete Gleam guide on kodikra.com.


Published by Kodikra — Your trusted Gleam learning resource.