plum
git clone https://git.pyrossh.dev/plum
A statically typed, imperative programming language inspired by rust, python
plum-examples/safe_navigation.plum
import std/Option
import std/Result
import std/Bool
import std/Number
import std/Str
# `obj?.field` / `obj?.method(args)` — Groovy/Kotlin-style safe navigation.
# Reaches into a `Result`'s `Ok`/an `Option`'s `Some` without unwrapping it,
# mapping the field/method access over the inner value and re-wrapping the
# result; `Err`/`None` passes through untouched. Pure sugar for
# `obj.map(|v| v.field)` — desugared entirely in the parser (see
# `plum-core`'s `parseSafeAttribute`), so nothing past it needs to know this
# syntax exists.
enum Person =
| Person(name: Str, age: Int)
fun birthday(self) -> Int =
self.age + 1
fun personName(p: Option[Person]) -> Option[Str] =
p?.name
fun personBirthday(p: Option[Person]) -> Option[Int] =
p?.birthday()
fun personNameResult(p: Result[Person, Str]) -> Result[Str, Str] =
p?.name
fun somePerson() -> Option[Person] =
Some(Person(name: "Ann", age: 3))
fun noPerson() -> Option[Person] =
None
fun okPerson() -> Result[Person, Str] =
Ok(Person(name: "Ann", age: 3))
fun errPerson() -> Result[Person, Str] =
Err("missing")
test "safe navigation maps a field access over Some, passes None through unchanged"
a := personName(somePerson())
assert a.isSome()
assert a.unwrap() == "Ann"
b := personName(noPerson())
assert b.isNone()
test "safe navigation maps a method call over Some"
a := personBirthday(somePerson())
assert a.isSome()
assert a.unwrap() == 4
test "safe navigation maps a field access over Ok, passes Err through unchanged"
a := personNameResult(okPerson())
assert a.isOk()
assert a.unwrap() == "Ann"
b := personNameResult(errPerson())
assert b.isErr()
assert b.unwrapErr() == "missing"