Comparative Programming Languages
Functional Languages Comparison: Scheme, Smalltalk, Python, Ruby
CS 363 Spring 2005 GMU 2
Fundamentals of Functional Programming Languages
• The objective of the design of a functional programming language (FPL) is to mimic mathematical functions to the greatest extent possible
• The basic process of computation is fundamentally different in a FPL than in an imperative language– In an imperative language, operations are done and the results are
stored in variables for later use– Management of variables is a constant concern and source of
complexity for imperative programming
• In an FPL, variables are not necessary, as is the case in mathematics
CS 363 Spring 2005 GMU 3
Fundamentals of Functional Programming Languages
• In an FPL, the evaluation of a function always produces the same result given the same parameters– This is called referential transparency
CS 363 Spring 2005 GMU 4
Lisp
• Lisp – based on lambda calculus (Church)– Uniform representation of programs and data
using single general data structure (list)– Interpreter based (written in Lisp)– Automatic memory management– Evolved over the years– Dialects: COMMON LISP, Scheme
5
Smalltalk• Smalltalk – a dynamically typed object oriented
programming and functional language designed at Xerox PARC by Alan Kay, Dan Ingalls, Ted Kaehler, Adele Goldberg, during the 1970s. – Released as Smalltalk-80
– Influenced the development of languages such as Objective-C, Java and Ruby
– Everything is an object
– Everything is available for modification. If you want to change the IDE, you can do it
– Types are dynamic -- you don't have to define types in the code
– Garbage collection is built in, invisible to the developer.
6
Squeak• Squeak is an open, highly-portable
Smalltalk-80 implementation whose virtual machine is written entirely in Smalltalk – The image below was created in Squeak, and illustrates
several of Squeak's abilities, including the ability to scale and rotate bitmap images at any colour depth, anti-aliased TrueType fonts and vector graphics
7
Ruby• Ruby – combines syntax inspired by Ada
and Perl with Smalltalk-like object-oriented features – Also shares some features with Python, Lisp
– Ruby is an interpreted language.
– Created by Yukihiro "Matz" Matsumoto, started working on Ruby in Feb. 1993 and released it to the public in 1995.
– Name chosen to reflect the language's Perl heritage.
– Designed Ruby to follow the principle of least surprise - the language should be free from traps and inconsistencies of other languages
8
Python• Python is an interpreted, interactive
programming language created by Guido van Rossum in 1990 – Originally as a scripting language for Amoeba OS
capable of making system calls.
– Amoeba distributed operating system is a microkernel-based research operating system written by Andrew S. Tanenbaum at Vrije Universiteit
– The aim of the project was to build a timesharing system that appeared to the user as a single machine even though it was running on multiple machines.
9
Python• Python
– Often compared to Tcl, Perl, Scheme, Java, and Ruby
– Developed as an open source project, managed by the non-profit Python Software Foundation.
– Python is a multi-paradigm language, like Perl, Oz or C++ and unlike Smalltalk or Haskell
– Rather than forcing coders to adopt one particular style of coding, it permits several
– Object orientation, structured programming, functional programming are all supported
– Python is dynamically type-checked and uses garbage collection for memory management
– origin of the name - after the television series Monty Python's Flying Circus
10
Python
• Python (from wikipedia)– Many similarities to Perl
– However, Python's designers reject Perl's exuberant syntax in favor of a more spare, less cluttered one
– As with Perl, Python's developers expressly promote a particular "culture" or ideology (http://python.org/dev/culture.html) based on what they want the language to be, favoring language forms they see as "beautiful", "explicit" and "simple".
– Although Python is sometimes classified as a "scripting language", it has been used to develop many large software projects such as the Zope application server
11
Python
• Python (from wikipedia)– Though the designer of Python is somewhat hostile to
functional programming and the Lisp tradition, there are significant parallels between the philosophy of Python and that of minimalist Lisp-family languages such as Scheme
– Many past Lisp programmers have found Python appealing for this reason
– Python is a dynamically typed language, like Lisp and unlike Java or C
CS 363 Spring 2005 GMU 12
Scheme (dr scheme, guile)
(define (gcd u v) (if ( = v 0) u (gcd v (remainder u v)) ))
(define (reverse l) (if (null? l) l (append (reverse (cdr l))(list (car l))) ))
CS 363 Spring 2005 GMU 13
Scheme (dr scheme, guile)
Using guile (gnu scheme):
(load "slides.scm")(gcd 56 108) --> 4(reverse '(2 3 556)) --> (556 3 2)
14
Common Lisp (clisp)(defun mygcd (u v)
(if (= v 0)
u
(mygcd v (rem u v))
)
)
(defun myreverse (l)
(if (null l) l
(append (myreverse (cdr l))(list (car l)))
)
)
;; (load "slides.lsp"), (mygcd 56 108) --> 4
;; (myreverse '(2 3 556)) --> (556 3 2)
15
Smalltalk (Squeak - inisqueak)
myGcd: numTwo
" 112 myGcd: 224 --> 112”
(numTwo = 0) ifTrue: [^self].
^numTwo myGcd: self \\ numTwo.
myReverse
"#(1 2 3 43 a b) myReverse -> ($b $a 43 3 2 1 )"
(self size = 0) ifTrue: [^self].
^self allButFirst myReverse,
self first asOrderedCollection.
16
Gnu-Smalltalk – gst
!SequenceableCollection methodsFor: 'algorithms'!
"Or use Array, but that limits your objects."
myCount
" #(1 2 3 $a $b $c myCount! --> 6
In gst: Filestream inFile: count.st "
(self size = 0) ifTrue: [^0].
^(1 + (self copyFrom: 2) myCount).
!
17
Gnu-Smalltalk – gst (cont.)
myReverse
"#(1 2 3 43 a b) myReverse -> » ($b $a 43 3 2 1 )"
| temp |
(self size = 0) ifTrue: [^self].
temp := OrderedCollection new: 1.
temp add: self first.
^(self copyFrom: 2) myReverse, temp.
!!
18
Gnu-Smalltalk – gst (cont.)
!Number methodsFor: 'algorithms'!
myGcd: numTwo
"120 myGcd: 200! --> 40"
(numTwo = 0) ifTrue: [^self].
^numTwo myGcd: self \\ numTwo.
!!
19
Ruby (ruby)def myGcd(numOne, numTwo)
if numTwo == 0
return numOne
end
return myGcd(numTwo, numOne % numTwo)
end
def myReverse(list)
if list.length == 1
return list
end
return myReverse(list[1..list.length-1]).concat(myReverse([list[0]]))
end
20
Ruby - “Class version”count.rb
class Integer
def myGcd(numTwo)
if numTwo == 0
return self
else
return numTwo.myGcd(self % numTwo)
end
end
end
- load “file.rb” into the Ruby interpreter (eval.rb)
- 120.myGcd(500) --> 20
21
Ruby - “Class version”class Integer
def greet
print "Hello world\n"
end
def plus(numTwo)
return self + numTwo
end
def times(numTwo)
return self * numTwo
end
end
- load “file.rb” into the Ruby interpreter (eval.rb)
- 120.greet --> “Hello..”, 3.plus(4).times(5) -> 35
22
Ruby (non-class vers.)def myCount (mylist)
if mylist.length == 0
return 0
else
return 1 + myCount(mylist[1..mylist.length-1])
end
end
print "Length of [1,2,3,4,5,6]= ",
myCount([1,2,3,4,5,6]), "\n"
To run: ruby count.rb
23
Ruby (class vers.)class Array
def myCount
if self.length == 0
return 0
else
return 1 + self[1..self.length].myCount
end
end
end
This version is “object oriented”...
[3,4,5,6,7,78].myCount --> 6
24
Python (python)def myGcd(numOne, numTwo):
if(numTwo == 0):
return numOne
return myGcd(numTwo, numOne % numTwo)
def myReverse(mylist):
if len(mylist) == 1:
return mylist
return myReverse(mylist[1:len(mylist)]) + myReverse([mylist[0]])
25
Python (python)def myCount (mylist):
if len(mylist) == 0:
return 0
else:
return 1 + myCount(mylist[1:len(mylist)])
print "Length of [1,2,3,4,5,6]= ", myCount([1,2,3,4,5,6])
To run: python count.py
Squeak Browser Window – Lists classes and methods in classes
Squeak Workspace WindowTo “run” each line, middle-button click, choose
“do it” or “print it”
Squeak Transcript WindowTo “run” each line, middle-button click, choose
“do it” or “print it”
Gnu Smalltalk Browser Window
Gnu Smalltalk, X11Worksheet and Transcript
Worksheet window Transcript window
To “run” a line, right click and choose “do it” and/or “print it”
Gnu Smalltalk - gst
Note the use of “!” at the end of each line.
Also, printNl is specific to gst.
Ruby – example run, see count.rb
Ruby – example run from eval.rb
Python – example run, see count.rb
CS 363 Spring 2005 GMU 35
Introduction to Scheme
• A mid-1970s dialect of LISP, designed to be a cleaner, more modern, and simpler version than the contemporary dialects of LISP
• Uses only static scoping• Functions are first-class entities
– They can be the values of expressions and elements of lists
– They can be assigned to variables and passed as parameters
CS 363 Spring 2005 GMU 36
Scheme
(define (gcd u v) (if ( = v 0) u (gcd v (remainder u v)) ))
• Once defined in the interpreter: (gcd 25 10) 5
CS 363 Spring 2005 GMU 37
Scheme Syntax
expression atom | listatom number | string
| identifier | character | booleanlist ‘(‘ expression-sequence ‘)’expression-sequence expression
| expression-sequence expression
simplest elements
CS 363 Spring 2005 GMU 38
Scheme atoms
• Constants:– numbers, strings, #T = True, …
• Identifier names:
• Function/operator names– pre-defined & user defined
CS 363 Spring 2005 GMU 39
Scheme Expression vs. C
In Scheme:(+ 3 (* 4 5 ))
(and (= a b)(not (= a 0)))
(gcd 10 35)
In C:3 + 4 * 5
(a = = b) && (a != 0)
gcd(10,35)
CS 363 Spring 2005 GMU 40
Smalltalk Expressions vs. C
In Smalltalk:3 + 4 * 5
( = 35, “ + 4 mess. sent to 3, then * 5 mess.)
(a = = b) & (a ~= 0)
10 gcd: 35
gcd: 35 mess. sent to 10
In C:3 + 4 * 5
(a = = b) && (a != 0)
gcd(10,35)
CS 363 Spring 2005 GMU 41
Ruby/Python Expressions vs. C(very similar)
In Ruby/Python:3 + 4 * 5
(a = = b) && (a != 0)
gcd(10,35)
In C:3 + 4 * 5
(a = = b) && (a != 0)
gcd(10,35)
CS 363 Spring 2005 GMU 42
Ruby Expressions vs. CClass version
In Ruby:3.plus(4).times(5)
(= 35)
(a = = b) && (a != 0)
10.gcd(35)
In C:3 + 4 * 5
(a = = b) && (a != 0)
gcd(10,35)
CS 363 Spring 2005 GMU 43
Evaluation Rules for Scheme Expressions
1. Constant atoms (numbers, strings) evaluate to themselves
2. Identifiers are looked up in the current environment and replaced by the value found there (using dynamically maintained symbol table)
3. A list is evaluated by recursively evaluating each element in the list as an expression; the first expression must evaluate to a function. The function is applied to the evaluated values of the rest of the list.
CS 363 Spring 2005 GMU 44
Scheme Evaluation
To evaluate (* (+ 2 3)(+ 4 5))1. * is the function – must evaluate the two
expressions (+ 2 3) and (+ 4 5)2. To evaluate (+ 2 3)
1. + is the function – must evaluation the two expressions 2 and 3
2. 2 evaluates to the integer 23. 3 evaluates to the integer 34. + 2 3 = 5
3. To evaluate (+ 4 5) follow similar steps4. * 5 9 = 45
*
+ +
2 3 4 5
CS 363 Spring 2005 GMU 45
Scheme Conditionals
If statement:
(if ( = v 0)
u
(gcd v (remainder u v))
)
(if (= a 0) 0 (/ 1 a))
Cond statement:(cond (( = a 0) 0)
((= a 1) 1)
(else (/ 1 a))
)
Both if and cond functions usedelayed evaluation for the expressions in their bodies (i.e. (/ 1 a) is not evaluated unlessthe appropriate branch is chosen).
CS 363 Spring 2005 GMU 46
Smalltalk Conditionals
If statement:(v = 0) ifTrue: [^u].
^v gcd: u \\ v)
(a = 0) ifTrue: [^0].
^ 1/a
(or use ifFalse: for the
else portion above)
Cond statement:
None in Smalltalk(?)
http://c2.com/cgi/wiki?CaseStatementsConsideredHarmful
Case statements considered
harmful??
CS 363 Spring 2005 GMU 47
Ruby ConditionalsIf statement:if v == 0
return u
else
return
gcd(v, u % v)
end
if a == 0
return 0
else return 1/a
end
Use elsif for “else if”
Cond statement:case a
when 0
0
when 1
1
else
1/a
end
CS 363 Spring 2005 GMU 48
Python Conditionals
If statement:if v == 0:
return u
else:
return gcd(v, u % v)
if a == 0:
return 0
else:
return 1/a
Blocks are indented.
Use elif for “else if”
Cond statement:
Use:
if
elif
elif
...
CS 363 Spring 2005 GMU 49
Example of COND
(DEFINE (compare x y) (COND ((> x y) (DISPLAY “x is greater than y”)) ((< x y) (DISPLAY “y is greater than x”)) (ELSE (DISPLAY “x and y are equal”)) ) )
CS 363 Spring 2005 GMU 50
Example of CONDcompare: y (self > y) ifTrue: [
Transcript show: “x is greater than y”
printString.
Transcript show: cr.]
ifFalse: [
(self < y) ifTrue: [
Transcript show: “y is greater than x”
printString. Transcript show: cr.] ifFalse: [ Transcript show: “x and y are equal”
printString. Transcript show: cr.]].
CS 363 Spring 2005 GMU 51
Example of COND – Ruby class vers.
class Integer
def compare(y) if self > y
print “x is greater than y\n”
elsif self < y
print “y is greater than x\n”
else print “x and y are equal\n”
end
Syntax: 4 compare(5)
CS 363 Spring 2005 GMU 52
Example of COND – Ruby non-class vers.
def compare(x, y) if x > y
print “x is greater than y\n”
elsif x < y
print “y is greater than x\n”
else print “x and y are equal\n”
end
Syntax: compare(4,5)
CS 363 Spring 2005 GMU 53
Example of COND – Python
def compare(x, y): if x > y:
print “x is greater than y”
elif x < y:
print “y is greater than x”
else: print “x and y are equal\n”
Syntax: compare(4,5)
(Also – blocks are indented)
CS 363 Spring 2005 GMU 54
Predicate Functions
1. EQ? takes two symbolic parameters; it returns #T if both parameters are atoms and the two are the same
e.g., (EQ? 'A 'A) yields #T
(EQ? 'A '(A B)) yields ()– Note that if EQ? is called with list parameters, the result
is not reliable– EQ? does not work for numeric atoms (use = )
CS 363 Spring 2005 GMU 55
Predicate Functions
2. LIST? takes one parameter; it returns #T if the parameter is a list; otherwise()
3. NULL? takes one parameter; it returns #T if the parameter is the empty list; otherwise()
Note that NULL? returns #T if the parameter is()
4. Numeric Predicate Functions
=, <>, >, <, >=, <=, EVEN?, ODD?, ZERO?, NEGATIVE?
CS 363 Spring 2005 GMU 56
Predicate Functions - Python
1. == returns True if both parameters are the same
e.g., 'A' == 'A' yields True
'A' == 'A B' False
2. != returns True if both parameters are not the same.
e.g., 'A' != 'A' yields False
'A' != 'A B' True
CS 363 Spring 2005 GMU 57
Predicate Functions - Python3. type() returns the type of an object. type([1,2,3]) == list returns True
4. len([]) returns True if the parameter is the empty list; otherwise the length of the list
5. Numeric Predicate Functions
==, !=, >, <, >=, <=
CS 363 Spring 2005 GMU 58
let function
• Allows values to be given temporary names within an expression– (let ((a 2 ) (b 3)) ( + a b))– 5
• Semantics: Evaluate all expressions, then bind the values to the names; evaluate the body
CS 363 Spring 2005 GMU 59
List Comprehensions - Python
• provide a concise way to create lists without resorting to use of map(), filter() and/or lambda.– >>> freshfruit = [' banana', ' loganberry ',
'passion fruit ']– >>> [weapon.strip() for weapon in freshfruit]– ['banana', 'loganberry', 'passion fruit']
CS 363 Spring 2005 GMU 60
List Comprehensions - Python• >>> vec = [2, 4, 6]
– >>> [3*x for x in vec]– [6, 12, 18]– >>> [3*x for x in vec if x > 3]– [12, 18]– >>> [3*x for x in vec if x < 2]– []– >>> [[x,x**2] for x in vec]– [[2, 4], [4, 16], [6, 36]]
CS 363 Spring 2005 GMU 61
for statements - Python>>> # Measure some strings:
... a = ['cat', 'window', 'defenestrate']
>>> for x in a:
... print x, len(x)
cat 3
window 6
defenestrate 12
CS 363 Spring 2005 GMU 62
for statements - Python>>> # Measure some strings:
... a = ['cat', 'window', 'defenestrate']
>>> for x in a:
... print x, len(x)
cat 3
window 6
defenestrate 12
CS 363 Spring 2005 GMU 63
for statements - Python>>> for x in a[:]: # make a slice copy of the
entire list
... if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']
CS 363 Spring 2005 GMU 64
range() function - Python>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(5, 10)
[5, 6, 7, 8, 9]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(-10, -100, -30)
[-10, -40, -70]
CS 363 Spring 2005 GMU 65
range() function - Python>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print i, a[i]
0 Mary
1 had
2 a
3 little
4 lamb
CS 363 Spring 2005 GMU 66
More looping - Python>>> knights = {'gallahad': 'the pure', 'robin':
'the brave'}
>>> for k, v in knights.iteritems():
... print k, v
...
gallahad the pure
robin the brave
CS 363 Spring 2005 GMU 67
More looping - Python
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print i, v
...
0 tic
1 tac
2 toe
CS 363 Spring 2005 GMU 68
More looping - Python
>>> for i in reversed(xrange(1,10,2)):
... print i
...
9
7
5
3
1
CS 363 Spring 2005 GMU 69
More looping - Python>>> basket = ['apple', 'orange', 'apple', 'pear',
'orange', 'banana']
>>> for f in sorted(set(basket)):
... print f
apple
banana
orange
pear
CS 363 Spring 2005 GMU 70
Quote (‘) function• A list that is preceeded by QUOTE or a quote mark (‘) is
NOT evaluated.• QUOTE is required because the Scheme interpreter, named EVAL, always evaluates parameters to function applications before applying the function. QUOTE is used to avoid parameter evaluation when it is not appropriate– QUOTE can be abbreviated with the apostrophe prefix operator
• Can be used to provide function arguments– (myfunct ‘(a b) ‘(c d))
CS 363 Spring 2005 GMU 71
Output functions
• Output Utility Functions:
(DISPLAY expression)
(NEWLINE)
CS 363 Spring 2005 GMU 72
Output functions - Python
• printprint "Hello, World!"
print "(33 + 2) / 5 + 11.5 = ",(33 + 2) / 5 + 11.5
print "Halt!"
s = raw_input("Who Goes there? ")
print "You may pass,", s
CS 363 Spring 2005 GMU 73
define function
Form 1: Bind a symbol to a expression:
(define a 2)
(define emptylist ‘( ))
(define pi 3.141593)
CS 363 Spring 2005 GMU 74
assignment and def functions - Python
Form 1: Bind a symbol to a expression:
a = 2
emptylist = []
pi = 3.141593
CS 363 Spring 2005 GMU 75
“define” function - SmalltalkForm 1: Bind a symbol to a expression:
a := 2
mylist := OrderedCollection new: 0
mylist addAll: #(1 2 3 $a $b)
pi := 3.141593
CS 363 Spring 2005 GMU 76
“define” function - Ruby/Python
Form 1: Bind a symbol to a expression:
a = 2emptylist = []
mylist = [1,2,3,'a']
pi = 3.141593
CS 363 Spring 2005 GMU 77
define function
Form 2: To bind names to lambda expressions
(define (cube x) (* x (* x x )))
(define (gcd u v) (if ( = v 0) u (gcd v (remainder u v)) ))
function name and parameters
function body – lambda expression
CS 363 Spring 2005 GMU 78
define function - Smalltalk
Form 2: To bind names to methods (the “first” parameter becomes the object of the message; it becomes “self” in the method definition)
cube ^(self * self * self)
gcd: v (v = 0) ifTrue: [^self]. ^(self gcd: (self \\ v))
syntax: 50 cube
syntax: 50 gcd: 2020
CS 363 Spring 2005 GMU 79
define function - RubyForm 2: To bind names to methods (the “first” parameter becomes the
object of the message; it becomes “self” in the method definition)
class Integer def cube return self * self * self end
def gcd(v) if v == 0 return self else return v.gcd(self % v) endend
syntax: 50.cube
syntax: 50.gcd(2020)
CS 363 Spring 2005 GMU 80
define function - Rubynon-class vers.
Form 2: To bind names to methods (the “first” parameter becomes the object of the message; it becomes “self” in the method definition)
def cube(x) return x * x * x end
def gcd(u, v) if v == 0 return u else return gcd(v, u % v) end
syntax: cube(50)
syntax: gcd(50, 2020)
CS 363 Spring 2005 GMU 81
define function - PythonForm 2: To bind names to methods (the “first” parameter becomes the
object of the message; it becomes “self” in the method definition)
def cube(x): return x * x * x
def gcd(u, v): if v == 0: return u else: return gcd(v, u % v) Note: blocks are indented
syntax: cube(50)
syntax: gcd(50, 2020)
CS 363 Spring 2005 GMU 82
Function Evaluation
• Evaluation process (for normal functions): 1. Parameters are evaluated, in no particular order
2. The values of the parameters are substituted into the function body
3. The function body is evaluated
4. The value of the last expression in the body is the value of the function
(Special forms use a different evaluation process)
CS 363 Spring 2005 GMU 83
Data Structures in Scheme: Box Notation for Lists
first element (car) rest of list (cdr)
1
List manipulation is typically written using ‘car’ and ‘cdr’
CS 363 Spring 2005 GMU 84
Data Structures in Scheme
1 2 3 (1,2,3)
c
da
b((a b) c (d))
CS 363 Spring 2005 GMU 85
Basic List Manipulation
• (car L) – returns the first element of L
• (cdr L) – returns L minus the first element
(car ‘(1 2 3)) = 1
(car ‘((a b)(c d))) = (a b)
(cdr ‘(1 2 3)) = (2 3)
(cdr ‘((a b)(c d))) = ((c d))
CS 363 Spring 2005 GMU 86
Basic List Manipulation - Python
• L[0] – returns the first element of L
• L[1:] – returns L minus the first element
x, y = [1,2,3], [['a','b'], ['c','d']]x[0] = 1
y[0] = ['a', 'b']
x[1:] = [2, 3]
y[1:] = [['c', 'd']]
CS 363 Spring 2005 GMU 87
Basic List Manipulation Smalltalk
• L first – returns the first element of L
• L allButFirst – returns L minus the first element (Squeak), in gst use L copyFrom:2
#(1 2 3) first -> 1
#(($a $b)($c $d))) first -> ($a $b)
#(1 2 3) copyFrom: 2 -> (2 3)
#(($a $b)($c $d))) copyFrom:2 ->(($c $d))
CS 363 Spring 2005 GMU 88
Basic List Manipulation Ruby
• L.first – returns the first element of L
• L.slice(1..m) – returns L minus the first element
[1, 2, 3].first -> 1
[['a', 'b'] ['c', 'd']].first ->[“a”,”b”]
#(1 2 3) copyFrom: 2 -> (2 3)
#(($a $b)($c $d))) copyFrom:2 ->(($c $d))
CS 363 Spring 2005 GMU 89
Basic List Manipulation
• (list e1 … en) – return the list created from the individual elements
• (cons e L) – returns the list created by adding expression e to the beginning of list L
(list 2 3 4) = (2 3 4)
(list ‘(a b) x ‘(c d) ) = ((a b)x(c d))
(cons 2 ‘(3 4)) = (2 3 4)
(cons ‘((a b)) ‘(c)) = (((a b)) c)
CS 363 Spring 2005 GMU 90
Basic List Manipulation - Python
>>> a = ['spam', 'eggs', 100, 1234]>>> a['spam', 'eggs', 100, 1234]>>> a[0]
'spam'
>>> a[3]
1234
>>> a[-2]
100
>>> a[1:-1]
['eggs', 100]
CS 363 Spring 2005 GMU 91
Basic List Manipulation - Python
>>> a[:2] + ['bacon', 2*2]
['spam', 'eggs', 'bacon', 4]
>>> 3*a[:3] + ['Boe!']
['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boe!']
List items can be changed:>>> a
['spam', 'eggs', 100, 1234]
>>> a[2] = a[2] + 23
>>> a
['spam', 'eggs', 123, 1234]
CS 363 Spring 2005 GMU 92
Basic List Manipulation - Python
It is possible to nest lists (create lists containing other lists), for example:
>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2
CS 363 Spring 2005 GMU 93
Basic List Manipulation - Python
>>> p[1].append('xtra')
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']
Note that in the last example, p[1] and q really refer to the same object!
CS 363 Spring 2005 GMU 94
Example Functions
1. member - takes an atom and a simple list; returns #T if the atom is in the list; () otherwise
(DEFINE (member atm lis) (COND ((NULL? lis) '()) ((EQ? atm (CAR lis)) #T) ((ELSE (member atm (CDR lis))) ))
CS 363 Spring 2005 GMU 95
Example Functions2. equalsimp - takes two simple lists as parameters;
returns #T if the two simple lists are equal; () otherwise
(DEFINE (equalsimp lis1 lis2) (COND ((NULL? lis1) (NULL? lis2)) ((NULL? lis2) '()) ((EQ? (CAR lis1) (CAR lis2)) (equalsimp(CDR lis1)(CDR lis2))) (ELSE '())))
CS 363 Spring 2005 GMU 96
Example Functions3. equal - takes two general lists as parameters; returns #T if the two
lists are equal; ()otherwise(DEFINE (equal lis1 lis2) (COND ((NOT (LIST? lis1))(EQ? lis1 lis2)) ((NOT (LIST? lis2)) '()) ((NULL? lis1) (NULL? lis2)) ((NULL? lis2) '()) ((equal (CAR lis1) (CAR lis2)) (equal (CDR lis1) (CDR lis2))) (ELSE '())))
CS 363 Spring 2005 GMU 97
Example Functions
(define (count L)
(if (null? L) 0
(+ 1 (count (cdr L)))
)
)
(count ‘( a b c d)) =
(+ 1 (count ‘(b c d))) =
(+ 1 (+ 1(count ‘(c d))))
(+ 1 (+ 1 (+ 1 (count ‘(d)))))=
(+ 1 (+ 1 (+ 1 (+ 1 (count ‘())))))=
(+ 1 (+ 1 (+ 1 (+ 1 0))))= 4
CS 363 Spring 2005 GMU 98
Scheme Functions
Now define(define (count1 L) ??
)
so that (count1 ‘(a (b c d) e)) = 5
CS 363 Spring 2005 GMU 99
Scheme Functions
This function counts the individual elements:
(define (count1 L)
(cond ( (null? L) 0 )
( (list? (car L))
(+ (count1 (car L))(count1 (cdr L))))
(else (+ 1 (count (cdr L))))
)
)
so that (count1 ‘(a (b c d) e)) = 5
CS 363 Spring 2005 GMU 100
Example Functions
(define (append L M)
(if (null? L) M
(cons (car L)(append(cdr L) M))
)
)
(append ‘(a b) ‘(c d)) = (a b c d)
CS 363 Spring 2005 GMU 101
How does append do its job?
(define (append L M)
(if (null? L) M
(cons (car L)(append(cdr L) M))))
(append ‘(a b) ‘(c d)) =
(cons a (append ‘(b) ‘(c d))) =
CS 363 Spring 2005 GMU 102
How does append do its job?
(define (append L M)
(if (null? L) M
(cons (car L)(append(cdr L) M))))
(append ‘(a b) ‘(c d)) =
(cons a (append ‘(b) ‘(c d))) =
(cons a (cons b (append ‘() ‘(c d)))) =
CS 363 Spring 2005 GMU 103
How does append do its job?
(define (append L M) (if (null? L) M (cons (car L)(append(cdr L) M))))
(append ‘(a b) ‘(c d)) =(cons a (append ‘(b) ‘(c d))) =
(cons a (cons b (append ‘() ‘(c d)))) =(cons a (cons b ‘(c d))) =
CS 363 Spring 2005 GMU 104
How does append do its job?
(define (append L M)
(if (null? L) M
(cons (car L)(append(cdr L) M))))
(append ‘(a b) ‘(c d)) =
(cons a (append ‘(b) ‘(c d))) =
(cons a (cons b (append ‘() ‘(c d)))) =
(cons a (cons b ‘(c d))) =
(cons a ‘(b c d)) =
CS 363 Spring 2005 GMU 105
How does append do its job?
(define (append L M)
(if (null? L) M
(cons (car L)(append(cdr L) M))))
(append ‘(a b) ‘(c d)) =
(cons a (append ‘(b) ‘(c d))) =
(cons a (cons b (append ‘() ‘(c d)))) =
(cons a (cons b ‘(c d))) =
(cons a ‘(b c d)) =
(a b c d)
CS 363 Spring 2005 GMU 106
Reverse
Write a function that takes a list of elements and reverses it:
(reverse ‘(1 2 3 4)) = (4 3 2 1)
CS 363 Spring 2005 GMU 107
Reverse
(define (reverse L)
(if (null? L) ‘()
(append (reverse (cdr L))(list (car L)))
)
)
CS 363 Spring 2005 GMU 108
Selection Sort in Scheme
Let’s define a few useful functions first:(DEFINE (findsmallest lis small) (COND ((NULL? lis) small) ((< (CAR lis) small) (findsmallest (CDR lis) (CAR lis))) (ELSE (findsmallest (CDR lis) small)) ) )
CS 363 Spring 2005 GMU 109
Selection Sort in Scheme
(DEFINE (remove lis item) (COND ((NULL? lis) ‘() ) ((= (CAR lis) item) lis) (ELSE (CONS (CAR lis) (remove (CDR lis)
item))) ))
Cautious programming!
Assuming integers
CS 363 Spring 2005 GMU 110
Selection Sort in Scheme
(DEFINE (selectionsort lis)
(IF (NULL? lis) lis
(LET ((s (findsmallest (CDR lis) (CAR lis))))
(CONS s (selectionsort (remove lis s)) )
)
)
CS 363 Spring 2005 GMU 111
Higher order functions
• Def: A higher-order function, or functional form, is one that either takes functions as parameters, yields a function as its result, or both
• Mapcar
• Eval
CS 363 Spring 2005 GMU 112
Higher-Order Functions: mapcar
Apply to All - mapcar - Applies the given function to all elements of the
given list; result is a list of the results
(DEFINE (mapcar fun lis) (COND ((NULL? lis) '()) (ELSE (CONS (fun (CAR lis)) (mapcar fun (CDR lis)))) ))
CS 363 Spring 2005 GMU 113
Higher-Order Functions: mapcar
• Using mapcar:(mapcar (LAMBDA (num) (* num num num)) ‘(3 4 2 6))
returns (27 64 8 216)
CS 363 Spring 2005 GMU 114
Higher Order Functions: EVAL
• It is possible in Scheme to define a function that builds Scheme code and requests its interpretation
• This is possible because the interpreter is a user-available function, EVAL
CS 363 Spring 2005 GMU 115
Using EVAL for adding a List of Numbers
Suppose we have a list of numbers that must be added:(DEFINE (adder lis) (COND((NULL? lis) 0) (ELSE (+ (CAR lis) (adder(CDR lis ))))))
Using Eval((DEFINE (adder lis) (COND ((NULL? lis) 0) (ELSE (EVAL (CONS '+ lis)))))
(adder ‘(3 4 5 6 6))Returns 24
CS 363 Spring 2005 GMU 116
Other Features of Scheme• Scheme includes some imperative features:
1. SET! binds or rebinds a value to a name
2. SET-CAR! replaces the car of a list
3. SET-CDR! replaces the cdr part of a list
CS 363 Spring 2005 GMU 117
COMMON LISP
• A combination of many of the features of the popular dialects of LISP around in the early 1980s
• A large and complex language – the opposite of Scheme
CS 363 Spring 2005 GMU 118
COMMON LISP
• Includes:– records
– arrays
– complex numbers
– character strings
– powerful I/O capabilities
– packages with access control
– imperative features like those of Scheme
– iterative control statements
CS 363 Spring 2005 GMU 119
ML
• A static-scoped functional language with syntax that is closer to Pascal than to LISP
• Uses type declarations, but also does type inferencing to determine the types of undeclared variables
• It is strongly typed (whereas Scheme is essentially typeless) and has no type coercions
• Includes exception handling and a module facility for implementing abstract data types
CS 363 Spring 2005 GMU 120
ML
• Includes lists and list operations
• The val statement binds a name to a value (similar to DEFINE in Scheme)
• Function declaration form:
fun function_name (formal_parameters) =
function_body_expression;
e.g.,
fun cube (x : int) = x * x * x;
CS 363 Spring 2005 GMU 121
Haskell
• Similar to ML (syntax, static scoped, strongly typed, type inferencing)
• Different from ML (and most other functional languages) in that it is purely functional (e.g., no variables, no assignment statements, and no side effects of any kind)
CS 363 Spring 2005 GMU 122
Haskell
• Most Important Features– Uses lazy evaluation (evaluate no
subexpression until the value is needed)– Has list comprehensions, which allow it to deal
with infinite lists
CS 363 Spring 2005 GMU 123
Haskell Examples
1. Fibonacci numbers (illustrates function definitions with different parameter forms)
fib 0 = 1
fib 1 = 1
fib (n + 2) = fib (n + 1)
+ fib n
CS 363 Spring 2005 GMU 124
Haskell Examples
2. Factorial (illustrates guards)
fact n
| n == 0 = 1
| n > 0 = n * fact (n - 1)
The special word otherwise can appear as a guard
CS 363 Spring 2005 GMU 125
Haskell Examples3. List operations
– List notation: Put elements in brackets
e.g., directions = [“north”, “south”, “east”, “west”]
– Length: #
e.g., #directions is 4– Arithmetic series with the .. operator
e.g., [2, 4..10] is [2, 4, 6, 8, 10]
CS 363 Spring 2005 GMU 126
Haskell Examples
3. List operations (cont)– Catenation is with ++
e.g., [1, 3] ++ [5, 7] results in
[1, 3, 5, 7]– CONS, CAR, CDR via the colon operator (as in Prolog)
e.g., 1:[3, 5, 7] results in
[1, 3, 5, 7]
CS 363 Spring 2005 GMU 127
Haskell Examples
• Quicksort:
sort [] = []
sort (a:x) = sort [b | b ← x; b <= a]
++ [a] ++
sort [b | b ← x; b > a]
CS 363 Spring 2005 GMU 128
Applications of Functional Languages
• LISP is used for artificial intelligence– Knowledge representation– Machine learning– Natural language processing– Modeling of speech and vision
• Scheme is used to teach introductory programming at a significant number of universities
CS 363 Spring 2005 GMU 129
Comparing Functional and Imperative Languages
• Imperative Languages:– Efficient execution– Complex semantics– Complex syntax– Concurrency is programmer designed
• Functional Languages:– Simple semantics– Simple syntax– Inefficient execution– Programs can automatically be made concurrent