Upload
lorena-fleming
View
269
Download
0
Embed Size (px)
Citation preview
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-functional-languages-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 LISPftp://ftp.gnu.org/pub/gnu/gcl/binaries/stable/
– CLISPhttp://www.clisp.org/
Positioning…
• The programming language class includes roughly the following topics
Language Design
PhilosophyGrammar
Binding, type, scope
Expression, statement
Subprogram, parameter
passing
Language implement-
ation
Imperative language
Functional language
Logical language
…
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 Translation ExecutionUser
Interface
I want to rotate a picture
Human ideas Translation ExecutionProgramming
language
I want to invent a new search engine
Imperative language
Functional language
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.v1alert("get the lobster"); PutInPot("lobster"); PutInPot("water");
alert("get the chicken"); BoomBoom("chicken"); BoomBoom("coconut");
Program b.v2function 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 PutInPot( x ){ alert( “pot ” + x ); }funciton BoomBoom( x ){ alert( “boom ” + x ); }
function Cook( i1, i2, f ) {
alert("get the " + i1); f(i1); f(i2);
}
Cook( "lobster", "water", PutInPot ); Cook( "chicken", "coconut", BoomBoom );
Program b.v3function 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.v1var 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.v2function 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.v1function 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.v2function 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
Copyright © 2009 Addison-Wesley. All rights reserved.
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
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”
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
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
43
Genealogy of Common Languages
(Fig. 2.1)
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 value42 42(+ 5 7) 12(+ 5 7 8) 20(- 15 7 2) 6(- 24 (* 4 3)) 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 return value(QUOTE A) A‘A A‘(A B C) (A B C)(CAR (A B C)) error
(CAR ‘(A B C)) A(CAR (+ 5 7)) error(CAR ‘(+ 5 7)) +
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 NILCopied and altered from textbook “Concepts of Programming Languages”
Defining Symbols: SETQ
• SETQ– To set value to a symbol– E.g.> (SETQ a 5)5> a5> (+ 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 = 2return 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 6return 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”