1.4 KiB
1.4 KiB
puyo 3 (this time it's nameful)
semantics
single-threaded, dynamically-typed (because lol), multiple named returns by default, pass-by-value
functions take and return a map ALWAYS
Values:
- function
- number (f64)
- map (HashMap<Symbol, >)
examples
double x = x * 2
double = fn([x] [x]) (
^x = x * 2;
);
apply f x = f x
;; same as apply = fn([f x] [x]) ( ... )
fn apply([f x] [x]) (
^x = f x;
);
;; f would have to be like fn([a] [a]) ( ... )
(define (make-counter)
(let ([i 0])
(lambda ()
(set! i (+ i 1))
i)))
fn make_counter([] [inc]) (
i = 0;
^inc = fn([] [i]) (
i = i + 1;
^i = i;
);
;; or fn ^inc(...)
)
desat hsla = { hsla with s := hsla.s / 2 }
;; omitting the return means it's the same
fn desat([h s l a]) (
^s = ^s / 2;
)
compose f g x = f (g x)
fn compose([f g x] [x]) (
^x = g x;
^x = f x;
)
f = fn([x]) (^x = x + 2;);
g = fn([x]) (^x = x * 3;);
f2 = f;
compose f g x == (((compose f) g) x) == compose {f: f2, g} x == compose {x} f g
id x = x
fn id([x]) ()
"Maps" should really just be blocks
foo := 3;
{
x := 42;
^twice_x := x * 2;
^thrice_x := x * 3;
^foo;
}
becomes
{
"twice_x": 84,
"thrice_x": 126,
// ^foo as a statement behaves like ^foo := foo, so we get that nice record field punning
"foo": 3,
}