Download functional form

Document related concepts

Lambda calculus wikipedia , lookup

Currying wikipedia , lookup

Combinatory logic wikipedia , lookup

Anonymous function wikipedia , lookup

Tail call wikipedia , lookup

Closure (computer programming) wikipedia , lookup

Lambda lifting wikipedia , lookup

Falcon (programming language) wikipedia , lookup

C Sharp (programming language) wikipedia , lookup

Standard ML wikipedia , lookup

Lisp (programming language) wikipedia , lookup

Common Lisp wikipedia , lookup

Transcript
Ch.15 Functional Programming
Languages
清華大學資工系 孫文宏
CS2403 Programming Languages
Spring, 2011
Timing
一
3/21
二
三
四
五
3/24
• HW2 (50%)
未定
未定
• HW? (50%)
References
• Articles:
– 思考函數編程
http://jerrylovesrebol.blogspot.com/2008/05/fp_22.html
– Why functional languages rock with multi-core
http://prettyprint.me/2009/08/01/why-functionallanguages-rock-with-multi-core/
– Can Your Programming Language Do This?
http://www.joelonsoftware.com/items/2006/08/01.html
• Book:
– 《計算機怎樣解幾何題:談談自動推理》
• Manuals:
– 維基教科書 – Lisp 入門
http://zh.wikibooks.org/zh-tw/Lisp_入門
– Common Lisp the Language, 2nd Edition
http://www-prod-gif.supelec.fr/docs/cltl/clm/clm.html
– Common LISP Hints
http://www.n-a-n-o.com/lisp/cmucl-tutorials/LISP-tutorial.html
– GNU Emacs Lisp Reference Manual
http://www.delorie.com/gnu/docs/elisp-manual-21/elisp_toc.html
• Downloading LISP interpreter:
– GNU Common LISP
ftp://ftp.gnu.org/pub/gnu/gcl/binaries/stable/
– CLISP
http://www.clisp.org/
Positioning…
• The programming language class includes
roughly the following topics
Language
Design
Philosophy
Grammar
Imperative language
Functional language
Logical language
…
Binding,
type,
scope
Expression,
statement
Subprogram,
parameter
passing
Language
implementation
I’m good at C/C++ or Java.
Why should I learn another kind
of language?
Answer 1: Would you like to learn
how to use “multi-touch”?
Human ideas
I want to
rotate a
picture
User
Interface
Translation
Execution
Human ideas
I want to
invent a new
search engine
Programming
language
Imperative language
Functional language
Translation
Execution
Answer 2: Functional Language
Renaissance
• Its power in parallel programming makes it
hot again
• Parallel programming
– It seems Moore’s law is reaching a limit. CPU clock
rate is not going faster infinitely
– Multi-core architecture
– Large computing/data center, cloud computing
Imperative Languages vs. Parallel Computing
• “There are quite a few new challenges, most of them
are about scale, such as scaling your database, scaling
your users sessions etc, but one of the most significant
challenges is scaling your algorithm by parallelizing it.”
• “The problem is that imperative languages keep state.
The state is in their variables. …When you want two or
more threads to access the same variable, or the same
state (and modify it) you need to synchronize them;
Creating correct synchronization is hard and many
times results in bottlenecks.”
Copied from http://prettyprint.me/2009/08/01/why-functional-languages-rock-with-multi-core/
“State, Mutable Data”
Copied from http://prettyprint.me/2009/08/01/why-functional-languages-rock-with-multi-core/
“Can Your Programming Language
Do This?”
Copied from http://www.joelonsoftware.com/items/2006/08/01.html
Program a.v1
// A trivial example:
alert("I'd like some Spaghetti!");
alert("I'd like some Chocolate Moose!");
The following programs are all from http://www.joelonsoftware.com/items/2006/08/01.html
Program a.v2
function SwedishChef( food )
{
alert("I'd like some " + food + "!");
}
SwedishChef("Spaghetti");
SwedishChef("Chocolate Moose");
• Code reuse
• Maintainability, readability, abstraction…
Program b.v1
alert("get the lobster");
PutInPot("lobster");
PutInPot("water");
alert("get the chicken");
BoomBoom("chicken");
BoomBoom("coconut");
Program b.v2
function Cook( i1, i2, f )
{
alert("get the " + i1);
f(i1);
f(i2);
}
Cook( "lobster", "water", PutInPot );
Cook( "chicken", "coconut", BoomBoom );
• Pass functions as parameters
Program b.v2
function Cook( i1, i2, f )
{
alert("get the " + i1);
f(i1);
f(i2);
}
Cook( "lobster", "water", PutInPot );
Cook( "chicken", "coconut", BoomBoom );
function PutInPot( x )
{
alert( “pot ” + x );
}
funciton BoomBoom( x )
{
alert( “boom ” + x ); }
Program b.v3
function Cook( i1, i2, f )
{
alert("get the " + i1);
f(i1);
f(i2);
}
Cook( "lobster", "water",
function(x) { alert("pot " + x); } );
Cook( "chicken", "coconut",
function(x) { alert("boom " + x); } );
• Create the function on the fly without naming it
Program c.v1
var a = [1,2,3];
for (i=0; i<a.length; i++)
{
a[i] = a[i] * 2;
}
for (i=0; i<a.length; i++)
{
alert(a[i]);
}
Program c.v2
function map(fn, a)
{
for (i = 0; i < a.length; i++)
{
a[i] = fn(a[i]);
}
}
map( function(x){return x*2;}, a );
map( alert, a );
• Do something to every element in an array
Program d.v1
function sum(a)
{
var s = 0;
for (i = 0; i < a.length; i++)
s += a[i];
return s;
}
function join(a)
{
var s = "";
for (i = 0; i < a.length; i++)
s += a[i];
return s;
}
alert( sum([1,2,3]) );
alert( join(["a","b","c"]) );
Program d.v2
function reduce(fn, a, init)
{
var s = init;
for (i = 0; i < a.length; i++)
s = fn( s, a[i] );
return s;
}
function sum(a)
{
return reduce( function(a, b){ return a + b; }, a, 0 );
}
function join(a)
{
return reduce( function(a, b){ return a + b; }, a, "" );
}
alert( sum([1,2,3]) );
alert( join(["a","b","c"]) );
• Combine all elements in an array to one
• “Without understanding functional programming, you
can't invent MapReduce, the algorithm that makes
Google so massively scalable.”
• “Programming languages with first-class functions let
you find more opportunities for abstraction, which
means your code is more scalable. Lots of Google
applications use MapReduce and they all benefit
whenever someone optimizes it or fixes bugs.”
• “The terms Map and Reduce come from LISP and
functional programming.”
• “Ok. I hope you're convinced by now.”
Copied from http://www.joelonsoftware.com/items/2006/08/01.html
History Class…
Pictures copied from Internet
Pictures copied from Internet
Pictures copied from Internet
Bertrand Russell (1872-1970)
Pictures copied from Internet
1+1=2
Pictures copied from Internet
John Von Neumann (1903-1957)
Pictures copied from Internet
Alan Turing (1912-1954)
Pictures copied from Internet
Alonzo Church (1903-1995)
Pictures copied from Internet
Functional Programming
Concepts
Introduction
• The design of the imperative languages is based
directly on the von Neumann architecture
– Efficiency is the primary concern, rather than the
suitability of the language for software development
• The design of the functional languages is based
on mathematical functions
– A solid theoretical basis that is also closer to the user,
but relatively unconcerned with the architecture of
the machines on which programs will run
Copyright © 2009 Addison-Wesley. All rights reserved.
Mathematical Functions
• In an imperative language,
– Operations are done and the results are stored in
variables for later use
• The objective of the design of a functional
language is to mimic mathematical functions to
the greatest extent possible
– In an functional language, the evaluation of a
function always produces the same result given the
same parameters
– No side effect, a.k.a. referential transparency
Copied and altered from textbook “Concepts of Programming Languages”
Lambda Calculus
• Lambda calculus, λ-calculus
– Alonzo Church, 1930s
– A formal system for function definition and
application
• A mathematical function is a mapping
– of members of one set, called the domain set,
– to another set, called the range set
• E.g.
cube(x)  x*x*x
cube(2) results in 8
Copied and altered from textbook “Concepts of Programming Languages”
Lambda Expressions
• A method for defining nameless functions
• It specifies the parameter(s) and the mapping
of a function in the following form
• E.g.
(x) x*x*x
((x) x*x*x)(2) results in 8
Copied and altered from textbook “Concepts of Programming Languages”
Functional Forms
• A higher-order function, or functional form, is
one that
– either takes functions as parameters,
– or yields a function as its result,
– or both
• Some kinds of function forms
–
–
–
–
Function composition
Apply-to-all (map)
Construction
Reduce
Copied and altered from textbook “Concepts of Programming Languages”
Function Composition
• A functional form that
– takes two functions as parameters
– and yields a function whose value is the first actual
parameter function applied to the application of the
second
• Form:
–h  f ° g
– which means h (x)  f ( g ( x))
• E.g.
– For f(x)
 x + 2
and
g(x)  3 * x,
– h  f ° g yields (3 * x)+ 2
Copied and altered from textbook “Concepts of Programming Languages”
Apply-to-all (map)
• A functional form that
– takes a single function as a parameter
– and yields a list of values obtained by applying the
given function to each element of a list of parameters
• Form:
–
• E.g.
– For h(x)  x * x
– (h, (2, 3, 4)) yields (4, 9, 16)
Copied and altered from textbook “Concepts of Programming Languages”
Construction
• A functional form that
– takes a list of functions as parameters
– and yields a list of values obtained by applying the list
of functional parameters to an argument
• Form:
– [f, g, h]
• E.g.
–
–
–
–
f(x)  x*x
g(x)  x*2
h(x)  x/2
[f,g,h](4) yields (16, 8, 2)
Copied and altered from textbook “Concepts of Programming Languages”
Some Famous Functional
Languages
Genealogy
of Common
Languages
(Fig. 2.1)
43
LISP
• LISP is Invented by John McCarthy in 1958 at MIT
– Lisp is the second-oldest high-level programming language in
widespread use today (Fortran is the oldest)
– The name LISP strands for "LISt Processing“
– The original LISP uses dynamic scope
• The 1st LISP interpreter
– was implemented by Steve Russell on a IBM 704 mainframe
• The first LISP compiler
– was implemented by Tim Hart and Mike Levin in 1962 at MIT
• It has a large family of dialects
– Such as Stanford LISP 1.6, XLISP, AutoLISP
– Scheme and Common LISP are the most widely known dialects
Copied and altered from http://en.wikipedia.org/wiki/Lisp_(programming_language)
Scheme
• Scheme was developed
– by Guy L. Steele and Gerald Jay Sussman, in the
mid-1970s, at the MIT AI Lab
• It was designed to be a cleaner, more modern,
and simpler version than the contemporary
dialects of LISP
– Uses only static scoping
Copied and altered from textbook “Concepts of Programming Languages”
COMMON LISP
• A combination of many popular LISP dialects
– It is developed in 1980s, by the efforts of Guy L. Steele
– Included in the ANSI standard in 1984
• A large and complex language -- the opposite of Scheme
• Features include:
–
–
–
–
–
–
–
records
arrays
character strings
powerful I/O capabilities
iterative control statements
supporting both static and dynamic scope
…etc.
Copied and altered from textbook “Concepts of Programming Languages”
Other Well-know FPLs
• ML (1970s)
– Uses type declarations, and type inferencing
– It is strongly typed (LISP and Scheme are essentially
typeless)
– Uses less parenthesis, the syntax is closer to Pascal
than to LISP
• Haskell (1990)
– Similar to ML (static scoped, strongly typed, type
inferencing)
– Different from ML in that it is purely functional (e.g.,
no variables, no assignment statements)
Copied and altered from textbook “Concepts of Programming Languages”
• Erlang (1986)
– Developed by Ericsson
– Originally Ericsson's proprietary language, released as
open source in 1998
– Supporting soft-real-time and hop swapping
• Scala (2003)
– Run on JVM and is compatible with Java programs
• F# (2005?)
– Developed by Microsoft Research
– Supported by .Net framework and Visual Studio
LISP / Common LISP
Getting Started
• In this lecture, we will be using GNU Common LISP
(GCL) interpreter
– The development of the original LISP language has been
frozen for a long time
– There are many implementations for Common LISP
interpreter
• CLISP, CMUCL, GNU Common Lisp, Emacs Lisp, …etc
– The syntax of Common LISP is very much the same with
the original LISP (, comparing with Scheme)
• Downloading :
– GNU Common LISP
ftp://ftp.gnu.org/pub/gnu/gcl/binaries/stable/
LISP Data Types and Structures
• There were two types of data objects in the
original LISP:
– Atoms
– Lists
• List form:
– parenthesized collections of sub-lists and/or atoms
– e.g., (A B C), (A B (C D) E)
• Original LISP was a typeless language
– Numbers and symbols…
• LISP lists are stored internally as single-linked lists
Copied and altered from textbook “Concepts of Programming Languages”
LISP Functions
• A function is expressed in the same way that
data is expressed
• Function form:
– (func_name arg_1 … arg_n)
– E.g. (A B C), (+ 5 7)
• If the list (A B C) is interpreted as data
– it is a simple list of three atoms, A, B, and C
• If it is interpreted as a function application
– it means that the function named A is applied to the two
parameters, B and C
• The value of the last expression in the body is
the value of the function
Copied and altered from textbook “Concepts of Programming Languages”
Arithmetic Functions
•
+, -, *, /, ABS, SQRT, MOD,
REMAINDER, MIN, MAX
–
expression
42
(+ 5 7)
(+ 5 7 8)
(- 15 7 2)
(- 24 (* 4 3))
value
42
12
20
6
12
Copied and altered from textbook “Concepts of Programming Languages”
EVAL, QUOTE
•
•
EVAL
–
–
–
–
–
A function that can evaluate any other functions
An implementation of EVAL could serve as a LISP
interpreter
QUOTE
It returns the parameter without evaluation
QUOTE is required because the interpreter, i.e.
EVAL, always evaluates the parameters. QUOTE is
used to avoid parameter evaluation when it is not
appropriate
QUOTE can be abbreviated with the apostrophe
prefix operator.
'(A B) is equivalent to (QUOTE (A B))
Copied and altered from textbook “Concepts of Programming Languages”
–
expression
(QUOTE A)
‘A
‘(A B C)
(CAR (A B C))
(CAR ‘(A B C))
(CAR (+ 5 7))
(CAR ‘(+ 5 7))
return value
A
A
(A B C)
error
A
error
+
Copied and altered from textbook “Concepts of Programming Languages”
List Functions: CAR, CDR
• CAR
– takes a list parameter; returns the first element of that list
– e.g.,
(CAR '(A B C)) yields A
(CAR '((A B) C D)) yields (A B)
• CDR
– takes a list parameter; returns the list after removing its
first element
– e.g.
(CDR '(A B C)) yields (B C)
(CDR '((A B) C D)) yields (C D)
Copied and altered from textbook “Concepts of Programming Languages”
• The naming of CAR, CDR…
– The two functions are implemented in the 1st LISP
interpreter, on an IBM 704 mainframe, by Steve
Russell
– They evolved from two IBM 704 assembly
language macros
• CAR: Contents of Address Register
• CDR: Contents of Data Register
• Repetitions(compositions) of CAR and CDR
– C????R
• Both Common Lisp and Scheme supports up to 4
repetitions of A or D
– E.g.
(CADDDR ‘(1 2 3 4 5))
equals
(CAR (CDR (CDR (CDR ‘(1 2 3 4 5)))))
List Functions: CONS, LIST
• CONS
– takes two parameters, the first of which can be either
an atom or a list and the second of which is a list;
– returns a new list that includes the first parameter as
its first element and the second parameter as the
remainder of its result
– e.g. (CONS 'A '(B C)) returns (A B C)
• LIST
– takes any number of parameters; returns a list with
the parameters as elements
– e.g. (LIST A B C) returns (A B C)
Copied and altered from textbook “Concepts of Programming Languages”
Predicate Function: EQ
• EQ
– takes two symbolic parameters; it returns T if
both parameters are atoms and the two are the
same; otherwise NIL
– e.g.,
(EQ 'A 'A) yields T
(EQ 'A 'B) yields NIL
(EQ 2 2) yields T
Copied and altered from textbook “Concepts of Programming Languages”
Numeric Predicate Functions
• Comparison of numbers
– =, />, >, <, >=, <=
– e.g.,
(= 2 2) yields T
(= ‘A ‘A) yields error
• Type predicates for numbers
– ZEROP, NUMBERP, EVENP, ODDP,
INTEGERP, FLOATP
Copied and altered from textbook “Concepts of Programming Languages”
List Predicate Functions
• NULL
– takes one parameter; it returns T if the parameter
is an empty list; otherwise NIL
• ATOM
– takes one parameter; it returns T if the parameter
is an atom; otherwise NIL
• LISTP
– takes one parameter; it returns T if the parameter
is a list; otherwise NIL
Copied and altered from textbook “Concepts of Programming Languages”
Defining Symbols: SETQ
• SETQ
– To set value to a symbol
– E.g.
> (SETQ a 5)
5
> a
5
> (+ a 5)
10
Copied and altered from textbook “Concepts of Programming Languages”
Functions for Constructing
Functions,: DEFUN, LAMBDA
•
DEFUN
–
–
–
A Function for Constructing Functions
Forms:
(DEFUN func_name (para_name) (func_body) )
Ex1.
> (DEFUN cube (x) (* x x x))
> (cube 2)
8
Ex2.
> (DEFUN 2sides (x) (CONS (CAR x) (LAST x)))
> (2sides ‘(1 2 3 4 5))
(1 5)
Copied and altered from textbook “Concepts of Programming Languages”
• LAMBDA
– E.g.
> ((LAMBDA (x) (* x x x)) 2)
8
Copied and altered from textbook “Concepts of Programming Languages”
Defining Symbol Within Function:
LET
• LET
– To set value to a symbol temporarily within a function
– E.g.
> (DEFUN f (x)
(LET (i 2)
(j 3))
(* x i j))
• LET*
– It performs for each variable immediately
– E.g.
> (DEFUN f (x)
(LET* (i 2)
(j (+ i 1)))
(* x i j))
Copied and altered from textbook “Concepts of Programming Languages”
Control Flow: IF
• IF
– Forms:
(IF predicate than_body else_body)
– E.g.
> (DEFUN avg (total count)
(IF (= count 0)
0
(/ total count)))
> (avg 100 5)
20
Copied and altered from textbook “Concepts of Programming Languages”
Control Flow: COND
• COND
– Forms:
(COND
(predicate_1 body_1)
(predicate_2 body_2)
...
)
– Returns the value of the last expression in the
first pair whose predicate evaluates to true
Copied and altered from textbook “Concepts of Programming Languages”
– Ex1:
> (COND (nil 1) (t 2) (nil 3))
2
– Ex2:
> (COND (t 1 2 3))
3
– Ex3:
> (DEFUN compare (x y)
(COND
((> x y) “x is larger”)
((< x y) “y is larger”)))
> (compare 1 2)
“x is larger”
Copied and altered from textbook “Concepts of Programming Languages”
Functional Forms
• Composition
– It has been used in previous examples
– E.g.
> (CDR (CDR '(A B C)))
(C)
• Apply to All
– LISP function name: MAPCAR
– Applies the a function to all elements in a list
– E.g.
> (MAPCAR ‘CAR '((a b) (c d) (e f)))
(A C E)
• Reduce
– LISP function name: REDUCE
– E.g.
> (REDUCE ‘+ '(1 2 3))
6
Lazy Evaluation
• Lazy evaluation, a.k.a. delayed evaluation
– Such as LISP, Scheme, Haskell
– Do not compute the result until they are required
• Opposite: eager evaluation, a.k.a. greedy
evaluation
– Such as Erlang
Copied and altered from textbook “Concepts of Programming Languages”
Tail Recursion
• Definition: A function is tail recursive if its
recursive call is the last operation in the
function
• A tail recursive function can be automatically
converted by a compiler to use iteration,
making it faster
Copied and altered from textbook “Concepts of Programming Languages”
Factorial
• Factorial (recursive)
> (DEFUN factorial (n)
(IF (= n 0)
1
(* n (factorial (- n 1)))))
> (factorial 3)
6
Copied and altered from textbook http://www.psg.com/~dlamkins/sl/chapter04.html
call factorial(3)
call factorial(2)
call factorial(1)
call factorial(0)
return 1;
return 1*1 = 1
return 2*1 = 2
return 3*2 = 6
Copied and altered from textbook http://www.psg.com/~dlamkins/sl/chapter04.html
• Factorial (tail-recursive)
> (DEFUN factorial (n)
(factorial-helper n 1))
> (DEFUN factorial-helper (n product)
(COND
((= n 0) product)
(t
(factorial-helper (- n 1) (* product n)))))
Copied and altered from textbook http://www.psg.com/~dlamkins/sl/chapter04.html
call factorial(3)
call factorial-helper(3 1)
call factorial-helper(2 3)
call factorial-helper(1 6)
call factorial-helper(0 6)
return 6
return 6
return 6
return 6
return 6
Copied and altered from textbook http://www.psg.com/~dlamkins/sl/chapter04.html
Functions That Build Code
• We can write a function in LISP, which
generates some LISP codes, and then request
to interpret those codes
• This is possible because the interpreter is a
user-available function, EVAL
Copied and altered from textbook “Concepts of Programming Languages”
Adding a List of Numbers
• Recursive
> (DEFUN add (li)
(IF (NULL li)
0
(+ (CAR li) (add (CDR li)))))
> (add ‘(1 2 3))
6
Copied and altered from textbook “Concepts of Programming Languages”
• By EVAL
> (DEFUN add (li)
(COND
((NULL li) 0)
(t (EVAL (CONS '+ li)))))
– It inserts a + operator to the list, and submit the new list to
evaluate the list
Copied and altered from textbook “Concepts of Programming Languages”
Some LISP Sample Programs
APPEND
• my-append
– It takes two lists; returns the first parameter list with
the elements of the second parameter list appended
at the end
> (DEFUN my-append (li1 li2)
(IF (NULL li1)
li2
(CONS (CAR li1) (my-append (CDR li1) li2))))
> (my-append ‘(1 2) ‘(3 4))
(1 2 3 4)
Copied and altered from textbook “Concepts of Programming Languages”
REVERSE
• my-reverse
– It takes a lists; returns a list that reverses the order of
the elements in the given list
> (DEFUN my-reverse (li)
(IF (NULL li)
'()
(APPEND (my-reverse (CDR li)) (LIST (CAR li)))))
> (my-reverse ‘(1 2 3))
(3 2 1)
Copied and altered from textbook “Concepts of Programming Languages”
CONTAINS
• contains
– It takes a simple list and an atom as parameters;
returns T if the atom is in the list; otherwise returns
NIL
> (DEFUN contains (li a)
(COND
((NULL li) nil)
((EQ a (CAR li)) t)
(t (contains (CDR li) a))))
> (contains ‘(a b c) b)
T
Copied and altered from textbook “Concepts of Programming Languages”
EQLI
• eqli
– It takes two simple lists; returns whether the two
lists are equal
> (DEFUN eqli (li1 li2)
(COND
((NULL li1) (NULL li2))
((NULL li2) nil)
((EQ (CAR li1) (CAR li2))
(eqli (CDR li1) (CDR li2)))
(t nil)))
Copied and altered from textbook “Concepts of Programming Languages”
EQLI-GEN
• eqli-gen
– It takes two general lists; returns whether the two
lists are equal
> (DEFUN eqli-gen (li1 li2)
(COND
((ATOM li1) (EQ li1 li2))
((ATOM li2) nil)
((NULL li1) (NULL li2))
((NULL li2) nil)
((eqli-gen (CAR li1) (CAR li2))
(eqli-gen (CDR li1) (CDR li2)))
(t nil)))
Copied and altered from textbook “Concepts of Programming Languages”