(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