I recently stumbled across this article which describes how to code FizzBuzz using only Procs in Ruby, and since I was bored, thought it would be neat to try and implement the same thing in Python using lambdas.
I got to the section where you create numbers using nested functions, and wrote the following Python script:
#!/usr/bin/env python
zero = lambda p : (lambda x: x)
one = lambda p : (lambda x: p(x))
two = lambda p : (lambda x: p(p(x)))
three = lambda p : (lambda x: p(p(p(x))))
five = lambda p: (lambda x: p(p(p(p(p(x))))))
fifteen = lambda p : (lambda x: p(p(p(p(p( \
p(p(p(p(p( \
p(p(p(p(p(x))))))))))))))))
hundred = lambda p: (lambda x: p(p(p(p(p(p(p(p(p(p( \
p(p(p(p(p(p(p(p(p(p( \
p(p(p(p(p(p(p(p(p(p( \
p(p(p(p(p(p(p(p(p(p( \
p(p(p(p(p(p(p(p(p(p( \
p(p(p(p(p(p(p(p(p(p( \
p(p(p(p(p(p(p(p(p(p( \
p(p(p(p(p(p(p(p(p(p( \
p(p(p(p(p(p(p(p(p(p( \
p(p(p(p(p(p(p(p(p(p(x)))))))))))))))))))))))))))) \
))))))))))))))))))))))))))) \
))))))))))))))))))))))))))) \
)))))))))))))))))))
def to_int(func):
return func(lambda n: n + 1)(0)
print to_int(zero)
print to_int(one)
print to_int(two)
print to_int(three)
print to_int(five)
print to_int(fifteen)
print to_int(hundred)
Numbers zero through fifteen works fine, but if I try creating the number 100, the file won't run due to the following error:
s_push: parser stack overflow
MemoryError
I have to comment it out in order for the file to run at all.
This sort of sucks -- is there any way around this limitation so that I can arbitrarily nest lambdas and function calls without Python falling over and running out of memory?
Or alternatively, is there some kind of lambda-calculus trick I can use to express the number 100 without having so many nested functions?
express the number 100 without having so many nested functions?
here you go:
>>> test = lambda f: f(lambda x: x + 1)(0)
>>> z = lambda f: lambda x: x
>>> test(z)
0
>>> succ = lambda n: lambda f: lambda x: f(n(f)(x))
>>> _1 = succ(z)
>>> test(_1)
1
>>> _2 = succ(_1)
>>> test(_2)
2
>>> plus = lambda m: lambda n: lambda f: lambda x: m(f)(n(f)(x))
>>> _3 = plus(_1)(_2)
>>> test(_3)
3
>>> mult = lambda m: lambda n: lambda f: lambda x: m(n(f))(x)
>>> _6 = mult(_2)(_3)
>>> test(_6)
6
>>> _5 = plus(_2)(_3)
>>> _25 = mult(_5)(_5)
>>> _4 = plus(_2)(_2)
>>> _100 = mult(_25)(_4)
>>> test(_100)
100
>>>
It looks like it's not possible without recompiling Python. The parser stack size is set with the constant MAXSTACK in parser.h. You could increase this value and recompile to increase the limit. See http://bugs.python.org/issue3971 and http://mail.python.org/pipermail/python-list/2012-March/621555.html .
From the lambda-calculus standpoint, incrementing a number can be done with the following function:
succ = lambda n: lambda p: lambda x: p(n(p)(x))
Then, one = succ(zero), two = succ(one), and so forth.
Related
This question below is from a past year NUS exam paper, and im not sure how to go about solving this; how do you break down the lambda parts and figure out which bracket is for which lambda variable? I'm unable to trace the code to get 120
def combinator(y):
return (lambda x: lambda y: x(y))(lambda x:y)
combinator(lambda x:x*10)(11)(12)
Ive tried to google but the lambda tutorials are mostly basic so im not sure how to read and break down more complex lambda codes and higher order functions
The function is
def combinator(y):
return (lambda x: lambda y: x(y))(lambda x:y)
combinator(lambda x:x*10)(11)(12)
Let's try to simplify the function. First, take note that you can change the symbol for a function. For example, lambda x: x can be changed to lambda z: z.
As there are a lot of x and y, we will change the symbols to reduce the confusion.
def combinator(y):
return (lambda w: lambda z: w(z))(lambda x:y)
combinator(lambda x:x*10)(11)(12)
Let's try to define the function as mathematics function to make it easier to understand. Let's set
f represents lambda x:x*10, so f(x) = x*10
g represents lambda x:y, so g(x) = y
h represents lambda z:w(z), so h(z) = w(z) => h = w
k represents lambda w: lambda z: w(z), so k(w) = h = w
With the mathematics function defined, you can substitute them back to the function.
combinator(y)
= (lambda w: lambda z: w(z))(lambda x:y)
= k(g)
= g
Therefore, we know that combinator(y) = g
combinator(y)(x) = g(x) = y
combinator(y)(x)(z) = y(z)
Therefore
combinator(lambda x:x*10)(11)(12)
= combinator(f)(11)(12)
= f(12)
= 12*10
= 120
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
>>> test = lambda f: f(lambda x: x + 1)(0)
>>> z = lambda f: lambda x: x
>>> test(z)
0
>>> succ = lambda n: lambda f: lambda x: f(n(f)(x))
>>> _1 = succ(z)
>>> test(_1)
1
>>> _2 = succ(_1)
>>> test(_2)
2
>>> plus = lambda m: lambda n: lambda f: lambda x: m(f)(n(f)(x))
>>> _3 = plus(_1)(_2)
>>> test(_3)
3
>>> mult = lambda m: lambda n: lambda f: lambda x: m(n(f))(x)
>>> _6 = mult(_2)(_3)
>>> test(_6)
6
>>> _5 = plus(_2)(_3)
>>> _25 = mult(_5)(_5)
>>> _4 = plus(_2)(_2)
>>> _100 = mult(_25)(_4)
>>> test(_100)
100
First avoid same name hidden (local) variables to avoid extra confusion (as if you need anymore! :)
>>> test = lambda f: f(lambda x: x + 1)(0)
>>> z = lambda g: lambda y: y
>>> test(z)
0
Go step by step replacing the variables by their value:
test(z) = z(lambda x: x + 1)(0)
Now z is a function that return the identity function lambda y: y no matter what argument is passed (g does not appear in the expression defining the lambda).
test(z) = (lambda y: y)(0) = 0
I have a list of lambda functions. Lets say this one
l = [lambda x:x**i for i in range(n)]
For every n I need to be able to sum them so I'd have a function like this:
f = lambda x: x + x**2 + x**3 + ... + x**n
Is there any way?
Edit: I wasn't clear. I don't know anything about that functions.
Is this the solution you're looking for?
Python 3.x:
n = 5
g = lambda y: sum( f(y) for f in (lambda x: x**i for i in range(n)) )
print(g(5)) # 781
Python 2.x:
n = 5
g = lambda y: sum( f(y) for f in (lambda x: x**i for i in xrange(n)) )
print g(5) # 781
If you mean a finite sum, up to x**n, use the mathematical shortcut
f = lambda x: (x**(n+1) - 1) / (x - 1) if x != 1 else n
f = lambda x,n: sum( x**i for i in range(n) )
print f(3,4)
>> 40
The simplest way to do this is to avoid creating the list of lambda functions, and to instead sum over a single function. Assuming you've defined x and n, you can do:
f = lambda x, i: x**i
sum(f(x, i) for i in range(n))
In your original example, you have actually created a closure, so your lambda functions do not do what you think they do. Instead, they are all identical, since they all use the final value of i in the closure. That is certainly not what you intended.
n=5
xpower=[]
for i in range(n):
xpower.insert(i, i+1)
print(i,xpower)
f = lambda x, xpower: sum(x**xpower[i] for i in range(len(xpower)))
print("Example with n=5, x=2:"," ", f(2,xpower))
I'm trying to use Python to plot how the limit (1+1/n)^n as n->infinity will go towards e at large n.
Why is the plot going towards 1 instead of e?
n = np.arange(0,10000,1)
f = lambda x: np.power(1 + (1/x), x)
plt.plot(n,f(n))
in this line:
f = lambda x: np.power(1 + (1/x), x)
when x is an int so 1/X will always be 0, do
f = lambda x: np.power(1 + (1.0/x), x)
I have two (many) lambdas:
myFoo = lambda x,y: x + y
mySpecFoo = lambda x: myFoo(x, 1)
I want to print resulting expression for mySpecFoo. smth like
x = var('x')
print(mySpecFoo(x))
and I want to see in output:
lambda x: x + 1
Do you know how to do this?
Thank you!
This is called "symbolic evaluation", and you need some external library to do this, for example SymPy:
>>> import sympy
>>> myFoo = lambda x,y: x + y
>>> mySpecFoo = lambda x: myFoo(x, 1)
>>> x = sympy.var("x")
>>> print mySpecFoo(x)
1 + x