introduction to scheme cs 480/680 – comparative languages “and now for something completely...

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

Upload: augusta-hopkins

Post on 01-Jan-2016

223 views

Category:

Documents


0 download

TRANSCRIPT

Introduction to SchemeIntroduction to Scheme

CS 480/680 – Comparative LanguagesCS 480/680 – Comparative Languages

“And now for something completely different…”

– Monty Python

“And now for something completely different…”

– Monty Python

Intro to Scheme 2

Functional LanguagesFunctional 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?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 EvaluationForms 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 ModelSubstitution Model

The basic rule:

To evaluate a Scheme expression:

1. Evaluate its operands

2. Evaluate the operator

3. Apply the operator to the evaluated operands

Intro to Scheme 6

Warning!Warning! Boredom ahead!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 evalExample expression eval Example: (+ 3 (* 4 5) )

Intro to Scheme 8

Example expression evalExample expression eval Example: (+ 3 (* 4 5) )

operator

Intro to Scheme 9

Example expression evalExample expression eval Example: (+ 3 (* 4 5) )

operator

operand 1

Intro to Scheme 10

Example expression evalExample expression eval

Example: (+ 3 (* 4 5) )

operator

operand 1

operand 2

Intro to Scheme 11

Example expression evalExample 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 expressionsPrimitive 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 exampleAnother 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 variablesEvaluation with variables

An assignment provides an association between a symbol (variable) and its value

(define x 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 exampleVariable evaluation example (define x 3) Then evaluate x

• look up value of x• x has value 3 (due to define)• result: 3

Intro to Scheme 16

Simple expression evaluationSimple 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 formsSpecial forms

N.B. There are a few special forms which do not evaluate in the way we’ve described.

define is one of them(define x 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 formsSpecial forms

Another example: (define x (+ 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 TypesBasic 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 typesMore types Procedures (lambda) Booleans (#t and #f)

Intro to Scheme 21

SymbolsSymbols 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 StructuresArbitrary 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

Dotted PairsDotted 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) 21

Intro to Scheme 24

car and cdrcar 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

Dotted pairs can be nestedDotted 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)

4321

Intro to Scheme 26

Scheme shorthandScheme 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

ListsLists ’(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()

(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 cdrcar 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 ListsQuote 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

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

VectorsVectors 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 typesConversion 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

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

Scheme E-BNF SpecificationScheme E-BNF Specification

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

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

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

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

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

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

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

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