# 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) ## examples `double x = x * 2` ```rust double = fn([x] [x]) ( ^x := x * 2; ); ``` `apply f x = f x` ```rust ;; same as apply = fn([f x] [x]) ( ... ) fn apply([f x] [x]) ( ^x := f x; ); ;; f would have to be like fn([a] [a]) ( ... ) ``` ```scheme (define (make-counter) (let ([i 0]) (lambda () (set! i (+ i 1)) i))) ``` ```rust 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 }` ```rust ;; omitting the return means it's the same fn desat([h s l a]) ( ^s := ^s / 2; ) ``` `compose f g x = f (g x)` ```rust 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` ```rust fn id([x]) () ``` "Maps" should really just be blocks ```rust foo := 3; { x := 42; ^twice_x := x * 2; ^thrice_x := x * 3; ^foo; } ``` becomes ```json5 { "twice_x": 84, "thrice_x": 126, // ^foo as a statement behaves like ^foo := foo, so we get that nice record field punning "foo": 3, } ```