* What's cool about CHICKEN 5? #+STARTUP: inlineimages [[./chicken-logo.png]] ** Peter Bex T-DOSE Eindhoven May 11th, 2019 * Who am I? ** Peter Bex *** Work: codeyellow.nl We're hiring! Talk to me or Burhan later *** Freelancing on the side: pebble-software.nl *** Blog (mostly about CHICKEN): more-magic.net *** Fell in love with Scheme at university, ~2002 *** CHICKEN user since 2003 eggs: postgresql, spiffy, http-client, ... *** CHICKEN core contributor since late 2009 regex engine, macros, garbage collector, ... * Scheme: intro Dialect of /LISP/, a functional language (impure) LISP is from 1958, Scheme 1975; still here! Other Lisps: Common Lisp, Emacs Lisp, Clojure, .. Not for everyone -> Love it or hate it! #+BEGIN_SRC scheme (display "Hello, world!\n") ;; Obligatory (define (fib n) ;; Fibonacci, because why not (if (<= n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))) #+END_SRC * Scheme: philosophy ** Super minimal but powerful language User is an equal to the makers of the language Very few things *need* "special" support Advantages of small extensible core: - ease of understanding (fits in your head) - embeddability - facilitates experimental implementations - timelessness; e.g. classes can just be a library. C => C++/ObjC, Pascal => Object Pascal but Scheme => Scheme * Scheme superpowers: macros ** Fully hygienic macro system #+BEGIN_SRC scheme (define-syntax swap! (syntax-rules () ((_ a b) (let ((x a)) (set! a b) (set! b x))))) ;; Does the right thing, i.e. print 2: (let ((x 1) (y 2)) (swap! x y) (display y)) #+END_SRC * Scheme superpowers: closures ** Lexical scoping Gives us *closures* (now ubiquitous; first LISP) #+BEGIN_SRC scheme (define (make-counter) (let ((val 0)) (lambda () ; Anonymous fn, closes over "val" (set! val (+ val 1)) val))) (define c (make-counter)) (c) ; 1 (c) ; 2 #+END_SRC * Scheme superpowers: continuations ** Continuations Can be used to implement exceptions, co-routines, serialize full program state, etc etc Tail calls "for free" [Lambda the Ultimate Goto] Tail recursion is /required by the spec/! Bad implementations often conveniently ignore it Deep recursion is okay; just eats up more heap See also Stackless Python * Scheme superpowers: numeric tower ** Numeric tower Systematic support for /all the numbers/ Spec defines system, subset is allowed (see later) #+BEGIN_SRC scheme 1 ;; exact integer 0.5 ;; inexact real number 1/2 ;; exact rational number 1+2i ;; exact complex number 0.5+0.25i ;; inexact complex number 1/2+3/4i ;; ALSO an exact complex number (+ 3/4 1/2) ;; yes, this returns 5/4 #+END_SRC * Scheme superpowers: REPL ** Read-Eval-Print-Loop *** Interpreter prompt allows you to explore Type an expression (read) Have it evaluated (eval) See the result (print) Go to start (loop) Most interpreters do this now. Done right, can shape your way of thinking. LISP machines did it best! (SLIME/Geiser) * CHICKEN: intro /Implementation/ of Scheme (one of the few serious ones) Based on Henry Baker's [Cheney On The MTA] idea: Use C stack for initial heap (nursery) Been around since 2000. Compiles to C. Uses GCC, clang, ... to generate machine code, so: very portable *Great* community! Produced lots of libraries * CHICKEN: C interop Interop with C is trivial; just drop down to it #+BEGIN_SRC scheme (import (chicken foreign)) (foreign-declare "#include ") (define twice-exp (foreign-lambda* double ((double x)) "double result = exp(x);" "C_return(result * 2.0);")) (display (twice-exp 5)) ;; 296.826318205153 #+END_SRC * CHICKEN 5: Overhaul of module system ** Most user-visible change Old CHICKENs had such memorable module names as "utils" and "extras"... Most was in "chicken" Hard to remember, inconsistent Large libraries (but few imports needed) ** Naming scheme (haha) inspired by R7RS (scheme base) => (chicken base) (scheme file) => (chicken file) etc others: (chicken posix), (chicken foreign) etc * CHICKEN 5: Overhaul of module system; examples ** A few good examples to give you an idea: "sort" procedure in CHICKEN 4: data-structures "sort" procedure in CHICKEN 5: (chicken sort) "symbol-append" in CHICKEN 4: library?! chicken "symbol-append" in CHICKEN 5: (chicken base) "->string" in CHICKEN 4: data-structures "->string" in CHICKEN 5: (chicken string) "read-line" in CHICKEN 4: extras "read-line" in CHICKEN 5: (chicken io) * CHICKEN 5: Numeric tower; old situation ** Older CHICKENs had only "fixnums" and "flonums" *** Quite fast (compile to ~standard C float/int) *** Never felt very "complete" or "serious" to me LISP/Scheme is awesome, dammit! *** Issues with C FFI Only 62 (or 30) bits available for ints; precision loss ** So, I made it my mission to fix this * CHICKEN 5: Numeric tower; new situation ** Most important: large integers ("bignums") C FFI finally supports /size_t/ and friends! ** Exact rational numbers are nice too; Calculations will always be exact ** Complex numbers mostly for completeness Not that many use-cases(?) ** Pretty fast, but a bit slower than CHICKEN 4 Mostly due to pre-allocation. Working on it! *** Enough self-promotion, on to other features * CHICKEN 5: static compilation ** Great for binary deployment / distribution No need to mess around with "virtualenvs" etc Just plop the binary onto a server; done Killer feature of Go, for example ** CHICKEN always supported static compilation! Sucked for eggs (nobody tests it) ** Solution: declarative egg format Makes it harder to mess up * CHICKEN 5: static compilation; old situation ** Old (imperative) .setup-file format: #+BEGIN_SRC scheme (compile -s ncurses.scm -L -lncurses -j ncurses) (compile -s ncurses.import.scm) (compile -c ncurses.scm -L -lncurses -unit ncurses) ; Almost nobody did this (install-extension 'ncurses '("ncurses.o" "ncurses.so" "ncurses.import.so") '((version "1.6") (static "ncurses.o"))) ; And this #+END_SRC scheme * CHICKEN 5: static compilation; new situation ** New (declarative) .egg-file format: #+BEGIN_SRC scheme ((synopsis "An interface to ncurses") (category ui) (license "BSD") (build-dependencies bind) (author "felix winkelmann") (maintainer "The CHICKEN Team") ;; This replaces the .setup file: (components (extension ncurses (link-options -L -lncurses)))) #+END_SRC scheme * CHICKEN 5: declarative egg files; sh scripts ** Generates sh scripts (batch files on Windows) #+BEGIN_SRC sh chicken-do ncurses.so ncurses.import.scm : \ ncurses.scm ncurses.egg : \ csc -host -J -s -setup-mode -I . -C -I. \ -L -lncurses ncurses.scm -o ncurses.so chicken-do ncurses.static.o ncurses.link : \ ncurses.scm ncurses.egg : \ csc -setup-mode -static -I . -emit-link-file \ ncurses.link -host -c -unit ncurses \ -C -I. ncurses.scm -o ncurses.static.o #+END_SRC * CHICKEN 5: declarative egg files; advantages ** Advantages of declarative format Static linking is *always* built-in Cross-compilation is made easier Support for new features can be retroactively added to all eggs Security Less typing! * CHICKEN 5: binary reproducible builds ** Both CHICKEN itself and eggs Made output of Scheme to C conversion stable C to binary is left to the C tool chain ** Gives us verifiability See also [reproducible-builds.org] ** Nice bonus: Faster builds with ccache Generated C is identical! * Final words ** Most important eggs have already been ported! CHICKEN 5 is recommended for new code ** Start porting your CHICKEN 4 code How-to guide: wiki.call-cc.org/porting-c4-to-c5 ** CHICKEN 5.1 is upcoming *** Bugfixes, perf improvements, cleanups The usual *** New "c-objects" declaration in egg files Some eggs will require 5.1! * Thank you! [[./chicken-logo.png]] ** CHICKEN website call-cc.org ** IRC channel #chicken on Freenode ** My blog more-magic.net