Title: Functional languages e.g. Scheme, ML
1Functional languages(e.g. Scheme, ML)
- Scheme is a functional language.
- Scheme is based on lambda calculus.
- lambda abstraction function definition
- In Scheme, a function is defined using the
keyword lambda (lambda () )
- Syntax of Scheme is very simple
- primitive expressions
- numbers, such as 17
- symbols, such as fred
- names, such as fred
- complex expressions
- function applications, such as ( 3 2) or (addOne
x), consist of a function and arguments for the
function.
- special forms, such as (define x y), are
evaluated in special ways.
- ML is a functional language.
- ML is based on lambda calculus.
- lambda abstraction function definition
- In ML, a function is (typically) defined using
the fun keyword fun
- Syntax of ML is familiar
- block-structured syntax
- infix operators for , , etc
- function names appear before argument lists, not
inside parentheses
2Evaluation(Scheme and ML share model focus on
Scheme)
- Numbers are interpreted in base 10.
- Names are looked up in an environment, starting
with the current environment, following static
links, until the name is found. If it is not
found, an error occurs. - (define ) is evaluated by first
evaluating , and binding, in the current
environment, the name to that value.
- (lambda ) is evaluated by creating an
appropriate closure (sometimes called a
procedure). The closures environment link
refers to the environment which was active when
the closure was created. - All members of an application are evaluated,
after which the first is applied to the rest.
- A procedure application is evaluated by creating
an environment to bind the parameters of the
procedure to its arguments, and then evaluating
the body relative to this new environment. The
static link of the environment refers to the same
environment as the closure, whereas the dynamic
link refers to the environment that was active
when the procedure was applied.
3Examples
- 12
- 12
- (define x 12)
- x
- 12
- (define addOne
- (lambda (x) ( x 1)))
- (addOne x)
- 13
- (define add
- (lambda (x y) ( x y)))
- (add 3 x)
- 15
- (define adder
- (lambda (x)
- (lambda (y) ( x y))))
- (define add3 (adder 3))
- (add3 x)
- 15
- 12 val it12int - val x12 val x12int -
x val it12int - fun addOne x x1 val addOn
efnint-int - addOne x val it13int - fun ad
d (x,y) xy val addfnintint-int - add(3,
x) val it15int - fun adder x y xy val ad
derfnint-int-int - val add3 adder 3 val a
dd3fnint-int - add3 x val it15int - val
add7 adder 7 val add7fnint-int - add7 x
val it19int
4Scheme
- Although Scheme is syntactically a simple
language, it supports sophisticated modeling
higher-order functions are a powerful tool in
describing problems. - Many ideas in design patterns have their roots in
functional programming (e.g. strategy allows us
to treat methods as first-class, a decorator acts
like a function which maps a function to a
function think of the stream decorators in
Java). - With mutation (the ability to change a name-value
binding in an environment) sophisticated systems
can be built quite compactly.
5Review of evaluation model
- Numbers evaluation to themselves (a character
string representing a number evaluates to its
base 10 numeric representation).
- For example
- 213 if you ask Scheme to evaluate a number
- 213 you get the number as a result
6Evaluating names
- A name is evaluated by looking it up. Lookup
starts in the current environment, and continues
along the chain of statically-linked environments
until either a binding is found (in which case
the corresponding value is returned) or it isnt
(in which case an error occurs). - For example (assuming no binding for x exists
yet)
- x
- Error reference to undefined identifier x
- (define x 12)
- x
- 12
7Primitives
- Primitives, such as and -, are ordinary names
with name-value bindings established at start-up
in the primitive environment, the base
environment for evaluation (base in the sense
that its static link is null). - We can use wherever we need a function.
- For example
- (define applyOperator (lambda (op) (op 3 4)))
- (applyOperator )
- 7
- (applyOperator -)
- -1
-
- We can also rebind the names of primitives (not a
good idea in general, but this shows that
primitives are not treated differently from other
names in the language). - ( 3 4) name refers to addition function
- 7
- (define -) name now refers to subtraction
function
- ( 3 4)
- -1
8lambda forms
- A lambda form (lambda abstraction) defines a
function in Scheme.
- Informally, the syntax is
- (lambda () )
- When a lambda form is evaluated a closure results
(which is printed as ).
- For example
- (define addOne (lambda (p) ( p 1)))
- addOne
-
-
9Function applications
- A function application is evaluated by first
evaluating each expression inside the
application, then applying the function to its
arguments. - This is accomplished by first creating a new
environment in which the functions parameters
are bound to its arguments, and then evaluating
the functions body with respect to the new
environment (which is now the current
environment).
10Evaluating (addOne 4)
primitive env
-
cons
user env
addOne
p
4
( p 1)
11Local bindings
- In a language like C or Java we can create local
bindings inside a function/method by defining
local variables
- int mystery(int x, int y, int z)
- int a func1(x,y)
- int b func2(y,z)
-
-
- Local bindings can be created using a let-form
- (define mystery (lambda (x y z)
- (let ((a (func1 x y)) (b (func2 y z)))
)
- Let-form is just syntactic sugar for a procedure
application the above let-form is equivalent
to
- ((lambda (a b) ) (func1 x y) (func2 y z))
12Evaluating(define foo (let ((a 1) (b 2)) (lambda
(c) ( a b c))))
primitive env
c
( a b c)
-
cons
user env
a b
(lambda (c) ( a b c))
addOne
a
1
foo
b
2
(lambda (c) ( a b c))
13Mutation
- set! allows an existing name-value binding to be
changed.
14Structuring data
- So far weve seen two types of values that we can
bind to names
- numbers
- functions
- two others are
- symbols
- pairs
15Symbols
- A symbol is an unevaluated name.
- Consider the following interaction
- (define x 12)
- x
- 12
- The x in the define is not evaluated. It is a
symbol.
- The x in the second line is evaluated by looking
up the value it is bound to in the current
environment.
16Using symbols
- We can bind a name to a symbolic value by quoting
the symbol quoting prevents evaluation
- (define fifi 'poodle)
- fifi
- poodle
- The quote mark (') is syntactic sugar for the
form (quote ) the above is equivalent to
- (define fifi (quote poodle))
17Pairs
- cons is a primitive function which builds a
pair.
- A pair has two members.
- (cons 'a 'b) builds a pair
- whose first member is the symbol a
- whose second member is the symbol b
- cons is therefore a pair constructor.
- Graphically
b
a
18accessors
- car returns the first member of a pair
- cdr returns the second member of a pair
- (define myPair (cons 'a 'b))
- (car myPair)
- a
- (cdr myPair)
- b
19How is a pair displayed?
- (define myPair (cons 'a 'b))
- myPair
- (a . b)
- Pairs are printed with a dot (.) separating the
first (left) and second (right) components.
20The REPL
- When interacting with a Scheme system, a
Read-Eval-Print Loop (REPL) reads what you type,
evaluates it, prints the resulting value, and
loops back to repeat. - The reader and printer parts of the REPL handle
syntactic sugar (like converting 'a into (quote
a)) and also printing things like lists.
21Lists
- What is a list?
- A recursive definition
- the empty list () is a list
- a pair whose cdr is a list is a list
- We can build a list using cons and ()
- (define myList (cons 'a '()))
- myList
- (a)
22Wait a minute!!
- (define myPair (cons 'a 'b))
- myPair
- (a . b)
- (define myList (cons 'a '())
- myList
- (a)
23What's going on?
- Why did myList print as (a) rather than as (a .
())?
- In fact, they are entirely equivalent the REPL
strikes again. The printer formats pairs which
cdr is a pair in a special way to make lists
easier to read.
24Printing lists
- (a . (b . (c . (d . ())))) is printed as (a b c
d)
- Graphically the structure is
- This structure can be built in a variety of ways,
some of which are shown on the next slide.
a
b
c
d
25Choiceschoices
- (cons 'a (cons 'b (cons 'c (cons 'd '()))))
- (list 'a 'b 'c 'd)
- '(a b c d)
- '(a . (b c d))
- (cons 'a (list 'b 'c 'd))
- and so on!
26Association lists
- An association list is a list of pairs.
- Used to implement a look-up table of key-value
pairs.
- The primitive assoc is used to search an
association list, given a key.
- Example on next slide.
27- (define aList '((fifi . poodle)
- (fido . bulldog) (clifford . bigRed)
- (lassie . collie)))
- (assoc 'fido aList)
- (fido . bulldog)
- (assoc 'rufus aList)
- f
28Mutating pair components
- set-car! mutates the value of the car of a pair
- set-cdr! mutates the value of the cdr of a pair
- (define myPair (cons 'a 'b))
- myPair
- (a . b)
- (set-car! myPair 'fred)
- myPair
- (fred . b)
- (set-cdr! myPair 'wilma)
- myPair
- (fred . wilma)
29Lists in other languages
- Lists in ML
- Lists in Prolog
30Homework issues
31Homework issues
- What is basic algorithm?
- while file is not empty
- read in a line
- if the line is an odd line,
- then write line to output file
- else dont