Skip to content

Instantly share code, notes, and snippets.

View mbuhot's full-sized avatar

Mike Buhot mbuhot

View GitHub Profile

The Ultimate Guide to Gleam's Typed Actors

How Gleam builds type-safe concurrent programming on the BEAM

The BEAM virtual machine (which runs Erlang, Elixir, and now Gleam) is renowned for its actor model concurrency. But traditionally, message passing has been untyped - any process can send any message to any other process, leading to runtime crashes when unexpected messages arrive.

Gleam changes this game entirely by building a sophisticated type-safe layer on top of BEAM's primitives. In this deep dive, we'll explore exactly how Gleam achieves compile-time type safety for concurrent programming, revealing the elegant implementation strategies that make it all work.

The Foundation: BEAM Processes and Raw Message Passing

@mbuhot
mbuhot / opaque_user.ex
Created September 14, 2020 23:38
Enforcing smart constructor in Elixir
defmodule Opaque.User do
@moduledoc """
Demonstrates a ridiculous method for enforcing that a type remains in a valid state using a closure and internal secret
"""
alias __MODULE__
# Ensure that the internal closure can only be called from within this module
@update_key :crypto.strong_rand_bytes(8)
@mbuhot
mbuhot / FSharpConverters.fs
Last active July 19, 2025 21:09
System.Text.Json converters for F# Option, List and Map types
namespace System.Text.Json
open System
open System.Collections.Generic
open System.Text.Json.Serialization
// Converts Option<T> to/from JSON by projecting to null or T
type OptionValueConverter<'T>() =
inherit JsonConverter<'T option>()
@mbuhot
mbuhot / text_process.ex
Created July 31, 2018 22:41
Fast text processing in elixir
defmodule TextProcess do
def generate_files(num_files, lines_per_file) do
Enum.each(1..num_files, fn i ->
filename = "data/test_#{i |> Integer.to_string() |> String.pad_leading(3, "0")}.csv"
File.open!(filename, [:write], fn file ->
Enum.each(1..lines_per_file, fn _ ->
IO.puts(file, line())
end)
end)
@mbuhot
mbuhot / exq_statsd_middleware.ex
Created March 26, 2018 22:15
StatsD middleware for Exq
defmodule ExqStatsD do
@behaviour Exq.Middleware.Behaviour
alias Exq.Middleware.Pipeline
@moduledoc """
This behavior will send stats to statsd endpoint for monitoring.
"""
require Logger
defmodule NumberToWord do
@spec say(integer) :: String.t
def say(n), do: n |> say_io() |> IO.iodata_to_binary()
@spec say_io(integer) :: iodata
def say_io(1), do: "one"
def say_io(2), do: "two"
def say_io(3), do: "three"
def say_io(4), do: "four"
def say_io(5), do: "five"
defmodule Scrabble do
def score("", n), do: n
def score("A" <> rest, n), do: score(rest, n + 1)
def score("B" <> rest, n), do: score(rest, n + 3)
def score("C" <> rest, n), do: score(rest, n + 3)
def score("D" <> rest, n), do: score(rest, n + 2)
def score("E" <> rest, n), do: score(rest, n + 1)
def score("F" <> rest, n), do: score(rest, n + 4)
def score("G" <> rest, n), do: score(rest, n + 2)
def score("H" <> rest, n), do: score(rest, n + 4)
@mbuhot
mbuhot / GenServerSwapOutTest.ex
Created June 15, 2016 05:00
Swap out genserver implementation per test
defmodule MyService do
def foo() do
GenServer.call(:my_service, :foo)
end
end
defmodule MyServiceFake do
use GenServer
def handle_call(:foo, _from, state) do
{:reply, :fake, state}
@mbuhot
mbuhot / index.md
Last active June 7, 2016 00:32
Bureaucrat output with Swagger info
title search
Simple API
true

Simple API

A Simple API.

@mbuhot
mbuhot / swagger.json
Created June 7, 2016 00:28
Example swagger for bureaucrat integration
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Simple API",
"description": "A Simple API.",
"termsOfService": "Use at your own risk!",
"contact": {
"name": "Joe P. Coder"
},