diff --git a/website/presentation.html b/website/presentation.html index 3e4ef9f..76cf578 100644 --- a/website/presentation.html +++ b/website/presentation.html @@ -105,7 +105,7 @@ Pattern matching, hygenic by default b))))))) --- -# Background: Fexprs tho +# Background: Fexprs Something of a combo between the two - direct style, but naturally hygenic by default.
(vau de (a b) (let ((temp (eval a de)))
@@ -114,6 +114,93 @@ Something of a combo between the two - direct style, but naturally hygenic by de
(eval b de))))
---
+# Background: Fexprs - detail
+
+Ok, Fexprs are calls to combiners - combiners are either applicatives or operatives.
+Combiners are introduced with _vau_ and take an extra paramter (here called _dynamic_env_, earlier called _de_) which is the dynamic environment.
+(vau dynamicEnv (normalParam1 normalParam2) (body of combiner))
+
+--
+Lisps, as well as Kraken, have an _eval_ function.
+This function takes in code as a data structure, and in R5RS Scheme an "environment specifier", and in Kraken, a full environment (like what is passed as _dynamicEnv_).
+(eval some_code an_environment)
+---
+# Background: Fexprs - detail
+
+- **Normal Lisp** (Scheme, Common Lisp, etc)
+--
+
+ - Functions - runtime, evaluate parameters once, return value
+--
+
+ - Macros - expansion time, do not evaluate parameters, return code to be inlined
+--
+
+ - Special Forms - look like function or macro calls, but do something special (if, lambda, etc)
+--
+
+- **Kraken** (and Kernel)
+--
+
+ - Combiners
+--
+
+ - Applicatives (like normal functions, combiners that evaluate all their parameters once in their dynamic environment)
+--
+ - Operatives (combiners that do something unusual with their parameters, do not evaluate them right away)
+--
+
+_Operatives can replace macros and special forms, so combiners replace all_
+---
+# Background: Fexprs - detail
+
+Combiners, like functions in Lisp, are first class.
+This means that unlike in Lisp, Kraken's version of macros and special forms are *both* first class.
+
+---
+# Background: Fexprs - detail
+As we've mentioned, in Scheme _or_ is a macro expanding
+(or a b)
+
+to
+(let ((temp a))
+ (if temp temp
+ b))
+
+
+So passing it to a higher-order function doesn't work, you have to wrap it in a function:
+> (fold or #f (list #t #f))
+Exception: invalid syntax and
+> (fold (lambda (a b) (or a b)) #f (list #t #f))
+#t
+
+---
+# Background: Fexprs - detail
+But in Kraken, _or_ is a combiner (an operative!), so it's first-class
+(vau de (a b) (let ((temp (eval a de)))
+ (if temp temp
+ (eval b de))))
+
+So it's pefectly legal to pass to a higher-order combiner:
+> (foldl or false (array true false))
+true
+
+---
+# Background: Fexprs - detail
+
+All special forms in Kaken are combiners too, and are thus also first class.
+In this case, we can not only pass the raw _if_ around, but we can make an _inverse_if_ which inverts its condition (kinda macro-like) and pass it around.
+> (let ((use_if (lambda (new_if) (new_if true 1 2)))
+ (inverse_if (vau de (c t e) (if (not (eval c de))
+ (eval t de)
+ (eval e de))))
+ )
+ (list (use_if if) (use_if inverse_if)))
+(1 2)
+
+What were special forms in Lisp are now just built-in combiners in Kraken.
+*if* is not any more special than *+*, and in both cases you can define your own versions that would be indistinguishable, and in both cases they are first-class.
+---
# Motivation and examples
1. Vau/Combiners unify and make first class functions, macros, and built-in forms in a single simple system
diff --git a/website/recursive.css b/website/recursive.css
index 8517fda..bec3e86 100644
--- a/website/recursive.css
+++ b/website/recursive.css
@@ -48,6 +48,7 @@ h4 { font-size: 1.2em; }
i { --rec-slnt: -14; }
em { --rec-slnt: -14; }
b { --rec-wght: 600; }
+strong { --rec-wght: 600; }
.run_container { position: relative; }
.editor, .remark-code, .remark-inline-code {
font-family: 'Recursive', monospace;