$30 off During Our Annual Pro Sale. View Details »

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

Christian Stigen Larsen

August 29, 2013
Tweet

More Decks by Christian Stigen Larsen

Other Decks in Programming

Transcript

  1. R7RS SCHEME
    C
    hr
    i
    st
    i
    an
    S
    t
    i
    gen Larsen
    2013
    -
    08
    -
    29

    View Slide

  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

    View Slide

  3. View Slide

  4. View Slide

  5. The entire language can be
    built with quote, if, lambda, set!
    + variables, constants and procedure calls

    View Slide

  6. It’s a symbolic, homoiconic
    language with strong
    metaprogramming features.

    View Slide

  7. One standard, many
    implementations.

    View Slide

  8. More than 70 implementations
    targeting native code, JVM, CLR,
    JS, micro-CPUs, etc.

    View Slide

  9. ABSTRACT SYNTAX TREES

    View Slide

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

    View Slide

  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);
    }

    View Slide

  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))))

    View Slide

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

    View Slide

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

    View Slide

  15. PROPER TAIL RECURSION

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  22. n
    *
    fact
    -
    1
    n

    View Slide

  23. n
    *
    fact
    -
    1
    n

    View Slide

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

    View Slide

  25. -
    1
    n
    fact
    n
    *
    acc
    TAIL RECURSIVE

    View Slide

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

    View Slide

  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))))

    View Slide

  28. QUOTATION

    View Slide

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

    View Slide

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

    View Slide

  31. HOMOICONICITY

    View Slide

  32. Code is Data
    Data is Code

    View Slide

  33. (define code
    ‘(let ((age 36))
    (* age 365)))
    (print code) > ‘’(define ...)’’
    (eval code) > 13140

    View Slide

  34. (assert-equal
    (* 36 365)
    1314)
    «Error:
    (* 36 365) returned 13140,
    which is not equal to 1314»

    View Slide

  35. (asm
    (mov ax 1)
    (int #x10))

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  39. CLOSURES

    View Slide

  40. closure = code + environment

    View Slide

  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)))

    View Slide

  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)))

    View Slide

  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))

    View Slide

  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))

    View Slide

  45. MACROS

    View Slide

  46. A macro is a compile-time
    change in the AST.
    It is used to control
    evaluation.

    View Slide

  47. (defmacro (when test do-stuff)
    `(if ,test ,do-stuff))
    (when #false (format-disk))

    View Slide

  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 ...)))))

    View Slide

  49. CONTINUATIONS

    View Slide

  50. continuation = reified call-stack

    View Slide

  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))))

    View Slide

  52. (print
    (* 10 12))

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

  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

    View Slide

  60. DEMO TIME

    View Slide