print 'open the fridge'
print 'put elephant into the fridge'
print 'close the fridge'
class Fridge:
def open(self):
print 'open the fridge'
def put(self, something):
print 'put %s into the fridge' % something
def close(self):
print 'close the fridge'
fridge = Fridge()
fridge.open()
fridge.put('elephant')
fridge.close()
def open(something): print 'open the %s' % something return something def put(object, container): print 'put %s into the %s' % (object, container) return container def close(something): print 'close the %s' % something return something
close(put('elephant', open('fridge')))
In computer science, functional programming is a programming paradigm, a style of building the structure and elements of computer programs, that:
>>>i = i + 1
>>>
>>>i + 1
43
>>>
def fac(n):
n = 1 #mutation
for i in range(n): #states
n = n * (i + 1) #mutation
return n
def fac(n):
if n == 0:
return 1
else:
return n * fac(n - 1)
b^n = b * b * b ... * b (b occurs n times)
def exp(b, n):
result = 1
for _ in range(n):
result *= b
return result
b^n = b * b^(n - 1)
b^0 = 1
def exp(b, n):
if n:
return b * exp(b, n - 1)
else:
return 1
How to compute exponential more efficiently?
b^n = b^(n/2) * b^(n/2) (if n is even)
b^n = b * b^(n-1) (if n is odd)
b^0 = 1
So
def exp(b, n):
if n%2:
return b * exp(b, n - 1)
elif n:
return exp(b, n/2) * exp(b, n/2)
else:
return 1
def fib(n):
if n < 2:
return n
else:
return fib(n - 1) + fib(n - 2)
fib(4) called [#1]
--fib(3) called [#2]
----fib(2) called [#3]
------fib(1) called [#4]
------fib(1) returned 1 [#4]
------fib(0) called [#5]
------fib(0) returned 0 [#5]
----fib(2) returned 1 [#3]
----fib(1) called [#6]
----fib(1) returned 1 [#6]
--fib(3) returned 2 [#2]
--fib(2) called [#7]
----fib(1) called [#8]
----fib(1) returned 1 [#8]
----fib(0) called [#9]
----fib(0) returned 0 [#9]
--fib(2) returned 1 [#7]
fib(4) returned 3 [#1]
def fib(n):
def fib_iter(a, b, n):
if n:
return fib_iter(b, a + b, n - 1)
else:
return a
return fib_iter(0, 1, n)
>>> (lambda x: x * x)(2)
4
>>> square = lambda x: x * x
>>> square(2)
4
>>> sq = square
>>> sq(2)
4
>>> name = ['Leonardo DiCaprio', 'Johnny Depp', 'Tom Cruise']
>>> sorted(name) #sort by full name
['Johnny Depp', 'Leonardo DiCaprio', 'Tom Cruise']
>>> sorted(name, key = lambda x: x.split(' ')[1]) #sort by last name
['Tom Cruise', 'Johnny Depp', 'Leonardo DiCaprio']
>>> sorted(name, key = lambda x: len(x)) #sort by name length
['Tom Cruise', 'Johnny Depp', 'Leonardo DiCaprio']
get_cursors_if(source, satisfy_func, transform_func)
>>> def addn(n):
def add(m):
return m + n
return add
>>> add2 = addn(2)
>>> add2(3)
5
def fib(n):
if n < 2:
return n
else:
return fib(n - 1) + fib(n - 2)
def memoize(f): cache = {} def g(x): if x not in cache: cache[x] = f(x) return cache[x] return g fib = memoize(fib)
>>> fib(5) fib(5) called [#1] fib(4) called [#2] fib(3) called [#3] fib(2) called [#4] fib(1) called [#5] fib(1) returned 1 [#5] fib(0) called [#6] fib(0) returned 0 [#6] fib(2) returned 1 [#4] fib(3) returned 2 [#3] fib(4) returned 3 [#2] fib(5) returned 5 [#1]
__report_indent = [0]
def trace(fn):
def wrap(*params,**kwargs):
call = wrap.callcount = wrap.callcount + 1
indent = ' ' * __report_indent[0]
fc = "%s(%s)" % (fn.__name__, ', '.join(
[a.__repr__() for a in params] +
["%s = %s" % (a, repr(b)) for a,b in kwargs.items()]
))
print "%s%s called [#%s]"\
% (indent, fc, call)
__report_indent[0] += 1
ret = fn(*params,**kwargs)
__report_indent[0] -= 1
print "%s%s returned %s [#%s]"\
% (indent, fc, repr(ret), call)
return ret
wrap.callcount = 0
return wrap
fib = memorize(fib)
@memorize
def fib(n):
...
def addx(x):
def func(y):
return x + y
return func
foo = addx(5)
x = 3
>>>foo(10)
15 # in lexical scope, 5 is bind to x in foo
#Argument passing
def addx(x): def func(a, b = x): return a + b return func >>> a = addx(2) >>> a(3) 5
#use object
class addx(): def __init__(self, x): self.x = x def __call__(self, y): return self.x + y >>> a = addx(2) >>> a(3) 5
The venerable master was walking with his student. The student said "Master, I have heard that objects are a very good thing - is this true?" Master looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."
On his next walk with master, student said "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Master responded by hitting student with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, the student became enlightened.
http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html
def counter():
count = 0
def func():
count += 1
return count
return func
>>> count = counter()
>>> count()
Traceback (most recent call last):
File "", line 1, in
count()
File "C:/Users/JC/Desktop/a.py", line 152, in func
count += 1
UnboundLocalError: local variable 'count' referenced before assignment
def counter():
count = [0]
def func():
count[0] += 1
return count[0]
return func
>>> count = counter()
>>> count()
1
>>> count()
2
get_cursors_if(source, satisfy_func, transform_func)
get_cursor_names_if = partial(get_cursors_if,
transform_func = lambda c: c.displayname)
get_class_cursor = partial(get_cursors_if,
satisfy_func = lambda c: c.kind == CursorKind.CXX_CLASS,
transform_func = lambda c: c)
def Ackermann(x, y):
if not y:
return 0
elif not x:
return 2 * y
elif y == 1:
return 2
else:
return A(x - 1, A(x, y - 1))
>>> Ackermann(0, 4) 8 #hyper 2 multipication 2 * 4 >>> Ackermann(1, 4) 16 #hyper 3 exponentiation 2 ^ 4>>> Ackermann(2, 3) 16 #hyper 4 tetration 2 ^^ 3 >>> Ackermann(2, 4) 65536 # 2 ^^ 4
def partial_Ack(n): def func(b): return Ackermann(n, b) return func
multiply2 = partial_Ack(0) exp2 = partial_Ack(1) teration2 = partial_Ack(2)
from functools import partial
multiply = partial(Ackermann, 0)
def func(a, b, c):
return a + b + c
def curried_func(a):
return lambda b: lambda c: a + b + c
>>> print func('a', 'b', 'c')
abc
>>> print curried_func('a')('b')('c')
abc
computation a b c d = (a + b^2+ c^3 + d^4)
fillOne = computation 1 fillTwo = fillOne 2 fillThree = fillTwo 3 answer = fillThree 5 -- Result: answer == 657
#a ? b : c
(a and b) or c
#a ? b : c
my_if(a, b, c)
Consider the following situation:
def bad_exp():
while True:
pass
The If statement works well:
if True:
good_exp()
else:
bad_exp()
But my_if() will run into infinity loop:
my_if(True, good_exp(), bad_exp())
Because function arguments will be evaluated first.
def my_if(a, b, c):
if a:
return b()
else:
return c()
my_if(a, lambda : b, lambda : c)
def fib():
def stream(a, b):
return (a, lambda : stream(a + b, a))
return stream(1, 0)
>>> fib()[0]
1
>>> fib()[1]()[0]
1
def get_nth(stream, n): val, next_str = stream() if n != 1: return get_nth(next_str, n - 1) else: return val
>>> get_nth(fib, 10) 55
def isprime(n):
for x in xrange(2, int(n**0.5)+1):
if n % x == 0:
return False
return True
def prime():
def stream(n):
if isprime(n):
return (n, lambda : stream(n + 1))
else:
return stream(n + 1)
return stream(2)
def twin_prime(): def stream(n): if isprime(n) and isprime(n + 2): return ((n, n + 2), lambda : stream(n + 1)) else: return stream(n + 1) return stream(2) >>> for i in range(1, 5): . . . print get_nth(twin_prime, i) (3, 5) (5, 7) (11, 13) (17, 19)
def gen_prime():
n = 2
def gen(n):
if isprime(n):
return n
else:
return gen(n + 1)
while True:
n = gen(n)
yield n
n += 1
def gen_twin_prime():
prime = gen_prime()
a = prime.next()
def gen(a):
b = prime.next()
if b - a == 2:
return (a, b)
else:
return gen(b)
while True:
tmp = gen(a)
a = tmp[1]
yield tmp
class Zoo:
def open(self):
...
def put(self, object):
...
def close(self):
...
def open(something): if something == 'fridge': ... elif something == 'zoo': ... def put if...
def close
if...
class Fridge:
...
def clean(self):
print 'clean the fridge'
class Zoo:
...
def clean(self):
print 'clean the zoo'
def clean(something):
if something == 'fridge':
print 'clean the fridge'
elif something == 'zoo':
print 'clean the zoo'
return something