Introduction to Functional Programming in Python David Jones - - PowerPoint PPT Presentation
Introduction to Functional Programming in Python David Jones - - PowerPoint PPT Presentation
Introduction to Functional Programming in Python David Jones drj@ravenbrook.com Python and Functional Programming Beginner Journeyman Master Programming: Modes of Operation Functional Programming Object Oriented Programming Imperative
Python and Functional Programming Beginner Journeyman Master
Functional Programming Object Oriented Programming Imperative Programming
Programming: Modes of Operation
FP versus Imperative
a spectrum of possibilities Java
more functional more imperative
Common Lisp Python ML Haskell Scheme C
A Function
double
in
- ut
double
in
- ut
5 10 double
in
- ut
'foo' 'foofoo'
def double(x) : return x * 2
>>> double(5) 10 >>> double('foo') 'foofoo'
First Class Functions
Can be... stored in variables; passed as arguments to
- ther functions;
returned as results from functions; created at runtime.
def hello() : return 'hello'
>>> hello() 'hello' >>> y = hello >>> y() 'hello' >>> type(y) <type 'function'>
Variables refer to Values hello y
The hello function
>>> y() 'hello' >>> del hello >>> hello()
Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'hello' is not defined
>>> help(y)
Help on function hello in module __main__: hello()
Factorial
def factorial(x) : # Imperative y = 1 for i in range(1,x+1) : y *= i return y def factorial(x) : # Functional if x <= 1 : return 1 else : return x * factorial(x-1)
Lists for a in l : ... map(..., l)
>>> r=[] >>> for x in range(10) : ... r.append(math.sqrt(x)) ... >>> r
[0.0, 1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.2360679774997898, 2.4494897427831779, 2.6457513110645907, 2.8284271247461903, 3.0]
>>> map(math.sqrt, range(10))
[0.0, 1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.2360679774997898, 2.4494897427831779, 2.6457513110645907, 2.8284271247461903, 3.0]
Imperative Functional
>>> posts = blog.metaWeblog.getRecentPosts (apiKey, 'drj11', password, 999) >>> len(posts) 59 >>> def postid(p) : return int(p['postid']) ... >>> map(postid, posts)
[97, 96, 94, 93, 92, 91, 90, 89, 87, 83, 77, 74, 80, 79, 78, 75, 73, 72, 70, 64, 30, 66, 65, 63, 60, 42, 57, 54, 56, 55, 52, 53, 38, 43, 40, 39, 37, 29, 28, 27, 25, 20, 19, 12, 9, 7, 5, 26, 41, 67, 68, 71, 76, 81, 82, 84, 86, 88, 95]
>>> map(lambda p: int(p['postid']), posts)
Lambda
def fibi(x) : # Imperative s = 0 ; t = 1 for i in range(x) : s,t = t,s+t return s def fibf(x) : # Functional if x <= 1 : return x return fibf(x-1) + fibf(x-2)
def timeit(f) : import time def t(*l) : t0 = time.time() x = f(*l) t1 = time.time() print "Time: %f" % (t1 - t0) return x return t
Timing
>>> timefibi = timeit(fibi) >>> timefibf = timeit(fibf) >>> timefibi(30) Time: 0.000026 832040 >>> timefibf(30) Time: 1.042492 832040
Timing Fibonacci
def memo(f) : cache = {} def m(*l) : if not cache.has_key(l) : cache[l] = f(*l) return cache[l] return m
Rembering Computations
>>> timefibf(30) Time: 1.036864 832040 >>> fibf = memo(fibf) >>> timefibf = timeit(fibf) >>> timefibf(30) Time: 0.000012 832040
Faster Fibonacci
Filter
>>> filter(lambda x : x % 2 == 0, range(11)) [0, 2, 4, 6, 8, 10] >>> filter(lambda x : x == int(math.sqrt(x))**2, range(40)) [0, 1, 4, 9, 16, 25, 36]
>>> l = ['food', 'python', 'pyfoo'] >>> r = re.compile('fo+') >>> filter(lambda x : r.search(x), l) ['food', 'pyfoo']
Object Methods and Functions
>>> filter(r.search, l) ['food', 'pyfoo']
Further Reading
Colophon
Slides were prepared using Omnigrae and Apple's OS X. Python code was generally executed in the CPython implementation version 2.5.1. Presentation was performed using PNG graphics and Apple Preview. The fonts used were Lucida Grande and Monaco, both designed by Bigelow and Holmes. The coee bean image is public domain and was created by Mark Sweep. The idea for improving the running time of Fibonacci using memo was suggested by Rici Lake on the Lua mailing list.