miller/docs6/docs/_build/html/reference-dsl-user-defined-functions.html

146 lines
No EOL
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DSL reference: user-defined functions &#8212; Miller 6.0.0-alpha documentation</title>
<link rel="stylesheet" href="_static/scrolls.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/print.css" type="text/css" />
<script id="documentation_options" data-url_root="./" 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/language_data.js"></script>
<script src="_static/theme_extras.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="DSL reference: built-in functions" href="reference-dsl-builtin-functions.html" />
<link rel="prev" title="DSL reference: control structures" href="reference-dsl-control-structures.html" />
</head><body>
<div id="content">
<div class="header">
<h1 class="heading"><a href="index.html"
title="back to the documentation overview"><span>DSL reference: user-defined functions</span></a></h1>
</div>
<div class="relnav" role="navigation" aria-label="related navigation">
<a href="reference-dsl-control-structures.html">&laquo; DSL reference: control structures</a> |
<a href="#">DSL reference: user-defined functions</a>
| <a href="reference-dsl-builtin-functions.html">DSL reference: built-in functions &raquo;</a>
</div>
<div id="contentwrapper">
<div id="toc" role="navigation" aria-label="table of contents navigation">
<h3>Table of Contents</h3>
<ul>
<li><a class="reference internal" href="#">DSL reference: user-defined functions</a><ul>
<li><a class="reference internal" href="#user-defined-functions">User-defined functions</a></li>
<li><a class="reference internal" href="#user-defined-subroutines">User-defined subroutines</a></li>
</ul>
</li>
</ul>
</div>
<div role="main">
<div class="section" id="dsl-reference-user-defined-functions">
<h1>DSL reference: user-defined functions<a class="headerlink" href="#dsl-reference-user-defined-functions" title="Permalink to this headline"></a></h1>
<p>As of Miller 5.0.0 you can define your own functions, as well as subroutines.</p>
<div class="section" id="user-defined-functions">
<h2>User-defined functions<a class="headerlink" href="#user-defined-functions" title="Permalink to this headline"></a></h2>
<p>Heres the obligatory example of a recursive function to compute the factorial function:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span><span class="hll"> mlr --opprint --from data/small put &#39;
</span><span class="hll"> func f(n) {
</span><span class="hll"> if (is_numeric(n)) {
</span><span class="hll"> if (n &gt; 0) {
</span><span class="hll"> return n * f(n-1);
</span><span class="hll"> } else {
</span><span class="hll"> return 1;
</span><span class="hll"> }
</span><span class="hll"> }
</span><span class="hll"> # implicitly return absent-null if non-numeric
</span><span class="hll"> }
</span><span class="hll"> $ox = f($x + NR);
</span><span class="hll"> $oi = f($i);
</span><span class="hll"> &#39;
</span> a b i x y ox oi
pan pan 1 0.3467901443380824 0.7268028627434533 0.46705354854811026 1
eks pan 2 0.7586799647899636 0.5221511083334797 3.680838410072862 2
wye wye 3 0.20460330576630303 0.33831852551664776 1.7412511955594865 6
eks wye 4 0.38139939387114097 0.13418874328430463 18.588348778962008 24
wye pan 5 0.5732889198020006 0.8636244699032729 211.38730958519247 120
</pre></div>
</div>
<p>Properties of user-defined functions:</p>
<ul class="simple">
<li><p>Function bodies start with <code class="docutils literal notranslate"><span class="pre">func</span></code> and a parameter list, defined outside of <code class="docutils literal notranslate"><span class="pre">begin</span></code>, <code class="docutils literal notranslate"><span class="pre">end</span></code>, or other <code class="docutils literal notranslate"><span class="pre">func</span></code> or <code class="docutils literal notranslate"><span class="pre">subr</span></code> blocks. (I.e. the Miller DSL has no nested functions.)</p></li>
<li><p>A function (uniqified by its name) may not be redefined: either by redefining a user-defined function, or by redefining a built-in function. However, functions and subroutines have separate namespaces: you can define a subroutine <code class="docutils literal notranslate"><span class="pre">log</span></code> which does not clash with the mathematical <code class="docutils literal notranslate"><span class="pre">log</span></code> function.</p></li>
<li><p>Functions may be defined either before or after use (there is an object-binding/linkage step at startup). More specifically, functions may be either recursive or mutually recursive. Functions may not call subroutines.</p></li>
<li><p>Functions may be defined and called either within <code class="docutils literal notranslate"><span class="pre">mlr</span> <span class="pre">put</span></code> or <code class="docutils literal notranslate"><span class="pre">mlr</span> <span class="pre">put</span></code>.</p></li>
<li><p>Functions have read access to <code class="docutils literal notranslate"><span class="pre">$</span></code>-variables and <code class="docutils literal notranslate"><span class="pre">&#64;</span></code>-variables but may not modify them. See also <a class="reference internal" href="misc-examples.html#cookbook-memoization-with-oosvars"><span class="std std-ref">Memoization with out-of-stream variables</span></a> for an example.</p></li>
<li><p>Argument values may be reassigned: they are not read-only.</p></li>
<li><p>When a return value is not implicitly returned, this results in a return value of absent-null. (In the example above, if there were records for which the argument to <code class="docutils literal notranslate"><span class="pre">f</span></code> is non-numeric, the assignments would be skipped.) See also the section on <a class="reference internal" href="reference-main-null-data.html"><span class="doc">Reference: null data</span></a>.</p></li>
<li><p>See the section on <a class="reference internal" href="reference-dsl-variables.html#reference-dsl-local-variables"><span class="std std-ref">Local variables</span></a> for information on scope and extent of arguments, as well as for information on the use of local variables within functions.</p></li>
<li><p>See the section on <a class="reference internal" href="reference-dsl-syntax.html#reference-dsl-expressions-from-files"><span class="std std-ref">Expressions from files</span></a> for information on the use of <code class="docutils literal notranslate"><span class="pre">-f</span></code> and <code class="docutils literal notranslate"><span class="pre">-e</span></code> flags.</p></li>
</ul>
</div>
<div class="section" id="user-defined-subroutines">
<h2>User-defined subroutines<a class="headerlink" href="#user-defined-subroutines" title="Permalink to this headline"></a></h2>
<p>Example:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span><span class="hll"> mlr --opprint --from data/small put -q &#39;
</span><span class="hll"> begin {
</span><span class="hll"> @call_count = 0;
</span><span class="hll"> }
</span><span class="hll"> subr s(n) {
</span><span class="hll"> @call_count += 1;
</span><span class="hll"> if (is_numeric(n)) {
</span><span class="hll"> if (n &gt; 1) {
</span><span class="hll"> call s(n-1);
</span><span class="hll"> } else {
</span><span class="hll"> print &quot;numcalls=&quot; . @call_count;
</span><span class="hll"> }
</span><span class="hll"> }
</span><span class="hll"> }
</span><span class="hll"> print &quot;NR=&quot; . NR;
</span><span class="hll"> call s(NR);
</span><span class="hll"> &#39;
</span> NR=1
numcalls=1
NR=2
numcalls=3
NR=3
numcalls=6
NR=4
numcalls=10
NR=5
numcalls=15
</pre></div>
</div>
<p>Properties of user-defined subroutines:</p>
<ul class="simple">
<li><p>Subroutine bodies start with <code class="docutils literal notranslate"><span class="pre">subr</span></code> and a parameter list, defined outside of <code class="docutils literal notranslate"><span class="pre">begin</span></code>, <code class="docutils literal notranslate"><span class="pre">end</span></code>, or other <code class="docutils literal notranslate"><span class="pre">func</span></code> or <code class="docutils literal notranslate"><span class="pre">subr</span></code> blocks. (I.e. the Miller DSL has no nested subroutines.)</p></li>
<li><p>A subroutine (uniqified by its name) may not be redefined. However, functions and subroutines have separate namespaces: you can define a subroutine <code class="docutils literal notranslate"><span class="pre">log</span></code> which does not clash with the mathematical <code class="docutils literal notranslate"><span class="pre">log</span></code> function.</p></li>
<li><p>Subroutines may be defined either before or after use (there is an object-binding/linkage step at startup). More specifically, subroutines may be either recursive or mutually recursive. Subroutines may call functions.</p></li>
<li><p>Subroutines may be defined and called either within <code class="docutils literal notranslate"><span class="pre">mlr</span> <span class="pre">put</span></code> or <code class="docutils literal notranslate"><span class="pre">mlr</span> <span class="pre">put</span></code>.</p></li>
<li><p>Subroutines have read/write access to <code class="docutils literal notranslate"><span class="pre">$</span></code>-variables and <code class="docutils literal notranslate"><span class="pre">&#64;</span></code>-variables.</p></li>
<li><p>Argument values may be reassigned: they are not read-only.</p></li>
<li><p>See the section on <a class="reference internal" href="reference-dsl-variables.html#reference-dsl-local-variables"><span class="std std-ref">Local variables</span></a> for information on scope and extent of arguments, as well as for information on the use of local variables within functions.</p></li>
<li><p>See the section on <a class="reference internal" href="reference-dsl-syntax.html#reference-dsl-expressions-from-files"><span class="std std-ref">Expressions from files</span></a> for information on the use of <code class="docutils literal notranslate"><span class="pre">-f</span></code> and <code class="docutils literal notranslate"><span class="pre">-e</span></code> flags.</p></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2021, John Kerl.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>