Basic unit type:
λ> replTy "()"
() :: ()Basic functions:
λ> replTy "(fn x x)"
(fn x x) :: b -> b
λ> replTy "((fn x ()) (fn x x))"
((fn x ()) (fn x x)) :: ()
λ> repl "((fn x x) (fn x x))"
((fn x x) (fn x x)) :: c -> c
(fn x x)Statically typed:
λ> repl "(() (fn x x))"
-- *** Exception: Couldn't match expected type: ()
-- against type: (b -> b) -> eStandard quotation:
λ> replTy "'()"
'() :: 'Symbol
λ> repl "'(foo bar)"
'(foo bar) :: 'Symbol
(foo bar)Statically typed quotation:
λ> replTy "~()"
~() :: '()All quotes have type 'a. Normal symbolic Lisp style is 'Symbol,
quoting anything else, e.g. for unit, is '(). Also things have to be
in scope:
λ> repl "~a"
-- *** Exception: Not in scope: `a'Quoted function:
λ> replTy "'(fn x x)"
'(fn x x) :: 'SymbolQuoted function:
λ> replTy "~(fn x x)"
~(fn x x) :: '(b -> b)Notice the type is '(b -> b).
There's an eval function:
λ> replTy "eval"
eval :: 'a -> aIt accepts a quoted a and returns the a that it represents. It
won't accept anything not quoted:
λ> replTy "(eval ())"
-- *** Exception: Couldn't match expected type: 'a
-- against type: ()If given a symbolic quoted expression, it will just return it as-is:
λ> repl "(eval '())"
(eval '()) :: Symbol
()
λ> repl "(eval '((fn x x) '()))"
(eval '((fn x x) '())) :: Symbol
((fn x x) ())Given a well-typed quoted expression it will run the code:
λ> repl "(eval ~((fn x x) '()))"
(eval ~((fn x x) '())) :: 'Symbol
()
λ> repl "(eval ~((fn x x) ()))"
(eval ~((fn x x) ())) :: ()
()
What is the distinction between typed quotation and lazy lambdas? I've been wondering how to describe exactly what macros provide relative to lazy lambdas (just syntactic flexibility, or something more?). This seems bring them closer.
Neat!