(input) (output "one argument of two words: 7" "two arguments of one: 7" "unsigned, one argument: 9" "unsigned, two arguments: 3" "captured global: 12" "captured function: 8") (return 0) ;;; A closure's struct is named after its signature, so that two ;;; translation units agree on it without sharing a header. The name is ;;; built by flattening the argument list, and flattening loses where one ;;; argument ends and the next begins: `((long long))' and ;;; `((long) (long))' are different signatures that used to mangle alike, ;;; and the second quietly reused the first one's struct. ;;; ;;; A capture that borrows a name reads it from wherever the name is ;;; declared, a global or a function included. (include stdio.h) (var scale int 3) (fn double-it ((n int)) int (return (* n 2))) (pub fn main () int (var one-wide (closure ((long long)) int) (closure ((a (long long))) int () (return (cast a int)))) (printf "one argument of two words: %d\n" (one-wide 7)) (var two-longs (closure ((long) (long)) int) (closure ((a long) (b long)) int () (return (cast (+ a b) int)))) (printf "two arguments of one: %d\n" (two-longs 3 4)) (var one-unsigned (closure ((unsigned int)) int) (closure ((a (unsigned int))) int () (return (cast a int)))) (printf "unsigned, one argument: %d\n" (one-unsigned 9)) (var two-unsigned (closure ((unsigned) (int)) int) (closure ((a unsigned) (b int)) int () (return (+ (cast a int) b)))) (printf "unsigned, two arguments: %d\n" (two-unsigned 1 2)) ;; a capture names what it borrows, and the name need not be a local (var scaled (closure ((int)) int) (closure ((x int)) int (scale) (return (* x scale)))) (printf "captured global: %d\n" (scaled 4)) (var doubled (closure ((int)) int) (closure ((x int)) int (double-it) (return (double-it x)))) (printf "captured function: %d\n" (doubled 4)) (return 0))