Skip to content

Commit d9c2561

Browse files
committed
Add explanation to recursive lambdas notebook
1 parent b21d90c commit d9c2561

1 file changed

Lines changed: 114 additions & 81 deletions

File tree

source_code/recursive_lambdas.ipynb

Lines changed: 114 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,165 +1,198 @@
11
{
22
"cells": [
33
{
4-
"cell_type": "code",
5-
"execution_count": 2,
6-
"id": "930ec69a-d8d3-44af-8de9-967fe18b2a5d",
4+
"cell_type": "markdown",
5+
"id": "7993cc74-47c2-4064-a5f2-145bd3248638",
76
"metadata": {},
8-
"outputs": [],
97
"source": [
10-
"from typing import Callable, TypeAlias"
8+
"Although it may seem impossible at first, it is in fact possible to define a recursive function using lambda functions."
9+
]
10+
},
11+
{
12+
"cell_type": "markdown",
13+
"id": "6191e0ce-e3fe-41d6-8e67-e51315fb13a1",
14+
"metadata": {},
15+
"source": [
16+
"The first step is to define a function that takes a parameter that is a callable, and applies it to itself.\n",
17+
"```\n",
18+
" lambda f: f(f)\n",
19+
"```"
1120
]
1221
},
1322
{
1423
"cell_type": "code",
15-
"execution_count": 4,
16-
"id": "4c399a58-f64b-4e66-9d78-6b2470bb1aaf",
24+
"execution_count": 1,
25+
"id": "ecb5c7d3-d2c3-4751-9bc0-a3d6701ba653",
1726
"metadata": {},
18-
"outputs": [],
27+
"outputs": [
28+
{
29+
"name": "stdout",
30+
"output_type": "stream",
31+
"text": [
32+
"<built-in function print>\n"
33+
]
34+
}
35+
],
1936
"source": [
20-
"IntFunc: TypeAlias = Callable[(int, ), int]"
37+
"(lambda f: f(f))(print)"
2138
]
2239
},
2340
{
2441
"cell_type": "markdown",
25-
"id": "7993cc74-47c2-4064-a5f2-145bd3248638",
42+
"id": "531b2bb7-b9b9-4ec3-8979-bd04097107ab",
2643
"metadata": {},
2744
"source": [
28-
"Although it may seem impossible at first, it is in fact possible to define a recursive function using lambda functions."
45+
"In the example above, the lambda function is called with the `print` function as a parameter, hence that function will be applied to itself."
46+
]
47+
},
48+
{
49+
"cell_type": "code",
50+
"execution_count": 2,
51+
"id": "b0a5e592-6382-4bbd-a262-6b4202961079",
52+
"metadata": {},
53+
"outputs": [
54+
{
55+
"name": "stdout",
56+
"output_type": "stream",
57+
"text": [
58+
"<built-in function print>\n"
59+
]
60+
}
61+
],
62+
"source": [
63+
"print(print)"
2964
]
3065
},
3166
{
3267
"cell_type": "markdown",
3368
"id": "b09f4ae1-4ea3-4257-abf7-1b830ab8593c",
3469
"metadata": {},
3570
"source": [
36-
"The first step is to define a function that takes a parameter that is a callable, and applies it to itself.\n",
37-
"```\n",
38-
" lambda f: f(f)\n",
39-
"```\n",
4071
"The second step is to define a lambda function that takes a single `int` parameter and computes the factorial of that integer. Hwever, it uses a function `F` that is provided from context.\n",
4172
"```\n",
4273
" lambda n: 1 if n == 0 else n*F(F)(n - 1)\n",
4374
"```\n",
44-
"This function `F` is a function that takes an integer as "
75+
"This function `F` is a function that takes a function as an argument. When that function `F` is applied to itself, it returns an `int`, possibly only after multiple recursive calls."
4576
]
4677
},
4778
{
4879
"cell_type": "code",
49-
"execution_count": null,
50-
"id": "18509fdb-7d14-4bd4-aa55-f6538ebb5f66",
51-
"metadata": {},
52-
"outputs": [],
53-
"source": []
54-
},
55-
{
56-
"cell_type": "code",
57-
"execution_count": 5,
80+
"execution_count": 3,
5881
"id": "5f8686ba-d202-4af1-992c-80dad5245fc5",
5982
"metadata": {},
6083
"outputs": [
6184
{
62-
"data": {
63-
"text/plain": [
64-
"120"
65-
]
66-
},
67-
"execution_count": 5,
68-
"metadata": {},
69-
"output_type": "execute_result"
85+
"name": "stdout",
86+
"output_type": "stream",
87+
"text": [
88+
"1\n",
89+
"1\n",
90+
"2\n",
91+
"6\n",
92+
"24\n",
93+
"120\n"
94+
]
7095
}
7196
],
7297
"source": [
73-
"(lambda f: f(f)) (lambda F: lambda n: 1 if n == 0 else n*F(F)(n - 1))(5)"
98+
"for i in range(6):\n",
99+
" print((lambda f: f(f)) (lambda F: lambda n: 1 if n == 0 else n*F(F)(n - 1))(i))"
74100
]
75101
},
76102
{
77-
"cell_type": "code",
78-
"execution_count": 8,
79-
"id": "9f501593-4fc9-4da5-b3c3-5df4ae8631e5",
103+
"cell_type": "markdown",
104+
"id": "06fbb197-1a9f-458c-a7a6-ab27087e9d71",
80105
"metadata": {},
81-
"outputs": [],
82106
"source": [
83-
"b = (lambda F: F(F)) (lambda f: lambda n: 1 if n == 0 else n*f(f)(n - 1))"
107+
"Another example of a function that can be implemented recursively is the Fibonnaci function."
84108
]
85109
},
86110
{
87111
"cell_type": "code",
88-
"execution_count": 15,
89-
"id": "e800cc8e-7b3e-4477-a8bf-8266fa9dc0a6",
112+
"execution_count": 4,
113+
"id": "f65726d6-7f4f-45aa-ad0e-92fd0eb26309",
90114
"metadata": {},
91115
"outputs": [
92116
{
93-
"data": {
94-
"text/plain": [
95-
"120"
96-
]
97-
},
98-
"execution_count": 15,
99-
"metadata": {},
100-
"output_type": "execute_result"
117+
"name": "stdout",
118+
"output_type": "stream",
119+
"text": [
120+
"1\n",
121+
"1\n",
122+
"2\n",
123+
"3\n",
124+
"5\n",
125+
"8\n",
126+
"13\n",
127+
"21\n",
128+
"34\n",
129+
"55\n",
130+
"89\n"
131+
]
101132
}
102133
],
103134
"source": [
104-
"b(5)"
135+
"for i in range(11):\n",
136+
" print((lambda f: f(f))(lambda F: lambda n: 1 if n <= 1 else F(F)(n - 1) + F(F)(n - 2))(i))"
105137
]
106138
},
107139
{
108140
"cell_type": "code",
109-
"execution_count": 16,
110-
"id": "269c9ad8-b5c2-4465-b14d-8ba38325b3ac",
141+
"execution_count": 5,
142+
"id": "ac699583-0a52-449e-a1ba-7ee5e664eb29",
111143
"metadata": {},
112-
"outputs": [],
144+
"outputs": [
145+
{
146+
"name": "stdout",
147+
"output_type": "stream",
148+
"text": [
149+
"4.31 ms ± 431 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
150+
]
151+
}
152+
],
113153
"source": [
114-
"F = lambda f: lambda n: 1 if n == 0 else n*f(f)(n - 1)"
154+
"%timeit (lambda f: f(f))(lambda F: lambda n: 1 if n <= 1 else F(F)(n - 1) + F(F)(n - 2))(20)"
115155
]
116156
},
117157
{
118158
"cell_type": "code",
119-
"execution_count": 17,
120-
"id": "9346d8d1-d5b4-4a1d-9c10-fefd96dc80b0",
159+
"execution_count": 6,
160+
"id": "884b2dfe-dad6-4e73-93fd-9f8dca2998b2",
121161
"metadata": {},
122162
"outputs": [],
123163
"source": [
124-
"b = F(F)"
164+
"def fib(n: int) -> int:\n",
165+
" if n < 2:\n",
166+
" return 1\n",
167+
" else:\n",
168+
" return fib(n - 1) + fib(n - 2)"
125169
]
126170
},
127171
{
128172
"cell_type": "code",
129-
"execution_count": null,
130-
"id": "a65c680c-0f50-461d-b992-e84176b82729",
131-
"metadata": {},
132-
"outputs": [],
133-
"source": []
134-
},
135-
{
136-
"cell_type": "code",
137-
"execution_count": 18,
138-
"id": "2a9ee0a7-85e2-400f-81cc-e05bccde8dd3",
173+
"execution_count": 7,
174+
"id": "6ff8db37-91c4-4c52-8be4-6529e6b818cb",
139175
"metadata": {},
140176
"outputs": [
141177
{
142-
"data": {
143-
"text/plain": [
144-
"120"
145-
]
146-
},
147-
"execution_count": 18,
148-
"metadata": {},
149-
"output_type": "execute_result"
178+
"name": "stdout",
179+
"output_type": "stream",
180+
"text": [
181+
"1.15 ms ± 81.1 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n"
182+
]
150183
}
151184
],
152185
"source": [
153-
"b(5)"
186+
"%timeit fib(20)"
154187
]
155188
},
156189
{
157-
"cell_type": "code",
158-
"execution_count": null,
159-
"id": "f65726d6-7f4f-45aa-ad0e-92fd0eb26309",
190+
"cell_type": "markdown",
191+
"id": "6dcc5b52-b40f-4d48-8f39-362f8e3544f3",
160192
"metadata": {},
161-
"outputs": [],
162-
"source": []
193+
"source": [
194+
"It is clear that the non-lambda recursive implementation is significantly faster, so recursion with lambda functions is merely a curiosity to test your understanding of Python."
195+
]
163196
}
164197
],
165198
"metadata": {

0 commit comments

Comments
 (0)