-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathClosures.html
More file actions
590 lines (545 loc) · 51.7 KB
/
Closures.html
File metadata and controls
590 lines (545 loc) · 51.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Closures and Function Currying — Programming in Python 7.0 documentation</title>
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
<script src="../_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="lambda and keyword Magic" href="../exercises/lambda_magic.html" />
<link rel="prev" title="IPython Parallel Quickstart" href="IPythonParallel.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" style="background: #4b2e83" >
<a href="../index.html">
<img src="../_static/UWPCE_logo_full.png" class="logo" alt="Logo"/>
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Topics in the Program</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../topics/01-setting_up/index.html">1. Setting up your Environment</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/02-basic_python/index.html">2. Basic Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/03-recursion_booleans/index.html">3. Booleans and Recursion</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/04-sequences_iteration/index.html">4. Sequences and Iteration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/05-text_handling/index.html">5. Basic Text Handling</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/06-exceptions/index.html">6. Exception Handling</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/07-unit_testing/index.html">7. Unit Testing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/08-dicts_sets/index.html">8. Dictionaries and Sets</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/09-files/index.html">9. File Handling</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/10-modules_packages/index.html">10. Modules and Packages</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/11-argument_passing/index.html">11. Advanced Argument Passing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/12-comprehensions/index.html">12. Comprehensions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/13-intro_oo/index.html">13. Intro to Object Oriented Programing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/14-magic_methods/index.html">14. Properties and Magic Methods</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/15-subclassing/index.html">15. Subclassing and Inheritance</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/16-multiple_inheritance/index.html">16. Multiple Inheritance</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../topics/17-functional_programming/index.html">17. Introduction to Functional Programming</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="OO_vs_functional.html">Object Oriented vs Functional Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="Lambda.html">Anonymous Functions: Lambda</a></li>
<li class="toctree-l2"><a class="reference internal" href="MapFilterReduce.html">Map Filter and Reduce</a></li>
<li class="toctree-l2"><a class="reference internal" href="IPythonParallel.html">IPython Parallel Quickstart</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Closures and Function Currying</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exercises/lambda_magic.html">lambda and keyword Magic</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exercises/trapezoid.html">Trapezoidal Rule</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../topics/18-advanced_testing/index.html">18. Advanced Testing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topics/99-extras/index.html">19. Extra Topics</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" style="background: #4b2e83" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">Programming in Python</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content style-external-links">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home"></a> »</li>
<li><a href="../topics/17-functional_programming/index.html"><span class="section-number">17. </span>Introduction to Functional Programming</a> »</li>
<li>Closures and Function Currying</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/modules/Closures.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul><div class="rst-breadcrumbs-buttons" role="navigation" aria-label="Sequential page navigation">
<a href="IPythonParallel.html" class="btn btn-neutral float-left" title="IPython Parallel Quickstart" accesskey="p"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="../exercises/lambda_magic.html" class="btn btn-neutral float-right" title="lambda and keyword Magic" accesskey="n">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="closures-and-function-currying">
<span id="closures"></span><h1>Closures and Function Currying<a class="headerlink" href="#closures-and-function-currying" title="Permalink to this headline"></a></h1>
<p>Defining specialized functions on the fly.</p>
<p>A “Closure” is a fancy CS term that can be very hard to understand. Partly because they are expressed a little differently in every computer language that supports them But this is easiest definition I could find:</p>
<blockquote>
<div><p>Closure is when a function “remembers” its lexical scope even when the function is executed outside that lexical scope</p>
</div></blockquote>
<p>This definition is provided by Kyle Simpson
(by way of <a class="reference external" href="https://medium.com/beginners-guide-to-mobile-web-development/closures-in-functional-programming-and-javascript-3ed730e08fc2">an article about closures in Javascript</a>).</p>
<p>The basic idea behind the concept of a closure lies in the understanding of the fact that closure is a mechanism by which an inner function will have access to the variables defined in its outer function’s lexical scope even after the outer function has returned.</p>
<p>Which brings us to the key practical part of how this works in Python:</p>
<div class="section" id="scope">
<h2>Scope<a class="headerlink" href="#scope" title="Permalink to this headline"></a></h2>
<p>In order to get a handle on all this, it’s important to understand variable scoping rules in Python.</p>
<p>“Scope” is the word for <cite>where</cite> the names in your code are accessible. Another word for a scope is namespace.</p>
<div class="section" id="global-scope">
<h3>Global Scope<a class="headerlink" href="#global-scope" title="Permalink to this headline"></a></h3>
<p>The simplest is the global scope. This is where all the names defined right in your code file (module) are. When running in an interactive interpreter, it is in the global namespace as well.</p>
<p>You can get the global namespace with the <code class="docutils literal notranslate"><span class="pre">globals()</span></code> function, but …</p>
<p>The Python interpreter defines a handful of names when it starts up, and iPython defines a whole bunch more.
Recall that a convention in Python is that names that start with an underscore are “special” in some way – double underscore names have a special meaning to Python, and single underscore names are considered “private”.
Most of the extra names defined by the Python interpreter or iPython that are designed for internal use start with an underscore. These can really “clutter up” the namespace, but they can be filtered out for a more reasonable result:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">print_globals</span><span class="p">():</span>
<span class="n">ipy_names</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'In'</span><span class="p">,</span> <span class="s1">'Out'</span><span class="p">,</span> <span class="s1">'get_ipython'</span><span class="p">,</span> <span class="s1">'exit'</span><span class="p">,</span> <span class="s1">'quit'</span><span class="p">]</span>
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"_"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">ipy_names</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
</pre></div>
</div>
<p>Try running that in a newly started interpreter:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [3]: </span> <span class="k">def</span> <span class="nf">print_globals</span><span class="p">():</span>
<span class="gp"> ...: </span> <span class="n">ipy_names</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'In'</span><span class="p">,</span> <span class="s1">'Out'</span><span class="p">,</span> <span class="s1">'get_ipython'</span><span class="p">,</span> <span class="s1">'exit'</span><span class="p">,</span> <span class="s1">'quit'</span><span class="p">]</span>
<span class="gp"> ...: </span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
<span class="gp"> ...: </span> <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"_"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">ipy_names</span><span class="p">):</span>
<span class="gp"> ...: </span> <span class="nb">print</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="gp"> ...:</span>
<span class="gp">In [4]: </span><span class="n">print_globals</span><span class="p">()</span>
<span class="go">print_globals</span>
</pre></div>
</div>
<p>The only name left is “print_globals” itself – created when we defined the function.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Try running <code class="docutils literal notranslate"><span class="pre">globals()</span></code> by itself to see all the cruft iPython adds. Also note that <code class="docutils literal notranslate"><span class="pre">globals</span></code> returns not just the names, but a dictionary, where the keys are the names, and the items are the values bound to those names.</p>
</div>
<p>If we add a name or two, they show up in the global scope:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [6]: </span><span class="n">x</span> <span class="o">=</span> <span class="mi">5</span>
<span class="gp">In [7]: </span><span class="n">this</span> <span class="o">=</span> <span class="s2">"that"</span>
<span class="gp">In [8]: </span><span class="n">print_globals</span><span class="p">()</span>
<span class="go">print_globals</span>
<span class="go">x</span>
<span class="go">this</span>
</pre></div>
</div>
<p>names are created by assignment, and by <code class="docutils literal notranslate"><span class="pre">def</span></code> and <code class="docutils literal notranslate"><span class="pre">class</span></code> statements. We already saw a <code class="docutils literal notranslate"><span class="pre">def</span></code>, here is a <code class="docutils literal notranslate"><span class="pre">class</span></code> definition.</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [11]: </span><span class="k">class</span> <span class="nc">TestClass</span><span class="p">:</span>
<span class="go"> ...: pass</span>
<span class="go"> ...:</span>
<span class="gp">In [12]: </span><span class="n">print_globals</span><span class="p">()</span>
<span class="go">print_globals</span>
<span class="go">x</span>
<span class="go">this</span>
<span class="go">test</span>
<span class="go">TestClass</span>
</pre></div>
</div>
<p>Always keep in mind that in Python, “global” means “global to the module”, <em>not</em> global to the entire program. In the case of the interactive interpreter, the module is the “__main__” module (remember <code class="docutils literal notranslate"><span class="pre">if</span> <span class="pre">__name__</span> <span class="pre">==</span> <span class="pre">__main__:</span></code>?). But in a particular python file (usually one file is one module), the global scope is global to that one file.</p>
</div>
<div class="section" id="local-scope">
<h3>Local Scope<a class="headerlink" href="#local-scope" title="Permalink to this headline"></a></h3>
<p>So that’s the global scope – what creates a new scope?</p>
<p>A new, “local” scope is created by a function or class definition:</p>
<p>There is a built-in function to get the names in the local scope, too, so we can use it to show us the names in a function’s local namespace. There isn’t a lot of cruft in the local namespace, so we don’t need a special function to print it.</p>
<p>Note that <code class="docutils literal notranslate"><span class="pre">locals()</span></code> and <code class="docutils literal notranslate"><span class="pre">globals()</span></code> returns a dict of the names and the objects they are bound to, so we can print the keys to get the names:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [15]: </span><span class="k">def</span> <span class="nf">test</span><span class="p">():</span>
<span class="go">...: x = 5</span>
<span class="go">...: y = 6</span>
<span class="go">...: print(locals().keys())</span>
<span class="go">...:</span>
<span class="gp">In [16]: </span><span class="n">test</span><span class="p">()</span>
<span class="go">dict_keys(['y', 'x'])</span>
</pre></div>
</div>
<p>When a function is called, it creates a clean local namespace.</p>
<p>Similarly a class definition does the same thing:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [18]: </span><span class="k">class</span> <span class="nc">Test</span><span class="p">:</span>
<span class="go"> ...: this = "that"</span>
<span class="go"> ...: z = 54</span>
<span class="go"> ...: def __init__(self):</span>
<span class="go"> ...: pass</span>
<span class="go"> ...: print(locals().keys())</span>
<span class="go"> ...:</span>
<span class="go">dict_keys(['__module__', '__qualname__', 'this', 'z', '__init__'])</span>
</pre></div>
</div>
<p>Interesting – that print statement ran when the class was defined…</p>
<p>But you see that class attributes are there, as is the <code class="docutils literal notranslate"><span class="pre">__init__</span></code> function.</p>
<p>So each function gets a local namespace (or scope), and so does each class. And it follows that each method (function) in the class gets its own namespace as well.</p>
<p>Turns out that this holds true for functions defined within functions also:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [23]: </span><span class="k">def</span> <span class="nf">outer</span><span class="p">():</span>
<span class="go"> ...: x = 5</span>
<span class="go"> ...: y = 6</span>
<span class="go"> ...: def inner():</span>
<span class="go"> ...: w = 7</span>
<span class="go"> ...: z = 8</span>
<span class="go"> ...: print("inner scope:", locals().keys())</span>
<span class="go"> ...: print("outer scope:", locals().keys())</span>
<span class="go"> ...: inner()</span>
<span class="gp">In [24]: </span><span class="n">outer</span><span class="p">()</span>
<span class="go">outer scope: dict_keys(['inner', 'y', 'x'])</span>
<span class="go">inner scope: dict_keys(['z', 'w'])</span>
</pre></div>
</div>
</div>
<div class="section" id="function-parameters">
<h3>Function Parameters<a class="headerlink" href="#function-parameters" title="Permalink to this headline"></a></h3>
<p>The other way you can define names in a function’s local namespace is with function parameters:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [14]: </span><span class="k">def</span> <span class="nf">fun_with_parameters</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="go"> ...: print("local names are:", locals().keys())</span>
<span class="go"> ...:</span>
<span class="go"> ...:</span>
<span class="gp">In [15]: </span><span class="n">fun_with_parameters</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="go">local names are: dict_keys(['a', 'b'])</span>
</pre></div>
</div>
<p>Notice that no other names have been defined in the function, but both of the parameters (positional and keyword) are local names.</p>
</div>
<div class="section" id="finding-names">
<h3>Finding Names<a class="headerlink" href="#finding-names" title="Permalink to this headline"></a></h3>
<p>At any point, there are multiple scopes in play: the local scope, and all the surrounding scopes.
When you use a name, python checks in the local scope first, then moves out one by one until it finds the name.
If you define a new name inside a function, it “overrides” the name in any of the outer scopes.
But any names not defined in an inner scope will be found by looking in the enclosing scopes.</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [33]: </span><span class="n">name1</span> <span class="o">=</span> <span class="s2">"this is global"</span>
<span class="gp">In [34]: </span><span class="n">name2</span> <span class="o">=</span> <span class="s2">"this is global"</span>
<span class="gp">In [35]: </span><span class="k">def</span> <span class="nf">outer</span><span class="p">():</span>
<span class="go"> ...: name2 = "this is in outer"</span>
<span class="go"> ...: def inner():</span>
<span class="go"> ...: name3 = "this is in inner"</span>
<span class="go"> ...: print(name1)</span>
<span class="go"> ...: print(name2)</span>
<span class="go"> ...: print(name3)</span>
<span class="go"> ...: inner()</span>
<span class="go"> ...:</span>
<span class="gp">In [36]: </span><span class="n">outer</span><span class="p">()</span>
<span class="go">this is global</span>
<span class="go">this is in outer</span>
<span class="go">this is in inner</span>
</pre></div>
</div>
<p>Look carefully to see where each of those names came from. All the print statements are in the inner function, so its local scope is searched first, and then the outer function’s scope, and then the global scope. <code class="docutils literal notranslate"><span class="pre">name1</span></code> is only defined in the global scope, so that one is found. but <code class="docutils literal notranslate"><span class="pre">name2</span></code> is redfined in the scope of the <code class="docutils literal notranslate"><span class="pre">outer</span></code> function, so that one is found. And <code class="docutils literal notranslate"><span class="pre">name3</span></code> is only defined in the <code class="docutils literal notranslate"><span class="pre">inner</span></code> function scope.</p>
</div>
<div class="section" id="the-global-keyword">
<h3>The <code class="docutils literal notranslate"><span class="pre">global</span></code> keyword<a class="headerlink" href="#the-global-keyword" title="Permalink to this headline"></a></h3>
<p>Global names can be accessed from within functions, but not if that same name is created in the local scope. So you can’t change an immutable object that is outside the local scope:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [37]: </span><span class="n">x</span> <span class="o">=</span> <span class="mi">5</span>
<span class="gp">In [38]: </span><span class="k">def</span> <span class="nf">increment_x</span><span class="p">():</span>
<span class="go"> ...: x += 5</span>
<span class="go"> ...:</span>
<span class="gp">In [39]: </span><span class="n">increment_x</span><span class="p">()</span>
<span class="gt">---------------------------------------------------------------------------</span>
<span class="ne">UnboundLocalError</span><span class="g g-Whitespace"> </span>Traceback (most recent call last)
<span class="nn"><ipython-input-39-c9a57e8c0d14></span> in <span class="ni"><module></span><span class="nt">()</span>
<span class="ne">----> </span><span class="mi">1</span> <span class="n">increment_x</span><span class="p">()</span>
<span class="nn"><ipython-input-38-dc4f30fe2ac4></span> in <span class="ni">increment_x</span><span class="nt">()</span>
<span class="g g-Whitespace"> </span><span class="mi">1</span> <span class="k">def</span> <span class="nf">increment_x</span><span class="p">():</span>
<span class="ne">----> </span><span class="mi">2</span> <span class="n">x</span> <span class="o">+=</span> <span class="mi">5</span>
<span class="g g-Whitespace"> </span><span class="mi">3</span>
<span class="ne">UnboundLocalError</span>: local variable 'x' referenced before assignment
</pre></div>
</div>
<p>The problem here is that <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">+=</span> <span class="pre">5</span></code> is the same as <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">5</span></code>, so it is creating a local name, but it can’t be incremented, because it hasn’t had a value set yet.</p>
<p>How does the interpreter know that <code class="docutils literal notranslate"><span class="pre">x</span></code> is a local name? When it compiles the function definition, it marks all the names assigned in the function as local. So when the function runs, it knows that <code class="docutils literal notranslate"><span class="pre">x</span></code> is local, and thus it won’t go look in the global scope for it.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">global</span></code> keyword tells python that you want to use the global name, rather than create a new, local name:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [40]: </span><span class="k">def</span> <span class="nf">increment_x</span><span class="p">():</span>
<span class="go"> ...: global x</span>
<span class="go"> ...: x += 5</span>
<span class="go"> ...:</span>
<span class="go"> ...:</span>
<span class="gp">In [41]: </span><span class="n">increment_x</span><span class="p">()</span>
<span class="gp">In [42]: </span><span class="n">x</span>
<span class="gh">Out[42]: </span><span class="go">10</span>
</pre></div>
</div>
<p><strong>NOTE:</strong> The use of <code class="docutils literal notranslate"><span class="pre">global</span></code> is frowned upon – having global variables manipulated in arbitrary other scopes makes for buggy, hard to maintain code! You hardly ever need to use <code class="docutils literal notranslate"><span class="pre">global</span></code> – if a function needs to manipulate a value, you should pass that value into the function, or have it return a value that can then be used to change the global name.</p>
</div>
<div class="section" id="nonlocal-keyword">
<h3><code class="docutils literal notranslate"><span class="pre">nonlocal</span></code> keyword<a class="headerlink" href="#nonlocal-keyword" title="Permalink to this headline"></a></h3>
<p>The other limitation with <code class="docutils literal notranslate"><span class="pre">global</span></code> is that there is only one global namespace. What if you are in a nested scope, and want to get at the value outside the current scope, but not all the way up at the global scope:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [1]: </span><span class="n">x</span> <span class="o">=</span> <span class="mi">5</span>
<span class="gp">In [2]: </span><span class="k">def</span> <span class="nf">outer</span><span class="p">():</span>
<span class="gp"> ...: </span> <span class="n">x</span> <span class="o">=</span> <span class="mi">10</span>
<span class="gp"> ...: </span> <span class="k">def</span> <span class="nf">inner</span><span class="p">():</span>
<span class="gp"> ...: </span> <span class="n">x</span> <span class="o">+=</span> <span class="mi">5</span>
<span class="gp"> ...: </span> <span class="n">inner</span><span class="p">()</span>
<span class="gp"> ...: </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"x in outer is:"</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
</pre></div>
</div>
<p>That’s not going to work as the inner x hasn’t been initialized:</p>
<p><code class="docutils literal notranslate"><span class="pre">UnboundLocalError:</span> <span class="pre">local</span> <span class="pre">variable</span> <span class="pre">'x'</span> <span class="pre">referenced</span> <span class="pre">before</span> <span class="pre">assignment</span></code></p>
<p>But if we use <code class="docutils literal notranslate"><span class="pre">global</span></code>, we’ll get the global <code class="docutils literal notranslate"><span class="pre">x</span></code>:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [4]: </span><span class="k">def</span> <span class="nf">outer</span><span class="p">():</span>
<span class="gp"> ...: </span> <span class="n">x</span> <span class="o">=</span> <span class="mi">10</span>
<span class="gp"> ...: </span> <span class="k">def</span> <span class="nf">inner</span><span class="p">():</span>
<span class="gp"> ...: </span> <span class="k">global</span> <span class="n">x</span>
<span class="gp"> ...: </span> <span class="n">x</span> <span class="o">+=</span> <span class="mi">5</span>
<span class="gp"> ...: </span> <span class="n">inner</span><span class="p">()</span>
<span class="gp"> ...: </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"x in outer is:"</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
<span class="gp"> ...:</span>
<span class="gp">In [5]: </span><span class="n">x</span>
<span class="gh">Out[5]: </span><span class="go">5</span>
<span class="gp">In [6]: </span><span class="n">outer</span><span class="p">()</span>
<span class="go">x in outer is: 10</span>
<span class="gp">In [7]: </span><span class="n">x</span>
<span class="gh">Out[7]: </span><span class="go">10</span>
<span class="gp">In [8]: </span><span class="n">outer</span><span class="p">()</span>
<span class="go">x in outer is: 10</span>
<span class="gp">In [9]: </span><span class="n">x</span>
<span class="gh">Out[9]: </span><span class="go">15</span>
</pre></div>
</div>
<p>This indicates that the global <code class="docutils literal notranslate"><span class="pre">x</span></code> is getting changed, but not the one in the <code class="docutils literal notranslate"><span class="pre">outer</span></code> scope.</p>
<p>This is enough of a limitation that Python 3 added a new keyword: <code class="docutils literal notranslate"><span class="pre">nonlocal</span></code>.
What it means is that the name should be looked for outside the local scope, but only as far as you need to go to find it:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [10]: </span><span class="k">def</span> <span class="nf">outer</span><span class="p">():</span>
<span class="go"> ...: x = 10</span>
<span class="go"> ...: def inner():</span>
<span class="go"> ...: nonlocal x</span>
<span class="go"> ...: x += 5</span>
<span class="go"> ...: inner()</span>
<span class="go"> ...: print("x in outer is:", x)</span>
<span class="go"> ...:</span>
<span class="gp">In [11]: </span><span class="n">outer</span><span class="p">()</span>
<span class="go">x in outer is: 15</span>
</pre></div>
</div>
<p>So the <code class="docutils literal notranslate"><span class="pre">x</span></code> in the <code class="docutils literal notranslate"><span class="pre">outer</span></code> function scope is the one being changed.</p>
<p>While using <code class="docutils literal notranslate"><span class="pre">global</span></code> is discouraged, <code class="docutils literal notranslate"><span class="pre">nonlocal</span></code> is safer – as long as it is referring to a name in a scope that is closely defined like the above example. In fact, <code class="docutils literal notranslate"><span class="pre">nonlocal</span></code> will not go all the way up to the global scope to find a name:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [15]: </span><span class="k">def</span> <span class="nf">outer</span><span class="p">():</span>
<span class="go"> ...: def inner():</span>
<span class="go"> ...: nonlocal x</span>
<span class="go"> ...: x += 5</span>
<span class="go"> ...: inner()</span>
<span class="go"> ...: print("x in outer is:", x)</span>
<span class="go"> ...:</span>
<span class="gt"> File</span><span class="nn"> "<ipython-input-15-fc6f8de72dfc>"</span><span class="gt">, line </span><span class="mi">3</span>
<span class="k">nonlocal</span> <span class="n">x</span>
<span class="o">^</span>
<span class="ne">SyntaxError</span>: no binding for nonlocal 'x' found
</pre></div>
</div>
<p>But it will go up multiple levels in nested scopes:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [16]: </span><span class="k">def</span> <span class="nf">outer</span><span class="p">():</span>
<span class="go"> ...: x = 10</span>
<span class="go"> ...: def inner():</span>
<span class="go"> ...: def inner2():</span>
<span class="go"> ...: nonlocal x</span>
<span class="go"> ...: x += 10</span>
<span class="go"> ...: inner2()</span>
<span class="go"> ...: inner()</span>
<span class="go"> ...: print("x in outer is:", x)</span>
<span class="go"> ...:</span>
<span class="gp">In [17]: </span><span class="n">outer</span><span class="p">()</span>
<span class="go">x in outer is: 20</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="id1">
<h2>Closures<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h2>
<p>Now that we have a good handle on namespace scope, we can get to see why this is all really useful.</p>
<p>“Closures” is a cool CS term for what is really just defining functions on the fly with some saved state. You can find a “proper” definition here:</p>
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Closure_(computer_programming)">Closures on Wikipedia</a></p>
<p>But I have trouble following that, so we’ll look at real world examples to get the idea – it’s actually pretty logical, once you have idea about how scope works in Python.</p>
<div class="section" id="functions-within-functions">
<h3>Functions Within Functions<a class="headerlink" href="#functions-within-functions" title="Permalink to this headline"></a></h3>
<p>We’ve been defining functions within functions to explore namespace scope. But functions are “first class objects” in python, so we can not only define them and call them, but we can assign names to them and pass them around like any other object.</p>
<p>So after we define a function within a function, we can actually return that function as an object:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">counter</span><span class="p">(</span><span class="n">start_at</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="n">count</span> <span class="o">=</span> <span class="n">start_at</span>
<span class="k">def</span> <span class="nf">incr</span><span class="p">():</span>
<span class="k">nonlocal</span> <span class="n">count</span>
<span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="n">count</span>
<span class="k">return</span> <span class="n">incr</span>
</pre></div>
</div>
<p>This looks a lot like the previous examples, but we are returning the function that was defined inside the function. Which means is can be used elsewhere.</p>
<div class="section" id="what-s-going-on-here">
<h4>What’s going on here?<a class="headerlink" href="#what-s-going-on-here" title="Permalink to this headline"></a></h4>
<p>We have passed the <code class="docutils literal notranslate"><span class="pre">start_at</span></code> value into the <code class="docutils literal notranslate"><span class="pre">counter</span></code> function.</p>
<p>We have stored it in <code class="docutils literal notranslate"><span class="pre">counter</span></code>’s scope as a local variable: <code class="docutils literal notranslate"><span class="pre">count</span></code></p>
<p>Then we defined a function, <code class="docutils literal notranslate"><span class="pre">incr</span></code> that adds one to the value of count, and returns that value.</p>
<p>Note that we declared <code class="docutils literal notranslate"><span class="pre">count</span></code> to be nonlocal in <code class="docutils literal notranslate"><span class="pre">incr</span></code>’s scope, so that it would be the same <code class="docutils literal notranslate"><span class="pre">count</span></code> that’s in counter’s scope.</p>
<p>What type of object do you get when you call <code class="docutils literal notranslate"><span class="pre">counter()</span></code>?</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [37]: </span><span class="n">c</span> <span class="o">=</span> <span class="n">counter</span><span class="p">(</span><span class="n">start_at</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="gp">In [38]: </span><span class="nb">type</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
<span class="gh">Out[38]: </span><span class="go">function</span>
</pre></div>
</div>
<p>So we get a function back – makes sense. The <code class="docutils literal notranslate"><span class="pre">def</span></code> defines a function, and that function is what’s getting returned.</p>
<p>Being a function, we can, of course, call it:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [39]: </span><span class="n">c</span><span class="p">()</span>
<span class="gh">Out[39]: </span><span class="go">6</span>
<span class="gp">In [40]: </span><span class="n">c</span><span class="p">()</span>
<span class="gh">Out[40]: </span><span class="go">7</span>
</pre></div>
</div>
<p>Each time is it called, it increments the value by one – as you’d expect.</p>
<p>But what happens if we call <code class="docutils literal notranslate"><span class="pre">counter()</span></code> multiple times?</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [41]: </span><span class="n">c1</span> <span class="o">=</span> <span class="n">counter</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="gp">In [42]: </span><span class="n">c2</span> <span class="o">=</span> <span class="n">counter</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="gp">In [43]: </span><span class="n">c1</span><span class="p">()</span>
<span class="gh">Out[43]: </span><span class="go">6</span>
<span class="gp">In [44]: </span><span class="n">c2</span><span class="p">()</span>
<span class="gh">Out[44]: </span><span class="go">11</span>
</pre></div>
</div>
<p>So each time <code class="docutils literal notranslate"><span class="pre">counter()</span></code> is called, a new <code class="docutils literal notranslate"><span class="pre">incr</span></code> function is created. Along with the new function, a new namespace is created that holds the <code class="docutils literal notranslate"><span class="pre">count</span></code> name. So the new <code class="docutils literal notranslate"><span class="pre">incr</span></code> function is holding a reference to that new <code class="docutils literal notranslate"><span class="pre">count</span></code> name.</p>
<p>This is what makes it a “closure” – it carries with it the scope in which it was created (or enclosed - I guess that’s where the word closure comes from).</p>
<p>The returned <code class="docutils literal notranslate"><span class="pre">incr</span></code> function is a “curried” function – a function with some parameters pre-specified.</p>
<p>Let’s experiment a bit more with these ideas:</p>
<p><a class="reference download internal" download="" href="../_downloads/b522fc8f0c034466a69d85fe72bc3a0d/play_with_scope.py"><code class="xref download docutils literal notranslate"><span class="pre">play_with_scope.py</span></code></a></p>
</div>
</div>
</div>
<div class="section" id="currying">
<h2>Currying<a class="headerlink" href="#currying" title="Permalink to this headline"></a></h2>
<p>“Currying” is a special case of closures:</p>
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Currying">Currying on Wikipedia</a></p>
<p>The idea behind currying is that you may have a function with a number of parameters, and you want to make a specialized version of that function with a couple of parameters pre-set.</p>
<div class="section" id="real-world-example">
<h3>Real world Example<a class="headerlink" href="#real-world-example" title="Permalink to this headline"></a></h3>
<p>I was writing some code to compute the concentration of a contaminant in a river, as it was reduced by exponential decay, defined by a half-life:</p>
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Half-life">https://en.wikipedia.org/wiki/Half-life</a></p>
<p>So I wanted a function that would compute how much the concentration would reduce as a function of time – that is:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">scale</span><span class="p">(</span><span class="n">time</span><span class="p">):</span>
<span class="k">return</span> <span class="n">scale_factor</span>
</pre></div>
</div>
<p>The trick is, how much the concentration would be reduced depends on both time and the half life. And for a given material, and given flow conditions in the river, that half life is pre-determined. Once you know the half-life, the scale is given by:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">scale</span> <span class="o">=</span> <span class="mf">0.5</span> <span class="o">**</span> <span class="p">(</span><span class="n">time</span> <span class="o">/</span> <span class="p">(</span><span class="n">half_life</span><span class="p">))</span>
</pre></div>
</div>
<p>So to compute the scale, I could pass that half-life in each time I called the function:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">scale</span><span class="p">(</span><span class="n">time</span><span class="p">,</span> <span class="n">half_life</span><span class="p">):</span>
<span class="k">return</span> <span class="mf">0.5</span> <span class="o">**</span> <span class="p">(</span><span class="n">time</span> <span class="o">/</span> <span class="p">(</span><span class="n">half_life</span><span class="p">))</span>
</pre></div>
</div>
<p>But this is a bit klunky – I need to keep passing that <code class="docutils literal notranslate"><span class="pre">half_life</span></code> around, even though it isn’t changing. And there are places, like <code class="docutils literal notranslate"><span class="pre">map</span></code> that require a function that takes only one argument!</p>
<p>What if I could create a function, on the fly, that had a particular half-life “baked in”?</p>
<p><em>Enter Currying</em> – Currying is a technique where you reduce the number of parameters that function takes, creating a specialized function with one or more of the original parameters set to a particular value. Here is that technique, applied to the half-life decay problem:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">get_scale_fun</span><span class="p">(</span><span class="n">half_life</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">half_life_fun</span><span class="p">(</span><span class="n">time</span><span class="p">):</span>
<span class="k">return</span> <span class="mf">0.5</span> <span class="o">**</span> <span class="p">(</span><span class="n">time</span> <span class="o">/</span> <span class="n">half_life</span><span class="p">)</span>
<span class="k">return</span> <span class="n">half_life_fun</span>
</pre></div>
</div>
<p><strong>NOTE:</strong> This is simple enough to use a lambda for a bit more compact code:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">get_scale_fun</span><span class="p">(</span><span class="n">half_life</span><span class="p">):</span>
<span class="k">return</span> <span class="k">lambda</span> <span class="n">time</span><span class="p">:</span> <span class="mf">0.5</span> <span class="o">**</span> <span class="p">(</span><span class="n">time</span> <span class="o">/</span> <span class="n">half_life</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="using-the-curried-function">
<h4>Using the Curried Function<a class="headerlink" href="#using-the-curried-function" title="Permalink to this headline"></a></h4>
<p>Create a scale function with a half-life of one hour:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [8]: </span><span class="n">scale</span> <span class="o">=</span> <span class="n">get_scale_fun</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="gp">In [9]: </span><span class="p">[</span><span class="n">scale</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">7</span><span class="p">)]</span>
<span class="gh">Out[9]: </span><span class="go">[1.0, 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625]</span>
</pre></div>
</div>
<p>The value is reduced by half every hour.</p>
<p>Now create one with a half life of 2 hours:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [10]: </span><span class="n">scale</span> <span class="o">=</span> <span class="n">get_scale_fun</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="gp">In [11]: </span><span class="p">[</span><span class="n">scale</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">7</span><span class="p">)]</span>
<span class="gh">Out[11]:</span>
<span class="go">[1.0,</span>
<span class="go"> 0.7071067811865476,</span>
<span class="go"> 0.5,</span>
<span class="go"> 0.3535533905932738,</span>
<span class="go"> 0.25,</span>
<span class="go"> 0.1767766952966369,</span>
<span class="go"> 0.125]</span>
</pre></div>
</div>
<p>And the value is reduced by half every two hours…</p>
<p>And it can be used with <code class="docutils literal notranslate"><span class="pre">map</span></code>, too:</p>
<div class="highlight-ipython notranslate"><div class="highlight"><pre><span></span><span class="gp">In [13]: </span><span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">scale</span><span class="p">,</span> <span class="nb">range</span><span class="p">(</span><span class="mi">7</span><span class="p">)))</span>
<span class="gh">Out[13]:</span>
<span class="go">[1.0,</span>
<span class="go"> 0.7071067811865476,</span>
<span class="go"> 0.5,</span>
<span class="go"> 0.3535533905932738,</span>
<span class="go"> 0.25,</span>
<span class="go"> 0.1767766952966369,</span>
<span class="go"> 0.125]</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="functools-partial">
<h3><code class="docutils literal notranslate"><span class="pre">functools.partial</span></code><a class="headerlink" href="#functools-partial" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">functools</span></code> module in the standard library provides utilities for working with functions:</p>
<p><a class="reference external" href="https://docs.python.org/3.5/library/functools.html">https://docs.python.org/3.5/library/functools.html</a></p>
<p>Creating a curried function turns out to be common enough that the <code class="docutils literal notranslate"><span class="pre">functools.partial</span></code> function provides an optimized way to do it:</p>
<p>What <code class="docutils literal notranslate"><span class="pre">functools.partial</span></code> does is:</p>
<blockquote>
<div><ul class="simple">
<li><p>Makes a new version of a function with one or more arguments already filled in.</p></li>
<li><p>The new version of a function documents itself.</p></li>
</ul>
</div></blockquote>
<p>Example:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">power</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">exponent</span><span class="p">):</span>
<span class="sd">"""returns based raised to the give exponent"""</span>
<span class="k">return</span> <span class="n">base</span> <span class="o">**</span> <span class="n">exponent</span>
</pre></div>
</div>
<p>Simple enough. but what if we wanted a specialized <code class="docutils literal notranslate"><span class="pre">square</span></code> and <code class="docutils literal notranslate"><span class="pre">cube</span></code> function?</p>
<p>We can use <code class="docutils literal notranslate"><span class="pre">functools.partial</span></code> to <em>partially</em> evaluate the function, giving us a specialized version:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">square</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">power</span><span class="p">,</span> <span class="n">exponent</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="n">cube</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">power</span><span class="p">,</span> <span class="n">exponent</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="IPythonParallel.html" class="btn btn-neutral float-left" title="IPython Parallel Quickstart" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="../exercises/lambda_magic.html" class="btn btn-neutral float-right" title="lambda and keyword Magic" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>© Copyright 2020, University of Washington, Natasha Aleksandrova, Christopher Barker, Brian Dorsey, Cris Ewing, Christy Heaton, Jon Jacky, Maria McKinley, Andy Miles, Rick Riehle, Joseph Schilz, Joseph Sheedy, Hosung Song. Creative Commons Attribution-ShareAlike 4.0 license.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>