Stream: beginners

Topic: Coming from Gleam


view this post on Zulip Locria Cyber (Jul 17 2026 at 04:57):

After being horrified by the decoder pattern in Gleam, I stumbled upon the Zig rewrite blog post, so I came here to see what's available.

The pattern in Gleam:

import gleam/dynamic/decode
import gleam/io
import gleam/json
import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/string
import simplifile

type Greeting {
  Greeting(hello: String, extra: Option(String))
}

fn greeting_decoder() -> decode.Decoder(Greeting) {
  use hello <- decode.field("hello", decode.string)
  use extra <- decode.optional_field(
    "extra",
    None,
    decode.field("sub", decode.optional(decode.string), decode.success),
  )
  decode.success(Greeting(hello:, extra:))
}

pub fn main() {
  case simplifile.read("a.jsonl") {
    Ok(contents) -> {
      contents
      |> string.split("\n")
      |> list.filter(fn(line) { string.trim(line) != "" })
      |> list.each(fn(line) {
        case json.parse(line, greeting_decoder()) {
          Ok(g) ->
            case g.extra {
              Some(extra) ->
                io.println("hello: " <> g.hello <> ", extra.sub: " <> extra)
              None -> io.println("hello: " <> g.hello)
            }
          Error(err) ->
            io.println(
              "bad json: " <> line <> " (" <> string.inspect(err) <> ")",
            )
        }
      })
    }
    Error(err) -> io.println("could not read a.jsonl: " <> string.inspect(err))
  }
}

How is it like in Roc?

view this post on Zulip Luke Boswell (Jul 17 2026 at 05:07):

app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" }

import pf.OsStr
import pf.Path
import pf.Stdout

Greeting : {
    hello : Str,
    extra : Try({ sub : Try(Str, [Null]) }, [Missing]),
}

main! : List(OsStr) => Try({}, _)
main! = |_args| {
    path : Path
    path = "example.jsonl"
    contents = path.read_utf8!()?

    for line in contents.split_on("\n") {
        if !line.trim().is_empty() {
            decoded : Try(Greeting, Json.ParseErr)
            decoded = Json.parse(line)

            match decoded {
                Ok(greeting) =>
                    match greeting.extra {
                        Ok({ sub: Ok(extra) }) =>
                            Stdout.line!("hello: ${greeting.hello}, extra.sub: ${extra}")?

                        Ok({ sub: Err(Null) }) =>
                            Stdout.line!("hello: ${greeting.hello}")?

                        Err(Missing) =>
                            Stdout.line!("hello: ${greeting.hello}")?
                        }

                Err(err) =>
                    Stdout.line!("bad json: ${line} (${Str.inspect(err)})")?
                }
        }
    }

    Ok({})
}
15:06:36 ~/Documents/GitHub/basic-cli main $ cat example.jsonl
{"hello":"world"}
{"hello":"roc","extra":{"sub":"kree"}}
{"hello":"nullable","extra":{"sub":null}}
{"hello":"missing-sub","extra":{}}
not json
15:06:46 ~/Documents/GitHub/basic-cli main $ roc example.roc
hello: world
hello: roc, extra.sub: kree
hello: nullable
bad json: {"hello":"missing-sub","extra":{}} (MissingRequiredField("sub"))
bad json: not json (InvalidJson("Invalid JSON"))

view this post on Zulip Locria Cyber (Jul 17 2026 at 05:24):

This feels like it's hidding magic. Zig's comptime at least I can look at the source code and understand. How do I understand this?

view this post on Zulip Luke Boswell (Jul 17 2026 at 05:26):

It's similar to Rust's serde pattern I guess... maybe you could find content on that?

view this post on Zulip Luke Boswell (Jul 17 2026 at 05:27):

Also in case you haven't seen it, the langref topic on this https://github.com/roc-lang/roc/blob/main/docs/langref/static-dispatch.md#parsing-and-encoding

view this post on Zulip Luke Boswell (Jul 17 2026 at 05:29):

I'm not tracking anything Roc specific like guides or tutorials yet.. this specific feature is recently implemented -- though the design has been around a while. I think Richard talks about it (or static dispatch more generally) in a video, but I'm not sure which one.

view this post on Zulip Eric Rogstad (Jul 17 2026 at 07:44):

I think Richard talks about it (or static dispatch more generally) in a video, but I'm not sure which one.

This one covered static dispatch pretty extensively, as I recall: Richard Feldman, "New Ways to Roc!"


Last updated: Jul 23 2026 at 13:15 UTC