wisp
 
(Arne Babenhauserheide)
2016-01-29: merge

merge

diff --git a/docs/fosdem2016.org b/docs/fosdem2016.org
new file mode 100644
--- /dev/null
+++ b/docs/fosdem2016.org
@@ -0,0 +1,454 @@
+#+title: 
+# ^ no title page, but title on the slides
+#+LATEX: \title{wisp}
+
+#+LaTeX_CLASS: beamer
+#+LaTeX_CLASS_OPTIONS: [presentation]
+#+BEAMER_THEME: Boadilla
+#+options: toc:nil
+
+#+latex: \renewcommand{\inserttotalframenumber}{10}
+
+
+* Wisp - SRFI-119
+
+#+latex: \vspace{1.3cm}
+
+**                                                                :B_columns:
+    :PROPERTIES:
+    :BEAMER_env: columns
+    :END:
+***                                                                   :BMCOL:
+   :PROPERTIES:
+   :BEAMER_col: 0.42
+   :END:
+
+#+BEGIN_SRC wisp 
+define : factorial n
+    if : zero? n
+       . 1
+       * n : factorial {n - 1}
+#+END_SRC
+
+**                                                                  :B_quote:
+   :PROPERTIES:
+   :BEAMER_env: quote
+   :END:
+
+#+latex: \vspace{1.3cm}
+
+\begin{center}
+I love the syntax of Python, \\
+but crave the simplicity and power of Lisp.
+\end{center}
+
+
+* Why Wisp?
+
+
+
+** 
+   :PROPERTIES:
+   :BEAMER_act: <2-2>
+   :END:
+
+\centering
+\Large
+
+\textyen Hello World!\pounds
+
+** 
+   :PROPERTIES:
+   :BEAMER_act: <3-4>
+   :END:
+
+\centering
+\Large
+
+Hello World!
+
+** 
+   :PROPERTIES:
+   :BEAMER_act: <1-1>
+   :END:
+
+\centering
+\Large
+
+(Hello World!)
+
+** Notes                                                            :B_quote:
+   :PROPERTIES:
+   :BEAMER_act: <4-4>
+   :BEAMER_env: quote
+   :END:
+
+- The first and last letter are important for word recognition.¹
+
+- Over 70% of the codelines in the Guile scheme source start with a paren \Rightarrow ceremony.
+
+- Many people avoid Lisp-like languages because of the parens.² 
+
+\footnotesize
+
+¹: Though not all-important. See \\ [[http://www.mrc-cbu.cam.ac.uk/people/matt.davis/cmabridge/][www.mrc-cbu.cam.ac.uk/people/matt.davis/cmabridge/]]
+
+²: Also see [[http://srfi.schemers.org/srfi-110/srfi-110.html#cant-improve][srfi.schemers.org/srfi-110/srfi-110.html#cant-improve]]
+
+* The most common letters: Lisp and Scheme are awesome
+
+** 
+
+\centering
+\Huge
+=.,":'_#?!;=
+
+**                                                          :B_ignoreheading:
+   :PROPERTIES:
+   :BEAMER_env: ignoreheading
+   :END:
+
+\centering
+/The most common non-letter, non-math characters in prose¹/
+
+\vspace{0.3cm}
+
+** 
+
+\centering
+\Huge
+=()=
+
+**                                                          :B_ignoreheading:
+   :PROPERTIES:
+   :BEAMER_env: ignoreheading
+   :END:
+
+\centering
+/The most common paired characters¹/
+
+**                                                          :B_ignoreheading:
+   :PROPERTIES:
+   :BEAMER_env: ignoreheading
+   :END:
+
+
+\vspace{0.5cm}
+
+\raggedright
+\footnotesize
+¹: From letter distributions in newspapers, see: \\ [[https://bitbucket.org/ArneBab/evolve-keyboard-layout/src/tip/1-gramme.arne.txt][bitbucket.org/ArneBab/evolve-keyboard-layout/src/tip/1-gramme.arne.txt]]
+
+* Wisp in a nutshell
+**                                                                :B_columns:
+   :PROPERTIES:
+   :BEAMER_env: columns
+   :END:
+
+
+
+***                                                                   :BMCOL:
+   :PROPERTIES:
+   :BEAMER_col: 0.48
+   :END:
+\vspace{0.5cm}
+
+#+BEGIN_SRC wisp 
+define : factorial n
+    if : zero? n
+       . 1
+       * n : factorial {n - 1}
+#+END_SRC
+
+
+***                                                                   :BMCOL:
+   :PROPERTIES:
+   :BEAMER_col: 0.48
+   :END:
+\vspace{0.5cm}
+
+#+BEGIN_SRC wisp
+(define (factorial n)
+    (if (zero? n)
+      1
+      (* n (factorial {n - 1}))))
+#+END_SRC
+
+**                                                          :B_ignoreheading:
+   :PROPERTIES:
+   :BEAMER_env: ignoreheading
+   :END:
+
+\vspace{1cm}
+
+\footnotesize
+
+- indent as with parens, dot-prefix, inline-:, and use SRFI-105.
+
+- Wisp uses the minimal syntax required to represent arbitrary structure: \\ Syntax justification: [[http://draketo.de/english/wisp#sec-4][draketo.de/english/wisp#sec-4]]
+
+- Many more examples in “From Python to Guile Scheme”: \\ info: [[http://draketo.de/py2guile][draketo.de/py2guile]] \\ download: [[http://draketo.de/proj/py2guile/py2guile.pdf][draketo.de/proj/py2guile/py2guile.pdf]]
+
+
+* Implementation
+
+** REPL and Reader (language wisp spec)                       :B_block:BMCOL:
+   :PROPERTIES:
+   :BEAMER_col: 0.57
+   :BEAMER_env: block
+   :END:
+
+#+BEGIN_SRC wisp
+  define-language wisp
+    . #:title "Wisp Scheme Syntax.."
+    . #:reader read-one-wisp-sexp
+    . #:compilers `(
+        (tree-il . ,compile-tree-il))
+    . #:decompilers `(
+        (tree-il . ,decompile-tree-il))
+    . #:evaluator (lambda (x module) 
+                     primitive-eval x)
+    . #:printer write
+    . #:make-default-environment
+    lambda :
+      let : : m : make-fresh-user-module
+        module-define! m 'current-reader 
+                          make-fluid
+        module-set! m 'format simple-format
+        . m
+#+END_SRC
+
+** Preprocessor (wisp.scm)                                    :B_block:BMCOL:
+   :PROPERTIES:
+   :BEAMER_col: 0.39
+   :BEAMER_env: block
+   :END:
+
+#+BEGIN_SRC sh
+guile wisp.scm tests/hello.w
+#+END_SRC
+
+#+BEGIN_SRC scheme
+(define (hello who)
+  ;; include the newline
+  (format #t "~A ~A!\n"
+          "Hello" who))
+(hello "Wisp")
+#+END_SRC
+
+\footnotesize
+(Plan B: You can always go back)
+
+
+* Applications?
+**                                                                    :BMCOL:
+   :PROPERTIES:
+   :BEAMER_col: 0.50
+   :END:
+
+*** Example: User Scripts
+
+#+BEGIN_SRC wisp
+Enter : First_Witch
+        Second_Witch
+        Third_Witch
+
+First_Witch
+  When shall we three meet again
+  In thunder, lightning, or in rain?
+#+END_SRC
+
+***                                                         :B_ignoreheading:
+    :PROPERTIES:
+    :BEAMER_env: ignoreheading
+    :END:
+
+This displays
+
+***                                                                 :B_block:
+   :PROPERTIES:
+   :BEAMER_env: block
+   :END:
+\footnotesize
+#+BEGIN_EXAMPLE
+First Witch
+  When shall we three meet again
+  In thunder, lightning, or in rain?
+#+END_EXAMPLE
+
+***                                                         :B_ignoreheading:
+    :PROPERTIES:
+    :BEAMER_env: ignoreheading
+    :END:
+
+\footnotesize
+- [[http://draketo.de/english/wisp/shakespeare][draketo.de/english/wisp/shakespeare]]
+- Templates, executable pseudocode, REPL-interaction, configuration, ...
+
+* Solutions
+
+** Run examples/newbase60.w as script
+
+#+BEGIN_SRC wisp
+#!/usr/bin/env sh
+# -*- wisp -*-
+exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp \
+           -e '(@@ (examples newbase60) main)' \
+           -s "$0" "$@"
+; !#
+define-module : examples newbase60
+
+define : main args
+  ...
+#+END_SRC
+
+** Use Wisp code from parenthesized Scheme
+
+- precompile: =guile --language=wisp module=
+- then just import as usual: =(use-modules (...))=
+
+* Experience
+
+**                                                                  :B_quote:
+   :PROPERTIES:
+   :BEAMER_env: quote
+   :END:
+
+\vspace{1cm}
+
+»ArneBab's alternate sexp syntax is best I've seen; pythonesque, hides parens but keeps power« — Christopher Webber \\ \rightarrow [[http://dustycloud.org/blog/wisp-lisp-alternative/][dustycloud.org/blog/wisp-lisp-alternative/]]
+
+\vspace{1cm}
+
+**                                                                  :B_block:
+   :PROPERTIES:
+   :BEAMER_env: block
+   :END:
+
+- Wisp is implemented in Wisp (850 lines, two implementations).
+- Examples: 4 lines (factorial) to 330 lines (advection on icosaheder).
+
+* Try Wisp
+
+** Install
+
+#+BEGIN_SRC sh
+guix package -i guile guile-wisp
+guile --language=wisp
+#+END_SRC
+
+#+BEGIN_SRC sh
+wget https://bitbucket.org/ArneBab/wisp/downloads/wisp-0.9.0.tar.gz;
+tar xf wisp-0.9.0.tar.gz ; cd wisp-0.9.0/;
+./configure; make check;
+examples/newbase60.w 123
+#+END_SRC
+
+- [[http://draketo.de/english/wisp][http://draketo.de/english/wisp]]
+
+** Emacs mode for syntax highlighting
+
+- M-x package-install [RET] *wisp-mode* [RET]
+- https://marmalade-repo.org/packages/wisp-mode
+
+
+* Thank you!
+
+***                                               :B_alertblock:BMCOL:
+    :PROPERTIES:
+    :BEAMER_col: 0.032
+    :BEAMER_env: alertblock
+    :END:
+
+$\ddot \smile$
+
+* Appendix                                                       :B_appendix:
+  :PROPERTIES:
+  :BEAMER_env: appendix
+  :END:
+
+* Why not SRFI-110 or SRFI-49?
+
+** SRFI-49                                                            :BMCOL:
+   :PROPERTIES:
+   :BEAMER_col: 0.45
+   :END:
+
+*** SRFI-49                                                         :B_block:
+    :PROPERTIES:
+    :BEAMER_env: block
+    :END:
+
+#+BEGIN_SRC wisp
+  + 5
+    * 4 3
+    2
+    1
+    0
+#+END_SRC
+
+- Cannot continue the argument list
+
+*** Wisp                                                            :B_block:
+    :PROPERTIES:
+    :BEAMER_env: block
+    :END:
+
+#+BEGIN_SRC wisp
+  + 5
+    * 4 3
+    . 2 1 0
+
+#+END_SRC
+
+** SRFI-110                                                   :B_block:BMCOL:
+   :PROPERTIES:
+   :BEAMER_col: 0.45
+   :BEAMER_env: block
+   :END:
+
+#+BEGIN_SRC wisp
+myfunction 
+  x: \\ original-x
+  y: \\ calculate-y original-y
+#+END_SRC
+
+#+BEGIN_SRC wisp
+  a b $ c d e $ f g
+#+END_SRC
+
+#+BEGIN_SRC wisp
+  let <* x getx() \\ y gety() *>
+  ! {{x * x} + {y * y}}
+#+END_SRC
+
+- most common letters?
+
+* Keep parens where they help readability
+
+
+**                                                                    :BMCOL:
+   :PROPERTIES:
+   :BEAMER_col: 0.45
+   :END:
+
+
+#+BEGIN_SRC wisp
+cond 
+  : and (null? l) (zero? a)
+    . '()
+  else
+    cons a l
+#+END_SRC
+
+
+#+BEGIN_SRC wisp
+map 
+  lambda (x) (+ x 1)
+  list 1 2 3
+#+END_SRC
+
+
+# Local Variables:
+# org-latex-minted-options: (("linenos" "false") ("frame" "lines") ("framesep" "6pt") ("fontsize" "\\footnotesize"))
+# End:
diff --git a/examples/ensemble-estimation.w b/examples/ensemble-estimation.w
--- a/examples/ensemble-estimation.w
+++ b/examples/ensemble-estimation.w
@@ -78,19 +78,31 @@ define* : write-multiple . x
 
 ;; Start with the simple case: One variable and independent observations (R diagonal)
 ;; First define a truth
-define x^seed '(0.5 0.6 7 0.1 0.7 0.9 0.8 0.4)
+define x^seed '(0.5 0.6 2 0.1) ; 0.7 0.9 0.8 0.4)
+;; The size is the length of the seed, squared, each multiplied by each
 define x^true : append-ec (: i (length x^seed)) : list-ec (: j x^seed) : * j : list-ref x^seed i
 ;; And add an initial guess of the parameters
-define x^b : append-ec (: i (length x^seed))  '(1 1 1 1 1 1 1 1) ; initial guess
-define P : make-covariance-matrix-from-standard-deviations : append-ec (: i (length x^seed)) '(0.5 0.1 0.3 0.1 0.2 0.2 0.2 0.2)
+define x^b : append-ec (: i (length x^seed))  '(1 1 1 1) ; 1 1 1 1) ; initial guess
+define P : make-covariance-matrix-from-standard-deviations : append-ec (: i (length x^seed)) '(0.5 0.1 0.3 0.1) ; 0.2 0.2 0.2 0.2)
 
 ;; Then generate observations
-define y⁰-num 3000
+define y⁰-num 1000
 define y⁰-pos-max 100
 ;; At the positions where they are measured. Drawn randomly to avoid
 ;; giving an undue weight to later values.
 define y⁰-pos : list-ec (: i y⁰-num) : * (random:uniform) y⁰-pos-max
 
+define : H-single-parameter xi xi-pos pos
+       . "Observation function for a single parameter."
+       let* 
+         : xi-posdist : abs : / {pos - xi-pos} {y⁰-pos-max / 20}
+         cond
+           : < 5 xi-posdist 
+             . 0
+           else
+             * xi pos 
+               exp : - : expt xi-posdist 2
+
 ;; We need an observation operator to generate observations from true values
 define : H x pos
        . "Observation operator. It generates modelled observations from the input.
@@ -103,20 +115,16 @@ x are parameters to be optimized, pos is
              x-pos : list-ec (: i len) : * ystretch {{i + 0.5} / {len + 1}}
            apply +
                  list-ec (: i len)
-                      * : list-ref x i
-                          . pos
-                          exp 
-                            - 
-                              expt 
-                                / {pos - (list-ref x-pos i)} {ystretch / 20}
-                                . 2
-
+                      H-single-parameter 
+                        list-ref x i
+                        list-ref x-pos i
+                        . pos
 
 ;; We start with true observations which we will disturb later to get
 ;; the equivalent of measured observations
 define y^true : list-ec (: i y⁰-pos) : H x^true i
 ;; now we disturb the observations with a fixed standard deviation. This assumes uncorrelated observations.
-define y⁰-std 50
+define y⁰-std 10
 define y⁰ : list-ec (: i y^true) : + i : * y⁰-std : random:normal
 ;; and define the covariance matrix. This assumes uncorrelated observations.
 define R : make-covariance-matrix-from-standard-deviations : list-ec (: i y⁰-num) y⁰-std
@@ -201,21 +209,40 @@ Limitations: y is a single value. R and 
 
 define : main args
     let*
-      : optimized : EnSRT H x^b P y⁰ R y⁰-pos 30
+      : optimized : EnSRT H x^b P y⁰ R y⁰-pos 100
         x-opt : list-ref optimized 0
         x-deviations : list-ref optimized 1
         ; std : sqrt : * {1 / {(length x-deviations) - 1}} : sum-ec (: i x-deviations) : expt i 2
-      format #t "x⁰: ~A ± ~A\nx:  ~A ± ~A\nx^t:~A\ny:  ~A ± \ny⁰: ~A ± ~A\nnoise: ~A\n" 
+      format #t "x⁰:   ~A ± ~A\nx:    ~A ± ~A\nx^t:  ~A\nx-t/σ:~A\ny̅:    ~A ± ~A\ny̅⁰:   ~A ± ~A\ny̅^t:  ~A\nnoise:~A\n" 
                  . x^b
                  list-ec (: i (length x^b)) : list-ref (list-ref P i) i
                  . x-opt 
                  list-ec (: i (length x-opt))
                     apply standard-deviation-from-deviations : list-ec (: j x-deviations) : list-ref j i
                  . x^true
+                 list-ec (: i (length x-opt)) 
+                   / : - (list-ref x-opt i) (list-ref x^true i)
+                       apply standard-deviation-from-deviations : list-ec (: j x-deviations) : list-ref j i
                  * {1 / (length y⁰)} : apply + : map (lambda (x) (H x-opt x)) y⁰-pos
+                 apply standard-deviation-from-deviations
+                   append-ec (: i (length x-deviations))
+                     let*
+                       : 
+                         x-opt+dev
+                           list-ec (: j (length x-opt))
+                             + : list-ref x-opt j
+                                 list-ref
+                                   list-ref x-deviations i
+                                   . j
+                         y-opt+dev : map (lambda (x) (H x-opt+dev x)) y⁰-pos
+                         y-opt : map (lambda (x) (H x-opt x)) y⁰-pos
+                       map (lambda (x y) (- x y)) y-opt+dev y-opt
+                     ; list-ec (: i (length y-opt))
+                     ;   - (list-ref y-opt+dev i) (list-ref y-opt i)
                  ; apply standard-deviation-from-deviations : map H x-deviations ; FIXME: This only works for trivial H.
                  mean y⁰
                  standard-deviation y⁰
+                 * {1 / (length y⁰)} : apply + : map (lambda (x) (H x^true x)) y⁰-pos
                  . y⁰-std
       ; now plot the result
       let : : port : open-output-pipe "python"
diff --git a/examples/enter-three-witches.w b/examples/enter-three-witches.w
new file mode 100755
--- /dev/null
+++ b/examples/enter-three-witches.w
@@ -0,0 +1,49 @@
+#!/usr/bin/env sh
+exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples enter-three-witches) main)' -s "$0" "$@"
+; !#
+
+define-module : examples enter-three-witches
+
+use-modules : ice-9 optargs
+
+define-syntax Enter
+ syntax-rules ()
+  : _ (name) b ...
+    begin
+      define-syntax name
+        syntax-rules ::: ()
+          : _ (c :::) d :::
+            format #t "~A\n  ~A\n\n" 
+               string-join 
+                 string-split (symbol->string 'name) #\_
+               string-join 
+                 map : lambda (x) (string-join (map symbol->string x))
+                       quote : (c :::) d :::
+                 . "\n  "
+          : _ c d :::
+            ;; allow for modifier keywords after the name
+            begin
+              format #t "~A:\n" : symbol->string 'c
+              name d :::
+          : _ c :::
+            begin #t c :::
+      Enter b ...
+  : _ b ...
+    begin 
+
+
+define : main args
+  Enter : First_Witch
+          Second_Witch
+          Third_Witch
+  
+  First_Witch
+      When shall we three meet again
+      In thunder, lightning, or in rain?
+  
+  Second_Witch
+      When the hurlyburly's done,
+      When the battle's lost and won.
+
+  Third_Witch
+      That will be ere the set of sun.
diff --git a/examples/factorial.w b/examples/factorial.w
--- a/examples/factorial.w
+++ b/examples/factorial.w
@@ -7,7 +7,7 @@ define-module : examples factorial
 
 define : factorial n            ;   (define (factorial n)
     if : zero? n                ;       (if (zero? n)
-       . n                      ; =>        n
+       . 1                      ; =>        1
        * n : factorial {n - 1}  ;           (* n (factorial {n - 1}))))
 
 define : main args
diff --git a/tests/hello.scm b/tests/hello.scm
--- a/tests/hello.scm
+++ b/tests/hello.scm
@@ -1,4 +1,5 @@
 (define (hello who)
+  ;; include the newline
   (format #t "~A ~A!\n"
           "Hello" who))
 (hello "Wisp")
diff --git a/tests/hello.w b/tests/hello.w
--- a/tests/hello.w
+++ b/tests/hello.w
@@ -1,4 +1,5 @@
 define : hello who
+  ;; include the newline
   format #t "~A ~A!\n"
           . "Hello" who
 hello "Wisp"
diff --git a/wisp-reader.w b/wisp-reader.w
--- a/wisp-reader.w
+++ b/wisp-reader.w
@@ -53,7 +53,7 @@ define : read-one-wisp-sexp port env
 define-language wisp
   . #:title "Wisp Scheme Syntax. See SRFI-119 for details. THIS IS EXPERIMENTAL, USE AT YOUR OWN RISK"
   ; . #:reader read-one-wisp-sexp
-  . #:reader : lambda (port env) : let ((x (read-one-wisp-sexp port env))) x
+  . #:reader read-one-wisp-sexp ; : lambda (port env) : let ((x (read-one-wisp-sexp port env))) x
   . #:compilers `((tree-il . ,compile-tree-il))
   . #:decompilers `((tree-il . ,decompile-tree-il))
   . #:evaluator : lambda (x module) : primitive-eval x