mirror of
https://github.com/johnkerl/miller.git
synced 2026-01-24 02:36:15 +00:00
146 lines
No EOL
11 KiB
HTML
146 lines
No EOL
11 KiB
HTML
|
||
<!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 — 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">« 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 »</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>Here’s 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 '
|
||
</span><span class="hll"> func f(n) {
|
||
</span><span class="hll"> if (is_numeric(n)) {
|
||
</span><span class="hll"> if (n > 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"> '
|
||
</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">@</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 '
|
||
</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 > 1) {
|
||
</span><span class="hll"> call s(n-1);
|
||
</span><span class="hll"> } else {
|
||
</span><span class="hll"> print "numcalls=" . @call_count;
|
||
</span><span class="hll"> }
|
||
</span><span class="hll"> }
|
||
</span><span class="hll"> }
|
||
</span><span class="hll"> print "NR=" . NR;
|
||
</span><span class="hll"> call s(NR);
|
||
</span><span class="hll"> '
|
||
</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">@</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">
|
||
© Copyright 2021, John Kerl.
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||
</div>
|
||
</body>
|
||
</html> |