1 / 44

Introduction to Scheme

CS 480/680 – Comparative Languages. Introduction to Scheme. “And now for something completely different…” – Monty Python. Functional Languages. Scheme is a functional language. It belongs to a class of languages that differ from imperative languages in a number of ways:

urban
Download Presentation

Introduction to Scheme

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CS 480/680 – Comparative Languages Introduction to Scheme “And now for something completely different…” – Monty Python

  2. Functional Languages • Scheme is a functional language. It belongs to a class of languages that differ from imperative languages in a number of ways: • Elegant, concise, syntax (and specification). • Definition of functions is paramount – Order is not that important! • No iteration! -- Use of recursion instead. • Data is generally weakly/dynamically typed. Intro to Scheme

  3. Why Scheme? • Very simple syntax (the E-BNF specification is only 8 pages – see the last slides) • Lisp is the standard for functional languages, Scheme is a rising star • Many efforts to make it a teachable language • Cal-Tech, MIT, etc. • DR-Scheme Intro to Scheme

  4. Forms and Evaluation • The basic scheme construct is called a form • (function argument1 argument2 argument3…) • (+ 2 5) » 7 • (+ 3 4 5) » 12 • (/ 22 7) » 22/7 • (number? 5) » #t • (boolean? 5) » #f • (boolean? #5) » #t • (eqv? 42 42) » #t • (eqv? 42 42.0) » #f • (= 42 42.0) » #t • (= 42 #x2A) » #t • (expt 4 2) » 16 • (expt 4 1/2) » 2 • (max 1 3 5 7) » 7 • (min 1 3 5 7) » 1 • (abs -2) » 2 • (abs -2 5)  abs: expects 1 argument, given 2: -2 5 Intro to Scheme

  5. Substitution Model The basic rule: To evaluate a Scheme expression: • Evaluate its operands • Evaluate the operator • Apply the operator to the evaluated operands Intro to Scheme

  6. Warning!Boredom ahead! • We will walk through evaluations • in painful, excruciating detail • Not the most exciting part of course • but necessary to give a precise model Intro to Scheme

  7. Example expression eval • Example: (+ 3 (* 4 5) ) Intro to Scheme

  8. operator Example expression eval • Example: (+3 (* 4 5) ) Intro to Scheme

  9. operator operand 1 Example expression eval • Example: (+3 (* 4 5) ) Intro to Scheme

  10. operator operand 1 operand 2 Example expression eval • Example: (+3 (* 4 5)) Intro to Scheme

  11. Example expression eval • Example: (+ 3 (* 4 5)) • evaluate 3 • evaluate (* 4 5) • evaluate 4 • evaluate 5 • evaluate * • apply * to 4, 5  20 • evaluate + • apply + to 3, 20 23 Intro to Scheme

  12. Primitive expressions • Numbers evaluate to themselves • 105  105 • Primitive procedures • +, -, *, /, abs … • evaluate to the corresponding internal procedure • e.g. "+" evaluates to the procedure that adds numbers together • Can write this as: +  + • or as: + [primitive procedure +] • write this out explicitly for now Intro to Scheme

  13. Another example • (+ 3 (- 4 (* 5 (expt 2 2)))) • evaluate 3  3 • evaluate (- 4 (* 5 (expt 2 2))) • evaluate 4  4 • evaluate (* 5 (expt 2 2)) • evaluate 5  5 • evaluate (expt 2 2) • evaluate 2  2, evaluate 2  2, expt  expt • apply expt to 2, 2  4 • evaluate *  * • apply * to 5, 4  20 • apply - to 4, 20  -16 • apply + to 3, -16  -13 Intro to Scheme

  14. Evaluation with variables • An assignment provides an association between a symbol (variable) and its value (definex 3) • Here x is the variable, 3 is the value • To evaluate a variable: • look up the value associated with the variable • and replace the variable with its value Intro to Scheme

  15. Variable evaluation example • (definex 3) • Then evaluate x • look up value of x • x has value 3 (due to define) • result: 3 Intro to Scheme

  16. Simple expression evaluation • Assignment and evaluation (define x 3) (define y 4) • evaluate (+ x y) • evaluate x 3 • evaluate y 4 • evaluate + [primitive procedure +] • apply + to 3, 4 7 Intro to Scheme

  17. Special forms • N.B. There are a few special formswhich do not evaluate in the way we’ve described. • define is one of them (definex 3) • We do not evaluate x before applying define to x and 3 • Instead, we • evaluate the second operand (3 3) • make an association between it and the first operand (x) Intro to Scheme

  18. Special forms • Another example: (definex (+ 2 3)) • Evaluate (+ 2 3) • evaluate 2 2 • evaluate 3  3 • evaluate +  [primitive procedure +] • apply + to 2, 3  5 • Make association between x and 5 • details of how association is made aren't important Intro to Scheme

  19. Basic Data Types • Numbers: 3, -3, 22/7, 3+2i, #xF3A, #o721, #b110110, 3.1416 (= 42 #x2A) » #t • Single characters: #\c, #\newline, #\tab, #\space • (char? #\c), (char=? #\c #\b), (char<=? #\c #\b) • Strings: “Hello World” • (string #\h #\i) • (string-ref “Hello” 1) » #\e • (string-append “E” “Pluribus” “Unum”) » “E Pluribus Unum” Intro to Scheme

  20. More types • Procedures (lambda) • Booleans (#t and #f) Intro to Scheme

  21. Symbols • Symbols have two parts, a name and a value • Similar to variables in other languages, but beware of the many differences! • We’ll see a lot more about the differences later. • (define xyz 9) • xyz » 9 • (symbol? xyz) » #f • (symbol? ’xyz) » #t • (set! xyz 8) • (set! qrs 7)  set!: cannot set undefined identifier: qrs Intro to Scheme

  22. Arbitrary Data Structures • What is the simplest data structure that you can use to create any other data structure, including dynamically sized structures? • What is the smallest component of this structure? Intro to Scheme

  23. 1 2 Dotted Pairs • Scheme uses pairs for many, many things • Programs (forms) • Arguments • Data structures • A pair is a two-cell node. Each cell contains a pointer to a value or another pair. • A node with two pointers is called a dotted pair • (cons 1 2) » (1 . 2) • ’(1 . 2) » (1 . 2) Intro to Scheme

  24. car and cdr • You access the two parts of a dotted pair with the accessors car and cdr: • (define x (cons 1 2)) • (car x) » 1 • (cdr x) » 2 • (pair? a) returns true if a is a dotted pair • (pair? (cons 3 4)) » #t • (pair? 3) » #f Intro to Scheme

  25. 3 1 4 2 Dotted pairs can be nested • (define x (cons (cons 1 2) (cons 3 4)) • (define x ‘((1 . 2) . (3 . 4))) • (car x) » (1 . 2) • (cdr x) » (3 . 4) Intro to Scheme

  26. Scheme shorthand • (cons 1 (cons 2 (cons 3 (cons 4 5)))) » (1 2 3 4 . 5) • (1 2 3 4 . 5) is an abbreviation for (1 . (2 . (3 . (4 . 5)))) 1 2 3 4 5 Intro to Scheme

  27. Lists • ’(1 2 3 4) » (1 2 3 4) • (1 2 3 4) is an abbreviation for (1 . (2 . (3 . (4 . ())))) • Just like a standard linked list • An empty list, ’(), is essentially a null pointer • This is often how parameters are passed, etc. This special construct of nested dotted pairs is called a list 1 2 3 4 Intro to Scheme

  28. List() (list 1 2 3 4 5) Is the same as… (cons 1 (cons 2 (cons 3 (cons 4 cons 5 nil)))) Both produce: (1 . (2 . (3 . (4 . (5 . ()))))) Or, as scheme would print it… (1 2 3 4 5) Intro to Scheme

  29. car and cdr • The car of a list is a value • The cdr of a list is a list • Special names: cadr, cddr, cdar, etc. • (define x ’(1 2 3 4 5) • (car x) » 1 • (cdr x) » (2 3 4 5) • (cadr x) » 2 • (cddr x) » (3 4 5) Intro to Scheme

  30. Quote and Lists • ‘(item1, item2, item3, …) is syntactic sugar for (list ‘item1 ‘item2 ‘item3 …) • ‘(1 2 3 4 5)»(1 2 3 4 5) • ‘(a b c d e)»(a b c d e) • ‘(1 2 3 4 5)  procedure application: expected procedure, given: 1; arguments were: 2 3 4 5 Intro to Scheme

  31. Equivalence • (eq? item item) checks for object equivalence. Are the two variables bound/pointing to the same object? (define l '(a b c)) (eq? l '(a b c)) » #f (define a l) (eq? a l) » #t (define a 3) (eq? a 3) » #t Intro to Scheme

  32. Equivalence (2) • Equal? Recursively performes eq? on each entry in a list, etc. • Most types have their own equality operations • (char=? #\c #\b) • (= 3 3.0), etc. (define l '(a b c)) (equal? l '(a b c)) » #t Intro to Scheme

  33. Vectors • Scheme’s answer to arrays are called vectors • Not used as much as lists • (define x (vector 1 2 3 4 5))x » #(1 2 3 4 5) • (vector-ref x 3) » 4 • (vector-set! x 2 1) x » #(1 2 1 4 5) Intro to Scheme

  34. Conversion between data types • (char->integer #\d) » 100 • (integer->char 50) » #\2 • (string->list “hi!”) » (#\h #\i #\!) • (number->string 23) » “23” • (string->number “20”) » 20 • (string->number “bob”) » #f • (string->number “23” 16) » 35 • (symbol->string xyz) » “xyz” • (string->symbol “xyz”) » xyz All these data types are special cases of Scheme S-expressions Intro to Scheme

  35. Problems • Draw the linked list structure that would result from each of the following expressions: (cons (cons (cons a b) c (cons d e)) f) (cons (cons (cons (cons a b) c) d) ()) ’(a b c (d e (f . g))) ’(1 2 3 (4 . 5) . 6) Intro to Scheme

  36. Scheme E-BNF Specification

  37. 7.1.1 Lexical structure • This section describes how individual tokens (identifiers, numbers, etc.) are formed from sequences of characters. The following sections describe how expressions and programs are formed from sequences of tokens. • <Intertoken space> may occur on either side of any token, but not within a token. • Tokens which require implicit termination (identifiers, numbers, characters, and dot) may be terminated by any <delimiter>, but not necessarily by anything else. • The following five characters are reserved for future extensions to the language: [ ] { } | • <token> --> <identifier> | <boolean> | <number> • | <character> | <string> • | ( | ) | #( | ' | ` | , | ,@ | . • <delimiter> --> <whitespace> | ( | ) | " | ; • <whitespace> --> <space or newline> • <comment> --> ; <all subsequent characters up to a • line break> • <atmosphere> --> <whitespace> | <comment> • <intertoken space> --> <atmosphere>* • <identifier> --> <initial> <subsequent>* • | <peculiar identifier> • <initial> --> <letter> | <special initial> • <letter> --> a | b | c | ... | z • <special initial> --> ! | $ | % | & | * | / | : | < | = • | > | ? | ^ | _ | ~ • <subsequent> --> <initial> | <digit> • | <special subsequent> • <digit> --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 • <special subsequent> --> + | - | . | @ • <peculiar identifier> --> + | - | ... • <syntactic keyword> --> <expression keyword> • | else | => | define • | unquote | unquote-splicing

  38. <expression keyword> --> quote | lambda | if | set! | begin | cond | and | or | case | let | let* | letrec | do | delay | quasiquote `<variable> => <'any <identifier> that isn't also a <syntactic keyword>> <boolean> --> #t | #f <character> --> #\ <any character> | #\ <character name> <character name> --> space | newline <string> --> " <string element>* " <string element> --> <any character other than " or \> | \" | \\ <number> --> <num 2>| <num 8> | <num 10>| <num 16> The following rules for <num R>, <complex R>, <real R>, <ureal R>, <uinteger R>, and <prefix R> should be replicated for R = 2, 8, 10, and 16. There are no rules for <decimal 2>, <decimal 8>, and <decimal 16>, which means that numbers containing decimal points or exponents must be in decimal radix. <num R> --> <prefix R> <complex R> <complex R> --> <real R> | <real R> @ <real R> | <real R> + <ureal R> i | <real R> - <ureal R> i | <real R> + i | <real R> - i | + <ureal R> i | - <ureal R> i | + i | - i <real R> --> <sign> <ureal R> <ureal R> --> <uinteger R> | <uinteger R> / <uinteger R> | <decimal R>

  39. <decimal 10> --> <uinteger 10> <suffix> • | . <digit 10>+ #* <suffix> • | <digit 10>+ . <digit 10>* #* <suffix> • | <digit 10>+ #+ . #* <suffix> • <uinteger R> --> <digit R>+ #* • <prefix R> --> <radix R> <exactness> • | <exactness> <radix R> • <suffix> --> <empty> • | <exponent marker> <sign> <digit 10>+ • <exponent marker> --> e | s | f | d | l • <sign> --> <empty> | + | - • <exactness> --> <empty> | #i | #e • <radix 2> --> #b • <radix 8> --> #o • <radix 10> --> <empty> | #d • <radix 16> --> #x • <digit 2> --> 0 | 1 • <digit 8> --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 • <digit 10> --> <digit> • <digit 16> --> <digit 10> | a | b | c | d | e | f • 7.1.2 External representations • <Datum> is what the read procedure (section see section 6.6.2 Input) successfully parses. Note that any string that parses as an <expression> will also parse as a <datum>. • <datum> --> <simple datum> | <compound datum> • <simple datum> --> <boolean> | <number> • | <character> | <string> | <symbol> • <symbol> --> <identifier> • <compound datum> --> <list> | <vector>

  40. <list> --> (<datum>*) | (<datum>+ . <datum>) • | <abbreviation> • <abbreviation> --> <abbrev prefix> <datum> • <abbrev prefix> --> ' | ` | , | ,@ • <vector> --> #(<datum>*) • 7.1.3 Expressions • <expression> --> <variable> • | <literal> • | <procedure call> • | <lambda expression> • | <conditional> • | <assignment> • | <derived expression> • | <macro use> • | <macro block> • <literal> --> <quotation> | <self-evaluating> • <self-evaluating> --> <boolean> | <number> • | <character> | <string> • <quotation> --> '<datum> | (quote <datum>) • <procedure call> --> (<operator> <operand>*) • <operator> --> <expression> • <operand> --> <expression> • <lambda expression> --> (lambda <formals> <body>) • <formals> --> (<variable>*) | <variable> • | (<variable>+ . <variable>) • <body> --> <definition>* <sequence> • <sequence> --> <command>* <expression> • <command> --> <expression>

  41. <conditional> --> (if <test> <consequent> <alternate>) <test> --> <expression> <consequent> --> <expression> <alternate> --> <expression> | <empty> <assignment> --> (set! <variable> <expression>) <derived expression> --> (cond <cond clause>+) | (cond <cond clause>* (else <sequence>)) | (case <expression> <case clause>+) | (case <expression> <case clause>* (else <sequence>)) | (and <test>*) | (or <test>*) | (let (<binding spec>*) <body>) | (let <variable> (<binding spec>*) <body>) | (let* (<binding spec>*) <body>) | (letrec (<binding spec>*) <body>) | (begin <sequence>) | (do (<iteration spec>*) (<test> <do result>) <command>*) | (delay <expression>) | <quasiquotation> <cond clause> --> (<test> <sequence>) | (<test>) | (<test> => <recipient>) <recipient> --> <expression> <case clause> --> ((<datum>*) <sequence>) <binding spec> --> (<variable> <expression>) <iteration spec> --> (<variable> <init> <step>)

  42. | (<variable> <init>) • <init> --> <expression> • <step> --> <expression> • <do result> --> <sequence> | <empty> • <macro use> --> (<keyword> <datum>*) • <keyword> --> <identifier> • <macro block> --> • (let-syntax (<syntax spec>*) <body>) • | (letrec-syntax (<syntax spec>*) <body>) • <syntax spec> --> (<keyword> <transformer spec>) • 7.1.4 Quasiquotations • The following grammar for quasiquote expressions is not context-free. It is presented as a recipe for generating an infinite number of production rules. Imagine a copy of the following rules for D = 1, 2,3, .... D keeps track of the nesting depth. • <quasiquotation> --> <quasiquotation 1> • <qq template 0> --> <expression> • <quasiquotation D> --> `<qq template D> • | (quasiquote <qq template D>) • <qq template D> --> <simple datum> • | <list qq template D> • | <vector qq template D> • | <unquotation D> • <list qq template D> --> (<qq template or splice D>*) • | (<qq template or splice D>+ . <qq template D>) • | '<qq template D> • | <quasiquotation D+1>

  43. <vector qq template D> --> #(<qq template or splice D>*) • <unquotation D> --> ,<qq template D-1> • | (unquote <qq template D-1>) • <qq template or splice D> --> <qq template D> • | <splicing unquotation D> • <splicing unquotation D> --> ,@<qq template D-1> • | (unquote-splicing <qq template D-1>) • In <quasiquotation>s, a <list qq template D> can sometimes be confused with either an <unquotation D> or a <splicing unquotation D>. The interpretation as an <unquotation> or <splicing unquotation D> takes precedence. • 7.1.5 Transformers • <transformer spec> --> • (syntax-rules (<identifier>*) <syntax rule>*) • <syntax rule> --> (<pattern> <template>) • <pattern> --> <pattern identifier> • | (<pattern>*) • | (<pattern>+ . <pattern>) • | (<pattern>* <pattern> <ellipsis>) • | #(<pattern>*) • | #(<pattern>* <pattern> <ellipsis>) • | <pattern datum> • <pattern datum> --> <string> • | <character> • | <boolean> • | <number> • <template> --> <pattern identifier> • | (<template element>*) • | (<template element>+ . <template>) • | #(<template element>*) • | <template datum> • <template element> --> <template> • | <template> <ellipsis>

  44. <template datum> --> <pattern datum> • <pattern identifier> --> <any identifier except `...'> • <ellipsis> --> <the identifier `...'> • 7.1.6 Programs and definitions • <program> --> <command or definition>* • <command or definition> --> <command> • | <definition> • | <syntax definition> • | (begin <command or definition>+) • <definition> --> (define <variable> <expression>) • | (define (<variable> <def formals>) <body>) • | (begin <definition>*) • <def formals> --> <variable>* • | <variable>* . <variable> • <syntax definition> --> • (define-syntax <keyword> <transformer spec>)

More Related