Definition of success function - python

In church numerals, if we have:
# (define zero (lambda (f) (lambda (x) x)))
zero = lambda f: lambda x: x
Then the successor function can be defined as:
# (define succ (lambda (n) (lambda (f) (lambda (x) (f ((n f) x))))))
succ = lambda n: lambda f: lambda x: f(n(f)(x))
Maybe this is a silly question, but if the successor essentially adds one more wrapper f(...) to the previous equation, why couldn't this just be defined as f(n)? Is this more for consistency of definition, or why can't that shorter form be used?
(Note: using python definitions here as well as scheme as it makes it a bit simpler for me to test with.)

The numeral n is defined as n applications of the function f to some argument x.
Thus,
0 = λf.λx.x
1 = λf.λx.f x
2 = λf.λx.f (f x)
3 = λf.λx.f (f (f (x))
...
Note that 1 is not the same as λf.λx.f 0, so succ 0 can't be, either. (The same is true for the other numerals.)
Your definition, λn.λf.λx.(f n) would give
succ 0 = (λn.λf.λx.(f n)) (λg.λy.y)
= λf.λx.f (λg.λy.y)
which is not the same as 1, but
(λn.λf.λx.f (n f x)) (λg.λy.y)
= λf.λx.f ((λg.λy.y) f x)
= λf.λx.f ((λy.y) x)
= λf.λx.f x
= 1

Related

s Counterexamples for invalid model for Z3

This is an extension of the question:
Use Z3 to find counterexamples for a 'guess solution' to a particular CHC system?
In the below code, I am trying to use Z3 to get s counterexamples to a guess candidate for I satisfying some CHC clauses:
from z3 import *
x, xp = Ints('x xp')
P = lambda x: x == 0
B = lambda x: x < 5
T = lambda x, xp: xp == x + 1
Q = lambda x: x == 5
s = 10
def Check(mkConstraints, I, P , B, T , Q):
s = Solver()
# Add the negation of the conjunction of constraints
s.add(Not(mkConstraints(I, P , B, T , Q)))
r = s.check()
if r == sat:
return s.model()
elif r == unsat:
return {}
else:
print("Solver can't verify or disprove, it says: %s for invariant %s" %(r, I))
def System(I, P , B, T , Q):
# P(x) -> I(x)
c1 = Implies(P(x), I(x))
# P(x) /\ B(x) /\ T(x,xp) -> I(xp)
c2 = Implies(And(B(x), I(x), T(x, xp)) , I(xp))
# I(x) /\ ~B(x) -> Q(x)
c3 = Implies(And(I(x), Not(B(x))), Q(x))
return And(c1, c2, c3)
cex_List = []
I_guess = lambda x: x < 3
for i in range(s):
cex = Check(System, I_guess, P , B , T , Q)
I_guess = lambda t: Or(I_guess(t) , t == cex['x'])
cex_List.append( cex[x] )
print(cex_List )
The idea is to use Z3 to learn a counterexample x0 for guess invariant I, then run Z3 to learn a counterexample for I || (x == x0) and so on till we get s counterexamples. However the following code gives 'RecursionError: maximum recursion depth exceeded
'. I am confused because I am not even recursing with depth > 1 anywhere. Could anyone describe what's going wrong?
Your problem really has nothing to do with z3; but rather a Python peculiarity. Consider this:
f = lambda x: x
f = lambda x: f(x)
print(f(5))
If you run this program, you'll also see that it falls in to the same infinite-recursion loop, since by the time you "get" to the inner f, the outer f is bound to itself again. In your case, this is exhibited in the line:
I_guess = lambda t: Or(I_guess(t) , t == cex['x'])
which falls into the same trap by making I_guess recursive, which you did not intend.
The way to avoid this is to use an intermediate variable. It's ugly and counter-intuitive but that's the way of the python! For the example above, you'd write it as:
f = lambda x: x
g = f
f = lambda x: g(x)
print(f(5))
So, you need to do the same trick for your I_guess variable.
Note that since you're updating the function iteratively, you need to make sure to remember the function in each step, instead of using the same name over and over. That is, capture the old version each time you create the new function. When applied to the above case, it'll be something like:
f = lambda x: x
f = lambda x, old_f=f: old_f(x)
print(f(5))
This'll make sure the iterations don't clobber the captured function. Applying this idea to your problem, you can code as follows:
for i in range(s):
cex = Check(System, I_guess, P, B, T, Q)
I_guess = lambda t, old_I_guess=I_guess: Or(old_I_guess(t), t == cex[x])
cex_List.append(cex[x])
When run, this prints:
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
without any infinite-recursion problem. (Whether this is the correct output or what you really wanted to do, I'm not sure. Looks to me like you need to tell z3 to give you a "different" solution, and maybe you've forgotten to do that. But that's a different question. We're really discussing a Python issue here, not z3 modeling.)

Print the first n numbers of the fibonacci sequence in one expression

So I've been messing around with Python a bit lately and I'm trying to find a way to output the nth number of the fibonacci sequence in a single expression. This is the code that I've written so far:
(lambda f: f if f<2 else (f-1)+(f-2))(n)
# n == 1 -> 1
# n == 2 -> 1
# n == 3 -> 3
# n == 4 -> 5
# n == 5 -> 7
....
However, as I commented above this simply outputs a set of odd numbers. I'm confused as to why this is happening because if I am to re-write this as a named lambda function, it would look something like this:
f = lambda n: n if n<2 else f(f-1)+f(f-2)
# f(1) -> 1
# f(2) -> 1
# f(3) -> 2
# f(4) -> 3
...
# f(10) -> 55
...
Now the reason I've added the Lambda Calculus tag is because I'm not sure if this question falls under the domain of simply understanding how Python handles this. I've read a tiny bit about the Y combinator in lambda calculus, but that's a foreign language to me and couldn't derive anything from resources I found for this about lambda calculus.
Now, the reason I'm trying to do this in one line of code, as opposed to naming it, is because I want to try and put this lambda function into list comprehension. So do something like this:
[(lambda f: f if f<2 else (f-1)+(f-2))(n) for n in range(10)]
and create an array of the first x numbers in the fibonacci sequence.
What I'm looking for is a method of doing this whole thing in one expression, and should this fall under the domain of Lambda calculus, which I believe it does, for someone to explain how this would work.
Feel free to offer an answer in JavaScript, C#, or other C-like languages that support Lambda functions.
EDIT: I've found the solution to what I was attempting to do:
[(lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f:(lambda n: n if n<2 else f(n-1)+f(n-2)))(y) for y in range(10)]
I know that this is not at all practical and this method should never be used, but I was concerned with CAN I do this as opposed to SHOULD I ever do this.
You'll need to assign your lambda to an actual variable, and then call the lambda inside the lambda:
>>> g = lambda f: f if f < 2 else g(f-1)+g(f-2)
>>> [g(n) for n in range(10)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
I have a one-line solution that meets your criteria, but it is one of the most crazy codes I ever written. It doesn't use list comprehension, but it mixes dynamic solution and lambda function in one line.
fib = (lambda n: (lambda fib: fib(fib, [], n, None))(lambda fib, arr, i, _: arr if i == 0 else fib(fib, arr, i-1, arr.append(1) if len(arr) < 2 else arr.append(arr[-1]+arr[-2]))))
Just to explain it a bit. The first part (lambda fib: fib(fib, [], n, None)) take a lambda function as parameter and then call it with the parameters it expect. This trick allows us to assign a name to the lambda function and to pass this name to itself.. this is the magic.
Instead second part, the core function, lambda fib, arr, i, _: arr if i == 0 else fib(fib, arr, i-1, arr.append(1) if len(arr) < 2 else arr.append(arr[-1]+arr[-2]))) uses another trick to implement the dynamic solution. The first parameter fib is a reference to itself, the second parameter, arr, is the array containing our solution and it is filled from left to right calling recursively fib exactly n times. The recursion ends when the third parameter i becomes 0. The fourth parameter is an ugly trick: it is not used by the function, but it is used to call the append method of arr.
This is absolutely the less elegant solution, but it is also the fastest one. I report the timings for N=500 below.
The naive solution is unfeasible, but here you can find the code to compute one element at a time of the series (this is probably what you wanted to mix lambda function and recursion):
(lambda n: ((lambda fib: fib(fib,n+1))(lambda fib, i: (1 if i <= 2 else fib(fib,i-2) + fib(fib,i-1)))))(N)
Solution proposed by #cdlane:
%timeit [0, 1] + [(4<<n*(3+n)) // ((4<<2*n)-(2<<n)-1) & ((2<<n)-1) for n in range(N)][1:]
10 loops, best of 3: 88.3 ms per loop
Solution proposed by #lehiester:
%timeit [int(round((lambda n: ((1+5**0.5)**n-(1-5**0.5)**n)/(2**n*5**0.5))(x))) for x in range(N)]
1000 loops, best of 3: 1.49 ms per loop
My ugly solution:
%timeit (lambda n: (lambda fib: fib(fib, [], n, None))(lambda fib, arr, i, _: arr if i == 0 else fib(fib, arr, i-1, arr.append(1) if len(arr) < 2 else arr.append(arr[-1]+arr[-2]))))(N)
1000 loops, best of 3: 434 us per loop
Another ugly and faster solution which doesn't use the recursion:
%timeit (lambda n: (lambda arr, fib_supp: [arr] + [fib_supp(arr) for i in xrange(n)])([], (lambda arr: arr.append(1) if len(arr) < 2 else arr.append(arr[-1]+arr[-2])))[0])(N)
1000 loops, best of 3: 346 us per loop
UPDATE
Finally I found an elegant way to formulate the one-line function. The idea is always the same, but using the setitem method instead of the append. Some of the trick I used can be found at this link. This approach is just a bit slower, but at least is readable:
%timeit (lambda n: (lambda arr, fib_supp: any(fib_supp(i, arr) for i in xrange(2,n)) or arr)([1] * n, (lambda i, arr: arr.__setitem__(i,(arr[i-1]+arr[i-2])))))(N)
1000 loops, best of 3: 385 us per loop
How about:
(lambda f: (4 << f * (3 + f)) // ((4 << 2 * f) - (2 << f) - 1) & ((2 << f) - 1))(n)
It doesn't start the sequence in the usual way:
0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, ...
But once you get past 1, you're fine. You'll find a detailed explanation in the blog entry An integer formula for Fibonacci numbers along with lots of related information.
On my system, #lehiester's golden ratio based solution goes off the rails at F71, producing 308061521170130, instead of 308061521170129 and continues to deviate from there.
lambda calculus via Python
Since this is tagged with lambda-calculus, rather than write an answer that relies on clever tricks or language features that are specific to python, I'm only going to use simple lambdas
U = lambda f: f (f)
Y = U (lambda h: lambda f: f (lambda x: h (h) (f) (x)))
loop = Y (lambda recur: lambda acc: lambda a: lambda b: lambda n:
acc if n == 0 else
recur (acc + [a]) (a + b) (a) (n - 1))
fibonacci = loop ([]) (0) (1)
print (fibonacci (10))
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
Of course we used four named lambdas U, Y, loop, and fibonacci – because each lambda is a pure function, we can replace any reference to its name with its value
# in Y, replace U with its definition
Y = (lambda f: f (f)) (lambda h: lambda f: f (lambda x: h (h) (f) (x)))
# in loop, replace Y with its definition
loop = (lambda f: f (f)) (lambda h: lambda f: f (lambda x: h (h) (f) (x))) (lambda recur: lambda acc: lambda a: lambda b: lambda n:
acc if n == 0 else
recur (acc + [a]) (a + b) (a) (n - 1))
# in fibonacci, replace loop with its definition
fibonacci = (lambda f: f (f)) (lambda h: lambda f: f (lambda x: h (h) (f) (x))) (lambda recur: lambda acc: lambda a: lambda b: lambda n:
acc if n == 0 else
recur (acc + [a]) (a + b) (a) (n - 1)) ([]) (0) (1)
fibonacci is now a single, pure expression – we could call the lambda directly in the print statement...
# in print, replace fibonacci with its definition
print ((lambda f: f (f)) (lambda h: lambda f: f (lambda x: h (h) (f) (x))) (lambda recur: lambda acc: lambda a: lambda b: lambda n:
acc if n == 0 else
recur (acc + [a]) (a + b) (a) (n - 1)) ([]) (0) (1) (10))
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
once again, using another program
I wrote a very similar answer (also in Python) but in the context of a different program – it might be useful to help see the generality of the techniques
once again, in another language
We'll do the entire thing again only this time in JavaScript. JS is better suited for the demonstration this exercise because we can show the code working here in the browser and the lambda syntax is much more permissive (in terms of code formatting) – other than that, you'll notice the programs are almost identical
const U = f =>
f (f)
const Y =
U (h => f => f (x => h (h) (f) (x)))
const loop = Y (recur => acc => a => b => n =>
n === 0
? acc
: recur (acc.concat ([a])) (a + b) (a) (n - 1))
const fibonacci =
loop ([]) (0) (1)
console.log (fibonacci (10))
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
// in Y, replace U with its definition
Y = (f => f (f)) (h => f => f (x => h (h) (f) (x)))
// in loop, replace Y with its definition
loop = (f => f (f)) (h => f => f (x => h (h) (f) (x))) (recur => acc => a => b => n =>
n === 0
? acc
: recur (acc.concat ([a])) (a + b) (a) (n - 1))
// in fibonacci, replace loop with its definition
fibonacci = (f => f (f)) (h => f => f (x => h (h) (f) (x))) (recur => acc => a => b => n =>
n === 0
? acc
: recur (acc.concat ([a])) (a + b) (a) (n - 1)) ([]) (0) (1)
fibonacci is now a single, pure expression – we could call the lambda directly in the console.log statement...
oh and it's really fast, too
console.time ('fibonacci (500)')
console.log ((f => f (f)) (h => f => f (x => h (h) (f) (x))) (recur => acc => a => b => n =>
n === 0
? acc
: recur (acc.concat ([a])) (a + b) (a) (n - 1)) ([]) (0) (1) (500))
console.timeEnd ('fibonacci (500)')
// [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 490 more items ]
// fibonacci (500): 3 ms
practice makes perfect
The lambda calculus has been one of my favourite areas of study. With just the Y-combinator alone, I've spent countless hours exploring its beauty and sophistication. I hope you find these explorations helpful. If you have any other questions on the subject matter, don't be shy to ask ^_^
You have to somehow assign a name to it in order to use a recursive definition--otherwise a recursive lambda function is impossible in Python since it doesn't have any special reflexive keyword that refers to it.
As #TerryA mentioned, you could use the trick in this post in order to generate a sequence of x Fibonacci numbers in one statement with the recursive definition.
Or, you could use the closed form, which would be much faster:
[int(round((lambda n: ((1+5**0.5)**n-(1-5**0.5)**n)/(2**n*5**0.5))(x)))
for x in range(10)]
This assumes that x is not very large, though, because the float arithmetic will overflow around x=600 and will probably have large rounding errors before that point--as #cdlane points out, this starts diverging from the actual sequence at x=71, i.e. x in range(72).
EDIT: #cdlane shared a closed form with only integer arithmetic, which should work for any x in theory. I would probably use this one instead of the expression above.
[0, 1] + [(4<<n*(3+n)) // ((4<<2*n)-(2<<n)-1) & ((2<<n)-1)
for n in range(10)][1:]

Python: how to create many constraints for fmin_cobyla optimization using lambda functions

I have a vector of a few hundred numerical entries (like this: Xo = [x1, y1, x2, y2,..., xN, yN]) where N is an arbitrary number. I need to pass this vector to the scipy fmin_cobyla optimizer with simple simple constraints on each of the entries:
1. All of the x's (ie. x1, x2, ..., xN) are such that -1
I've tried to use lambda functions to specify the constraints like this
b0 = lambda Xo: 1 - Xo[n]
b1 = lambda Xo: Xo[n] + 1
however I am completely unsure of how to pass in the proper index n. I want all the even n to be subject to b0 and b1 but all the odd n to be subject to b2 and b3
b2 = lambda Xo: 2 - Xo[n]
b3 = lambda Xo: Xo[n] + 2
I may need to use consargs in fmin_cobyla. Any help would be much appreciated.
Do the constraints need to be continuous? If not, here's a simple way to do it with one function. It will return 1 if the constraints are met, and -1 if they're not:
def checkall(xs):
for j, x in enumerate(xs):
if abs(x) > (2 if j % 2 else 1):
return -1
return 1
cons = (checkall,)
If you need continuous constraints, there are many ways to do it. Here's one with 2N linear functions, N for the positive constraint, and N for the negative constraints.
def checkpos(j):
if j % 2:
return lambda xs: 2 - xs[j]
else:
return lambda xs: 1 - xs[j]
def checkneg(j):
if j % 2:
return lambda xs: 2 + xs[j]
else:
return lambda xs: 1 + xs[j]
cons = [checkpos(j) for j in range(N)] + [checkneg(j) for j in range(N)]
try this
even = lambda x: (x < 1 and x > -1)
odd = lambda x: (x < 2 and x > -2)
constraint = lambda index: (index % 2) and odd or even
filtered = [x for index, x in enumerate(Xo) if constraint(index)(x)]
Honestly, I have no idea what fmin_cobyla, but this is another try after reading David's comment
even = lambda n: ((lambda x: 1 - x[n]), (lambda x: x[n] + 1))
odd = lambda n: ((lambda x: 2 - x[n]), (lambda x: 2 - x[n]))
constraint = lambda n: (n % 2) and odd(n) or even(n)
constraint_list = sum([constraint(i) for i in range(2 * N)], ())

U combinator on a fibonacci : how would you translate this code to python?

I am trying to learn about combinators and I am having trouble understand the example given at (Y overriding self-application). I think I am beginning to grasp the concept but I am still far from understanding.
I would like to translate the following code to Python:
(define (U f) (f f))
(define (fib-nr f)
(lambda (n)
(if (< n 2) 1 (+ ((f f) (- n 1)) ((f f) (- n 2))))))
# Usage:
((U fib-nr) 35) ;==> 14930352
I tried a 'literal' translation by writing:
U = lambda u: u(u)
def fibnr(f):
return lambda n: 1 if (n<2) else (f (f (n-1))) + (f (f (n-2)))
But this doesnt work (I think it has to do with the order the functions are evaluated inside the lambda).
So I tried to use function composition as:
# http://code.activestate.com/recipes/52902-function-composition/
class compose:
'''compose functions. compose(f,g,x...)(y...) = f(g(y...),x...))'''
def __init__(self, f, g, *args, **kwargs):
self.f = f
self.g = g
self.pending = args[:]
self.kwargs = kwargs.copy()
def __call__(self, *args, **kwargs):
return self.f(self.g(*args, **kwargs), *self.pending, **self.kwargs)
U = lambda u: compose(u, u)
def fibnr(f):
ff = compose(f, f)
return lambda n: 1 if (n<2) else (ff (n-1)) + (ff (n-2))
But still didn't work, when calling my last snippet of code I get a lambda back:
>>> U(fibnr)(35)
<function <lambda> at 0x01A1B6B0>
So, is it possible to write a 'literal' translation of the given example in Python? How could I do it?
I wrote a simple translation that seems to produce correct results:
def U(f): return f(f)
def fibnr(f):
def lam(n):
if (n < 2): return 1
return f(f)(n-1) + f(f)(n-2)
return lam
Or if you really like lambdas:
def fibnr(f): return lambda n: 1 if (n < 2) else f(f)(n-1) + f(f)(n-2)
I think your initial problem was translating Lisp ((f f) x) into Python f(f(x)) instead of f(f)(x).
Good luck understanding combinators :)

Can a lambda function call itself recursively in Python?

A regular function can contain a call to itself in its definition, no problem. I can't figure out how to do it with a lambda function though for the simple reason that the lambda function has no name to refer back to. Is there a way to do it? How?
The only way I can think of to do this amounts to giving the function a name:
fact = lambda x: 1 if x == 0 else x * fact(x-1)
or alternately, for earlier versions of python:
fact = lambda x: x == 0 and 1 or x * fact(x-1)
Update: using the ideas from the other answers, I was able to wedge the factorial function into a single unnamed lambda:
>>> map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), range(10))
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
So it's possible, but not really recommended!
without reduce, map, named lambdas or python internals:
(lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10)
Contrary to what sth said, you CAN directly do this.
(lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))(n)
The first part is the fixed-point combinator Y that facilitates recursion in lambda calculus
Y = (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))
the second part is the factorial function fact defined recursively
fact = (lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))
Y is applied to fact to form another lambda expression
F = Y(fact)
which is applied to the third part, n, which evaulates to the nth factorial
>>> n = 5
>>> F(n)
120
or equivalently
>>> (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))(5)
120
If however you prefer fibs to facts you can do that too using the same combinator
>>> (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: f(i - 1) + f(i - 2) if i > 1 else 1))(5)
8
You can't directly do it, because it has no name. But with a helper function like the Y-combinator Lemmy pointed to, you can create recursion by passing the function as a parameter to itself (as strange as that sounds):
# helper function
def recursive(f, *p, **kw):
return f(f, *p, **kw)
def fib(n):
# The rec parameter will be the lambda function itself
return recursive((lambda rec, n: rec(rec, n-1) + rec(rec, n-2) if n>1 else 1), n)
# using map since we already started to do black functional programming magic
print map(fib, range(10))
This prints the first ten Fibonacci numbers: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55],
Yes. I have two ways to do it, and one was already covered. This is my preferred way.
(lambda v: (lambda n: n * __import__('types').FunctionType(
__import__('inspect').stack()[0][0].f_code,
dict(__import__=__import__, dict=dict)
)(n - 1) if n > 1 else 1)(v))(5)
This answer is pretty basic. It is a little simpler than Hugo Walter's answer:
>>> (lambda f: f(f))(lambda f, i=0: (i < 10)and f(f, i + 1)or i)
10
>>>
Hugo Walter's answer:
(lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10)
We can now use new python syntax to make it way shorter and easier to read:
Fibonacci:
>>> (f:=lambda x: 1 if x <= 1 else f(x - 1) + f(x - 2))(5)
8
Factorial:
>>> (f:=lambda x: 1 if x == 0 else x*f(x - 1))(5)
120
We use := to name the lambda: use the name directly in the lambda itself and call it right away as an anonymous function.
(see https://www.python.org/dev/peps/pep-0572)
def recursive(def_fun):
def wrapper(*p, **kw):
fi = lambda *p, **kw: def_fun(fi, *p, **kw)
return def_fun(fi, *p, **kw)
return wrapper
factorial = recursive(lambda f, n: 1 if n < 2 else n * f(n - 1))
print(factorial(10))
fibonaci = recursive(lambda f, n: f(n - 1) + f(n - 2) if n > 1 else 1)
print(fibonaci(10))
Hope it would be helpful to someone.
By the way, instead of slow calculation of Fibonacci:
f = lambda x: 1 if x in (1,2) else f(x-1)+f(x-2)
I suggest fast calculation of Fibonacci:
fib = lambda n, pp=1, pn=1, c=1: pp if c > n else fib(n, pn, pn+pp, c+1)
It works really fast.
Also here is factorial calculation:
fact = lambda n, p=1, c=1: p if c > n else fact(n, p*c, c+1)
Well, not exactly pure lambda recursion, but it's applicable in places, where you can only use lambdas, e.g. reduce, map and list comprehensions, or other lambdas. The trick is to benefit from list comprehension and Python's name scope. The following example traverses the dictionary by the given chain of keys.
>>> data = {'John': {'age': 33}, 'Kate': {'age': 32}}
>>> [fn(data, ['John', 'age']) for fn in [lambda d, keys: None if d is None or type(d) is not dict or len(keys) < 1 or keys[0] not in d else (d[keys[0]] if len(keys) == 1 else fn(d[keys[0]], keys[1:]))]][0]
33
The lambda reuses its name defined in the list comprehension expression (fn). The example is rather complicated, but it shows the concept.
Short answer
Z = lambda f : (lambda x : f(lambda v : x(x)(v)))(lambda x : f(lambda v : x(x)(v)))
fact = Z(lambda f : lambda n : 1 if n == 0 else n * f(n - 1))
print(fact(5))
Edited: 04/24/2022
Explanation
For this we can use Fixed-point combinators, specifically Z combinator, because it will work in strict languages, also called eager languages:
const Z = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)))
Define fact function and modify it:
1. const fact n = n === 0 ? 1 : n * fact(n - 1)
2. const fact = n => n === 0 ? 1 : n * fact(n - 1)
3. const _fact = (fact => n => n === 0 ? 1 : n * fact(n - 1))
Notice that:
fact === Z(_fact)
And use it:
const Z = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)));
const _fact = f => n => n === 0 ? 1 : n * f(n - 1);
const fact = Z(_fact);
console.log(fact(5)); //120
See also:
Fixed-point combinators in JavaScript: Memoizing recursive functions
I got some homework about it and figured out something, heres an example of a lambda function with recursive calls:
sucesor = lambda n,f,x: (f)(x) if n == 0 else sucesor(n-1,f,(f)(x))
I know this is an old thread, but it ranks high on some google search results :). With the arrival of python 3.8 you can use the walrus operator to implement a Y-combinator with less syntax!
fib = (lambda f: (rec := lambda args: f(rec, args)))\
(lambda f, n: n if n <= 1 else f(n-2) + f(n-1))
As simple as:
fac = lambda n: 1 if n <= 1 else n*fac(n-1)
Lambda can easily replace recursive functions in Python:
For example, this basic compound_interest:
def interest(amount, rate, period):
if period == 0:
return amount
else:
return interest(amount * rate, rate, period - 1)
can be replaced by:
lambda_interest = lambda a,r,p: a if p == 0 else lambda_interest(a * r, r, p - 1)
or for more visibility :
lambda_interest = lambda amount, rate, period: \
amount if period == 0 else \
lambda_interest(amount * rate, rate, period - 1)
USAGE:
print(interest(10000, 1.1, 3))
print(lambda_interest(10000, 1.1, 3))
Output:
13310.0
13310.0
If you were truly masochistic, you might be able to do it using C extensions, but this exceeds the capability of a lambda (unnamed, anonymous) functon.
No. (for most values of no).

Categories