CINXE.COM

PEP 312 – Simple Implicit Lambda | peps.python.org

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="color-scheme" content="light dark"> <title>PEP 312 – Simple Implicit Lambda | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0312/"> <link rel="stylesheet" href="../_static/style.css" type="text/css"> <link rel="stylesheet" href="../_static/mq.css" type="text/css"> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light"> <link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark"> <link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss"> <meta property="og:title" content='PEP 312 – Simple Implicit Lambda | peps.python.org'> <meta property="og:description" content="This PEP proposes to make argumentless lambda keyword optional in some cases where it is not grammatically ambiguous."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0312/"> <meta property="og:site_name" content="Python Enhancement Proposals (PEPs)"> <meta property="og:image" content="https://peps.python.org/_static/og-image.png"> <meta property="og:image:alt" content="Python PEPs"> <meta property="og:image:width" content="200"> <meta property="og:image:height" content="200"> <meta name="description" content="This PEP proposes to make argumentless lambda keyword optional in some cases where it is not grammatically ambiguous."> <meta name="theme-color" content="#3776ab"> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all"> <title>Following system colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="9"></circle> <path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path> </svg> </symbol> <symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all"> <title>Selected dark colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path> </svg> </symbol> <symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all"> <title>Selected light colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> </symbol> </svg> <script> document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto" </script> <section id="pep-page-section"> <header> <h1>Python Enhancement Proposals</h1> <ul class="breadcrumbs"> <li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li> <li><a href="../pep-0000/">PEP Index</a> &raquo; </li> <li>PEP 312</li> </ul> <button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())"> <svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg> <span class="visually-hidden">Toggle light / dark / auto colour theme</span> </button> </header> <article> <section id="pep-content"> <h1 class="page-title">PEP 312 – Simple Implicit Lambda</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Roman Suzi &lt;rnd&#32;&#97;t&#32;onego.ru&gt;, Alex Martelli &lt;aleaxit&#32;&#97;t&#32;gmail.com&gt;</dd> <dt class="field-even">Status<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Inactive draft that may be taken up again at a later time">Deferred</abbr></dd> <dt class="field-odd">Type<span class="colon">:</span></dt> <dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd> <dt class="field-even">Created<span class="colon">:</span></dt> <dd class="field-even">11-Feb-2003</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">2.4</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even"><p></p></dd> </dl> <hr class="docutils" /> <section id="contents"> <details><summary>Table of Contents</summary><ul class="simple"> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#deferral">Deferral</a></li> <li><a class="reference internal" href="#motivation">Motivation</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#syntax">Syntax</a></li> <li><a class="reference internal" href="#examples-of-use">Examples of Use</a></li> <li><a class="reference internal" href="#implementation">Implementation</a></li> <li><a class="reference internal" href="#discussion">Discussion</a></li> <li><a class="reference internal" href="#credits">Credits</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> </details></section> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>This PEP proposes to make argumentless lambda keyword optional in some cases where it is not grammatically ambiguous.</p> </section> <section id="deferral"> <h2><a class="toc-backref" href="#deferral" role="doc-backlink">Deferral</a></h2> <p>The BDFL hates the unary colon syntax. This PEP needs to go back to the drawing board and find a more Pythonic syntax (perhaps an alternative unary operator). See python-dev discussion on 17 June 2005 <a class="footnote-reference brackets" href="#id3" id="id1">[1]</a>.</p> <p>Also, it is probably a good idea to eliminate the alternative propositions which have no chance at all. The examples section is good and highlights the readability improvements. It would carry more weight with additional examples and with real-world referents (instead of the abstracted dummy calls to <code class="docutils literal notranslate"><span class="pre">:A</span></code> and <code class="docutils literal notranslate"><span class="pre">:B</span></code>).</p> </section> <section id="motivation"> <h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2> <p>Lambdas are useful for defining anonymous functions, e.g. for use as callbacks or (pseudo)-lazy evaluation schemes. Often, lambdas are not used when they would be appropriate, just because the keyword “lambda” makes code look complex. Omitting lambda in some special cases is possible, with small and backwards compatible changes to the grammar, and provides a cheap cure against such “lambdaphobia”.</p> </section> <section id="rationale"> <h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2> <p>Sometimes people do not use lambdas because they fear to introduce a term with a theory behind it. This proposal makes introducing argumentless lambdas easier, by omitting the “lambda” keyword. itself. Implementation can be done simply changing grammar so it lets the “lambda” keyword be implied in a few well-known cases. In particular, adding surrounding brackets lets you specify nullary lambda anywhere.</p> </section> <section id="syntax"> <h2><a class="toc-backref" href="#syntax" role="doc-backlink">Syntax</a></h2> <p>An argumentless “lambda” keyword can be omitted in the following cases:</p> <ul class="simple"> <li>immediately after “=” in named parameter assignment or default value assignment;</li> <li>immediately after “(” in any expression;</li> <li>immediately after a “,” in a function argument list;</li> <li>immediately after a “:” in a dictionary literal; (not implemented)</li> <li>in an assignment statement; (not implemented)</li> </ul> </section> <section id="examples-of-use"> <h2><a class="toc-backref" href="#examples-of-use" role="doc-backlink">Examples of Use</a></h2> <ol class="arabic"> <li>Inline <code class="docutils literal notranslate"><span class="pre">if</span></code>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">ifelse</span><span class="p">(</span><span class="n">cond</span><span class="p">,</span> <span class="n">true_part</span><span class="p">,</span> <span class="n">false_part</span><span class="p">):</span> <span class="k">if</span> <span class="n">cond</span><span class="p">:</span> <span class="k">return</span> <span class="n">true_part</span><span class="p">()</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="n">false_part</span><span class="p">()</span> <span class="c1"># old syntax:</span> <span class="nb">print</span> <span class="n">ifelse</span><span class="p">(</span><span class="n">a</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">,</span> <span class="k">lambda</span><span class="p">:</span><span class="n">A</span><span class="p">,</span> <span class="k">lambda</span><span class="p">:</span><span class="n">B</span><span class="p">)</span> <span class="c1"># new syntax:</span> <span class="nb">print</span> <span class="n">ifelse</span><span class="p">(</span><span class="n">a</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">,</span> <span class="p">:</span><span class="n">A</span><span class="p">,</span> <span class="p">:</span><span class="n">B</span><span class="p">)</span> <span class="c1"># parts A and B may require extensive processing, as in:</span> <span class="nb">print</span> <span class="n">ifelse</span><span class="p">(</span><span class="n">a</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">,</span> <span class="p">:</span><span class="n">ext_proc1</span><span class="p">(</span><span class="n">A</span><span class="p">),</span> <span class="p">:</span><span class="n">ext_proc2</span><span class="p">(</span><span class="n">B</span><span class="p">))</span> </pre></div> </div> </li> <li>Locking:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">with</span><span class="p">(</span><span class="n">alock</span><span class="p">,</span> <span class="n">acallable</span><span class="p">):</span> <span class="n">alock</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span> <span class="k">try</span><span class="p">:</span> <span class="n">acallable</span><span class="p">()</span> <span class="k">finally</span><span class="p">:</span> <span class="n">alock</span><span class="o">.</span><span class="n">release</span><span class="p">()</span> <span class="k">with</span><span class="p">(</span><span class="n">mylock</span><span class="p">,</span> <span class="p">:</span><span class="n">x</span><span class="p">(</span><span class="n">y</span><span class="p">(),</span> <span class="mi">23</span><span class="p">,</span> <span class="n">z</span><span class="p">(),</span> <span class="s1">&#39;foo&#39;</span><span class="p">))</span> </pre></div> </div> </li> </ol> </section> <section id="implementation"> <h2><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h2> <p>Implementation requires some tweaking of the <code class="docutils literal notranslate"><span class="pre">Grammar/Grammar</span></code> file in the Python sources, and some adjustment of <code class="docutils literal notranslate"><span class="pre">Modules/parsermodule.c</span></code> to make syntactic and pragmatic changes.</p> <p>(Some grammar/parser guru is needed to make a full implementation.)</p> <p>Here are the changes needed to <code class="docutils literal notranslate"><span class="pre">Grammar</span></code> to allow implicit lambda:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">varargslist</span><span class="p">:</span> <span class="p">(</span><span class="n">fpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">imptest</span><span class="p">]</span> <span class="s1">&#39;,&#39;</span><span class="p">)</span><span class="o">*</span> <span class="p">(</span><span class="s1">&#39;*&#39;</span> <span class="n">NAME</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="s1">&#39;**&#39;</span> <span class="n">NAME</span><span class="p">]</span> <span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">NAME</span><span class="p">)</span> <span class="o">|</span> <span class="n">fpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">imptest</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">fpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">imptest</span><span class="p">])</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="n">imptest</span><span class="p">:</span> <span class="n">test</span> <span class="o">|</span> <span class="n">implambdef</span> <span class="n">atom</span><span class="p">:</span> <span class="s1">&#39;(&#39;</span> <span class="p">[</span><span class="n">imptestlist</span><span class="p">]</span> <span class="s1">&#39;)&#39;</span> <span class="o">|</span> <span class="s1">&#39;[&#39;</span> <span class="p">[</span><span class="n">listmaker</span><span class="p">]</span> <span class="s1">&#39;]&#39;</span> <span class="o">|</span> <span class="s1">&#39;{&#39;</span> <span class="p">[</span><span class="n">dictmaker</span><span class="p">]</span> <span class="s1">&#39;}&#39;</span> <span class="o">|</span> <span class="s1">&#39;`&#39;</span> <span class="n">testlist1</span> <span class="s1">&#39;`&#39;</span> <span class="o">|</span> <span class="n">NAME</span> <span class="o">|</span> <span class="n">NUMBER</span> <span class="o">|</span> <span class="n">STRING</span><span class="o">+</span> <span class="n">implambdef</span><span class="p">:</span> <span class="s1">&#39;:&#39;</span> <span class="n">test</span> <span class="n">imptestlist</span><span class="p">:</span> <span class="n">imptest</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">imptest</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="n">argument</span><span class="p">:</span> <span class="p">[</span><span class="n">test</span> <span class="s1">&#39;=&#39;</span><span class="p">]</span> <span class="n">imptest</span> </pre></div> </div> <p>Three new non-terminals are needed: <code class="docutils literal notranslate"><span class="pre">imptest</span></code> for the place where implicit lambda may occur, <code class="docutils literal notranslate"><span class="pre">implambdef</span></code> for the implicit lambda definition itself, <code class="docutils literal notranslate"><span class="pre">imptestlist</span></code> for a place where <code class="docutils literal notranslate"><span class="pre">imptest</span></code>’s may occur.</p> <p>This implementation is not complete. First, because some files in Parser module need to be updated. Second, some additional places aren’t implemented, see Syntax section above.</p> </section> <section id="discussion"> <h2><a class="toc-backref" href="#discussion" role="doc-backlink">Discussion</a></h2> <p>This feature is not a high-visibility one (the only novel part is the absence of lambda). The feature is intended to make null-ary lambdas more appealing syntactically, to provide lazy evaluation of expressions in some simple cases. This proposal is not targeted at more advanced cases (demanding arguments for the lambda).</p> <p>There is an alternative proposition for implicit lambda: implicit lambda with unused arguments. In this case the function defined by such lambda can accept any parameters, i.e. be equivalent to: <code class="docutils literal notranslate"><span class="pre">lambda</span> <span class="pre">*args:</span> <span class="pre">expr</span></code>. This form would be more powerful. Grep in the standard library revealed that such lambdas are indeed in use.</p> <p>One more extension can provide a way to have a list of parameters passed to a function defined by implicit lambda. However, such parameters need some special name to be accessed and are unlikely to be included in the language. Possible local names for such parameters are: <code class="docutils literal notranslate"><span class="pre">_</span></code>, <code class="docutils literal notranslate"><span class="pre">__args__</span></code>, <code class="docutils literal notranslate"><span class="pre">__</span></code>. For example:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">reduce</span><span class="p">(:</span><span class="n">_</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">_</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span> <span class="mi">0</span><span class="p">)</span> <span class="n">reduce</span><span class="p">(:</span><span class="n">__</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">__</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span> <span class="mi">0</span><span class="p">)</span> <span class="n">reduce</span><span class="p">(:</span><span class="n">__args__</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">__args__</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span> <span class="mi">0</span><span class="p">)</span> </pre></div> </div> <p>These forms do not look very nice, and in the PEP author’s opinion do not justify the removal of the lambda keyword in such cases.</p> </section> <section id="credits"> <h2><a class="toc-backref" href="#credits" role="doc-backlink">Credits</a></h2> <p>The idea of dropping lambda was first coined by Paul Rubin at 08 Feb 2003 16:39:30 -0800 in comp.lang.python while discussing the thread “For review: PEP 308 - If-then-else expression” <a class="footnote-reference brackets" href="#id4" id="id2">[2]</a>.</p> </section> <section id="references"> <h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2> <aside class="footnote-list brackets"> <aside class="footnote brackets" id="id3" role="doc-footnote"> <dt class="label" id="id3">[<a href="#id1">1</a>]</dt> <dd>Guido van Rossum, Recommend accepting PEP 312 – Simple Implicit Lambda <a class="reference external" href="https://mail.python.org/pipermail/python-dev/2005-June/054304.html">https://mail.python.org/pipermail/python-dev/2005-June/054304.html</a></aside> <aside class="footnote brackets" id="id4" role="doc-footnote"> <dt class="label" id="id4">[<a href="#id2">2</a>]</dt> <dd>Guido van Rossum, For review: PEP 308 - If-then-else expression <a class="reference external" href="https://mail.python.org/pipermail/python-dev/2003-February/033178.html">https://mail.python.org/pipermail/python-dev/2003-February/033178.html</a></aside> </aside> </section> <section id="copyright"> <h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2> <p>This document has been placed in the public domain.</p> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0312.rst">https://github.com/python/peps/blob/main/peps/pep-0312.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0312.rst">2025-02-01 08:59:27 GMT</a></p> </article> <nav id="pep-sidebar"> <h2>Contents</h2> <ul> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#deferral">Deferral</a></li> <li><a class="reference internal" href="#motivation">Motivation</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#syntax">Syntax</a></li> <li><a class="reference internal" href="#examples-of-use">Examples of Use</a></li> <li><a class="reference internal" href="#implementation">Implementation</a></li> <li><a class="reference internal" href="#discussion">Discussion</a></li> <li><a class="reference internal" href="#credits">Credits</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> <br> <a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0312.rst">Page Source (GitHub)</a> </nav> </section> <script src="../_static/colour_scheme.js"></script> <script src="../_static/wrap_tables.js"></script> <script src="../_static/sticky_banner.js"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10