UFCS

Uniform Function Call Syntax lets you call any function using dot notation on its first argument. There are no methods or impl blocks in pyr - just regular functions that chain naturally.

Any function can be called with dot syntax on its first argument. No methods, no impl blocks.

fn double(x: int) -> int = x * 2
fn negate(x: int) -> int = 0 - x

fn main() {

These two calls are identical.

  println(double(5))
  println(5.double())

Chaining works naturally.

  result = 5.double().negate()
  println(result)

Multi-argument functions work too. The dot target becomes the first argument, the rest follow in parens.

  println(add(3, 4))
  println(3.add(4))
  println(clamp(15, 0, 10))
  println(15.clamp(0, 10))

Builtins work with UFCS too.

  nums = [3, 1, 4, 1, 5]
  println(nums.contains(4))
  println(nums.index_of(4))
  println(nums.slice(1, 3))

String builtins chain cleanly.

  println("hello world".replace("world", "pyr").to_upper())
  println("a,b,c".split(",").join(" - "))
}

fn add(a: int, b: int) -> int = a + b
fn clamp(val: int, lo: int, hi: int) -> int {
  if val < lo { return lo }
  if val > hi { return hi }
  val
}
$ pyr run ufcs.pyr
10
10
-10
7
7
10
10
true
2
[1, 4]
HELLO PYR
a - b - c