Files
wren/functions.html
2020-06-12 17:15:45 +00:00

283 lines
10 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>Functions &ndash; Wren</title>
<script type="application/javascript" src="prism.js" data-manual></script>
<script type="application/javascript" src="codejar.js"></script>
<script type="application/javascript" src="wren.js"></script>
<link rel="stylesheet" type="text/css" href="prism.css" />
<link rel="stylesheet" type="text/css" href="style.css" />
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
the viewport. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
</head>
<body id="top">
<header>
<div class="page">
<div class="main-column">
<h1><a href="./">wren</a></h1>
<h2>a classy little scripting language</h2>
</div>
</div>
</header>
<div class="page">
<nav class="big">
<a href="./"><img src="./wren.svg" class="logo"></a>
<ul>
<li><a href="getting-started.html">Getting Started</a></li>
<li><a href="contributing.html">Contributing</a></li>
<li><a href="blog">Blog</a></li>
<li><a href="try">Try it!</a></li>
</ul>
<section>
<h2>guides</h2>
<ul>
<li><a href="syntax.html">Syntax</a></li>
<li><a href="values.html">Values</a></li>
<li><a href="lists.html">Lists</a></li>
<li><a href="maps.html">Maps</a></li>
<li><a href="method-calls.html">Method Calls</a></li>
<li><a href="control-flow.html">Control Flow</a></li>
<li><a href="variables.html">Variables</a></li>
<li><a href="functions.html">Functions</a></li>
<li><a href="classes.html">Classes</a></li>
<li><a href="concurrency.html">Concurrency</a></li>
<li><a href="error-handling.html">Error Handling</a></li>
<li><a href="modularity.html">Modularity</a></li>
</ul>
</section>
<section>
<h2>API docs</h2>
<ul>
<li><a href="modules">Modules</a></li>
</ul>
</section>
<section>
<h2>reference</h2>
<ul>
<li><a href="cli">Wren CLI</a></li>
<li><a href="embedding">Embedding</a></li>
<li><a href="performance.html">Performance</a></li>
<li><a href="qa.html">Q &amp; A</a></li>
</ul>
</section>
</nav>
<nav class="small">
<table>
<tr>
<div><a href="getting-started.html">Getting Started</a></div>
<div><a href="contributing.html">Contributing</a></div>
<div><a href="blog">Blog</a></div>
<div><a href="try">Try it!</a></div>
</tr>
<tr>
<td colspan="2"><h2>guides</h2></td>
<td><h2>reference</h2></td>
</tr>
<tr>
<td>
<ul>
<li><a href="syntax.html">Syntax</a></li>
<li><a href="values.html">Values</a></li>
<li><a href="lists.html">Lists</a></li>
<li><a href="maps.html">Maps</a></li>
<li><a href="method-calls.html">Method Calls</a></li>
<li><a href="control-flow.html">Control Flow</a></li>
</ul>
</td>
<td>
<ul>
<li><a href="variables.html">Variables</a></li>
<li><a href="functions.html">Functions</a></li>
<li><a href="classes.html">Classes</a></li>
<li><a href="concurrency.html">Concurrency</a></li>
<li><a href="error-handling.html">Error Handling</a></li>
<li><a href="modularity.html">Modularity</a></li>
</ul>
</td>
<td>
<ul>
<li><a href="modules">API/Modules</a></li>
<li><a href="embedding">Embedding</a></li>
<li><a href="performance.html">Performance</a></li>
<li><a href="qa.html">Q &amp; A</a></li>
</ul>
</td>
</tr>
</table>
</nav>
<main>
<h2>Functions</h2>
<p>No self-respecting language today can get by without functions&mdash;first
class little bundles of code. Since Wren is object-oriented, most of your code
will live in methods on classes, but free-floating functions are still
eminently handy.</p>
<p>Functions are objects like everything else in Wren, instances of the <code>Fn</code>
class.</p>
<h2>Block arguments <a href="#block-arguments" name="block-arguments" class="header-anchor">#</a></h2>
<p>Most of the time you create a function just to pass it to some method. For
example, if you want to filter a <a href="lists.html">list</a> by some criteria, you&rsquo;ll
call its <code>where</code> method, passing in a function that defines the predicate
you&rsquo;re filtering on.</p>
<p>Since that&rsquo;s the most common usage pattern, Wren&rsquo;s syntax optimizes for that.
Taking a page from Ruby, a function is created by passing a <em>block argument</em> to
a method. At its simplest, it looks like this:</p>
<pre class="snippet">
blondie.callMe {
System.print("This is the body!")
}
</pre>
<p>Here we&rsquo;re invoking the <code>callMe</code> method on <code>blondie</code>. We&rsquo;re passing one
argument, a function whose body is the
following <a href="syntax.html#blocks">block</a>&mdash;everything between that pair of
curly braces.</p>
<p>Methods that take a block argument receive it as a normal parameter. <code>callMe</code>
could be defined like so:</p>
<pre class="snippet">
class Blondie {
callMe(fn) {
// Call it...
}
}
var blondie = Blondie.new()
</pre>
<p>A method can take other arguments in addition to the block. They appear before
the block just like a regular argument list. For example:</p>
<pre class="snippet">
blondie.callMeAt(867, 5309) {
System.print("This is the body!")
}
</pre>
<p>Of course, you don&rsquo;t <em>have</em> to use a block argument to pass a function to a
method. If you already have a function object, you can pass it like a regular
argument:</p>
<pre class="snippet">
var someFn = // Get a function...
blondie.callMe(someFn)
</pre>
<p>Block arguments are purely sugar for creating a function and passing it in one
little blob of syntax. There are some times when you want to create a function
but <em>don&rsquo;t</em> need to pass it to a method. For that, you can call the <code>Fn</code>
class&rsquo;s constructor:</p>
<pre class="snippet">
var someFn = Fn.new {
System.print("Hi!")
}
</pre>
<p>As you can see it takes a block argument too! All the constructor does it
return that, so this exists purely as a convenience method for you.</p>
<h2>Calling functions <a href="#calling-functions" name="calling-functions" class="header-anchor">#</a></h2>
<p>Once you have a function, how do you invoke it? Like everything in Wren, you do
so by calling a method on it:</p>
<pre class="snippet">
class Blondie {
callMe(fn) {
fn.call()
}
}
</pre>
<p>Functions expose a <code>call()</code> method that executes the body of the function. This
method is dynamically-dispatched like any other, so you can define your own
&ldquo;function-like&rdquo; classes and pass them to methods that expect &ldquo;real&rdquo; functions.</p>
<pre class="snippet">
class FakeFn {
call() {
System.print("I'm feeling functional!")
}
}
blondie.callMe(FakeFn.new())
</pre>
<h2>Function parameters <a href="#function-parameters" name="function-parameters" class="header-anchor">#</a></h2>
<p>Of course, functions aren&rsquo;t very useful if you can&rsquo;t pass values to them. The
functions that we&rsquo;ve seen so far take no arguments. To change that, you can
provide a parameter list surrounded by <code>|</code> immediately after the opening brace
of the body, like so:</p>
<pre class="snippet">
blondie.callMe {|first, last|
System.print("Hi, " + first + " " + last + "!")
}
</pre>
<p>Here we&rsquo;re passing a function to <code>callMe</code> that takes two parameters, <code>first</code> and
<code>last</code>. They are passed to the function when it&rsquo;s called:</p>
<pre class="snippet">
class Blondie {
callMe(fn) {
fn.call("Debbie", "Harry")
}
}
</pre>
<p>It&rsquo;s an error to call a function with fewer arguments than its parameter list
expects. If you pass too <em>many</em> arguments, the extras are ignored.</p>
<h2>Returning values <a href="#returning-values" name="returning-values" class="header-anchor">#</a></h2>
<p>The body of a function is a <a href="syntax.html#blocks">block</a>. If it is a single
expression&mdash;more precisely if there is no newline after the <code>{</code> or
parameter list&mdash;then the function implicitly returns the value of the
expression.</p>
<p>Otherwise, the body returns <code>null</code> by default. You can explicitly return a
value using a <code>return</code> statement. In other words, these two functions do the
same thing:</p>
<pre class="snippet">
Fn.new { "return value" }
Fn.new {
return "return value"
}
</pre>
<h2>Closures <a href="#closures" name="closures" class="header-anchor">#</a></h2>
<p>As you expect, functions are closures&mdash;they can access variables defined
outside of their scope. They will hold onto closed-over variables even after
leaving the scope where the function is defined:</p>
<pre class="snippet">
class Counter {
static create() {
var i = 0
return Fn.new { i = i + 1 }
}
}
</pre>
<p>Here, the <code>create</code> method returns the function created on its second line. That
function references a variable <code>i</code> declared outside of the function. Even after
the function is returned from <code>create</code>, it is still able to read and assign
to<code>i</code>:</p>
<pre class="snippet">
var counter = Counter.create()
System.print(counter.call()) //> 1
System.print(counter.call()) //> 2
System.print(counter.call()) //> 3
</pre>
<p><br><hr>
<a class="right" href="classes.html">Classes &rarr;</a>
<a href="variables.html">&larr; Variables</a></p>
</main>
</div>
<footer>
<div class="page">
<div class="main-column">
<p>Wren lives
<a href="https://github.com/wren-lang/wren">on GitHub</a>
&mdash; Made with &#x2764; by
<a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
<a href="https://github.com/wren-lang/wren/blob/main/AUTHORS">friends</a>.
</p>
<div class="main-column">
</div>
</footer>
</body>
</html>