R⁷RS Scheme

R⁷RS Scheme

An introduction to the Scheme programming language. Topics include abstract syntax trees (ASTs), proper tail recursion, quotation, homoiconicity, closures, macros and continuations.

After going through the slides, we went through some example Scheme programs. We spent some time looking at how we could implement things like exception handling, object orientation, non-deterministic programming and so on using Scheme primitives.

Link to MeetUp:
http://www.meetup.com/Functional-escape/events/126170252/

Link to Mickey Scheme:
https://github.com/cslarsen/mickey-scheme

62ec120256167ee34435f007becc2c13?s=128

Christian Stigen Larsen

August 29, 2013
Tweet

Transcript

  1. R7RS SCHEME C hr i st i an S t

    i gen Larsen 2013 - 08 - 29
  2. «Programming languages should be designed not by piling feature on

    top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.» From the SC HEME standards
  3. None
  4. None
  5. The entire language can be built with quote, if, lambda,

    set!  + variables, constants and procedure calls
  6. It’s a symbolic, homoiconic language with strong metaprogramming features.

  7. One standard, many implementations.

  8. More than 70 implementations targeting native code, JVM, CLR, JS,

    micro-CPUs, etc.
  9. ABSTRACT SYNTAX TREES

  10. public static int fact(int n) { if ( n ==

    0 ) return 1; else return n*fact(n-1); }
  11. if == n 0 1 n * fact - 1

    n public static int fact(int n) { if ( n == 0 ) return 1; else return n*fact(n-1); }
  12. if == n 0 1 n * fact - 1

    n public static int fact(int n) { if ( n == 0 ) return 1; else return n*fact(n-1); } (if (equal? n 0) 1 (* n (fact (- n 1))))
  13. Parse AST Codegen (if (equal? n 1 (* n (fact

    (- n 1)))) 0)
  14. Parse AST Codegen (if (equal? n 1 (* n (fact

    (- n 1)))) 0)
  15. PROPER TAIL RECURSION

  16. (if (zero? n) 1 (* n (fact (- n 1))))

  17. (define (fact n) (if (zero? n) 1 (* n (fact

    (- n 1)))))
  18. (define (fact n) (if (zero? n) 1 (* n (fact

    (- n 1)))))
  19. (define (fact n) (if (zero? n) 1 (* n (fact

    (- n 1))))) if == n 0 1 n * fact - 1 n
  20. (define (fact n) (if (zero? n) 1 (* n (fact

    (- n 1))))) if == n 0 1 n * fact - 1 n
  21. (define (fact n) (if (zero? n) 1 (* n (fact

    (- n 1))))) if == n 0 1 n * fact - 1 n
  22. n * fact - 1 n

  23. n * fact - 1 n

  24. - 1 n fact n * NON-TAIL RECURSIVE

  25. - 1 n fact n * acc TAIL RECURSIVE

  26. - 1 n fact n * acc TAIL RECURSIVE (define

    (fact n acc) (if (zero? n) acc (fact (- n 1) (* n acc))))
  27. - 1 n fact n * acc TAIL RECURSIVE (define

    (fact n acc) (if (zero? n) acc (fact (- n 1) (* n acc)))) (define (fact n acc) (if (zero? n) acc (fact (- n 1) (* n acc))))
  28. QUOTATION

  29. (quote (+ 1 2)) > (+ 1 2) ‘(+ 1

    2)) > (+ 1 2)
  30. (quasiquote (* 2 ,(+ 1 2))) > ‘(* 2 3)

    `(* 2 ,(+ 1 2))) > ´(* 2 3)
  31. HOMOICONICITY

  32. Code is Data Data is Code

  33. (define code ‘(let ((age 36)) (* age 365))) (print code)

    > ‘’(define ...)’’ (eval code) > 13140
  34. (assert-equal (* 36 365) 1314) «Error: (* 36 365) returned

    13140, which is not equal to 1314»
  35. (asm (mov ax 1) (int #x10))

  36. (select (age name) (from store))

  37. (html (head (title «Foo»)) (body (h1 «Bar») (p (= color

    red) «Welcome»)))
  38. (json (first-name «John») (last-name «Smith») (age 25))

  39. CLOSURES

  40. closure = code + environment

  41. (let ((name ‘‘foo’’)) (lambda (title) (print title name))) (let ((name

    ‘‘foo’’)) (lambda (title) (print title name))) (let ((name ‘‘foo’’)) (lambda (title) (print title name)))
  42. (let ((name ‘‘foo’’)) (lambda (title) (print title name))) (let ((name

    ‘‘foo’’)) (lambda (title) (print title name))) (let ((name ‘‘foo’’)) (lambda (title) (print title name)))
  43. (define send #f) ; initialize (define recv #f) (let ((secret-message

    ‘‘none’’)) (set! send (lambda (str) (set! secret-message str))) (set! recv (lambda () secret-message))) (send ‘‘Meet me by the docks at midnight’’) (print (recv))
  44. (define send #f) ; initialize (define recv #f) (let ((secret-message

    ‘‘none’’)) (set! send (lambda (str) (set! secret-message str))) (set! recv (lambda () secret-message))) (send ‘‘Meet me by the docks at midnight’’) (print (recv))
  45. MACROS

  46. A macro is a compile-time change in the AST. It

    is used to control evaluation.
  47. (defmacro (when test do-stuff) `(if ,test ,do-stuff)) (when #false (format-disk))

  48. (define-syntax when (syntax-rules () ((when test code ...) (if test

    (begin code ...))))) (define-syntax when (syntax-rules () ((when test code ...) (if test (begin code ...))))) (define-syntax when (syntax-rules () ((when test code ...) (if test (begin code ...))))) (define-syntax when (syntax-rules () ((when test code ...) (if test (begin code ...))))) (define-syntax when (syntax-rules () ((when test code ...) (if test (begin code ...))))) (define-syntax when (syntax-rules () ((when test code ...) (if test (begin code ...)))))
  49. CONTINUATIONS

  50. continuation = reified call-stack

  51. (print (* 10 (call/cc (lambda (c) 12)))) (print (* 10

    (call/cc (lambda (c) 12)))) (print (* 10 (call/cc (lambda (c) 12)))) (print (* 10 (call/cc (lambda (c) 12))))
  52. (print (* 10 12))

  53. (print (* 10 (call/cc (lambda (c) 12)))) (print (* 10

    (call/cc (lambda (c) 12))))
  54. (print (* 10 (call/cc (lambda (c) 12))))

  55. (print (* 10 (call/cc (lambda (c) 12)))) print | *

    | 10 | ? Continuation
  56. print | * | 10 | ? Continuation (lambda (val)

    (print (* 10 val))
  57. (define redo #f) ; initialize (print «Result: » (* 10

    (call/cc (lambda (cont) (set! redo cont) 0)))) (redo 10) (redo 12)
  58. (define redo #f) ; initialize (print «Result: » (* 10

    (call/cc (lambda (cont) (set! redo cont) 0)))) (redo 10) (redo 12) (define redo #f) ; initialize (print «Result: » (* 10 (call/cc (lambda (cont) (set! redo cont) 0)))) (redo 10) (redo 12)
  59. (define redo #f) ; initialize (print «Result: » (* 10

    (call/cc (lambda (cont) (set! redo cont) 0)))) (redo 10) (redo 12) (define redo #f) ; initialize (print «Result: » (* 10 (call/cc (lambda (cont) (set! redo cont) 0)))) (redo 10) (redo 12) (define redo #f) ; initialize (print «Result: » (* 10 (call/cc redo-val (lambda (cont) (set! redo cont) 0)))) (redo 10) ; redo-val (redo 12) ; redo-val
  60. DEMO TIME