#lang hyper-literate #:꩜ envlang/tiny ꩜title[#:tag "test-tiny"]{Tests and examples for ꩜racketmodname[envlang/tiny]} ꩜section{Identity} ꩜chunk[ (λ (x) x)] ꩜chunk[ (⧵ env env args args)] ꩜chunk[ (⧵ #f env args args)] ꩜section{Dummy value} ꩜chunk[ ] ꩜chunk[ ] ꩜section{Example: identity applied to identity} ꩜chunk[ ( )] ꩜chunk[ (@ env )] ꩜chunk[ ] ꩜section{False} a.k.a second-of-two ꩜chunk[ (λ (if-true) (λ (if-false) if-false))] ꩜chunk[ (⧵ env env args (⧵ args env args args))] ꩜chunk[ (⧵ #f env args (⧵ args env args args))] ꩜section{True} a.k.a first-of-two ꩜chunk[ (λ (if-true) (λ (if-false) if-true))] ꩜chunk[ (⧵ env env args (⧵ args env args captured))] ꩜chunk[ (⧵ #f env args (⧵ args env args captured))] ꩜subsection{Boolean usage example: if true} ꩜chunk[ (( ) )] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ ] ꩜subsection{Boolean usage example: if false} ꩜chunk[ (( ) )] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ ] ꩜; TODO: take my own red pill / blue pill picture ꩜; ꩜image{/tmp/Two-Buttons.jpg} ꩜section{Pairs} ꩜chunk[ (λ (a) (λ (b) (λ (f) ((f a) b))))] ꩜chunk[ ; ↑ a a ↓ ↑ b a ↓ f ↑ f ↓ a ↓ (⧵ env env args (⧵ args env args (⧵ captured env args (@ (@ args env captured) env BBBBBBBB))))] ꩜chunk[ ; ↑ a a ↓ ↑ b b ↓ f ↑ f ↓ b ↓ (⧵ env env args (⧵ args env args (⧵ args env args (@ (@ args env AAAAAAAA) env captured))))] Can't be done because our capture can only close over a single value. We use a primitive: ꩜chunk[ ×] ꩜chunk[ ×] ꩜chunk[ (@ × )] ꩜chunk[ (⧵ #f env args (@ (@ args env ) env ))] ꩜subsection{Fst} ꩜chunk[ (λ (p) (p ))] ꩜chunk[ (⧵ captured env args (@ args env ))] ꩜subsection{Snd} ꩜chunk[ (λ (p) (p ))] ꩜chunk[ (⧵ captured env args (@ args env ))] ꩜section{Either} ꩜subsection{Left} ꩜chunk[ (λ (v) (λ (if-left) (λ (if-right) (if-left v))))] ꩜chunk[ ; ↑ v v ↓ ↑ if-left ↓ if-left ↓ v ↑ if-right ↓ if-left × v (⧵ env env args (⧵ args env args (⧵ (@ args captured) env args (@ captured env ))))] ꩜chunk[ ; ↑ f f ↓ ↑ v ↓ f ↓ v (⧵ env env args (⧵ args env args (@ captured env args)))] ꩜chunk[ (⧵ #f env args (⧵ args env args (⧵ (@ × args captured) env args (@ captured env (⧵ env env args (⧵ args env args (@ captured env args)))))))] ꩜subsection{Right} ꩜chunk[ (λ (v) (λ (if-left) (λ (if-right) (if-right v))))] ꩜chunk[ ; ↑ v ↓v↑ if-left ↓ v ↑ ↑ if-right ↓ if-right ↓ v (⧵ env env args (⧵ args env args (⧵ captured env args (@ args env captured))))] ꩜chunk[ (⧵ #f env args (⧵ args env args (⧵ captured env args (@ args env captured))))] ꩜section{If} ꩜chunk[ (λ (c) (λ (if-true) (λ (if-false) ((c if-true) if-false))))] When passed a boolean as the first argument (as should be the case), it is equivalent to: ꩜chunk[ (λ (c) c)] ꩜chunk[ ] ꩜chunk[ ] ꩜subsection{Match "either"} ꩜chunk[ (λ (either) (λ (if-left) (λ (if-right) ((either if-true) if-false))))] When passed a constructor of the "either" variant as the first argument (as should be the case), it is equivalent to: ꩜chunk[ ] ꩜chunk[ ] ꩜chunk[ ] ꩜chunk[ ((( ( )) ) (λ (v) ))] ꩜chunk[ (@ (@ (@ env (@ env )) env ) env (⧵ captured env args ))] ꩜chunk[ ] ꩜chunk[ ((( )) (λ (v) )) )] ꩜chunk[ (@ (@ (@ env (@ env )) env (⧵ captured env args )) env )] ꩜chunk[ ] ꩜section{Null} ꩜chunk[ ( )] ꩜chunk[ (@ env )] ꩜chunk[ (⧵ (⧵ #f env args args) env args (⧵ (@ × args captured) env args (@ captured env (⧵ env env args (⧵ args env args (@ captured env args))))))] ꩜section{Cons} ꩜chunk[ (λ (a) (λ (b) ( ( a b))))] ꩜chunk[ (⧵ captured env args (⧵ args env args (@ env (@ captured args))))] ꩜chunk[ (⧵ #f env args (⧵ args env args (@ (⧵ env env args (⧵ args env args (⧵ captured env args (@ args env captured)))) env (@ × captured args))))] ꩜subsection{Match "list"} ꩜chunk[ ] ꩜chunk[ ] ꩜section{null?} ꩜chunk[ (λ (l) ((( l) (λ (v) )) (λ (v) )))] ꩜chunk[ (⧵ captured env args (@ (@ (@ env args) env (⧵ captured env args )) env (⧵ captured env args )))] ꩜section{Car} Since we don't have an error reporting mechanism, we make (car null) = null and (cdr null) = null ꩜chunk[ (λ (l) ((( l) ) ))] ꩜chunk[ (⧵ captured env args (@ (@ (@ env args) env (⧵ captured env args )) env ))] ꩜chunk[ (@ env (@ (@ env ) env ))] ꩜chunk[ ] ꩜chunk[ (@ env (@ (@ env ) env ))] ꩜chunk[ ] ꩜chunk[ (@ env )] ꩜chunk[ ] ꩜section{Cdr} Since we don't have an error reporting mechanism, we make (car null) = null and (cdr null) = null ꩜chunk[ (λ (l) ((( l) ) ))] ꩜chunk[ (⧵ captured env args (@ (@ (@ env args) env (⧵ captured env args )) env ))] ꩜chunk[ (@ env (@ (@ env ) env ))] ꩜chunk[ ] ꩜chunk[ (@ env (@ (@ env ) env (@ (@ env ) env )))] ꩜chunk[ ] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (⧵ (⧵ #f env args (@ (@ args env ) env )) env args (⧵ captured env args (@ args env captured)))] ꩜chunk[ (@ env (@ env (@ (@ env ) env (@ (@ env ) env ))))] ꩜chunk[ ] ꩜section{Zero} ꩜chunk[ ] ꩜chunk[ ] ꩜section{Not} ꩜chunk[ (λ (a) ((( a) ) ))] ꩜chunk[ (⧵ captured env args (@ (@ (@ env args) env ) env ))] ꩜section{And} ꩜chunk[ (λ (a) (λ (b) ((( a) b) )))] ꩜chunk[ ; a a b a b (⧵ captured env args (⧵ args env args (@ (@ (@ env captured) env args) env )))] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env )] ꩜section{Or} ꩜chunk[ (λ (a) (λ (b) ((( a) ) b)))] ꩜chunk[ ; a a b a b (⧵ captured env args (⧵ args env args (@ (@ (@ env captured) env ) env args)))] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env )] ꩜section{Equal bools} ꩜chunk[ (λ (a) (λ (b) ((( a) b) ( b))))] ꩜chunk[ (⧵ captured env args (⧵ args env args (@ (@ (@ env captured) env args) env (@ env args))))] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env )] ꩜section{Z combinator} ꩜chunk[ (λ (f) ( ))] ꩜chunk[ (λ (x) (f (λ (v) ((x x) v))))] ꩜chunk[ ; ↑ f (⧵ captured env args (@ env ))] ꩜chunk[ ; ↓f↑ ↑ x ↓ f ↓x↑ ↑v ↓ x ↓ x ↓ v (⧵ args env args (@ captured env (⧵ args env args (@ (@ captured env captured) env args))))] ꩜section{Equality of lists} ꩜chunk[ (λ (recur) (λ (cmp) (λ (a) (λ (b) (( (( ( a)) ( b)) (λ (_) (( ( a)) ( b))) (λ (_) (( ((cmp ( a)) ( b)) (λ (_) (((recur cmp) ( a)) ( b))) (λ (_) )) ))) )))))] ꩜chunk[ ; recur (⧵ captured env args ; recur cmp (⧵ args env args ; recur cmp a (⧵ (@ captured args) env args ; recur+cmp a b (⧵ (@ captured args) env args ; a b (@ (@ (@ (@ env (@ (@ env (@ env (@ env captured))) env (@ env args))) ; a b env (⧵ captured env args (@ (@ env (@ env (@ env captured))) env (@ env args)))) ; cmp a env (⧵ captured env args (@ (@ (@ (@ env (@ (@ (@ env (@ env captured)) env (@ env (@ env captured))) ; b env (@ env args))) env (⧵ captured env args ; recur (@ (@ (@ (@ env (@ env captured)) ; cmp env (@ env (@ env captured))) ; a env (@ env (@ env captured))) ; b env (@ env args)))) env (⧵ captured env args )) env args))) env args)))))] ꩜chunk[ (@ env )] ꩜chunk[ (@ env )] ꩜chunk[ (@ env (@ env ))] ꩜chunk[ ;; These return true (@ (@ env ) env ) (@ (@ env (@ (@ env ) env )) env (@ (@ env ) env )) (@ (@ env (@ (@ env ) env )) env (@ (@ env ) env )) (@ (@ env (@ (@ env ) env (@ (@ env ) env ))) env (@ (@ env ) env (@ (@ env ) env ))) ;; These return false (@ (@ env ) env (@ (@ env ) env )) (@ (@ env (@ (@ env ) env )) env ) (@ (@ env (@ (@ env ) env (@ (@ env ) env ))) env ) (@ (@ env ) env (@ (@ env ) env (@ (@ env ) env ))) (@ (@ env (@ (@ env ) env )) env (@ (@ env ) env )) (@ (@ env (@ (@ env ) env (@ (@ env ) env ))) env (@ (@ env ) env (@ (@ env ) env ))) ] ꩜section{Associative lists} ꩜chunk[ (λ (recur) (λ (k) (λ (l) ((if ( l) (λ (_) ) (( ( ( ( l)) k) (λ (_) ( ( l))) (λ (_) (recur k ( l)))) )) ))))] ꩜chunk[ ; ↑recur (⧵ captured env args ; ↓recur↑ ↓k↑ (⧵ args env args ; ↓recur ↓k ↓l (⧵ (@ captured args) env args (@ ; ↓l (@ (@ (@ env (@ env args)) env (⧵ captured env args )) env (⧵ captured env args ; ↓l ↓k (@ (@ (@ (@ env (@ (@ env (@ env (@ env args))) env (@ env captured))) ; ↓l env (⧵ captured env args(@ env (@ env args)))) ; ↓recur ↓k ↓l env (⧵ captured env args(@ (@ (@ env captured) env (@ env captured)) env (@ env args)))) env args))) env args))))] ꩜chunk[ (@ env )] ꩜chunk[ (@ (@ env ) env (@ (@ env ) env ))] ꩜chunk[ (@ (@ env ) env (@ (@ env ) env ))] ꩜chunk[ (@ (@ env ) env (@ (@ env ) env ))] ꩜chunk[ (@ (@ env ) env (@ (@ env ) env ))] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env )] ꩜chunk[ (@ (@ env ) env (@ (@ env ) env ))] ꩜chunk[ (@ (@ env ) env )] ꩜section{environment-manipulation functions} ꩜chunk[ ] ꩜chunk[ ] ꩜chunk[ ] ꩜chunk[ ] ꩜chunk[ ] ꩜chunk[ ] ꩜chunk[ ] ꩜chunk[ ] ꩜chunk[ ] ꩜chunk[ ] ꩜section{todo} ꩜chunk[ (@ (⧵ #hash() env args (list (((λλ x (λλ x 1)) 1) 2) (((λλ x (λλ x x)) 1) 2) (((λλ x (λλ y y)) 1) 2) (((λλ x (λλ y x)) 1) 2))) (hash-set env "λλ" ) (list))] ꩜chunk[ (⧵ #hash() env args (⧵ (hash "arg-name" (symbol->string (@ inspect-promise-root env (car (@ force env args)))) "body" (car (cdr (@ force env args))) "saved-env" env) env args (@ (hash-ref closure "body") (hash-set (hash-ref closure "saved-env") (hash-ref closure "arg-name") (map (make-racket-proc (⧵ #hash() env args (@ force env (car args))) env) (@ force env args))) args)))] ꩜chunk[<*> ]