plum

#treesitter#compiler#wasm

git clone https://git.pyrossh.dev/plum

A statically typed, imperative programming language inspired by rust, python


plum-examples/safe_navigation.plum
43e5250 1
import std/Option
43e5250 2
import std/Result
43e5250 3
import std/Bool
43e5250 4
import std/Number
43e5250 5
import std/Str
43e5250 6
# `obj?.field` / `obj?.method(args)` — Groovy/Kotlin-style safe navigation.
43e5250 7
# Reaches into a `Result`'s `Ok`/an `Option`'s `Some` without unwrapping it,
43e5250 8
# mapping the field/method access over the inner value and re-wrapping the
43e5250 9
# result; `Err`/`None` passes through untouched. Pure sugar for
43e5250 10
# `obj.map(|v| v.field)` — desugared entirely in the parser (see
43e5250 11
# `plum-core`'s `parseSafeAttribute`), so nothing past it needs to know this
43e5250 12
# syntax exists.
43e5250 13
43e5250 14
enum Person =
43e5250 15
  | Person(name: Str, age: Int)
43e5250 16
  fun birthday(self) -> Int =
43e5250 17
    self.age + 1
43e5250 18
43e5250 19
fun personName(p: Option[Person]) -> Option[Str] =
43e5250 20
  p?.name
43e5250 21
43e5250 22
fun personBirthday(p: Option[Person]) -> Option[Int] =
43e5250 23
  p?.birthday()
43e5250 24
43e5250 25
fun personNameResult(p: Result[Person, Str]) -> Result[Str, Str] =
43e5250 26
  p?.name
43e5250 27
43e5250 28
fun somePerson() -> Option[Person] =
43e5250 29
  Some(Person(name: "Ann", age: 3))
43e5250 30
43e5250 31
fun noPerson() -> Option[Person] =
43e5250 32
  None
43e5250 33
43e5250 34
fun okPerson() -> Result[Person, Str] =
43e5250 35
  Ok(Person(name: "Ann", age: 3))
43e5250 36
43e5250 37
fun errPerson() -> Result[Person, Str] =
43e5250 38
  Err("missing")
43e5250 39
43e5250 40
test "safe navigation maps a field access over Some, passes None through unchanged"
43e5250 41
  a := personName(somePerson())
43e5250 42
  assert a.isSome()
43e5250 43
  assert a.unwrap() == "Ann"
43e5250 44
  b := personName(noPerson())
43e5250 45
  assert b.isNone()
43e5250 46
43e5250 47
test "safe navigation maps a method call over Some"
43e5250 48
  a := personBirthday(somePerson())
43e5250 49
  assert a.isSome()
43e5250 50
  assert a.unwrap() == 4
43e5250 51
43e5250 52
test "safe navigation maps a field access over Ok, passes Err through unchanged"
43e5250 53
  a := personNameResult(okPerson())
43e5250 54
  assert a.isOk()
43e5250 55
  assert a.unwrap() == "Ann"
43e5250 56
  b := personNameResult(errPerson())
43e5250 57
  assert b.isErr()
43e5250 58
  assert b.unwrapErr() == "missing"