mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-11 22:28:45 +01:00
Republish docs.
This commit is contained in:
130
branching.html
130
branching.html
@ -1,130 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
|
||||
<title>Branching – Wren</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<link href='http://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="index.html">wren</a></h1>
|
||||
<h2>a classy little scripting language</h2>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="page">
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="getting-started.html">Getting Started</a></li>
|
||||
</ul>
|
||||
<section>
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>types</h2>
|
||||
<ul>
|
||||
<li><a href="values.html">Values</a></li>
|
||||
<li><a href="classes.html">Classes</a></li>
|
||||
<li><a href="fibers.html">Fibers</a></li>
|
||||
<li><a href="functions.html">Functions</a></li>
|
||||
<li><a href="lists.html">Lists</a></li>
|
||||
<li><a href="maps.html">Maps</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>reference</h2>
|
||||
<ul>
|
||||
<li><a href="core-library.html">Core Library</a></li>
|
||||
<li><a href="embedding-api.html">Embedding API</a></li>
|
||||
<li><a href="performance.html">Performance</a></li>
|
||||
<li><a href="contributing.html">Contributing</a></li>
|
||||
<li><a href="qa.html">Q & A</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Branching</h1>
|
||||
<p><em>Control flow</em> is used to determine which chunks of code are executed and how many times. Expressions and statements for deciding whether or not to execute some code are called <em>branching</em> and are covered here. To execute something more than once, you'll want <a href="looping.html"><em>looping</em></a>.</p>
|
||||
<h2>Truth <a href="#truth" name="truth" class="header-anchor">#</a></h2>
|
||||
<p>Branching is conditional on the value of some expression. We take the entire universe of possible values and divide them into two buckets: some we consider "true" and the rest are "false". If the expression results in a value in the true bucket, we branch one way. Otherwise, we go the other way.</p>
|
||||
<p>Obviously, the boolean <code>true</code> is in the "true" bucket and <code>false</code> is in "false", but what about values of other types? The choice is ultimately arbitrary, and different languages have different rules. Wren's rules follow Ruby:</p>
|
||||
<ul>
|
||||
<li>The boolean value <code>false</code> is false.</li>
|
||||
<li>The null value <code>null</code> is false.</li>
|
||||
<li>Everything else is true.</li>
|
||||
</ul>
|
||||
<p>This means <code>0</code>, empty strings, and empty collections are all considered "true" values.</p>
|
||||
<h2>If statements <a href="#if-statements" name="if-statements" class="header-anchor">#</a></h2>
|
||||
<p>The simplest branching statement, <code>if</code> lets you conditionally skip a chunk of code. It looks like this:</p>
|
||||
<div class="codehilite"><pre><span class="k">if</span> <span class="p">(</span><span class="n">ready</span><span class="p">)</span> <span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"go!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>That evaluates the parenthesized expression after <code>if</code>. If it's true, then the statement after the condition is evaluated. Otherwise it is skipped. Instead of a statement, you can have a <a href="syntax.html#blocks">block</a>:</p>
|
||||
<div class="codehilite"><pre><span class="k">if</span> <span class="p">(</span><span class="n">ready</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"getSet"</span><span class="p">)</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"go!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You may also provide an <code>else</code> branch. It will be executed if the condition is false:</p>
|
||||
<div class="codehilite"><pre><span class="k">if</span> <span class="p">(</span><span class="n">ready</span><span class="p">)</span> <span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"go!"</span><span class="p">)</span> <span class="k">else</span> <span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"not ready!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>And, of course, it can take a block too:</p>
|
||||
<div class="codehilite"><pre><span class="k">if</span> <span class="p">(</span><span class="n">ready</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"go!"</span><span class="p">)</span>
|
||||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"not ready!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h2>The logical operators <code>&&</code> and <code>||</code> <a href="#the-logical-operators-<code>&&</code>-and-<code>||</code>" name="the-logical-operators-<code>&&</code>-and-<code>||</code>" class="header-anchor">#</a></h2>
|
||||
<p>The <code>&&</code> and <code>||</code> operators are lumped here under branching because they conditionally execute some code—they short-circuit. Both of them are infix operators, and, depending on the value of the left-hand side, the right-hand operand expression may or may not be evaluated.</p>
|
||||
<p>An <code>&&</code> ("logical and") expression evaluates the left-hand argument. If it's false, it returns that value. Otherwise it evaluates and returns the right-hand argument.</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="kc">false</span> <span class="o">&&</span> <span class="m">1</span><span class="p">)</span> <span class="c1">// false</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="m">1</span> <span class="o">&&</span> <span class="m">2</span><span class="p">)</span> <span class="c1">// 2</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>An <code>||</code> ("logical or") expression is reversed. If the left-hand argument is true, it's returned, otherwise the right-hand argument is evaluated and returned:</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="kc">false</span> <span class="o">||</span> <span class="m">1</span><span class="p">)</span> <span class="c1">// 1</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="m">1</span> <span class="o">||</span> <span class="m">2</span><span class="p">)</span> <span class="c1">// 1</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h2>The conditional operator <code>?:</code> <a href="#the-conditional-operator-<code>" name="the-conditional-operator-</code>" class="header-anchor">#</a></h2>
|
||||
<p>Also known as the "ternary" operator since it takes three arguments, Wren has the little "if statement in the form of an expression" you know and love from C and its bretheren.</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="m">1</span> <span class="o">!=</span> <span class="m">2</span> <span class="o">?</span> <span class="s2">"math is sane"</span> <span class="o">:</span> <span class="s2">"math is not sane!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>It takes a condition expression, followed by <code>?</code>, followed by a then expression, a <code>:</code>, then an else expression. Just like <code>if</code>, it evaluates the condition. If true, it evaluates (and returns) the then expression. Otherwise it does the else expression.</p>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
<div class="page">
|
||||
<div class="main-column">
|
||||
<p>Wren lives <a href="https://github.com/munificent/wren">on GitHub</a> — Made with ❤ by <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a>.</p>
|
||||
<div class="main-column">
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
189
classes.html
189
classes.html
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -59,8 +58,11 @@
|
||||
<main>
|
||||
<h1>Classes</h1>
|
||||
<p>Every value in Wren is an object, and every object is an instance of a class.
|
||||
Even <code>true</code> and <code>false</code> are full-featured objects—instances of the <code>Bool</code> class.</p>
|
||||
<p>Classes contain both <em>behavior</em> and <em>state</em>. Behavior is defined in <em>methods</em> which are stored in the class. State is defined in <em>fields</em>, whose values are stored in each instance.</p>
|
||||
Even <code>true</code> and <code>false</code> are full-featured objects—instances of the <code>Bool</code>
|
||||
class.</p>
|
||||
<p>Classes contain both <em>behavior</em> and <em>state</em>. Behavior is defined in <em>methods</em>
|
||||
which are stored in the class. State is defined in <em>fields</em>, whose values are
|
||||
stored in each instance.</p>
|
||||
<h2>Defining a class <a href="#defining-a-class" name="defining-a-class" class="header-anchor">#</a></h2>
|
||||
<p>Classes are created using the <code>class</code> keyword, unsurprisingly:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{}</span>
|
||||
@ -78,7 +80,8 @@ Even <code>true</code> and <code>false</code> are full-featured objects—in
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>This defines a <code>prance</code> method that takes no arguments. To support parameters, add a parenthesized parameter list after the method's name:</p>
|
||||
<p>This defines a <code>prance</code> method that takes no arguments. To support parameters,
|
||||
add a parenthesized parameter list after the method's name:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||||
<span class="n">prance</span><span class="p">(</span><span class="n">where</span><span class="p">,</span> <span class="n">when</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"The unicorn prances in "</span> <span class="o">+</span> <span class="n">where</span> <span class="o">+</span> <span class="s2">" at "</span> <span class="o">+</span> <span class="n">when</span><span class="p">)</span>
|
||||
@ -87,7 +90,11 @@ Even <code>true</code> and <code>false</code> are full-featured objects—in
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Unlike most other dynamically-typed languages, in Wren you can have multiple methods in a class with the same name, as long as they take a different number of parameters. In technical terms, you can <em>overload by arity</em>. So this class is fine:</p>
|
||||
<h3>Arity <a href="#arity" name="arity" class="header-anchor">#</a></h3>
|
||||
<p>Unlike most other dynamically-typed languages, in Wren you can have multiple
|
||||
methods in a class with the same name, as long as they take a different number
|
||||
of parameters. In technical terms, you can <em>overload by arity</em>. So this class
|
||||
is fine:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||||
<span class="n">prance</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"The unicorn prances in a fancy manner!"</span><span class="p">)</span>
|
||||
@ -104,39 +111,25 @@ Even <code>true</code> and <code>false</code> are full-featured objects—in
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>When you <a href="method-calls.html">call</a> the <code>prance</code> method, it selects the right one based on how many arguments you pass it.</p>
|
||||
<h2>Constructors <a href="#constructors" name="constructors" class="header-anchor">#</a></h2>
|
||||
<p>To create a new instance of a class, you use the <code>new</code> keyword. We can make a unicorn like so:</p>
|
||||
<div class="codehilite"><pre><span class="k">new</span> <span class="n">Unicorn</span>
|
||||
<p>And you can call each of the methods like so:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">unicorn</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Unicorn</span>
|
||||
<span class="n">unicorn</span><span class="p">.</span><span class="n">prance</span>
|
||||
<span class="n">unicorn</span><span class="p">.</span><span class="n">prance</span><span class="p">(</span><span class="s2">"Antwerp"</span><span class="p">)</span>
|
||||
<span class="n">unicorn</span><span class="p">.</span><span class="n">prance</span><span class="p">(</span><span class="s2">"Brussels"</span><span class="p">,</span> <span class="s2">"high noon"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You almost always want to define some state or do some other initialization on a new object. For that, you'll want to define a constructor, like so:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||||
<span class="k">new</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"I am a constructor!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>When you create an instance with <code>new</code>, its constructor will be invoked. It's just a method with a special name. Like methods, you can pass arguments to the constructor by adding a parenthesized parameter list after <code>new</code>:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||||
<span class="k">new</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">color</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"My name is "</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s2">" and I am "</span> <span class="o">+</span> <span class="n">color</span> <span class="o">+</span> <span class="s2">"."</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Values are passed to the constructor like so:</p>
|
||||
<div class="codehilite"><pre><span class="k">new</span> <span class="n">Unicorn</span><span class="p">(</span><span class="s2">"Flicker"</span><span class="p">,</span> <span class="s2">"purple"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Like other methods, you can overload constructors by arity.</p>
|
||||
<h2>Operators <a href="#operators" name="operators" class="header-anchor">#</a></h2>
|
||||
<p>Operators are just special syntax for regular <a href="method-calls.html">method calls</a> on the left hand operand (or only operand in the case of unary operators like <code>!</code> and <code>~</code>). You can define them like so:</p>
|
||||
<p>The number of arguments provided at the callsite determines which method is
|
||||
chosen.</p>
|
||||
<p>It's often natural to have the same conceptual operation work with different
|
||||
sets of arguments. In other languages, you'd define a single method for the
|
||||
operation and have to check for "undefined" or missing arguments. Wren just
|
||||
treats them as different methods that you can implement separately.</p>
|
||||
<h3>Operators <a href="#operators" name="operators" class="header-anchor">#</a></h3>
|
||||
<p>Operators are just special syntax for a method call on the left hand operand
|
||||
(or only operand in the case of unary operators like <code>!</code> and <code>~</code>). In other
|
||||
words, you can think of <code>a + b</code> as meaning <code>a.+(b)</code>.</p>
|
||||
<p>You can define operators in your class like so:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||||
<span class="c1">// Infix:</span>
|
||||
<span class="o">+</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="p">{</span>
|
||||
@ -160,23 +153,120 @@ Even <code>true</code> and <code>false</code> are full-featured objects—in
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Note that <code>-</code> can be both a prefix and infix operator. If there's a parameter list, it's the infix one, otherwise, it's prefix. Since Wren supports overloading by arity, it's no problem for a class to define both.</p>
|
||||
<p>Operator overloading is really useful for types like vectors and complex numbers where the reader knows what the operators will do, but can make code deeply confusing if overused. When in doubt, use a real name.</p>
|
||||
<h2>Setters <a href="#setters" name="setters" class="header-anchor">#</a></h2>
|
||||
<p><strong>TODO: ...</strong></p>
|
||||
<h2>Fields <a href="#fields" name="fields" class="header-anchor">#</a></h2>
|
||||
<p>Note that <code>-</code> can be both a prefix and infix operator. If there's a parameter
|
||||
list, it's the infix one, otherwise, it's prefix. Since Wren supports
|
||||
overloading by arity, it's no problem for a class to define both.</p>
|
||||
<h3>Subscript operators <a href="#subscript-operators" name="subscript-operators" class="header-anchor">#</a></h3>
|
||||
<p><strong>TODO</strong></p>
|
||||
<h3>Setters <a href="#setters" name="setters" class="header-anchor">#</a></h3>
|
||||
<p><strong>TODO</strong></p>
|
||||
<h2>Constructors <a href="#constructors" name="constructors" class="header-anchor">#</a></h2>
|
||||
<p>To create a new instance of a class, you use the <code>new</code> keyword. We can make a
|
||||
unicorn like so:</p>
|
||||
<div class="codehilite"><pre><span class="k">new</span> <span class="n">Unicorn</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You almost always want to define some state or do some other initialization on
|
||||
a new object. For that, you'll want to define a constructor, like so:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||||
<span class="k">new</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"I am a constructor!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>When you create an instance with <code>new</code>, its constructor will be invoked. It's
|
||||
just a method with a special name. Like methods, you can pass arguments to the
|
||||
constructor by adding a parenthesized parameter list after <code>new</code>:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||||
<span class="k">new</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">color</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"My name is "</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s2">" and I am "</span> <span class="o">+</span> <span class="n">color</span> <span class="o">+</span> <span class="s2">"."</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Values are passed to the constructor like so:</p>
|
||||
<div class="codehilite"><pre><span class="k">new</span> <span class="n">Unicorn</span><span class="p">(</span><span class="s2">"Flicker"</span><span class="p">,</span> <span class="s2">"purple"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Like other methods, you can overload constructors by <a href="#arity">arity</a>.</p>
|
||||
<h2>Fields <a href="#fields" name="fields" class="header-anchor">#</a></h2>
|
||||
<p>All state stored in instances is stored in <em>fields</em>. Each field has a named
|
||||
that starts with an underscore.</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Rectangle</span> <span class="p">{</span>
|
||||
<span class="n">area</span> <span class="p">{</span> <span class="n">_width</span> <span class="o">*</span> <span class="n">_height</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Other stuff...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Here, <code>_width</code> and <code>_height</code> in the <code>area</code> <a href="classes.html#methods">getter</a> refer
|
||||
to fields on the rectangle instance. You can think of them like <code>this.width</code>
|
||||
and <code>this.height</code> in other languages.</p>
|
||||
<p>When a field name appears, Wren looks for the nearest enclosing class and looks
|
||||
up the field on the instance of that class. Field names cannot be used outside
|
||||
of an instance method. They <em>can</em> be used inside a <a href="functions.html">function</a>
|
||||
in a method. Wren will look outside any nested functions until it finds an
|
||||
enclosing method.</p>
|
||||
<p>Unlike <a href="variables.html">variables</a>, fields are implicitly declared by simply
|
||||
assigning to them. If you access a field before it has been initialized, its
|
||||
value is <code>null</code>.</p>
|
||||
<h3>Encapsulation <a href="#encapsulation" name="encapsulation" class="header-anchor">#</a></h3>
|
||||
<p>All fields are <em>protected</em> in Wren—an object's fields can only be
|
||||
directly accessed from within methods defined on the object's class, or its
|
||||
superclasses. You cannot even access fields on another instance of your own
|
||||
class, unlike C++ and Java.</p>
|
||||
<p>If you want to make a property of an object visible, you need to define a
|
||||
getter to expose it:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Rectangle</span> <span class="p">{</span>
|
||||
<span class="n">width</span> <span class="p">{</span> <span class="n">_width</span> <span class="p">}</span>
|
||||
<span class="n">height</span> <span class="p">{</span> <span class="n">_height</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// ...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>To allow outside code to modify the field, you'll also need to provide setters:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Rectangle</span> <span class="p">{</span>
|
||||
<span class="n">width</span><span class="o">=</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span> <span class="n">_width</span> <span class="o">=</span> <span class="n">value</span> <span class="p">}</span>
|
||||
<span class="n">height</span><span class="o">=</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span> <span class="n">_height</span> <span class="o">=</span> <span class="n">value</span> <span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>One thing we've learned in the past forty years of software engineering is that
|
||||
encapsulating state tends to make code easier to maintain, so Wren defaults to
|
||||
keeping your object's state pretty tightly bundled up. Don't feel that you have
|
||||
to or even should define getters or setters for most of your object's fields.</p>
|
||||
<h2>Metaclasses and static members <a href="#metaclasses-and-static-members" name="metaclasses-and-static-members" class="header-anchor">#</a></h2>
|
||||
<p><strong>TODO</strong></p>
|
||||
<h3>Static fields <a href="#static-fields" name="static-fields" class="header-anchor">#</a></h3>
|
||||
<p>A name that starts with <em>two</em> underscores is a <em>static</em> field. They work
|
||||
similar to <a href="#fields">fields</a> except the data is stored on the class itself, and
|
||||
not the instance. They can be used in <em>both</em> instance and static methods.</p>
|
||||
<p><strong>TODO: Example.</strong></p>
|
||||
<h2>Inheritance <a href="#inheritance" name="inheritance" class="header-anchor">#</a></h2>
|
||||
<p>A class can inherit from a "parent" or <em>superclass</em>. When you invoke a method on an object of some class, if it can't be found, it walks up the chain of superclasses looking for it there.</p>
|
||||
<p>By default, any new class inherits from <code>Object</code>, which is the superclass from which all other classes ultimately descend. You can specify a different parent class using <code>is</code> when you declare the class:</p>
|
||||
<p>A class can inherit from a "parent" or <em>superclass</em>. When you invoke a method
|
||||
on an object of some class, if it can't be found, it walks up the chain of
|
||||
superclasses looking for it there.</p>
|
||||
<p>By default, any new class inherits from <code>Object</code>, which is the superclass from
|
||||
which all other classes ultimately descend. You can specify a different parent
|
||||
class using <code>is</code> when you declare the class:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Pegasus</span> <span class="k">is</span> <span class="n">Unicorn</span> <span class="p">{}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>This declares a new class <code>Pegasus</code> that inherits from <code>Unicorn</code>.</p>
|
||||
<p>The metaclass hierarchy does <em>not</em> parallel the regular class hierarchy. So, if <code>Pegasus</code> inherits from <code>Unicorn</code>, <code>Pegasus</code>'s metaclass will not inherit from <code>Unicorn</code>'s metaclass. In more prosaic terms, this means that static methods are not inherited.</p>
|
||||
<p>The metaclass hierarchy does <em>not</em> parallel the regular class hierarchy. So, if
|
||||
<code>Pegasus</code> inherits from <code>Unicorn</code>, <code>Pegasus</code>'s metaclass will not inherit from
|
||||
<code>Unicorn</code>'s metaclass. In more prosaic terms, this means that static methods
|
||||
are not inherited.</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||||
<span class="c1">// Unicorns cannot fly. :(</span>
|
||||
<span class="kd">static</span> <span class="n">canFly</span> <span class="p">{</span> <span class="kc">false</span> <span class="p">}</span>
|
||||
@ -188,7 +278,9 @@ Even <code>true</code> and <code>false</code> are full-featured objects—in
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Constructors, however, initialize the instance <em>after</em> it has been created. They are defined as instance methods on the class and not on the metaclass. That means that constructors <em>are</em> inherited.</p>
|
||||
<p>Constructors, however, initialize the instance <em>after</em> it has been created.
|
||||
They are defined as instance methods on the class and not on the metaclass.
|
||||
That means that constructors <em>are</em> inherited.</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||||
<span class="k">new</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"My name is "</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s2">"."</span><span class="p">)</span>
|
||||
@ -199,11 +291,6 @@ Even <code>true</code> and <code>false</code> are full-featured objects—in
|
||||
|
||||
<span class="k">new</span> <span class="n">Pegasus</span><span class="p">(</span><span class="s2">"Fred"</span><span class="p">)</span> <span class="c1">// Prints "My name is Fred.".</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h2>Superclass method calls <a href="#superclass-method-calls" name="superclass-method-calls" class="header-anchor">#</a></h2>
|
||||
<p><strong>TODO</strong></p>
|
||||
<p><strong>TODO: this</strong></p>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -58,10 +57,18 @@
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Contributing</h1>
|
||||
<p>It should be obvious by now that Wren is under active development and there's lots left to do. I'd be delighted to have your help.</p>
|
||||
<p>Wren uses the OSI-approved <a href="http://opensource.org/licenses/MIT">MIT license</a>. I'm not sure exactly what that means, but I went with the most permissive license I could find.</p>
|
||||
<p>The source is developed <a href="https://github.com/munificent/wren">on GitHub</a>. My hope is that the codebase, tests, and documentation are easy to understand and contribute to. If they aren't, that's a bug. If you're looking for somewhere to get started, try writing some example programs in Wren and see what rough spots you run into. You can also look through to code for <code>// TODO</code> or help improve <a href="https://github.com/munificent/wren/tree/master/doc/site">these docs</a>.</p>
|
||||
<p>If you have questions, feel free to <a href="https://github.com/munificent/wren/issues">file an issue</a> or email me (<code>robert</code> at <code>stuffwithstuff.com</code>).</p>
|
||||
<p>It should be obvious by now that Wren is under active development and there's
|
||||
lots left to do. I'd be delighted to have your help.</p>
|
||||
<p>Wren uses the OSI-approved <a href="http://opensource.org/licenses/MIT">MIT license</a>. I'm not sure exactly what that
|
||||
means, but I went with the most permissive license I could find.</p>
|
||||
<p>The source is developed <a href="https://github.com/munificent/wren">on GitHub</a>. My hope is that the codebase,
|
||||
tests, and documentation are easy to understand and contribute to. If they
|
||||
aren't, that's a bug. If you're looking for somewhere to get started, try
|
||||
writing some example programs in Wren and see what rough spots you run into.
|
||||
You can also look through to code for <code>// TODO</code> or help improve
|
||||
<a href="https://github.com/munificent/wren/tree/master/doc/site">these docs</a>.</p>
|
||||
<p>If you have questions, feel free to <a href="https://github.com/munificent/wren/issues">file an issue</a> or email me
|
||||
(<code>robert</code> at <code>stuffwithstuff.com</code>).</p>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
|
||||
<title>Looping – Wren</title>
|
||||
<title>Control Flow – Wren</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<link href='http://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
|
||||
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -57,10 +56,65 @@
|
||||
</section>
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Looping</h1>
|
||||
<p>It's hard to write a useful program without executing some chunk of code repeatedly. To do that, you use looping statements. There are two in Wren, and they should be familiar if you've used other imperative languages.</p>
|
||||
<h1>Control Flow</h1>
|
||||
<p>Control flow is used to determine which chunks of code are executed and how
|
||||
many times. <em>Branching</em> statements deciding whether or not to execute some code
|
||||
and <em>looping</em> ones execute something more than once.</p>
|
||||
<h2>Truth <a href="#truth" name="truth" class="header-anchor">#</a></h2>
|
||||
<p>All control flow is based on <em>deciding</em> whether or not to do something. This
|
||||
decision is conditional on the value of some expression. We take the entire
|
||||
universe of possible values and divide them into two buckets: some we consider
|
||||
"true" and the rest are "false". If the expression results in a value in the
|
||||
true bucket, we do one thing. Otherwise, we do something else.</p>
|
||||
<p>Obviously, the boolean <code>true</code> is in the "true" bucket and <code>false</code> is in
|
||||
"false", but what about values of other types? The choice is ultimately
|
||||
arbitrary, and different languages have different rules. Wren's rules follow
|
||||
Ruby:</p>
|
||||
<ul>
|
||||
<li>The boolean value <code>false</code> is false.</li>
|
||||
<li>The null value <code>null</code> is false.</li>
|
||||
<li>Everything else is true.</li>
|
||||
</ul>
|
||||
<p>This means <code>0</code>, empty strings, and empty collections are all considered "true"
|
||||
values.</p>
|
||||
<h2>If statements <a href="#if-statements" name="if-statements" class="header-anchor">#</a></h2>
|
||||
<p>The simplest branching statement, <code>if</code> lets you conditionally skip a chunk of
|
||||
code. It looks like this:</p>
|
||||
<div class="codehilite"><pre><span class="k">if</span> <span class="p">(</span><span class="n">ready</span><span class="p">)</span> <span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"go!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>That evaluates the parenthesized expression after <code>if</code>. If it's true, then the
|
||||
statement after the condition is evaluated. Otherwise it is skipped. Instead of
|
||||
a statement, you can have a <a href="syntax.html#blocks">block</a>:</p>
|
||||
<div class="codehilite"><pre><span class="k">if</span> <span class="p">(</span><span class="n">ready</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"getSet"</span><span class="p">)</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"go!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You may also provide an <code>else</code> branch. It will be executed if the condition is
|
||||
false:</p>
|
||||
<div class="codehilite"><pre><span class="k">if</span> <span class="p">(</span><span class="n">ready</span><span class="p">)</span> <span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"go!"</span><span class="p">)</span> <span class="k">else</span> <span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"not ready!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>And, of course, it can take a block too:</p>
|
||||
<div class="codehilite"><pre><span class="k">if</span> <span class="p">(</span><span class="n">ready</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"go!"</span><span class="p">)</span>
|
||||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"not ready!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h2>While statements <a href="#while-statements" name="while-statements" class="header-anchor">#</a></h2>
|
||||
<p>A <code>while</code> statement executes a chunk of code as long as a condition continues to hold. For example:</p>
|
||||
<p>It's hard to write a useful program without executing some chunk of code
|
||||
repeatedly. To do that, you use looping statements. There are two in Wren, and
|
||||
they should be familiar if you've used other imperative languages.</p>
|
||||
<p>The simplest, a <code>while</code> statement executes a chunk of code as long as a
|
||||
condition continues to hold. For example:</p>
|
||||
<div class="codehilite"><pre><span class="c1">// Hailstone sequence.</span>
|
||||
<span class="kd">var</span> <span class="n">n</span> <span class="o">=</span> <span class="m">27</span>
|
||||
<span class="k">while</span> <span class="p">(</span><span class="n">n</span> <span class="o">!=</span> <span class="m">1</span><span class="p">)</span> <span class="p">{</span>
|
||||
@ -73,15 +127,23 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>This evaluates the expression <code>n != 1</code>. If it is <a href="branching.html">true</a>, then it executes the following body. After that, it loops back to the top, and evaluates the condition again. It keeps doing this as long as the condition evaluates to something true.</p>
|
||||
<p>The condition for a while loop can be any expression, and must be surrounded by parentheses. The body of the loop is usually a curly block but can also be a single statement:</p>
|
||||
<p>This evaluates the expression <code>n != 1</code>. If it is true, then it executes the
|
||||
following body. After that, it loops back to the top, and evaluates the
|
||||
condition again. It keeps doing this as long as the condition evaluates to
|
||||
something true.</p>
|
||||
<p>The condition for a while loop can be any expression, and must be surrounded by
|
||||
parentheses. The body of the loop is usually a curly block but can also be a
|
||||
single statement:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">n</span> <span class="o">=</span> <span class="m">27</span>
|
||||
<span class="k">while</span> <span class="p">(</span><span class="n">n</span> <span class="o">!=</span> <span class="m">1</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">%</span> <span class="m">2</span> <span class="o">==</span> <span class="m">0</span><span class="p">)</span> <span class="n">n</span> <span class="o">=</span> <span class="n">n</span> <span class="o">/</span> <span class="m">2</span> <span class="k">else</span> <span class="n">n</span> <span class="o">=</span> <span class="m">3</span> <span class="o">*</span> <span class="n">n</span> <span class="o">+</span> <span class="m">1</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h2>For statements <a href="#for-statements" name="for-statements" class="header-anchor">#</a></h2>
|
||||
<p>While statements are useful when you want to loop indefinitely or according to some complex condition. But in most cases, you're looping through a <a href="lists.html">list</a>, a series of numbers, or some other "sequence" object. That's what <code>for</code> is for. It looks like this:</p>
|
||||
<p>While statements are useful when you want to loop indefinitely or according to
|
||||
some complex condition. But in most cases, you're looping through a
|
||||
<a href="lists.html">list</a>, a series of numbers, or some other "sequence" object.
|
||||
That's what <code>for</code> is for. It looks like this:</p>
|
||||
<div class="codehilite"><pre><span class="k">for</span> <span class="p">(</span><span class="n">beatle</span> <span class="k">in</span> <span class="p">[</span><span class="s2">"george"</span><span class="p">,</span> <span class="s2">"john"</span><span class="p">,</span> <span class="s2">"paul"</span><span class="p">,</span> <span class="s2">"ringo"</span><span class="p">])</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">beatle</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
@ -91,17 +153,24 @@
|
||||
<p>A <code>for</code> loop has three components:</p>
|
||||
<ol>
|
||||
<li>
|
||||
<p>A <em>variable name</em> to bind. In the example, that's <code>beatle</code>. Wren will create a new variable with that name whose scope is the body of the loop.</p>
|
||||
<p>A <em>variable name</em> to bind. In the example, that's <code>beatle</code>. Wren will create
|
||||
a new variable with that name whose scope is the body of the loop.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>A <em>sequence expression</em>. This determines what you're looping over. It gets evaluated <em>once</em> before the body of the loop. In this case, it's a list literal, but it can be any expression.</p>
|
||||
<p>A <em>sequence expression</em>. This determines what you're looping over. It gets
|
||||
evaluated <em>once</em> before the body of the loop. In this case, it's a list
|
||||
literal, but it can be any expression.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>A <em>body</em>. This is a curly block or a single statement. It gets executed once for each iteration of the loop.</p>
|
||||
<p>A <em>body</em>. This is a curly block or a single statement. It gets executed once
|
||||
for each iteration of the loop.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<h2>Break statements <a href="#break-statements" name="break-statements" class="header-anchor">#</a></h2>
|
||||
<p>Sometimes, right in the middle of a loop body, you decide you want to bail out and stop. To do that, you can use a <code>break</code> statement. It's just the <code>break</code> keyword all by itself. That will immediately exit out of the nearest enclosing <code>while</code> or <code>for</code> loop.</p>
|
||||
<p>Sometimes, right in the middle of a loop body, you decide you want to bail out
|
||||
and stop. To do that, you can use a <code>break</code> statement. It's just the <code>break</code>
|
||||
keyword all by itself. That will immediately exit out of the nearest enclosing
|
||||
<code>while</code> or <code>for</code> loop.</p>
|
||||
<div class="codehilite"><pre><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="k">in</span> <span class="p">[</span><span class="m">1</span><span class="p">,</span> <span class="m">2</span><span class="p">,</span> <span class="m">3</span><span class="p">,</span> <span class="m">4</span><span class="p">])</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="m">3</span><span class="p">)</span> <span class="k">break</span>
|
||||
@ -111,23 +180,35 @@
|
||||
|
||||
<p>So this program will print the numbers from 1 to 3, but will not print 4.</p>
|
||||
<h2>Numeric ranges <a href="#numeric-ranges" name="numeric-ranges" class="header-anchor">#</a></h2>
|
||||
<p>Lists are one common use for <code>for</code> loops, but sometimes you want to walk over a sequence of numbers, or loop a number of times. For that, you can create a <a href="values.html#ranges">range object</a>, like so:</p>
|
||||
<p>Lists are one common use for <code>for</code> loops, but sometimes you want to walk over a
|
||||
sequence of numbers, or loop a number of times. For that, you can create a
|
||||
<a href="values.html#ranges">range</a>, like so:</p>
|
||||
<div class="codehilite"><pre><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="k">in</span> <span class="m">1.</span><span class="p">.</span><span class="m">100</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>This loops over the numbers from 1 to 100, including 100 itself. If you want to leave off the last value, use three dots instead of two:</p>
|
||||
<p>This loops over the numbers from 1 to 100, including 100 itself. If you want to
|
||||
leave off the last value, use three dots instead of two:</p>
|
||||
<div class="codehilite"><pre><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="k">in</span> <span class="m">1.</span><span class="p">..</span><span class="m">100</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>This looks like some special "range" syntax in the <code>for</code> loop, but it's actually just a pair of operators. The <code>..</code> and <code>...</code> syntax are infix "range" operators. Like <a href="method-calls.html">other operators</a>, they are just special syntax for a regular method call. The number type implements them and returns instances of a <code>Range</code> class. That class in turn knows how to iterate over a series of numbers.</p>
|
||||
<p>This looks like some special "range" syntax in the <code>for</code> loop, but it's
|
||||
actually just a pair of operators. The <code>..</code> and <code>...</code> syntax are infix "range"
|
||||
operators. Like <a href="expressions.html#operators">other operators</a>, they are just
|
||||
special syntax for a regular method call. The number type implements them and
|
||||
returns a <a href="values.html#ranges">range object</a> that knows how to iterate over a
|
||||
series of numbers.</p>
|
||||
<h2>The iterator protocol <a href="#the-iterator-protocol" name="the-iterator-protocol" class="header-anchor">#</a></h2>
|
||||
<p>Lists and ranges cover the two most common kinds of loops, but you should also be able to define your own sequences. To enable that, the semantics of a <code>for</code> are defined in terms of an "iterator protocol". The loop itself doesn't know anything about lists or ranges, it just knows how to call two particular methods on the object that resulted from evaluating the sequence expression.</p>
|
||||
<p>Lists and ranges cover the two most common kinds of loops, but you should also
|
||||
be able to define your own sequences. To enable that, the semantics of a <code>for</code>
|
||||
are defined in terms of an "iterator protocol". The loop itself doesn't know
|
||||
anything about lists or ranges, it just knows how to call two particular
|
||||
methods on the object that resulted from evaluating the sequence expression.</p>
|
||||
<p>When you write a loop like this:</p>
|
||||
<div class="codehilite"><pre><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="k">in</span> <span class="m">1.</span><span class="p">.</span><span class="m">100</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
|
||||
@ -145,10 +226,24 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>First, Wren evaluates the sequence expression and stores it in a hidden variable (written <code>seq_</code> in the example but in reality it doesn't have a name you can use). It also creates a hidden "iterator" variable and initializes it to <code>null</code>.</p>
|
||||
<p>Each iteration, it calls <code>iterate()</code> on the sequence, passing in the current iterator value. (In the first iteration, it passes in <code>null</code>.) The sequence's job is to take that iterator and advance it to the next element in the sequence. (Or, in the case where the iterator is <code>null</code>, to advance it to the <em>first</em> element). It then returns either the new iterator, or <code>false</code> to indicate that there are no more elements.</p>
|
||||
<p>If <code>false</code> is returned, Wren exits out of the loop and we're done. If anything else is returned, that means that we have advanced to a new valid element. To get that, Wren then calls <code>iteratorValue()</code> on the sequence and passes in the iterator value that it just got from calling <code>iterate()</code>. The sequence uses that to look up and return the appropriate element.</p>
|
||||
<p>The built-in <a href="lists.html">List</a> and <a href="values.html#ranges">Range</a> types implement <code>iterate()</code> and <code>iteratorValue()</code> to walk over their respective sequences. You can implement the same methods in your classes to make your own types iterable.</p>
|
||||
<p>First, Wren evaluates the sequence expression and stores it in a hidden
|
||||
variable (written <code>seq_</code> in the example but in reality it doesn't have a name
|
||||
you can use). It also creates a hidden "iterator" variable and initializes it
|
||||
to <code>null</code>.</p>
|
||||
<p>Each iteration, it calls <code>iterate()</code> on the sequence, passing in the current
|
||||
iterator value. (In the first iteration, it passes in <code>null</code>.) The sequence's
|
||||
job is to take that iterator and advance it to the next element in the
|
||||
sequence. (Or, in the case where the iterator is <code>null</code>, to advance it to the
|
||||
<em>first</em> element). It then returns either the new iterator, or <code>false</code> to
|
||||
indicate that there are no more elements.</p>
|
||||
<p>If <code>false</code> is returned, Wren exits out of the loop and we're done. If anything
|
||||
else is returned, that means that we have advanced to a new valid element. To
|
||||
get that, Wren then calls <code>iteratorValue()</code> on the sequence and passes in the
|
||||
iterator value that it just got from calling <code>iterate()</code>. The sequence uses
|
||||
that to look up and return the appropriate element.</p>
|
||||
<p>The built-in <a href="lists.html">List</a> and <a href="values.html#ranges">Range</a> types implement
|
||||
<code>iterate()</code> and <code>iteratorValue()</code> to walk over their respective sequences. You
|
||||
can implement the same methods in your classes to make your own types iterable.</p>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -60,7 +59,9 @@
|
||||
<h1>Core Library</h1>
|
||||
<h2>Object Class <a href="#object-class" name="object-class" class="header-anchor">#</a></h2>
|
||||
<h3><strong>==</strong>(other) and <strong>!=</strong>(other) operators <a href="#**==**(other)-and-**=**(other)-operators" name="**==**(other)-and-**=**(other)-operators" class="header-anchor">#</a></h3>
|
||||
<p>Compares two objects using built-in equality. This compares numbers by value, and all other objects are compared by identity—two objects are equal only if they are the exact same object.</p>
|
||||
<p>Compares two objects using built-in equality. This compares numbers by value,
|
||||
and all other objects are compared by identity—two objects are equal only
|
||||
if they are the exact same object.</p>
|
||||
<h3><strong>toString</strong> <a href="#**tostring**" name="**tostring**" class="header-anchor">#</a></h3>
|
||||
<p>A default string representation of the object.</p>
|
||||
<h3><strong>type</strong> <a href="#**type**" name="**type**" class="header-anchor">#</a></h3>
|
||||
@ -84,7 +85,8 @@
|
||||
<h2>Fiber Class <a href="#fiber-class" name="fiber-class" class="header-anchor">#</a></h2>
|
||||
<p>A lightweight coroutine. <a href="fibers.html">Here</a> is a gentle introduction.</p>
|
||||
<h3>new <strong>Fiber</strong>(function) <a href="#new-**fiber**(function)" name="new-**fiber**(function)" class="header-anchor">#</a></h3>
|
||||
<p>Creates a new fiber that executes <code>function</code> in a separate coroutine when the fiber is run. Does not immediately start running the fiber.</p>
|
||||
<p>Creates a new fiber that executes <code>function</code> in a separate coroutine when the
|
||||
fiber is run. Does not immediately start running the fiber.</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"I won't get printed"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
@ -92,7 +94,8 @@
|
||||
|
||||
|
||||
<h3>Fiber.<strong>yield</strong> <a href="#fiber**yield**" name="fiber**yield**" class="header-anchor">#</a></h3>
|
||||
<p>Pauses the current fiber and transfers control to the parent fiber. "Parent" here means the last fiber that was started using <code>call</code> and not <code>run</code>.</p>
|
||||
<p>Pauses the current fiber and transfers control to the parent fiber. "Parent"
|
||||
here means the last fiber that was started using <code>call</code> and not <code>run</code>.</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"Before yield"</span><span class="p">)</span>
|
||||
<span class="n">Fiber</span><span class="p">.</span><span class="n">yield</span>
|
||||
@ -106,7 +109,8 @@
|
||||
|
||||
|
||||
<p>When resumed, the parent fiber's <code>call</code> method returns <code>null</code>.</p>
|
||||
<p>If a yielded fiber is resumed by calling <code>call()</code> or <code>run()</code> with an argument, <code>yield</code> returns that value.</p>
|
||||
<p>If a yielded fiber is resumed by calling <code>call()</code> or <code>run()</code> with an argument,
|
||||
<code>yield</code> returns that value.</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">Fiber</span><span class="p">.</span><span class="n">yield</span><span class="p">)</span> <span class="c1">// "value"</span>
|
||||
<span class="p">}</span>
|
||||
@ -127,7 +131,8 @@
|
||||
|
||||
|
||||
<h3>Fiber.<strong>yield</strong>(value) <a href="#fiber**yield**(value)" name="fiber**yield**(value)" class="header-anchor">#</a></h3>
|
||||
<p>Similar to <code>Fiber.yield</code> but provides a value to return to the parent fiber's <code>call</code>.</p>
|
||||
<p>Similar to <code>Fiber.yield</code> but provides a value to return to the parent fiber's
|
||||
<code>call</code>.</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="n">Fiber</span><span class="p">.</span><span class="n">yield</span><span class="p">(</span><span class="s2">"value"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
@ -141,15 +146,20 @@
|
||||
<h3><strong>call</strong>(value) <a href="#**call**(value)" name="**call**(value)" class="header-anchor">#</a></h3>
|
||||
<p><strong>TODO</strong></p>
|
||||
<h3><strong>isDone</strong> <a href="#**isdone**" name="**isdone**" class="header-anchor">#</a></h3>
|
||||
<p>Whether the fiber's main function has completed and the fiber can no longer be run. This returns <code>false</code> if the fiber is currently running or has yielded.</p>
|
||||
<p>Whether the fiber's main function has completed and the fiber can no longer be
|
||||
run. This returns <code>false</code> if the fiber is currently running or has yielded.</p>
|
||||
<h3><strong>run</strong> <a href="#**run**" name="**run**" class="header-anchor">#</a></h3>
|
||||
<p><strong>TODO</strong></p>
|
||||
<h3><strong>run</strong>(value) <a href="#**run**(value)" name="**run**(value)" class="header-anchor">#</a></h3>
|
||||
<p><strong>TODO</strong></p>
|
||||
<h2>Fn Class <a href="#fn-class" name="fn-class" class="header-anchor">#</a></h2>
|
||||
<p>A first class function—an object that wraps an executable chunk of code. <a href="functions.html">Here</a> is a friendly introduction.</p>
|
||||
<p>A first class function—an object that wraps an executable chunk of code.
|
||||
<a href="functions.html">Here</a> is a friendly introduction.</p>
|
||||
<h3>new <strong>Fn</strong>(function) <a href="#new-**fn**(function)" name="new-**fn**(function)" class="header-anchor">#</a></h3>
|
||||
<p>Creates a new function from... <code>function</code>. Of course, <code>function</code> is already be a function, so this really just returns the argument. It exists mainly to let you create a "bare" function when you don't want to immediately pass it as a <a href="functions.html#creating-functions">block argument</a> to some other method.</p>
|
||||
<p>Creates a new function from... <code>function</code>. Of course, <code>function</code> is already be
|
||||
a function, so this really just returns the argument. It exists mainly to let
|
||||
you create a "bare" function when you don't want to immediately pass it as a
|
||||
<a href="functions.html#block-arguments">block argument</a> to some other method.</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fn</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fn</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"The body"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
@ -174,7 +184,9 @@
|
||||
<h3><strong>floor</strong> <a href="#**floor**" name="**floor**" class="header-anchor">#</a></h3>
|
||||
<p><strong>TODO</strong></p>
|
||||
<h3><strong>isNan</strong> <a href="#**isnan**" name="**isnan**" class="header-anchor">#</a></h3>
|
||||
<p>Whether the number is <a href="http://en.wikipedia.org/wiki/NaN">not a number</a>. This is <code>false</code> for normal number values and infinities, and <code>true</code> for the result of <code>0/0</code>, the square root of a negative number, etc.</p>
|
||||
<p>Whether the number is <a href="http://en.wikipedia.org/wiki/NaN">not a number</a>. This is
|
||||
<code>false</code> for normal number values and infinities, and <code>true</code> for the result of
|
||||
<code>0/0</code>, the square root of a negative number, etc.</p>
|
||||
<h3><strong>sin</strong> <a href="#**sin**" name="**sin**" class="header-anchor">#</a></h3>
|
||||
<p>The sine of the number.</p>
|
||||
<h3><strong>sqrt</strong> <a href="#**sqrt**" name="**sqrt**" class="header-anchor">#</a></h3>
|
||||
@ -187,19 +199,28 @@
|
||||
|
||||
|
||||
<h3><strong>-</strong>(other), <strong>+</strong>(other), <strong>/</strong>(other), <strong>*</strong>(other) operators <a href="#**-**(other),-**+**(other),-****(other),-**\***(other)-operators" name="**-**(other),-**+**(other),-****(other),-**\***(other)-operators" class="header-anchor">#</a></h3>
|
||||
<p>The usual arithmetic operators you know and love. All of them do 64-bit floating point arithmetic. It is a runtime error if the right-hand operand is not a number. Wren doesn't roll with implicit conversions.</p>
|
||||
<p>The usual arithmetic operators you know and love. All of them do 64-bit
|
||||
floating point arithmetic. It is a runtime error if the right-hand operand is
|
||||
not a number. Wren doesn't roll with implicit conversions.</p>
|
||||
<h3><strong>%</strong>(denominator) operator <a href="#**%**(denominator)-operator" name="**%**(denominator)-operator" class="header-anchor">#</a></h3>
|
||||
<p>The floating-point remainder of this number divided by <code>denominator</code>.</p>
|
||||
<p>It is a runtime error if <code>denominator</code> is not a number.</p>
|
||||
<h3><strong><</strong>(other), <strong>></strong>(other), <strong><=</strong>(other), <strong>>=</strong>(other) operators <a href="#**<**(other),-**>**(other),-**<=**(other),-**>=**(other)-operators" name="**<**(other),-**>**(other),-**<=**(other),-**>=**(other)-operators" class="header-anchor">#</a></h3>
|
||||
<p>Compares this and <code>other</code>, returning <code>true</code> or <code>false</code> based on how the numbers are ordered. It is a runtime error if <code>other</code> is not a number.</p>
|
||||
<p>Compares this and <code>other</code>, returning <code>true</code> or <code>false</code> based on how the numbers
|
||||
are ordered. It is a runtime error if <code>other</code> is not a number.</p>
|
||||
<h3><strong>~</strong> operator <a href="#**~**-operator" name="**~**-operator" class="header-anchor">#</a></h3>
|
||||
<p>Performs <em>bitwise</em> negation on the number. The number is first converted to a 32-bit unsigned value, which will truncate any floating point value. The bits of the result of that are then negated, yielding the result.</p>
|
||||
<p>Performs <em>bitwise</em> negation on the number. The number is first converted to a
|
||||
32-bit unsigned value, which will truncate any floating point value. The bits
|
||||
of the result of that are then negated, yielding the result.</p>
|
||||
<h3><strong>&</strong>(other) operator <a href="#**&**(other)-operator" name="**&**(other)-operator" class="header-anchor">#</a></h3>
|
||||
<p>Performs bitwise and on the number. Both numbers are first converted to 32-bit unsigned values. The result is then a 32-bit unsigned number where each bit is <code>true</code> only where the corresponding bits of both inputs were <code>true</code>.</p>
|
||||
<p>Performs bitwise and on the number. Both numbers are first converted to 32-bit
|
||||
unsigned values. The result is then a 32-bit unsigned number where each bit is
|
||||
<code>true</code> only where the corresponding bits of both inputs were <code>true</code>.</p>
|
||||
<p>It is a runtime error if <code>other</code> is not a number.</p>
|
||||
<h3><strong>|</strong>(other) operator <a href="#**|**(other)-operator" name="**|**(other)-operator" class="header-anchor">#</a></h3>
|
||||
<p>Performs bitwise or on the number. Both numbers are first converted to 32-bit unsigned values. The result is then a 32-bit unsigned number where each bit is <code>true</code> only where the corresponding bits of both inputs were <code>true</code>.</p>
|
||||
<p>Performs bitwise or on the number. Both numbers are first converted to 32-bit
|
||||
unsigned values. The result is then a 32-bit unsigned number where each bit is
|
||||
<code>true</code> only where the corresponding bits of both inputs were <code>true</code>.</p>
|
||||
<p>It is a runtime error if <code>other</code> is not a number.</p>
|
||||
<h3><strong>..</strong>(other) operator <a href="#****(other)-operator" name="****(other)-operator" class="header-anchor">#</a></h3>
|
||||
<p><strong>TODO</strong></p>
|
||||
|
||||
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -58,8 +57,16 @@
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Embedding API</h1>
|
||||
<p>As an embedded scripting language, the C API your host app uses to interact with Wren is one of the key facets of the system. It's so important that... I haven't fleshed it out much yet.</p>
|
||||
<p>I believe good API design can't be done in a vacuum and I haven't built many applications that embed Wren yet, so I don't have a good testbed for the embedding API. Now that the language itself is further along, I'm starting to work on this, but it isn't quite there yet. Feedback and contributions are definitely welcome!</p>
|
||||
<p>As an embedded scripting language, the C API your host app uses to interact
|
||||
with Wren is one of the key facets of the system. It's so important that... I
|
||||
haven't fleshed it out much yet.</p>
|
||||
<p>I believe good API design can't be done in a vacuum and I haven't built many
|
||||
applications that embed Wren yet, so I don't have a good testbed for the
|
||||
embedding API. Now that the language itself is further along, I'm starting to
|
||||
work on this, but it isn't quite there yet. Feedback and contributions are
|
||||
definitely welcome!</p>
|
||||
<p>In the meantime, you can see the current API in
|
||||
<a href="https://github.com/munificent/wren/blob/master/include/wren.h"><code>wren.h</code></a>.</p>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -60,17 +59,21 @@
|
||||
<h1>Error Handling</h1>
|
||||
<p>Errors come in a few fun flavors.</p>
|
||||
<h2>Syntax errors <a href="#syntax-errors" name="syntax-errors" class="header-anchor">#</a></h2>
|
||||
<p>The first errors you're likely to run into are syntax errors. These include simple bugs where your code doesn't follow the language's grammar, like:</p>
|
||||
<p>The first errors you're likely to run into are syntax errors. These include
|
||||
simple bugs where your code doesn't follow the language's grammar, like:</p>
|
||||
<div class="codehilite"><pre><span class="m">1</span> <span class="o">+</span> <span class="o">*</span> <span class="m">2</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Wren will detect these errors as soon as it tries to read your code. When it hits one, you'll get a friendly error message, like:</p>
|
||||
<p>Wren will detect these errors as soon as it tries to read your code. When it
|
||||
hits one, you'll get a friendly error message, like:</p>
|
||||
<div class="codehilite"><pre>[script.wren line 1] Error on '*': Unexpected token for expression.
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Some slightly more "semantic" errors fall into this bucket too. Things like using a variable that hasn't been defined, or declaring two variables with the same name in the same scope. So if you do:</p>
|
||||
<p>Some slightly more "semantic" errors fall into this bucket too. Things like
|
||||
using a variable that hasn't been defined, or declaring two variables with the
|
||||
same name in the same scope. So if you do:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">a</span> <span class="o">=</span> <span class="s2">"once"</span>
|
||||
<span class="kd">var</span> <span class="n">a</span> <span class="o">=</span> <span class="s2">"twice"</span>
|
||||
</pre></div>
|
||||
@ -81,11 +84,20 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Note that it does this before it executes <em>any</em> code. Unlike some other scripting languages, Wren tries to help you find your errors as soon as possible when it can.</p>
|
||||
<p>If it starts running your code, you can be sure you don't have any errors related to syntax or variable scope.</p>
|
||||
<p>Note that it does this before it executes <em>any</em> code. Unlike some other
|
||||
scripting languages, Wren tries to help you find your errors as soon as
|
||||
possible when it can.</p>
|
||||
<p>If it starts running your code, you can be sure you don't have any errors
|
||||
related to syntax or variable scope.</p>
|
||||
<h2>Runtime errors <a href="#runtime-errors" name="runtime-errors" class="header-anchor">#</a></h2>
|
||||
<p>Alas, just fixing all of the "compile-time" errors doesn't mean your code does what you want. Your program may still have errors that can't be detected statically. Since they can't be found until your code is run, they're called "runtime" errors.</p>
|
||||
<p>Most runtime errors come from the VM itself. They arise from code trying to perform an operation that the VM can't do. The most common error is a "method not found" one. If you call a method on an object and its class (and all of its superclasses) don't define that method, there's nothing Wren can do:</p>
|
||||
<p>Alas, just fixing all of the "compile-time" errors doesn't mean your code does
|
||||
what you want. Your program may still have errors that can't be detected
|
||||
statically. Since they can't be found until your code is run, they're called
|
||||
"runtime" errors.</p>
|
||||
<p>Most runtime errors come from the VM itself. They arise from code trying to
|
||||
perform an operation that the VM can't do. The most common error is a "method
|
||||
not found" one. If you call a method on an object and its class (and all of its
|
||||
superclasses) don't define that method, there's nothing Wren can do:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Foo</span> <span class="p">{}</span>
|
||||
|
||||
<span class="kd">var</span> <span class="n">foo</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Foo</span>
|
||||
@ -98,8 +110,14 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Then it stops executing code. Unlike some other languages, Wren doesn't keep plugging away after a runtime error has occurred. A runtime error implies there's a bug in your code and it wants to draw your attention to it. To help you out, it prints a stack trace showing where in the code the error occurred, and all of the method calls that led to it.</p>
|
||||
<p>Another common runtime error is passing an argument of the wrong type to a method. For example, lists are indexed using a number. If you try to pass some other type, it's an error:</p>
|
||||
<p>Then it stops executing code. Unlike some other languages, Wren doesn't keep
|
||||
plugging away after a runtime error has occurred. A runtime error implies
|
||||
there's a bug in your code and it wants to draw your attention to it. To help
|
||||
you out, it prints a stack trace showing where in the code the error occurred,
|
||||
and all of the method calls that led to it.</p>
|
||||
<p>Another common runtime error is passing an argument of the wrong type to a
|
||||
method. For example, lists are indexed using a number. If you try to pass some
|
||||
other type, it's an error:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">list</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">]</span>
|
||||
<span class="n">list</span><span class="p">[</span><span class="s2">"1"</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
@ -111,11 +129,21 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>These are the most two common kinds of runtime errors, but there are others. Stuff like out of bounds errors on lists, calling a function with the wrong number of arguments, etc.</p>
|
||||
<p>These are the most two common kinds of runtime errors, but there are others.
|
||||
Stuff like out of bounds errors on lists, calling a function with the wrong
|
||||
number of arguments, etc.</p>
|
||||
<h2>Handling runtime errors <a href="#handling-runtime-errors" name="handling-runtime-errors" class="header-anchor">#</a></h2>
|
||||
<p>Most of the time, runtime errors indicate a bug in your code and the best solution is to fix the bug. However, sometimes it's useful to be able to handle them at, uh, runtime.</p>
|
||||
<p>To keep the language simpler, Wren does not have exception handling. Instead, it takes advantage of <a href="fibers.html">fibers</a> for handling errors. When a runtime error occurs, the current fiber is aborted. Normally, Wren will also abort any fibers that invoked that one, all the way to the main fiber, and then exit the VM.</p>
|
||||
<p>However, you can run a fiber using the <code>try</code> method. If a runtime error occurs in the called fiber, the error is captured and the <code>try</code> method returns the error message as a string.</p>
|
||||
<p>Most of the time, runtime errors indicate a bug in your code and the best
|
||||
solution is to fix the bug. However, sometimes it's useful to be able to handle
|
||||
them at, uh, runtime.</p>
|
||||
<p>To keep the language simpler, Wren does not have exception handling. Instead,
|
||||
it takes advantage of <a href="fibers.html">fibers</a> for handling errors. When a runtime
|
||||
error occurs, the current fiber is aborted. Normally, Wren will also abort any
|
||||
fibers that invoked that one, all the way to the main fiber, and then exit the
|
||||
VM.</p>
|
||||
<p>However, you can run a fiber using the <code>try</code> method. If a runtime error occurs
|
||||
in the called fiber, the error is captured and the <code>try</code> method returns the
|
||||
error message as a string.</p>
|
||||
<p>For example, if you run this program:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="m">123.</span><span class="n">badMethod</span>
|
||||
@ -127,11 +155,13 @@
|
||||
|
||||
|
||||
<p>It prints:</p>
|
||||
<div class="codehilite"><pre>Num does not implement method 'badMethod'.
|
||||
<div class="codehilite"><pre>Caught error: Num does not implement method 'badMethod'.
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>The called fiber can no longer be used, but any other fibers can proceed as usual. When a fiber has been aborted because of a runtime error, you can also get the error from the fiber object. Continuing the above example:</p>
|
||||
<p>The called fiber can no longer be used, but any other fibers can proceed as
|
||||
usual. When a fiber has been aborted because of a runtime error, you can also
|
||||
get the error from the fiber object. Continuing the above example:</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">fiber</span><span class="p">.</span><span class="n">error</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
@ -141,19 +171,34 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>If you have a chain of fiber calls and a runtime error occurs, it will walk the chain looking for a <code>try</code> call, so this can also be used to capture runtime errors generated in fibers that are invoked by the one you called <code>try</code> on.</p>
|
||||
<p>If you have a chain of fiber calls and a runtime error occurs, it will walk the
|
||||
chain looking for a <code>try</code> call, so this can also be used to capture runtime
|
||||
errors generated in fibers that are invoked by the one you called <code>try</code> on.</p>
|
||||
<h2>Creating runtime errors <a href="#creating-runtime-errors" name="creating-runtime-errors" class="header-anchor">#</a></h2>
|
||||
<p>Most runtime errors come from within the Wren VM, but you may want to be able to cause your own runtime errors to occur. This can be done by calling the <code>abort()</code> static method on <code>Fiber</code>:</p>
|
||||
<p>Most runtime errors come from within the Wren VM, but you may want to be able
|
||||
to cause your own runtime errors to occur. This can be done by calling the
|
||||
<code>abort()</code> static method on <code>Fiber</code>:</p>
|
||||
<div class="codehilite"><pre><span class="n">Fiber</span><span class="p">.</span><span class="n">abort</span><span class="p">(</span><span class="s2">"Something bad happened"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You must pass in an error message, and it must be a string.</p>
|
||||
<h2>Failures <a href="#failures" name="failures" class="header-anchor">#</a></h2>
|
||||
<p>The last flavor of errors is the highest-level one. All of the above errors indicate <em>bugs</em>—places where the code itself is incorrect. But some errors indicate that the code simply couldn't accomplish its task for unforeseeable reasons. We'll call these "failures".</p>
|
||||
<p>Consider a program that reads in a string of input from the user and parses it to a number. Many strings are not valid numbers, so this parsing can fail. The only way the program could prevent that failure is by validating the string before its parsed, but validating that a string is a number is pretty much the same thing as parsing it.</p>
|
||||
<p>For cases like this where failure can occur and the program <em>will</em> want to handle it, fibers and <code>try</code> are too coarse-grained to work with. Instead, these operations will indicate failure by <em>returning</em> some sort of error indication.</p>
|
||||
<p>For example, a method for parsing a number could return a number on success and <code>null</code> to indicate parsing failed. Since Wren is dynamically typed, it's easy and natural for a method to return different types of values.</p>
|
||||
<p>The last flavor of errors is the highest-level one. All of the above errors
|
||||
indicate <em>bugs</em>—places where the code itself is incorrect. But some
|
||||
errors indicate that the code simply couldn't accomplish its task for
|
||||
unforeseeable reasons. We'll call these "failures".</p>
|
||||
<p>Consider a program that reads in a string of input from the user and parses it
|
||||
to a number. Many strings are not valid numbers, so this parsing can fail. The
|
||||
only way the program could prevent that failure is by validating the string
|
||||
before its parsed, but validating that a string is a number is pretty much the
|
||||
same thing as parsing it.</p>
|
||||
<p>For cases like this where failure can occur and the program <em>will</em> want to
|
||||
handle it, fibers and <code>try</code> are too coarse-grained to work with. Instead, these
|
||||
operations will indicate failure by <em>returning</em> some sort of error indication.</p>
|
||||
<p>For example, a method for parsing a number could return a number on success and
|
||||
<code>null</code> to indicate parsing failed. Since Wren is dynamically typed, it's easy
|
||||
and natural for a method to return different types of values.</p>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
300
expressions.html
Normal file
300
expressions.html
Normal file
@ -0,0 +1,300 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
|
||||
<title>Expressions – Wren</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<link href='http://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="index.html">wren</a></h1>
|
||||
<h2>a classy little scripting language</h2>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="page">
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="getting-started.html">Getting Started</a></li>
|
||||
</ul>
|
||||
<section>
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>types</h2>
|
||||
<ul>
|
||||
<li><a href="values.html">Values</a></li>
|
||||
<li><a href="classes.html">Classes</a></li>
|
||||
<li><a href="fibers.html">Fibers</a></li>
|
||||
<li><a href="functions.html">Functions</a></li>
|
||||
<li><a href="lists.html">Lists</a></li>
|
||||
<li><a href="maps.html">Maps</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>reference</h2>
|
||||
<ul>
|
||||
<li><a href="core-library.html">Core Library</a></li>
|
||||
<li><a href="embedding-api.html">Embedding API</a></li>
|
||||
<li><a href="performance.html">Performance</a></li>
|
||||
<li><a href="contributing.html">Contributing</a></li>
|
||||
<li><a href="qa.html">Q & A</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Expressions</h1>
|
||||
<p>Wren's syntax is based on C so if you're familiar with that (or any of the
|
||||
plethora of other languages based on it) you should be right at home. Since
|
||||
Wren is heavily object-oriented, you'll notice that most of the different
|
||||
expression forms are just different ways of invoking methods.</p>
|
||||
<h2>Literals <a href="#literals" name="literals" class="header-anchor">#</a></h2>
|
||||
<p>Literals produce objects of built-in types. The primitive <a href="values.html">value</a>
|
||||
types—numbers, strings and friends—have literal forms as do the
|
||||
built in collections: <a href="lists.html">lists</a> and <a href="maps.html">maps</a>.</p>
|
||||
<p><a href="functions.html">Functions</a> do not have standalone a literal form. Instead,
|
||||
they are created by passing a <a href="functions.html#block-arguments">block
|
||||
argument</a> to a method.</p>
|
||||
<h2>Identifiers <a href="#identifiers" name="identifiers" class="header-anchor">#</a></h2>
|
||||
<p>Names in expressions come in a few flavors. A name that starts with an
|
||||
underscore denotes a <a href="classes.html#fields">field</a>, a piece of data stored in an
|
||||
instance of a <a href="classes.html">class</a>. All other names refer to
|
||||
<a href="variables.html">variables</a>.</p>
|
||||
<h2>Method calls <a href="#method-calls" name="method-calls" class="header-anchor">#</a></h2>
|
||||
<p>Wren is object-oriented, so most code consists of method calls. Most of them
|
||||
look like so:</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
|
||||
<span class="n">items</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"another"</span><span class="p">)</span>
|
||||
<span class="n">items</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="s2">"value"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You have a <em>receiver</em> expression followed by a <code>.</code>, then a name and an argument
|
||||
list in parentheses. Arguments are separated by commas. Methods that do not
|
||||
take any arguments omit the <code>()</code>:</p>
|
||||
<div class="codehilite"><pre><span class="n">text</span><span class="p">.</span><span class="n">length</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>These are special "getters" or "accessors" in other languages. In Wren, they're
|
||||
just method calls.</p>
|
||||
<p>If the last (or only) argument to a method call is a
|
||||
<a href="functions.html">function</a>, it may be passed as a <a href="functions.html#block-arguments">block
|
||||
argument</a>:</p>
|
||||
<div class="codehilite"><pre><span class="n">blondie</span><span class="p">.</span><span class="n">callMeAt</span><span class="p">(</span><span class="m">867</span><span class="p">,</span> <span class="m">5309</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"This is the body!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Semantically, all method calls work like so:</p>
|
||||
<ol>
|
||||
<li>Evaluate the receiver and arguments.</li>
|
||||
<li>Look up the method on the receiver's class.</li>
|
||||
<li>Invoke it, passing in the arguments.</li>
|
||||
</ol>
|
||||
<h2>This <a href="#this" name="this" class="header-anchor">#</a></h2>
|
||||
<p>The special <code>this</code> keyword works sort of like a variable, but has special
|
||||
behavior. It always refers to the instance whose method is currently being
|
||||
executed. This lets you invoke methods on "yourself".</p>
|
||||
<p>It's an error to refer to <code>this</code> outside of a method. However, it's perfectly
|
||||
fine to use it inside a function contained in a method. When you do, <code>this</code>
|
||||
still refers to the instance whose method is being called.</p>
|
||||
<p>This is unlike Lua and JavaScript which can "forget" <code>this</code> when you create a
|
||||
callback inside a method. Wren does what you want here and retains the
|
||||
reference to the original object. (In technical terms, a function's closure
|
||||
includes <code>this</code>.)</p>
|
||||
<h2>Super <a href="#super" name="super" class="header-anchor">#</a></h2>
|
||||
<p>Sometimes you want to invoke a method on yourself, but only methods defined in
|
||||
one of your <a href="classes.html#inheritance">superclasses</a>. You typically do this in
|
||||
an overridden method when you want to access the original method being
|
||||
overridden.</p>
|
||||
<p>To do that, you can use the special <code>super</code> keyword as the receiver in a method
|
||||
call:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Base</span> <span class="p">{</span>
|
||||
<span class="n">method</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"base method"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="kd">class</span> <span class="nc">Derived</span> <span class="k">is</span> <span class="n">Base</span> <span class="p">{</span>
|
||||
<span class="n">method</span> <span class="p">{</span>
|
||||
<span class="k">super</span><span class="p">.</span><span class="n">method</span> <span class="c1">// Prints "base method".</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You can also use <code>super</code> without a method name inside a constructor to invoke a
|
||||
base class constructor:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Base</span> <span class="p">{</span>
|
||||
<span class="k">new</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"base constructor got "</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="kd">class</span> <span class="nc">Derived</span> <span class="k">is</span> <span class="n">Base</span> <span class="p">{</span>
|
||||
<span class="k">new</span> <span class="p">{</span>
|
||||
<span class="k">super</span><span class="p">(</span><span class="s2">"value"</span><span class="p">)</span> <span class="c1">// Prints "base constructor got value".</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p><strong>TODO: constructors</strong></p>
|
||||
<h2>Operators <a href="#operators" name="operators" class="header-anchor">#</a></h2>
|
||||
<p>Wren has most of the same operators you know and love with the same precedence
|
||||
and associativity. Wren has three prefix operators:</p>
|
||||
<div class="codehilite"><pre><span class="o">!</span> <span class="o">~</span> <span class="o">-</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>They are just method calls on their operand without any other arguments. An
|
||||
expression like <code>!possible</code> means "call the <code>!</code> method on <code>possible</code>".</p>
|
||||
<p>We have a few other operators to play with. The remaining ones are
|
||||
infix—they have operators on either side. They are:</p>
|
||||
<div class="codehilite"><pre><span class="o">==</span> <span class="o">!=</span> <span class="o"><</span> <span class="o">></span> <span class="o"><=</span> <span class="o">>=</span> <span class="p">..</span> <span class="p">...</span> <span class="o">|</span> <span class="o">&</span> <span class="o">+</span> <span class="o">-</span> <span class="o">*</span> <span class="o">/</span> <span class="o">%</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Like prefix operators, they are all funny ways of writing method calls. The
|
||||
left operand is the receiver, and the right operand gets passed to it. So
|
||||
<code>a + b</code> is semantically interpreted as "invoke the <code>+</code> method on <code>a</code>, passing
|
||||
it <code>b</code>".</p>
|
||||
<p>Most of these are probably familiar already. The <code>..</code> and <code>...</code> operators are
|
||||
"range" operators. The number type implements those to create a
|
||||
<a href="values.html#ranges">range</a> object, but they are just regular operators.</p>
|
||||
<p>Since operators are just method calls, this means Wren supports "operator
|
||||
overloading" (though "operator over-<em>riding</em>" is more accurate). This can be
|
||||
really useful when the operator is natural for what a class represents, but can
|
||||
lead to mind-crushingly unreadable code when used recklessly. There's a reason
|
||||
punctuation represents profanity in comic strips.</p>
|
||||
<h2>Assignment <a href="#assignment" name="assignment" class="header-anchor">#</a></h2>
|
||||
<p>The <code>=</code> operator is used to <em>assign</em> or store a value somewhere. The right-hand
|
||||
side can be any expression. If the left-hand side is an
|
||||
<a href="#identifiers">identifier</a>, then the value of the right operand is stored in
|
||||
the referenced <a href="variables.html">variable</a> or <a href="classes.html#fields">field</a>.</p>
|
||||
<p>The left-hand side may also be a method call, like:</p>
|
||||
<div class="codehilite"><pre><span class="n">point</span><span class="p">.</span><span class="n">x</span> <span class="o">=</span> <span class="m">123</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>In this case, the entire expression is a single "setter" method call. The above
|
||||
example invokes the <code>x=</code> setter on the <code>point</code> object, and passing in <code>123</code>.
|
||||
Sort of like <code>point.x=(123)</code>.</p>
|
||||
<p>Since these are just regular method calls, you can define whatever setters you
|
||||
like in your classes. However, you cannot change the behavior of <em>simple</em>
|
||||
assignment. If the left-hand side is a variable name or field, an assignment
|
||||
expression will always just store the value there.</p>
|
||||
<h2>Subscript operators <a href="#subscript-operators" name="subscript-operators" class="header-anchor">#</a></h2>
|
||||
<p>Most languages use square brackets (<code>[]</code>) for working with collection-like
|
||||
objects. For example:</p>
|
||||
<div class="codehilite"><pre><span class="n">list</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="c1">// Gets the first item in a list.</span>
|
||||
<span class="n">map</span><span class="p">[</span><span class="s2">"key"</span><span class="p">]</span> <span class="c1">// Gets the value associated with "key".</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You know the refrain by now. In Wren, these are just method calls that a class
|
||||
may define. Subscript operators may take multiple arguments, which is useful
|
||||
for things like multi-dimensional arrays:</p>
|
||||
<div class="codehilite"><pre><span class="n">matrix</span><span class="p">[</span><span class="m">3</span><span class="p">,</span> <span class="m">5</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Subscripts may also be used on the left-hand side of an assignment:</p>
|
||||
<div class="codehilite"><pre><span class="n">list</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"item"</span>
|
||||
<span class="n">map</span><span class="p">[</span><span class="s2">"key"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"value"</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Again, these are just method calls. The last example is equivalent to invoking
|
||||
the <code>[]=</code> method on <code>map</code>, passing in <code>"key"</code> and <code>"value"</code>.</p>
|
||||
<h2>Logical operators <a href="#logical-operators" name="logical-operators" class="header-anchor">#</a></h2>
|
||||
<p>The <code>&&</code> and <code>||</code> operators are not like the other infix operators. They work
|
||||
more like <a href="control-flow.html">control flow</a> structures than operators because
|
||||
they conditionally execute some code—they short-circuit. Depending on the
|
||||
value of the left-hand side, the right-hand operand expression may or may not
|
||||
be evaluated. Because of this, they cannot be overloaded and they behavior is
|
||||
fixed.</p>
|
||||
<p>A <code>&&</code> ("logical and") expression evaluates the left-hand argument. If it's
|
||||
<a href="control-flow.html#truth">false</a>, it returns that value. Otherwise it evaluates
|
||||
and returns the right-hand argument.</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="kc">false</span> <span class="o">&&</span> <span class="m">1</span><span class="p">)</span> <span class="c1">// false</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="m">1</span> <span class="o">&&</span> <span class="m">2</span><span class="p">)</span> <span class="c1">// 2</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>An <code>||</code> ("logical or") expression is reversed. If the left-hand argument is
|
||||
<a href="control-flow.html#truth">false</a>, it's returned, otherwise the right-hand
|
||||
argument is evaluated and returned:</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="kc">false</span> <span class="o">||</span> <span class="m">1</span><span class="p">)</span> <span class="c1">// 1</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="m">1</span> <span class="o">||</span> <span class="m">2</span><span class="p">)</span> <span class="c1">// 1</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h2>The conditional operator <code>?:</code> <a href="#the-conditional-operator-<code>" name="the-conditional-operator-</code>" class="header-anchor">#</a></h2>
|
||||
<p>Also known as the "ternary" operator since it takes three arguments, Wren has
|
||||
the little "if statement in the form of an expression" you know and love from C
|
||||
and its bretheren.</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="m">1</span> <span class="o">!=</span> <span class="m">2</span> <span class="o">?</span> <span class="s2">"math is sane"</span> <span class="o">:</span> <span class="s2">"math is not sane!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>It takes a condition expression, followed by <code>?</code>, followed by a then
|
||||
expression, a <code>:</code>, then an else expression. Just like <code>if</code>, it evaluates the
|
||||
condition. If true, it evaluates (and returns) the then expression. Otherwise
|
||||
it does the else expression.</p>
|
||||
<h2>The <code>is</code> operator <a href="#the-<code>is</code>-operator" name="the-<code>is</code>-operator" class="header-anchor">#</a></h2>
|
||||
<p>Wren has one last expression form. You can use the <code>is</code> keyword like an infix
|
||||
operator. It performs a type test. The left operand is an object and the right
|
||||
operand is a class. It evaluates to <code>true</code> if the object is an instance of the
|
||||
class (or one of its subclasses).</p>
|
||||
<div class="codehilite"><pre><span class="m">123</span> <span class="k">is</span> <span class="n">Num</span> <span class="c1">// true</span>
|
||||
<span class="s2">"s"</span> <span class="k">is</span> <span class="n">Num</span> <span class="c1">// false</span>
|
||||
<span class="kc">null</span> <span class="k">is</span> <span class="kt">String</span> <span class="c1">// false</span>
|
||||
<span class="p">[]</span> <span class="k">is</span> <span class="n">List</span> <span class="c1">// true</span>
|
||||
<span class="p">[]</span> <span class="k">is</span> <span class="n">Sequence</span> <span class="c1">// true</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h2>Precedence <a href="#precedence" name="precedence" class="header-anchor">#</a></h2>
|
||||
<p>When you mix these all together, you need to worry about
|
||||
<em>precedence</em>—which operators bind more tightly than others. Wren mostly
|
||||
follows C, except that it fixes the bitwise operator mistake. The full
|
||||
precedence table, from lowest to highest, is:</p>
|
||||
<div class="codehilite"><pre><span class="o">=</span> <span class="c1">// Assignment.</span>
|
||||
<span class="o">&&</span> <span class="o">||</span> <span class="o">?:</span> <span class="c1">// Logic.</span>
|
||||
<span class="k">is</span> <span class="c1">// Type test.</span>
|
||||
<span class="o">==</span> <span class="o">!=</span> <span class="c1">// Equality.</span>
|
||||
<span class="o"><</span> <span class="o">></span> <span class="o"><=</span> <span class="o">>=</span> <span class="c1">// Comparison.</span>
|
||||
<span class="p">..</span> <span class="p">...</span> <span class="c1">// Range.</span>
|
||||
<span class="o">|</span> <span class="o">&</span> <span class="c1">// Bitwise.</span>
|
||||
<span class="o">+</span> <span class="o">-</span> <span class="c1">// Terms.</span>
|
||||
<span class="o">*</span> <span class="o">/</span> <span class="o">%</span> <span class="c1">// Factors.</span>
|
||||
<span class="o">-</span> <span class="o">~</span> <span class="o">!</span> <span class="c1">// Unary.</span>
|
||||
<span class="p">.</span> <span class="p">[]</span> <span class="c1">// Call.</span>
|
||||
</pre></div>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
<div class="page">
|
||||
<div class="main-column">
|
||||
<p>Wren lives <a href="https://github.com/munificent/wren">on GitHub</a> — Made with ❤ by <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a>.</p>
|
||||
<div class="main-column">
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
102
fibers.html
102
fibers.html
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -58,26 +57,44 @@
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Fibers</h1>
|
||||
<p>Fibers are a key part of Wren. They form its execution model, its concurrency story and take the place of exceptions in <a href="error-handling.html">error handling</a>.</p>
|
||||
<p>They are a bit like threads except they are <em>cooperatively</em> scheduled. That means Wren doesn't pause one fiber and switch to another until you tell it to. You don't have to worry about context switches at random times and all of the headaches those cause.</p>
|
||||
<p>Fibers are managed entirely by Wren, so they don't use OS thread resources, or require heavyweight context switches. They just need a bit of memory for their stacks. A fiber will get garbage collected like any other object when not referenced any more, so you can create them freely.</p>
|
||||
<p>They are lightweight enough that you can, for example, have a separate fiber for each entity in a game. Wren can handle thousands of them without any trouble. For example, when you run Wren in interactive mode, it creates a new fiber for every line of code you type in.</p>
|
||||
<p>Fibers are a key part of Wren. They form its execution model, its concurrency
|
||||
story, and take the place of exceptions in <a href="error-handling.html">error
|
||||
handling</a>.</p>
|
||||
<p>They are a bit like threads except they are <em>cooperatively</em> scheduled. That
|
||||
means Wren doesn't pause one fiber and switch to another until you tell it to.
|
||||
You don't have to worry about context switches at random times and all of the
|
||||
headaches those cause.</p>
|
||||
<p>Fibers are managed entirely by Wren, so they don't use OS thread resources, or
|
||||
require heavyweight context switches. They just need a bit of memory for their
|
||||
stacks. A fiber will get garbage collected like any other object when not
|
||||
referenced any more, so you can create them freely.</p>
|
||||
<p>They are lightweight enough that you can, for example, have a separate fiber
|
||||
for each entity in a game. Wren can handle thousands of them without any
|
||||
trouble. For example, when you run Wren in interactive mode, it creates a new
|
||||
fiber for every line of code you type in.</p>
|
||||
<h2>Creating fibers <a href="#creating-fibers" name="creating-fibers" class="header-anchor">#</a></h2>
|
||||
<p>All Wren code runs within the context of a fiber. When you first start a Wren script, a main fiber is created for you automatically. You can spawn new fibers using the <code>Fiber</code> class's constructor:</p>
|
||||
<p>All Wren code runs within the context of a fiber. When you first start a Wren
|
||||
script, a main fiber is created for you automatically. You can spawn new fibers
|
||||
using the <code>Fiber</code> class's constructor:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"This runs in a separate fiber."</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Creating a fiber does not immediately run it. It's just a first class bundle of code sitting there waiting to be activated, a bit like a <a href="functions.html">function</a>.</p>
|
||||
<p>Creating a fiber does not immediately run it. It's just a first class bundle of
|
||||
code sitting there waiting to be activated, a bit like a
|
||||
<a href="functions.html">function</a>.</p>
|
||||
<h2>Invoking fibers <a href="#invoking-fibers" name="invoking-fibers" class="header-anchor">#</a></h2>
|
||||
<p>Once you've created a fiber, you can invoke it (which suspends the current fiber) by calling its <code>call</code> method:</p>
|
||||
<p>Once you've created a fiber, you can invoke it (which suspends the current
|
||||
fiber) by calling its <code>call</code> method:</p>
|
||||
<div class="codehilite"><pre><span class="n">fiber</span><span class="p">.</span><span class="n">call</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>The called fiber will execute its code until it reaches the end of its body or until it passes control to another fiber. If it reaches the end of its body, it's considered <em>done</em>:</p>
|
||||
<p>The called fiber will execute its code until it reaches the end of its body or
|
||||
until it passes control to another fiber. If it reaches the end of its body,
|
||||
it's considered <em>done</em>:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span> <span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"Hi"</span><span class="p">)</span> <span class="p">}</span>
|
||||
<span class="n">fiber</span><span class="p">.</span><span class="n">isDone</span> <span class="c1">// false</span>
|
||||
<span class="n">fiber</span><span class="p">.</span><span class="n">call</span>
|
||||
@ -85,10 +102,16 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>When it finishes, it automatically resumes the fiber that called it. It's a runtime error to try to call a fiber that is already done.</p>
|
||||
<p>When it finishes, it automatically resumes the fiber that called it. It's a
|
||||
runtime error to try to call a fiber that is already done.</p>
|
||||
<h2>Yielding <a href="#yielding" name="yielding" class="header-anchor">#</a></h2>
|
||||
<p>The main difference between fibers and functions is that a fiber can be suspended in the middle of its operation and then resumed later. Calling another fiber is one way to suspend a fiber, but that's more or less the same as one function calling another.</p>
|
||||
<p>Things get interesting when a fiber <em>yields</em>. A yielded fiber passes control <em>back</em> to the fiber that ran it, but <em>remembers where it is</em>. The next time the fiber is called, it picks up right where it left off and keeps going.</p>
|
||||
<p>The main difference between fibers and functions is that a fiber can be
|
||||
suspended in the middle of its operation and then resumed later. Calling
|
||||
another fiber is one way to suspend a fiber, but that's more or less the same
|
||||
as one function calling another.</p>
|
||||
<p>Things get interesting when a fiber <em>yields</em>. A yielded fiber passes control
|
||||
<em>back</em> to the fiber that ran it, but <em>remembers where it is</em>. The next time the
|
||||
fiber is called, it picks up right where it left off and keeps going.</p>
|
||||
<p>You can make a fiber yield by calling the static <code>yield</code> method on <code>Fiber</code>:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"fiber 1"</span><span class="p">)</span>
|
||||
@ -113,9 +136,14 @@ main 3
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Note that even though this program has <em>concurrency</em>, it's still <em>deterministic</em>. You can reason precisely about what it's doing and aren't at the mercy of a thread scheduler playing Russian roulette with your code.</p>
|
||||
<p>Note that even though this program has <em>concurrency</em>, it's still
|
||||
<em>deterministic</em>. You can reason precisely about what it's doing and aren't at
|
||||
the mercy of a thread scheduler playing Russian roulette with your code.</p>
|
||||
<h2>Passing values <a href="#passing-values" name="passing-values" class="header-anchor">#</a></h2>
|
||||
<p>Calling and yielding fibers is used for passing control, but it can also pass <em>data</em>. When you call a fiber, you can optionally pass a value to it. If the fiber has yielded and is waiting to resume, the value becomes the return value of the <code>yield</code> call:</p>
|
||||
<p>Calling and yielding fibers is used for passing control, but it can also pass
|
||||
<em>data</em>. When you call a fiber, you can optionally pass a value to it. If the
|
||||
fiber has yielded and is waiting to resume, the value becomes the return value
|
||||
of the <code>yield</code> call:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="n">result</span> <span class="o">=</span> <span class="n">Fiber</span><span class="p">.</span><span class="n">yield</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
|
||||
@ -126,8 +154,12 @@ main 3
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>This prints "sent". Note that the first value sent to the fiber through call is ignored. That's because the fiber isn't waiting on a <code>yield</code> call, so there's no where for the sent value to go.</p>
|
||||
<p>Fibers can also pass values <em>back</em> when they yield. If you pass an argument to <code>yield</code>, that will become the return value of the <code>call</code> that was used to invoke the fiber:</p>
|
||||
<p>This prints "sent". Note that the first value sent to the fiber through call is
|
||||
ignored. That's because the fiber isn't waiting on a <code>yield</code> call, so there's
|
||||
no where for the sent value to go.</p>
|
||||
<p>Fibers can also pass values <em>back</em> when they yield. If you pass an argument to
|
||||
<code>yield</code>, that will become the return value of the <code>call</code> that was used to
|
||||
invoke the fiber:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="n">Fiber</span><span class="p">.</span><span class="n">yield</span><span class="p">(</span><span class="s2">"sent"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
@ -138,8 +170,13 @@ main 3
|
||||
|
||||
<p>This also prints "sent".</p>
|
||||
<h2>Full coroutines <a href="#full-coroutines" name="full-coroutines" class="header-anchor">#</a></h2>
|
||||
<p>What we've seen so far is very similar to what you can do with languages like Python and C# that have <em>generators</em>. Those let you define a function call that you can suspend and resume. When using the function, it appears like a sequence you can iterate over.</p>
|
||||
<p>Wren's fibers can do that, but they can do much more. Like Lua, they are full <em>coroutines</em>—they can suspend from anywhere in the callstack. For example:</p>
|
||||
<p>What we've seen so far is very similar to what you can do with languages like
|
||||
Python and C# that have <em>generators</em>. Those let you define a function call that
|
||||
you can suspend and resume. When using the function, it appears like a sequence
|
||||
you can iterate over.</p>
|
||||
<p>Wren's fibers can do that, but they can do much more. Like Lua, they are full
|
||||
<em>coroutines</em>—they can suspend from anywhere in the callstack. For
|
||||
example:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">fiber</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="p">(</span><span class="m">1.</span><span class="p">.</span><span class="m">10</span><span class="p">).</span><span class="n">map</span> <span class="p">{</span><span class="o">|</span><span class="n">i</span><span class="o">|</span>
|
||||
<span class="n">Fiber</span><span class="p">.</span><span class="n">yield</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
|
||||
@ -148,11 +185,28 @@ main 3
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Here, we're calling <code>yield</code> from within a <a href="functions.html">function</a> being passed to the <code>map</code> method. This works fine in Wren because that inner <code>yield</code> call will suspend the call to <code>map</code> and the function passed to it as a callback.</p>
|
||||
<p>Here, we're calling <code>yield</code> from within a <a href="functions.html">function</a> being
|
||||
passed to the <code>map</code> method. This works fine in Wren because that inner <code>yield</code>
|
||||
call will suspend the call to <code>map</code> and the function passed to it as a
|
||||
callback.</p>
|
||||
<h2>Transferring control <a href="#transferring-control" name="transferring-control" class="header-anchor">#</a></h2>
|
||||
<p>Fibers have one more trick up their sleeves. When you execute a fiber using <code>call</code>, the fiber tracks which fiber it will return to when it yields. This lets you build up a chain of fiber calls that will eventually unwind back to the main fiber when all of the called ones yield or finish.</p>
|
||||
<p>This works fine for most uses, but sometimes you want something a little more freeform. For example, you may be creating a <a href="http://en.wikipedia.org/wiki/Finite-state_machine">state machine</a> where each state is a fiber. When you switch from one state to the next, you <em>don't</em> want to build an implicit stack of fibers to return to. There is no "returning" in this case. You just want to <em>transfer</em> to the next fiber and forget about the previous one entirely. (This is analogous to <a href="http://en.wikipedia.org/wiki/Tail_call">tail call elimination</a> for regular function calls.)</p>
|
||||
<p>To enable this, fibers also have a <code>run</code> method. This begins executing that fiber, and "forgets" the previous one. If the running fiber yields or ends, it will transfer control back to the last <em>called</em> one. (If there are no called fibers, it will end execution.)</p>
|
||||
<p>Fibers have one more trick up their sleeves. When you execute a fiber using
|
||||
<code>call</code>, the fiber tracks which fiber it will return to when it yields. This
|
||||
lets you build up a chain of fiber calls that will eventually unwind back to
|
||||
the main fiber when all of the called ones yield or finish.</p>
|
||||
<p>This works fine for most uses, but sometimes you want something a little more
|
||||
freeform. For example, you may be creating a <a href="http://en.wikipedia.org/wiki/Finite-state_machine">state
|
||||
machine</a> where each state is
|
||||
a fiber. When you switch from one state to the next, you <em>don't</em> want to build
|
||||
an implicit stack of fibers to return to. There is no "returning" in this case.
|
||||
You just want to <em>transfer</em> to the next fiber and forget about the previous one
|
||||
entirely. (This is analogous to <a href="http://en.wikipedia.org/wiki/Tail_call">tail call
|
||||
elimination</a> for regular function
|
||||
calls.)</p>
|
||||
<p>To enable this, fibers also have a <code>run</code> method. This begins executing that
|
||||
fiber, and "forgets" the previous one. If the running fiber yields or ends, it
|
||||
will transfer control back to the last <em>called</em> one. (If there are no called
|
||||
fibers, it will end execution.)</p>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -58,19 +57,31 @@
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Functions</h1>
|
||||
<p>No self-respecting language today can get by without functions—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>Creating functions <a href="#creating-functions" name="creating-functions" 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'll call its <code>where</code> method, passing in a function that defines the predicate you're filtering on.</p>
|
||||
<p>Since that's the most common usage pattern, Wren'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>
|
||||
<p>No self-respecting language today can get by without functions—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'll
|
||||
call its <code>where</code> method, passing in a function that defines the predicate
|
||||
you're filtering on.</p>
|
||||
<p>Since that's the most common usage pattern, Wren'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>
|
||||
<div class="codehilite"><pre><span class="n">blondie</span><span class="p">.</span><span class="n">callMe</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"This is the body!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Here we're invoking the <code>callMe</code> method on <code>blondie</code>. We're passing one argument, a function whose body is 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>
|
||||
<p>Here we're invoking the <code>callMe</code> method on <code>blondie</code>. We're passing one
|
||||
argument, a function whose body is the following
|
||||
<a href="syntax.html#blocks">block</a>—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>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Blondie</span> <span class="p">{</span>
|
||||
<span class="n">callMe</span><span class="p">(</span><span class="n">fn</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="c1">// Call it...</span>
|
||||
@ -79,29 +90,37 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<div class="codehilite"><pre><span class="n">blondie</span><span class="p">.</span><span class="n">callMeAt</span><span class="p">(</span><span class="m">867</span><span class="p">,</span> <span class="m">5309</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"This is the body!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Of course, you don'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>
|
||||
<p>Of course, you don'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>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">someFn</span> <span class="o">=</span> <span class="c1">// Get a function...</span>
|
||||
<span class="n">blondie</span><span class="p">.</span><span class="n">callMe</span><span class="p">(</span><span class="n">someFn</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<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't</em> need to pass it to a method. For that, you can call the <code>Fn</code> class's constructor:</p>
|
||||
<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't</em> need to pass it to a method. For that, you can call the <code>Fn</code>
|
||||
class's constructor:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">someFn</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fn</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"Hi!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Blondie</span> <span class="p">{</span>
|
||||
<span class="n">callMe</span><span class="p">(</span><span class="n">fn</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">fn</span><span class="p">.</span><span class="n">call</span>
|
||||
@ -110,7 +129,9 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<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 "function-like" classes and pass them to methods that expect "real" functions.</p>
|
||||
<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
|
||||
"function-like" classes and pass them to methods that expect "real" functions.</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">FakeFn</span> <span class="p">{</span>
|
||||
<span class="n">call</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"I'm feeling functional!"</span><span class="p">)</span>
|
||||
@ -122,14 +143,18 @@
|
||||
|
||||
|
||||
<h2>Function parameters <a href="#function-parameters" name="function-parameters" class="header-anchor">#</a></h2>
|
||||
<p>Of course, functions aren't very useful if you can't pass values to them. The functions that we'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>
|
||||
<p>Of course, functions aren't very useful if you can't pass values to them. The
|
||||
functions that we'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>
|
||||
<div class="codehilite"><pre><span class="n">blondie</span><span class="p">.</span><span class="n">callMe</span> <span class="p">{</span><span class="o">|</span><span class="n">first</span><span class="p">,</span> <span class="n">last</span><span class="o">|</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"Hi, "</span> <span class="o">+</span> <span class="n">first</span> <span class="o">+</span> <span class="s2">" "</span> <span class="o">+</span> <span class="n">last</span> <span class="o">+</span> <span class="s2">"!"</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Here we're passing a function to <code>greet</code> that takes two parameters, <code>first</code> and <code>last</code>. They are passed to the function when it's called:</p>
|
||||
<p>Here we're passing a function to <code>greet</code> that takes two parameters, <code>first</code> and
|
||||
<code>last</code>. They are passed to the function when it's called:</p>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Blondie</span> <span class="p">{</span>
|
||||
<span class="n">callMe</span><span class="p">(</span><span class="n">fn</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">fn</span><span class="p">.</span><span class="n">call</span><span class="p">(</span><span class="s2">"Debbie"</span><span class="p">,</span> <span class="s2">"Harry"</span><span class="p">)</span>
|
||||
@ -138,10 +163,16 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>It's an error to call a function with fewer or more arguments than its parameter list expects.</p>
|
||||
<p>It's an error to call a function with fewer or more arguments than its
|
||||
parameter list expects.</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—more precisely if there is no newline after the <code>{</code> or parameter list—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>
|
||||
<p>The body of a function is a <a href="syntax.html#blocks">block</a>. If it is a single
|
||||
expression—more precisely if there is no newline after the <code>{</code> or
|
||||
parameter list—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>
|
||||
<div class="codehilite"><pre><span class="k">new</span> <span class="n">Fn</span> <span class="p">{</span> <span class="s2">"return value"</span> <span class="p">}</span>
|
||||
|
||||
<span class="k">new</span> <span class="n">Fn</span> <span class="p">{</span>
|
||||
@ -151,7 +182,9 @@
|
||||
|
||||
|
||||
<h2>Closures <a href="#closures" name="closures" class="header-anchor">#</a></h2>
|
||||
<p>As you expect, functions are closures—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>
|
||||
<p>As you expect, functions are closures—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>
|
||||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Counter</span> <span class="p">{</span>
|
||||
<span class="kd">static</span> <span class="n">create</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="n">i</span> <span class="o">=</span> <span class="m">0</span>
|
||||
@ -161,7 +194,10 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">counter</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">.</span><span class="n">create</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">counter</span><span class="p">.</span><span class="n">call</span><span class="p">)</span> <span class="c1">// Prints "1".</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">counter</span><span class="p">.</span><span class="n">call</span><span class="p">)</span> <span class="c1">// Prints "2".</span>
|
||||
|
||||
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -58,7 +57,9 @@
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Getting Started</h1>
|
||||
<p>Getting Wren up and running on your machine should be pretty straightforward. Tiny C programs with no dependencies are nice that way. If you're on a Unix or Mac and you can rock a command line, it's just:</p>
|
||||
<p>Getting Wren up and running on your machine should be pretty straightforward.
|
||||
Tiny C programs with no dependencies are nice that way. If you're on a Unix or
|
||||
Mac and you can rock a command line, it's just:</p>
|
||||
<div class="codehilite"><pre><span class="nv">$ </span>git clone https://github.com/munificent/wren.git
|
||||
<span class="nv">$ </span><span class="nb">cd </span>wren
|
||||
<span class="nv">$ </span>make
|
||||
@ -66,10 +67,17 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>For Mac users, there is also an XCode project in the repo that you can use to hack on Wren. That's what I develop in. It builds fine from there but <em>may</em> not have the exact same build settings. The Makefile is the canonical way to compile it.</p>
|
||||
<p>For our Windows bretheren, there's still a little work to be done. Ideally, the repo would include a Visual Studio solution for building Wren. I don't have a Windows machine, but if you do, I would be delighted to take a patch for this.</p>
|
||||
<p>For Mac users, there is also an XCode project in the repo that you can use to
|
||||
hack on Wren. That's what I develop in. It builds fine from there but <em>may</em> not
|
||||
have the exact same build settings. The Makefile is the canonical way to
|
||||
compile it.</p>
|
||||
<p>For our Windows bretheren, there's still a little work to be done. Ideally, the
|
||||
repo would include a Visual Studio solution for building Wren. I don't have a
|
||||
Windows machine, but if you do, I would be delighted to take a patch for this.</p>
|
||||
<h2>Interactive mode <a href="#interactive-mode" name="interactive-mode" class="header-anchor">#</a></h2>
|
||||
<p>The above instructions will drop you into Wren's standalone interpreter in interactive mode. You can type in a line of code, and it will immediately execute it. Here's something to try:</p>
|
||||
<p>The above instructions will drop you into Wren's standalone interpreter in
|
||||
interactive mode. You can type in a line of code, and it will immediately
|
||||
execute it. Here's something to try:</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"Hello, world!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
@ -79,9 +87,12 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You can exit the interpreter using good old Ctrl-C or Ctrl-D, or just throw your computer to the ground and storm off.</p>
|
||||
<p>You can exit the interpreter using good old Ctrl-C or Ctrl-D, or just throw
|
||||
your computer to the ground and storm off.</p>
|
||||
<h2>Running scripts <a href="#running-scripts" name="running-scripts" class="header-anchor">#</a></h2>
|
||||
<p>The standalone interpreter can also load scripts from files and run them. Just pass the name of the script to wren. Create a file named "my_script.wren" in your favorite text editor and paste this into it:</p>
|
||||
<p>The standalone interpreter can also load scripts from files and run them. Just
|
||||
pass the name of the script to wren. Create a file named "my_script.wren" in
|
||||
your favorite text editor and paste this into it:</p>
|
||||
<div class="codehilite"><pre><span class="k">for</span> <span class="p">(</span><span class="n">yPixel</span> <span class="k">in</span> <span class="m">0.</span><span class="p">..</span><span class="m">24</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="n">y</span> <span class="o">=</span> <span class="n">yPixel</span> <span class="o">/</span> <span class="m">12</span> <span class="o">-</span> <span class="m">1</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="n">xPixel</span> <span class="k">in</span> <span class="m">0.</span><span class="p">..</span><span class="m">80</span><span class="p">)</span> <span class="p">{</span>
|
||||
@ -109,12 +120,14 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Neat, right? You're a Wren programmer now! The next step is to <a href="syntax.html">read more docs</a> and learn your way around the language. If you run into bugs, or have ideas or questions, any and all of the following work:</p>
|
||||
<p>Neat, right? You're a Wren programmer now! The next step is to <a href="syntax.html">read more
|
||||
docs</a> and learn your way around the language. If you run into
|
||||
bugs, or have ideas or questions, any and all of the following work:</p>
|
||||
<ul>
|
||||
<li>Tell me on twitter at <a href="https://twitter.com/intent/user?screen_name=munificentbob"><code>@munificentbob</code></a>.</li>
|
||||
<li>Tell me on twitter at <a href="https://twitter.com/intent/user?screen_name=munificentbob">@munificentbob</a>.</li>
|
||||
<li><a href="https://github.com/munificent/wren/issues">File a ticket</a> at <a href="https://github.com/munificent/wren">the GitHub repo</a>.</li>
|
||||
<li>Send a pull request.</li>
|
||||
<li>Email me at <a href="mailto:bob@stuffwithstuff.com"><code>bob@stuffwithstuff.com</code></a>.</li>
|
||||
<li>Email me at <a href="mailto:robert@stuffwithstuff.com"><code>robert@stuffwithstuff.com</code></a>.</li>
|
||||
</ul>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
39
index.html
39
index.html
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -58,26 +57,30 @@
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Welcome</h1>
|
||||
<p>Wren is a <em>small, clean, fast, class-based scripting language.</em> Think Smalltalk
|
||||
in a Lua-sized package.</p>
|
||||
<h2>Wren is a small, fast, class-based concurrent scripting language <a href="#wren-is-a-small,-fast,-class-based-concurrent-scripting-language" name="wren-is-a-small,-fast,-class-based-concurrent-scripting-language" class="header-anchor">#</a></h2>
|
||||
<p>Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in
|
||||
a familiar, modern <a href="syntax.html">syntax</a>.</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"Hello, world!"</span><span class="p">)</span>
|
||||
|
||||
<span class="kd">class</span> <span class="nc">Wren</span> <span class="p">{</span>
|
||||
<span class="n">adjectives</span> <span class="p">{</span> <span class="p">[</span><span class="s2">"small"</span><span class="p">,</span> <span class="s2">"clean"</span><span class="p">,</span> <span class="s2">"fast"</span><span class="p">]</span> <span class="p">}</span>
|
||||
<span class="n">languageType</span> <span class="p">{</span> <span class="s2">"scripting"</span> <span class="p">}</span>
|
||||
<span class="n">flyTo</span><span class="p">(</span><span class="n">city</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"Flying to "</span><span class="p">,</span> <span class="n">city</span><span class="p">)</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="kd">var</span> <span class="n">adjectives</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Fiber</span> <span class="p">{</span>
|
||||
<span class="p">[</span><span class="s2">"small"</span><span class="p">,</span> <span class="s2">"clean"</span><span class="p">,</span> <span class="s2">"fast"</span><span class="p">].</span><span class="n">map</span> <span class="p">{</span><span class="o">|</span><span class="n">word</span><span class="o">|</span> <span class="n">Fiber</span><span class="p">.</span><span class="n">yield</span><span class="p">(</span><span class="n">word</span><span class="p">)</span> <span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">adjectives</span><span class="p">.</span><span class="n">isDone</span><span class="p">)</span> <span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">adjectives</span><span class="p">.</span><span class="n">call</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><strong>Wren is small.</strong> The codebase is under 4,000 semicolons which keeps the
|
||||
language and libraries small enough to fit in your head. You can skim
|
||||
<a href="https://github.com/munificent/wren/tree/master/src">the whole thing</a> in one sitting.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Wren is clean.</strong> The codebase is <em>small</em>, but not <em>dense</em>. It is readable
|
||||
and <a href="https://github.com/munificent/wren/blob/46c1ba92492e9257aba6418403161072d640cb29/src/wren_value.h#L378-L433">lovingly-commented</a>. It's written in warning-free standard C99.</p>
|
||||
<p><strong>Wren is small.</strong> The codebase is about <a href="https://github.com/munificent/wren/tree/master/src">5,000 lines</a>. You can
|
||||
skim the whole thing in an afternoon. It's <em>small</em>, but not <em>dense</em>. It
|
||||
is readable and <a href="https://github.com/munificent/wren/blob/46c1ba92492e9257aba6418403161072d640cb29/src/wren_value.h#L378-L433">lovingly-commented</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Wren is fast.</strong> A fast single-pass compiler to tight bytecode, and a
|
||||
@ -90,9 +93,15 @@ in a Lua-sized package.</p>
|
||||
<a href="classes.html">classes</a> front and center.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Wren is concurrent.</strong> Lightweight <a href="fibers.html">fibers</a> are core to the execution
|
||||
model and let you organize your program into an army of communicating
|
||||
coroutines.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Wren is a scripting language.</strong> Wren is intended for embedding in
|
||||
applications. It has no dependencies, a small standard library,
|
||||
and <a href="embedding-api.html">an easy-to-use C API</a>.</p>
|
||||
and <a href="embedding-api.html">an easy-to-use C API</a>. It's written in warning-free
|
||||
standard C99.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</main>
|
||||
|
||||
49
lists.html
49
lists.html
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -58,14 +57,19 @@
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Lists</h1>
|
||||
<p>A list is a compound object that holds a collection of elements identified by integer index. You can create a list by placing a sequence of comma-separated expressions inside square brackets:</p>
|
||||
<p>A list is a compound object that holds a collection of elements identified by
|
||||
integer index. You can create a list by placing a sequence of comma-separated
|
||||
expressions inside square brackets:</p>
|
||||
<div class="codehilite"><pre><span class="p">[</span><span class="m">1</span><span class="p">,</span> <span class="s2">"banana"</span><span class="p">,</span> <span class="kc">true</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Here, we've created a list of three elements. Notice that the elements don't have to be the same type.</p>
|
||||
<p>Here, we've created a list of three elements. Notice that the elements don't
|
||||
have to be the same type.</p>
|
||||
<h2>Accessing elements <a href="#accessing-elements" name="accessing-elements" class="header-anchor">#</a></h2>
|
||||
<p>You can access an element from a list by calling the <a href="method-calls.html#subscript-operators">subscript operator</a> on it with the index of the element you want. Like most languages, indexes start at zero:</p>
|
||||
<p>You can access an element from a list by calling the <a href="expressions.html#subscript-operators">subscript
|
||||
operator</a> on it with the index of the
|
||||
element you want. Like most languages, indexes start at zero:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">hirsute</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"sideburns"</span><span class="p">,</span> <span class="s2">"porkchops"</span><span class="p">,</span> <span class="s2">"'stache"</span><span class="p">,</span> <span class="s2">"goatee"</span><span class="p">]</span>
|
||||
<span class="n">hirsute</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="c1">// "sideburns".</span>
|
||||
<span class="n">hirsute</span><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="c1">// "porkchops".</span>
|
||||
@ -78,31 +82,38 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>It's a runtime error to pass an index outside of the bounds of the list. If you don't know what those bounds are, you can find out using count:</p>
|
||||
<div class="codehilite"><pre><span class="n">hirsute</span><span class="p">.</span><span class="n">count</span> <span class="c1">// 3.</span>
|
||||
<p>It's a runtime error to pass an index outside of the bounds of the list. If you
|
||||
don't know what those bounds are, you can find out using count:</p>
|
||||
<div class="codehilite"><pre><span class="n">hirsute</span><span class="p">.</span><span class="n">count</span> <span class="c1">// 4.</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h2>Slices and ranges <a href="#slices-and-ranges" name="slices-and-ranges" class="header-anchor">#</a></h2>
|
||||
<p>Sometimes you want to slice out a chunk of elements from a list. You can do that by passing a <a href="values.html#ranges">range</a> to the subscript operator, like so:</p>
|
||||
<p>Sometimes you want to copy a chunk of elements from a list. You can do that by
|
||||
passing a <a href="values.html#ranges">range</a> to the subscript operator, like so:</p>
|
||||
<div class="codehilite"><pre><span class="n">hirsute</span><span class="p">[</span><span class="m">1.</span><span class="p">.</span><span class="m">2</span><span class="p">]</span> <span class="c1">// ["porkchops", "'stache"].</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>This returns a new list containing the elements of the original list whose indices are within the given range. Both inclusive and exclusive ranges work and do what you expect.</p>
|
||||
<p>Negative bounds also work like they do when passing a single number, so to copy a list, you can just do:</p>
|
||||
<p>This returns a new list containing the elements of the original list whose
|
||||
indices are within the given range. Both inclusive and exclusive ranges work
|
||||
and do what you expect.</p>
|
||||
<p>Negative bounds also work like they do when passing a single number, so to copy
|
||||
a list, you can just do:</p>
|
||||
<div class="codehilite"><pre><span class="n">hirsute</span><span class="p">[</span><span class="m">0.</span><span class="p">.</span><span class="o">-</span><span class="m">1</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h2>Adding elements <a href="#adding-elements" name="adding-elements" class="header-anchor">#</a></h2>
|
||||
<p>Lists are <em>mutable</em>, meaning their contents can be changed. You can swap out an existing element in the list using the subscript setter:</p>
|
||||
<p>Lists are <em>mutable</em>, meaning their contents can be changed. You can swap out an
|
||||
existing element in the list using the subscript setter:</p>
|
||||
<div class="codehilite"><pre><span class="n">hirsute</span><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"muttonchops"</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">hirsute</span><span class="p">[</span><span class="m">1</span><span class="p">])</span> <span class="c1">// muttonchops.</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>It's an error to set an element that's out of bounds. To grow a list, you can use <code>add</code> to append a single item to the end:</p>
|
||||
<p>It's an error to set an element that's out of bounds. To grow a list, you can
|
||||
use <code>add</code> to append a single item to the end:</p>
|
||||
<div class="codehilite"><pre><span class="n">hirsute</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"goatee"</span><span class="p">)</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">hirsute</span><span class="p">.</span><span class="n">count</span><span class="p">)</span> <span class="c1">// 4.</span>
|
||||
</pre></div>
|
||||
@ -113,8 +124,12 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>The first argument is the value to insert, and the second is the index to insert it at. All elements following the inserted one will be pushed down to make room for it.</p>
|
||||
<p>It's valid to "insert" after the last element in the list, but only <em>right</em> after it. Like other methods, you can use a negative index to count from the back. Doing so counts back from the size of the list <em>after</em> it's grown by one:</p>
|
||||
<p>The first argument is the value to insert, and the second is the index to
|
||||
insert it at. All elements following the inserted one will be pushed down to
|
||||
make room for it.</p>
|
||||
<p>It's valid to "insert" after the last element in the list, but only <em>right</em>
|
||||
after it. Like other methods, you can use a negative index to count from the
|
||||
back. Doing so counts back from the size of the list <em>after</em> it's grown by one:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">letters</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">]</span>
|
||||
<span class="n">letters</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s2">"d"</span><span class="p">,</span> <span class="m">3</span><span class="p">)</span> <span class="c1">// OK: inserts at end.</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">letters</span><span class="p">)</span> <span class="c1">// ["a", "b", "c", "d"]</span>
|
||||
@ -124,7 +139,9 @@
|
||||
|
||||
|
||||
<h2>Removing elements <a href="#removing-elements" name="removing-elements" class="header-anchor">#</a></h2>
|
||||
<p>The opposite of <code>insert</code> is <code>removeAt</code>. It removes a single element from a given position in the list. All following items are shifted up to fill in the gap:</p>
|
||||
<p>The opposite of <code>insert</code> is <code>removeAt</code>. It removes a single element from a
|
||||
given position in the list. All following items are shifted up to fill in the
|
||||
gap:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">letters</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">]</span>
|
||||
<span class="n">letters</span><span class="p">.</span><span class="n">removeAt</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">letters</span><span class="p">)</span> <span class="c1">// ["a", "c"]</span>
|
||||
|
||||
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -58,7 +57,8 @@
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Maps</h1>
|
||||
<p>Wren will have a built-in hash table type similar to objects in JavaScript and tables in Lua, but they haven't been implemented yet.</p>
|
||||
<p>Wren will have a built-in hash table type similar to objects in JavaScript and
|
||||
tables in Lua, but they haven't been implemented yet.</p>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
@ -1,160 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
|
||||
<title>Method Calls – Wren</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<link href='http://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="index.html">wren</a></h1>
|
||||
<h2>a classy little scripting language</h2>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="page">
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="getting-started.html">Getting Started</a></li>
|
||||
</ul>
|
||||
<section>
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>types</h2>
|
||||
<ul>
|
||||
<li><a href="values.html">Values</a></li>
|
||||
<li><a href="classes.html">Classes</a></li>
|
||||
<li><a href="fibers.html">Fibers</a></li>
|
||||
<li><a href="functions.html">Functions</a></li>
|
||||
<li><a href="lists.html">Lists</a></li>
|
||||
<li><a href="maps.html">Maps</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>reference</h2>
|
||||
<ul>
|
||||
<li><a href="core-library.html">Core Library</a></li>
|
||||
<li><a href="embedding-api.html">Embedding API</a></li>
|
||||
<li><a href="performance.html">Performance</a></li>
|
||||
<li><a href="contributing.html">Contributing</a></li>
|
||||
<li><a href="qa.html">Q & A</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Method Calls</h1>
|
||||
<p><strong>TODO: Refactor <code>method-calls</code> and <code>classes</code> into using and creating classes.</strong></p>
|
||||
<p>Wren is object-oriented, so most code consists of method calls. Most of them
|
||||
look like so:</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
|
||||
<span class="n">items</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"another"</span><span class="p">)</span>
|
||||
<span class="n">items</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="s2">"value"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You have a <em>receiver</em> on the left, followed by a <code>.</code>, then a name and an
|
||||
argument list in parentheses. Semantically, a method call works like this:</p>
|
||||
<ol>
|
||||
<li>Look up the class of the receiver.</li>
|
||||
<li>Look up the method on it by name.</li>
|
||||
<li>Invoke the method.</li>
|
||||
</ol>
|
||||
<p>Methods that do not take any arguments leave off the <code>()</code>:</p>
|
||||
<div class="codehilite"><pre><span class="n">text</span><span class="p">.</span><span class="n">length</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>These are special "getters" or "accessors" in other languages. In Wren, they're
|
||||
just methods.</p>
|
||||
<h2>Arity <a href="#arity" name="arity" class="header-anchor">#</a></h2>
|
||||
<p>Unlike most dynamic languages, the number of arguments to a method is part of
|
||||
its call signature. Methods with different signatures are distinct from each
|
||||
other. In technical terms, this means you can overload by <em>arity</em>.</p>
|
||||
<p>In normal human terms, it means you can overload by number of parameters. These
|
||||
are calls to two different methods:</p>
|
||||
<div class="codehilite"><pre><span class="n">items</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"one arg"</span><span class="p">)</span>
|
||||
<span class="n">items</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"first"</span><span class="p">,</span> <span class="s2">"second"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Instead of having a single <code>add</code> method where you have to check for "undefined"
|
||||
or missing arguments, Wren just treats them as different methods that you can
|
||||
implement separately.</p>
|
||||
<h2>Setters <a href="#setters" name="setters" class="header-anchor">#</a></h2>
|
||||
<p>Modifying a public property of some object looks like you expect:</p>
|
||||
<div class="codehilite"><pre><span class="n">point</span><span class="p">.</span><span class="n">x</span> <span class="o">=</span> <span class="m">123</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You can probably guess by now, but again this is just another special syntax
|
||||
for a regular method call. The semantics for the above are "invoke the <code>x=</code>
|
||||
method on <code>point</code>, passing <code>123</code> as an argument."</p>
|
||||
<h2>Operators <a href="#operators" name="operators" class="header-anchor">#</a></h2>
|
||||
<p>Wren has most of the same operators you know and love from C and friends, with
|
||||
the same precedence and associativity. They are listed here because they are
|
||||
just a special syntax for regular method calls.</p>
|
||||
<p>Wren has a few prefix operators:</p>
|
||||
<div class="codehilite"><pre><span class="o">!</span> <span class="o">~</span> <span class="o">-</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>They are just method calls on the operand without any other arguments. An
|
||||
expression like <code>!possible</code> just means "call the <code>!</code> method on <code>possible</code>".</p>
|
||||
<p>We have a few other operators to play with. The remaining ones are
|
||||
infix—they have operators on either side. In order of increasing
|
||||
precedence, they are:</p>
|
||||
<div class="codehilite"><pre><span class="o">==</span> <span class="o">!=</span>
|
||||
<span class="o"><</span> <span class="o">></span> <span class="o"><=</span> <span class="o">>=</span>
|
||||
<span class="p">..</span> <span class="p">...</span>
|
||||
<span class="o">|</span> <span class="o">&</span>
|
||||
<span class="o">+</span> <span class="o">-</span>
|
||||
<span class="o">*</span> <span class="o">/</span> <span class="o">%</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Like prefix operators, they are just a funny way of writing a method call. The
|
||||
left operand is the receiver, and the right operand gets passed to it. So
|
||||
<code>a + b</code> is semantically interpreted as "invoke the <code>+</code> method on <code>a</code>, passing
|
||||
it <code>b</code>".</p>
|
||||
<p>Most of these are probably familiar already. The <code>..</code> and <code>...</code> operators are
|
||||
"range" operators. The number type implements those and returns a range object,
|
||||
which can in turn be iterated over using a <code>for</code> <a href="looping.html">loop</a>.</p>
|
||||
<h2>Subscript operators <a href="#subscript-operators" name="subscript-operators" class="header-anchor">#</a></h2>
|
||||
<p>Most languages use square brackets (<code>[]</code>) for working with collection-like
|
||||
objects. For example:</p>
|
||||
<div class="codehilite"><pre><span class="n">first</span> <span class="o">=</span> <span class="n">list</span><span class="p">[</span><span class="m">0</span><span class="p">]</span>
|
||||
<span class="n">map</span><span class="p">[</span><span class="s2">"key"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"value"</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>You know the refrain by now. In Wren, these are just method calls. Subscript
|
||||
operators can also be overloaded by arity, which is useful for things like
|
||||
multi-dimensional arrays:</p>
|
||||
<div class="codehilite"><pre><span class="n">table</span><span class="p">[</span><span class="m">3</span><span class="p">,</span> <span class="m">5</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"value"</span>
|
||||
</pre></div>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
<div class="page">
|
||||
<div class="main-column">
|
||||
<p>Wren lives <a href="https://github.com/munificent/wren">on GitHub</a> — Made with ❤ by <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a>.</p>
|
||||
<div class="main-column">
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
131
performance.html
131
performance.html
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -58,7 +57,8 @@
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Performance</h1>
|
||||
<p>Even though most benchmarks aren't worth the pixels they're printed on, people seem to like them, so here's a few:</p>
|
||||
<p>Even though most benchmarks aren't worth the pixels they're printed on, people
|
||||
seem to like them, so here's a few:</p>
|
||||
<h3>Method Call</h3>
|
||||
|
||||
<table class="chart">
|
||||
@ -142,9 +142,20 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Longer bars are better. The score is the inverse of the running time, so if one language's score is twice another's, that means the language is twice as fast. Each benchmark is run ten times and the best time is kept. It only measures the time taken to execute the benchmarked code itself, not interpreter startup.</p>
|
||||
<p>These were run on my MacBook Pro 2.3 GHz Intel Core i7 with 16 GB of 1,600 MHz DDR3 RAM. Tested against Lua 5.2.3, LuaJIT 2.0.2, Python 2.7.5, Python 3.3.4, ruby 2.0.0p247. LuaJIT is run with the JIT <em>disabled</em> (i.e. in bytecode interpreter mode) since I want to support platforms where JIT-compilation is disallowed. LuaJIT with the JIT enabled is <em>much</em> faster than all of the other languages benchmarked, including Wren, because Mike Pall is a robot from the future.</p>
|
||||
<p>The benchmark harness and programs are <a href="https://github.com/munificent/wren/tree/master/benchmark">here</a>.</p>
|
||||
<p><strong>Longer bars are better.</strong> The score is the inverse of the running time, so if
|
||||
one language's score is twice another's, that means the language is twice as
|
||||
fast. Each benchmark is run ten times and the best time is kept. It only
|
||||
measures the time taken to execute the benchmarked code itself, not interpreter
|
||||
startup.</p>
|
||||
<p>These were run on my MacBook Pro 2.3 GHz Intel Core i7 with 16 GB of 1,600 MHz
|
||||
DDR3 RAM. Tested against Lua 5.2.3, LuaJIT 2.0.2, Python 2.7.5, Python 3.3.4,
|
||||
ruby 2.0.0p247. LuaJIT is run with the JIT <em>disabled</em> (i.e. in bytecode
|
||||
interpreter mode) since I want to support platforms where JIT-compilation is
|
||||
disallowed. LuaJIT with the JIT enabled is <em>much</em> faster than all of the other
|
||||
languages benchmarked, including Wren, because Mike Pall is a robot from the
|
||||
future.</p>
|
||||
<p>The benchmark harness and programs are
|
||||
<a href="https://github.com/munificent/wren/tree/master/benchmark">here</a>.</p>
|
||||
<h2>Why is Wren fast? <a href="#why-is-wren-fast" name="why-is-wren-fast" class="header-anchor">#</a></h2>
|
||||
<p>Languages come in four rough performance buckets, from slowest to fastest:</p>
|
||||
<ol>
|
||||
@ -164,32 +175,98 @@
|
||||
<p>Statically typed languages: C, C++, Java, C#, Haskell, etc.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<p>Most languages in the first bucket aren't suitable for production use. (Servers are one exception, because you can throw more hardware at a slow language there.) Languages in the second bucket are fast enough for many use cases, even on client hardware, as the success of the listed languages shows. Languages in the third bucket are quite fast, but their implementations are breathtakingly complex, often rivaling that of compilers for statically-typed languages.</p>
|
||||
<p>Wren is in the second bucket. If you want a simple implementation that's fast enough for real use, this is the sweet spot. In addition, Wren has a few tricks up its sleeve:</p>
|
||||
<p>Most languages in the first bucket aren't suitable for production use. (Servers
|
||||
are one exception, because you can throw more hardware at a slow language
|
||||
there.) Languages in the second bucket are fast enough for many use cases, even
|
||||
on client hardware, as the success of the listed languages shows. Languages in
|
||||
the third bucket are quite fast, but their implementations are breathtakingly
|
||||
complex, often rivaling that of compilers for statically-typed languages.</p>
|
||||
<p>Wren is in the second bucket. If you want a simple implementation that's fast
|
||||
enough for real use, this is the sweet spot. In addition, Wren has a few tricks
|
||||
up its sleeve:</p>
|
||||
<h3>A compact value representation <a href="#a-compact-value-representation" name="a-compact-value-representation" class="header-anchor">#</a></h3>
|
||||
<p>A core piece of a dynamic language implementation is the data structure used for variables. It needs to be able to store (or reference) a value of any type, while also being as compact as possible. Wren uses a technique called <em><a href="http://wingolog.org/archives/2011/05/18/value-representation-in-javascript-implementations">NaN tagging</a></em> for this.</p>
|
||||
<p>All values are stored internally in Wren as small, eight-byte double-precision floats. Since that is also Wren's number type, in order to do arithmetic, no conversion is needed before the "raw" number can be accessed: a value holding a number <em>is</em> a valid double. This keeps arithmetic fast.</p>
|
||||
<p>To store values of other types, it turns out there's a ton of unused bits in a NaN double. You can stuff a pointer for heap-allocated objects, with room left over for special values like <code>true</code>, <code>false</code>, and <code>null</code>. This means numbers, bools, and null are unboxed. It also means an entire value is only eight bytes, the native word size on 64-bit machines. Smaller = faster when you take into account CPU caching and the cost of passing values around.</p>
|
||||
<p>A core piece of a dynamic language implementation is the data structure used
|
||||
for variables. It needs to be able to store (or reference) a value of any type,
|
||||
while also being as compact as possible. Wren uses a technique called <em><a href="http://wingolog.org/archives/2011/05/18/value-representation-in-javascript-implementations">NaN
|
||||
tagging</a></em> for this.</p>
|
||||
<p>All values are stored internally in Wren as small, eight-byte double-precision
|
||||
floats. Since that is also Wren's number type, in order to do arithmetic, no
|
||||
conversion is needed before the "raw" number can be accessed: a value holding a
|
||||
number <em>is</em> a valid double. This keeps arithmetic fast.</p>
|
||||
<p>To store values of other types, it turns out there's a ton of unused bits in a
|
||||
NaN double. You can stuff a pointer for heap-allocated objects, with room left
|
||||
over for special values like <code>true</code>, <code>false</code>, and <code>null</code>. This means numbers,
|
||||
bools, and null are unboxed. It also means an entire value is only eight bytes,
|
||||
the native word size on 64-bit machines. Smaller = faster when you take into
|
||||
account CPU caching and the cost of passing values around.</p>
|
||||
<h3>Fixed object layout <a href="#fixed-object-layout" name="fixed-object-layout" class="header-anchor">#</a></h3>
|
||||
<p>Most dynamic languages treat objects as loose bags of named properties. You can freely add and remove properties from an object after you've created it. Languages like Lua and JavaScript don't even have a well-defined concept of a "type" of object.</p>
|
||||
<p>Wren is strictly class-based. Every object is an instance of a class. Classes in turn have a well-defined declarative syntax, and cannot be imperatively modified. In addition, fields in Wren are private to the class—they can only be accessed from methods defined directly on that class.</p>
|
||||
<p>Put all of that together and it means you can determine at <em>compile</em> time exactly how many fields an object has and what they are. In other languages, when you create an object, you allocate some initial memory for it, but that may have to be reallocated multiple times as fields are added and the object grows. Wren just does a single allocation up front for exactly the right number of fields.</p>
|
||||
<p>Likewise, when you access a field in other languages, the interpreter has to look it up by name in a hash table in the object, and then maybe walk its inheritance chain if it can't find it. It must do this every time since fields may be added freely. In Wren, field access is just accessing a slot in the instance by an offset known at compile time: it's just adding a few pointers.</p>
|
||||
<p>Most dynamic languages treat objects as loose bags of named properties. You can
|
||||
freely add and remove properties from an object after you've created it.
|
||||
Languages like Lua and JavaScript don't even have a well-defined concept of a
|
||||
"type" of object.</p>
|
||||
<p>Wren is strictly class-based. Every object is an instance of a class. Classes
|
||||
in turn have a well-defined declarative syntax, and cannot be imperatively
|
||||
modified. In addition, fields in Wren are private to the class—they can
|
||||
only be accessed from methods defined directly on that class.</p>
|
||||
<p>Put all of that together and it means you can determine at <em>compile</em> time
|
||||
exactly how many fields an object has and what they are. In other languages,
|
||||
when you create an object, you allocate some initial memory for it, but that
|
||||
may have to be reallocated multiple times as fields are added and the object
|
||||
grows. Wren just does a single allocation up front for exactly the right number
|
||||
of fields.</p>
|
||||
<p>Likewise, when you access a field in other languages, the interpreter has to
|
||||
look it up by name in a hash table in the object, and then maybe walk its
|
||||
inheritance chain if it can't find it. It must do this every time since fields
|
||||
may be added freely. In Wren, field access is just accessing a slot in the
|
||||
instance by an offset known at compile time: it's just adding a few pointers.</p>
|
||||
<h3>Copy-down inheritance <a href="#copy-down-inheritance" name="copy-down-inheritance" class="header-anchor">#</a></h3>
|
||||
<p>When you call a method on an object, the method must be located. It could be defined directly on the object's class, or it may be inheriting it from some superclass. This means that in the worst case, you may have to walk the inheritance chain to find it.</p>
|
||||
<p>Advanced implementations do very smart things to optimize this, but it's made more difficult by the mutable nature of the underlying language: if you can add new methods to existing classes freely or change the inheritance hierarchy, the lookup for a given method may actually change over time. You have to check for that which costs CPU cycles.</p>
|
||||
<p>Wren's inheritance hierarchy is static and fixed at class definition time. This means that we can copy down all inherited methods in the subclass when it's created since we know those will never change. Method dispatch then just requires locating the method in the class of the receiver.</p>
|
||||
<p>When you call a method on an object, the method must be located. It could be
|
||||
defined directly on the object's class, or it may be inheriting it from some
|
||||
superclass. This means that in the worst case, you may have to walk the
|
||||
inheritance chain to find it.</p>
|
||||
<p>Advanced implementations do very smart things to optimize this, but it's made
|
||||
more difficult by the mutable nature of the underlying language: if you can add
|
||||
new methods to existing classes freely or change the inheritance hierarchy, the
|
||||
lookup for a given method may actually change over time. You have to check for
|
||||
that which costs CPU cycles.</p>
|
||||
<p>Wren's inheritance hierarchy is static and fixed at class definition time. This
|
||||
means that we can copy down all inherited methods in the subclass when it's
|
||||
created since we know those will never change. Method dispatch then just
|
||||
requires locating the method in the class of the receiver.</p>
|
||||
<h3>Computed gotos <a href="#computed-gotos" name="computed-gotos" class="header-anchor">#</a></h3>
|
||||
<p>On compilers that support it, Wren's core bytecode interpreter loop uses something called <a href="http://eli.thegreenplace.net/2012/07/12/computed-goto-for-efficient-dispatch-tables/"><em>computed gotos</em></a>. The hot core of a bytecode interpreter is effectively a giant <code>switch</code> on the instruction being executed.</p>
|
||||
<p>Doing that using an actual <code>switch</code> confounds the CPU's <a href="http://en.wikipedia.org/wiki/Branch_predictor">branch predictor</a>: there is basically a single branch point for the entire interpreter. That quickly saturates the predictor and it just gets confused and fails to predict anything, which leads to more CPU stalls and pipeline flushes.</p>
|
||||
<p>Using computed gotos gives you a separate branch point at the end of each instruction. Each gets its own branch prediction, which often succeeds since some instruction pairs are more common than others. In my rough testing, this makes a 5-10% performance difference.</p>
|
||||
<p>On compilers that support it, Wren's core bytecode interpreter loop uses
|
||||
something called <a href="http://eli.thegreenplace.net/2012/07/12/computed-goto-for-efficient-dispatch-tables/"><em>computed gotos</em></a>. The hot core of a bytecode
|
||||
interpreter is effectively a giant <code>switch</code> on the instruction being executed.</p>
|
||||
<p>Doing that using an actual <code>switch</code> confounds the CPU's <a href="http://en.wikipedia.org/wiki/Branch_predictor">branch
|
||||
predictor</a>—there is basically a single branch point for the entire
|
||||
interpreter. That quickly saturates the predictor and it just gets confused and
|
||||
fails to predict anything, which leads to more CPU stalls and pipeline flushes.</p>
|
||||
<p>Using computed gotos gives you a separate branch point at the end of each
|
||||
instruction. Each gets its own branch prediction, which often succeeds since
|
||||
some instruction pairs are more common than others. In my rough testing, this
|
||||
makes a 5-10% performance difference.</p>
|
||||
<h3>A single-pass compiler <a href="#a-single-pass-compiler" name="a-single-pass-compiler" class="header-anchor">#</a></h3>
|
||||
<p>Compile time is a relatively small component of a language's performance: code only has to be compiled once but a given line of code may be run many times. However, fast compilation helps with <em>startup</em> speed—the time it takes to get anything up and running. For that, Wren's compiler is quite fast.</p>
|
||||
<p>It's modeled after Lua's compiler. Instead of tokenizing and then parsing to create a bunch of AST structures which are then consumed and deallocated by later phases, it emits code directly during parsing. This means it does minimal memory allocation during a parse and has very little overhead.</p>
|
||||
<p>Compile time is a relatively small component of a language's performance: code
|
||||
only has to be compiled once but a given line of code may be run many times.
|
||||
However, fast compilation helps with <em>startup</em> speed—the time it takes to
|
||||
get anything up and running. For that, Wren's compiler is quite fast.</p>
|
||||
<p>It's modeled after Lua's compiler. Instead of tokenizing and then parsing to
|
||||
create a bunch of AST structures which are then consumed and deallocated by
|
||||
later phases, it emits code directly during parsing. This means it does minimal
|
||||
memory allocation during a parse and has very little overhead.</p>
|
||||
<h2>Why don't other languages do this? <a href="#why-don't-other-languages-do-this" name="why-don't-other-languages-do-this" class="header-anchor">#</a></h2>
|
||||
<p>Most of Wren's performance comes from language design decisions. While it's dynamically <em>typed</em> and <em>dispatched</em>, classes are relatively statically <em>defined</em>. That makes a lot of things much easier. Other languages have a much more mutable object model, and cannot change that without breaking lots of existing code.</p>
|
||||
<p>Wren's closest sibling, by far, is Lua. Lua is more dynamic than Wren which makes its job harder. Lua also tries very hard to be compatible across a wide range of hardware and compilers. If you have a C89 compiler for it, odds are very good that you can run Lua on it.</p>
|
||||
<p>Wren cares about compatibility, but it requires C99 and IEEE double precision floats. That may exclude some edge case hardware, but makes things like NaN tagging, computed gotos, and some other tricks possible.</p>
|
||||
<p>Most of Wren's performance comes from language design decisions. While it's
|
||||
dynamically <em>typed</em> and <em>dispatched</em>, classes are relatively statically
|
||||
<em>defined</em>. That makes a lot of things much easier. Other languages have a much
|
||||
more mutable object model, and cannot change that without breaking lots of
|
||||
existing code.</p>
|
||||
<p>Wren's closest sibling, by far, is Lua. Lua is more dynamic than Wren which
|
||||
makes its job harder. Lua also tries very hard to be compatible across a wide
|
||||
range of hardware and compilers. If you have a C89 compiler for it, odds are
|
||||
very good that you can run Lua on it.</p>
|
||||
<p>Wren cares about compatibility, but it requires C99 and IEEE double precision
|
||||
floats. That may exclude some edge case hardware, but makes things like NaN
|
||||
tagging, computed gotos, and some other tricks possible.</p>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
79
qa.html
79
qa.html
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -59,12 +58,26 @@
|
||||
<main>
|
||||
<h1>Q & A</h1>
|
||||
<h2>Why did you create Wren? <a href="#why-did-you-create-wren" name="why-did-you-create-wren" class="header-anchor">#</a></h2>
|
||||
<p>Other creative endeavors aren't immediately met with existential crises, but for some reason programmers don't seem to like new languages. Here's the niche I'm trying to fill:</p>
|
||||
<p>There are a few scripting languages used for embedding in applications. Lua is the main one. TCL used to be. There's also Guile, increasingly JavaScript, and some applications embed Python. I'm an ex-game developer, so when I think "scripting", I tend to think "game scripting".</p>
|
||||
<p>Lua is nice: it's small, simple, and fast. But—and I don't mean this as a criticism—it's also weird if you're used to languages like C++ and Java. The syntax is different. The semantics, especially the object model are unusual. Anyone can get used to 1-based indexing, but things like metatables really show that objects were bolted onto Lua after the fact.</p>
|
||||
<p>I think there's room for a language as simple as Lua, but that feels natural to someone with an OOP background. Wren is my attempt at that.</p>
|
||||
<p>Other creative endeavors aren't immediately met with existential crises, but
|
||||
for some reason programmers don't seem to like new languages. Here's the niche
|
||||
I'm trying to fill:</p>
|
||||
<p>There are a few scripting languages used for embedding in applications. Lua is
|
||||
the main one. TCL used to be. There's also Guile, increasingly JavaScript, and
|
||||
some applications embed Python. I'm an ex-game developer, so when I think
|
||||
"scripting", I tend to think "game scripting".</p>
|
||||
<p>Lua is nice: it's small, simple, and fast. But—and I don't mean this as a
|
||||
criticism—it's also weird if you're used to languages like C++ and Java.
|
||||
The syntax is different. The semantics, especially the object model are
|
||||
unusual. Anyone can get used to 1-based indexing, but things like metatables
|
||||
really show that objects were bolted onto Lua after the fact.</p>
|
||||
<p>I think there's room for a language as simple as Lua, but that feels natural to
|
||||
someone with an OOP background. Wren is my attempt at that.</p>
|
||||
<h2>Why classes? <a href="#why-classes" name="why-classes" class="header-anchor">#</a></h2>
|
||||
<p>Thanks to JavaScript's popularity, lots of people are discovering prototypes right now, and the paradigm is experiencing a popularity boom. I think prototypes are interesting, but after <a href="https://github.com/munificent/finch">several years playing with them</a>, I concluded (like many people on the original Self project that invented prototypes) that classes are more usable.</p>
|
||||
<p>Thanks to JavaScript's popularity, lots of people are discovering prototypes
|
||||
right now, and the paradigm is experiencing a popularity boom. I think
|
||||
prototypes are interesting, but after <a href="http://finch.stuffwithstuff.com/">several years playing with them</a>,
|
||||
I concluded (like many people on the original Self project that invented
|
||||
prototypes) that classes are more usable.</p>
|
||||
<p>Here's an example of that kind of object-oriented programming in Lua:</p>
|
||||
<div class="codehilite"><pre><span class="n">Account</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="n">Account</span><span class="p">.</span><span class="n">__index</span> <span class="o">=</span> <span class="n">Account</span>
|
||||
@ -98,21 +111,49 @@
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Classes have a reputation for complexity because most of the widely used languages with them are quite complex: C++, Java, C#, Ruby, and Python. I hope to show with Wren that is those languages that are complex, and not classes themselves.</p>
|
||||
<p>Smalltalk, the language that inspired most of those languages, is famously simple. Its syntax <a href="http://www.jarober.com/blog/blogView?showComments=true&title=Readability+is+Key&entry=3506312690">fits on an index card</a>. My aim is to keep Wren that minimal while still having the expressive power of <a href="classes.html">classes</a>.</p>
|
||||
<p>Classes have a reputation for complexity because most of the widely used
|
||||
languages with them are quite complex: C++, Java, C#, Ruby, and Python. I hope
|
||||
to show with Wren that is those languages that are complex, and not classes
|
||||
themselves.</p>
|
||||
<p>Smalltalk, the language that inspired most of those languages, is famously
|
||||
simple. Its syntax <a href="http://www.jarober.com/blog/blogView?showComments=true&title=Readability+is+Key&entry=3506312690">fits on an index card</a>. My aim is to keep Wren that
|
||||
minimal while still having the expressive power of <a href="classes.html">classes</a>.</p>
|
||||
<h2>Why compile to bytecode? <a href="#why-compile-to-bytecode" name="why-compile-to-bytecode" class="header-anchor">#</a></h2>
|
||||
<p>The <a href="performance.html">performance page</a> has more details, but the short answer is that bytecode is a nice trade-off between performance and simplicity. Also:</p>
|
||||
<p>The <a href="performance.html">performance page</a> has more details, but the short answer
|
||||
is that bytecode is a nice trade-off between performance and simplicity. Also:</p>
|
||||
<ul>
|
||||
<li>Many devices like iPhones and game consoles don't allow executing code generated at runtime, which rules out just-in-time compilation.</li>
|
||||
<li>I think <a href="fibers.html">fibers</a> are a really powerful tool, and implementing them is straightforward in a bytecode VM that doesn't use the native stack.</li>
|
||||
<li>
|
||||
<p>Many devices like iPhones and game consoles don't allow executing code
|
||||
generated at runtime, which rules out just-in-time compilation.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>I think <a href="fibers.html">fibers</a> are a really powerful tool, and implementing
|
||||
them is straightforward in a bytecode VM that doesn't use the native stack.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>What about your other languages? <a href="#what-about-your-other-languages" name="what-about-your-other-languages" class="header-anchor">#</a></h2>
|
||||
<p>This is a strange question if you don't happen to know <a href="http://journal.stuffwithstuff.com/">who I am</a>. In the past, I've hacked on and blogged about a couple of other hobby languages like <a href="http://finch.stuffwithstuff.com/">Finch</a> and <a href="http://magpie-lang.org/">Magpie</a>.</p>
|
||||
<p>I started Finch to learn more about implementing an interpreter and also about the prototype paradigm. I learned a ton about both. Critically, I learned that I really prefer classes over prototypes. I started retrofitting classes into Finch but realized it was too big of a change, and thus Wren was born.</p>
|
||||
<p>Wren is a replacement for Finch to me. I gave it a new name mainly so that I can keep Finch around in case other people want to take it and do something with it. I don't have any intention to work on it anymore.</p>
|
||||
<p>Magpie is a trickier one. I really like the ideas behind Magpie. It's the general-purpose language I wish I had much of the time. I love pattern matching and multiple dispatch. I like how it integrates the event-based IO of <a href="https://github.com/joyent/libuv">libuv</a> with the simplicity of fibers.</p>
|
||||
<p>But it's also a much more challenging project. As a general-purpose language, there's a ton of library work to do before Magpie is useful for anything. It has some unresolved GC issues. And I'm frankly not skilled enough right now to implement multiple dispatch efficiently.</p>
|
||||
<p>Meanwhile, since I started working on Magpie, <a href="http://julialang.org/">Julia</a> appeared and <a href="http://opendylan.org/">Dylan</a> <em>re</em>appeared. I created Magpie partially to carry the torch of multiple dispatch, but others are starting to spread that light now.</p>
|
||||
<p>This is a strange question if you don't happen to know <a href="http://journal.stuffwithstuff.com">who I am</a>. In the
|
||||
past, I've hacked on and blogged about a couple of other hobby languages like
|
||||
<a href="http://finch.stuffwithstuff.com/">Finch</a> and <a href="http://magpie-lang.org/">Magpie</a>.</p>
|
||||
<p>I started Finch to learn more about implementing an interpreter and also about
|
||||
the prototype paradigm. I learned a ton about both. Critically, I learned that
|
||||
I really prefer classes over prototypes. I started retrofitting classes into
|
||||
Finch but realized it was too big of a change, and thus Wren was born.</p>
|
||||
<p>Wren is a replacement for Finch to me. I gave it a new name mainly so that I
|
||||
can keep Finch around in case other people want to take it and do something
|
||||
with it. I don't have any intention to work on it anymore.</p>
|
||||
<p>Magpie is a trickier one. I really like the ideas behind Magpie. It's the
|
||||
general-purpose language I wish I had much of the time. I love pattern matching
|
||||
and multiple dispatch. I like how it integrates the event-based IO of <a href="https://github.com/joyent/libuv">libuv</a>
|
||||
with the simplicity of fibers.</p>
|
||||
<p>But it's also a much more challenging project. As a general-purpose language,
|
||||
there's a ton of library work to do before Magpie is useful for anything. It
|
||||
has some unresolved GC issues. And I'm frankly not skilled enough right now to
|
||||
implement multiple dispatch efficiently.</p>
|
||||
<p>Meanwhile, since I started working on Magpie, <a href="http://julialang.org/">Julia</a>
|
||||
appeared and <a href="http://opendylan.org/">Dylan</a> <em>re</em>appeared. I created Magpie
|
||||
partially to carry the torch of multiple dispatch, but others are starting to
|
||||
spread that light now.</p>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
88
syntax.html
88
syntax.html
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -58,11 +57,12 @@
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Syntax</h1>
|
||||
<p>Wren's syntax is designed to be familiar to people coming from C-like languages while being as simple and expressive as possible within that framework.</p>
|
||||
<p>Wren's syntax is designed to be familiar to people coming from C-like languages
|
||||
while being a bit simpler and more streamlined.</p>
|
||||
<p>Scripts are stored in plain text files with a <code>.wren</code> file extension. Wren does
|
||||
not compile ahead of time: programs are run directly from source, from top to
|
||||
bottom like a typical scripting language. (Internally, programs are compiled to
|
||||
bytecode for efficiency, but that's an implementation detail).</p>
|
||||
bytecode for efficiency, but that's an implementation detail.)</p>
|
||||
<h2>Comments <a href="#comments" name="comments" class="header-anchor">#</a></h2>
|
||||
<p>Line comments start with <code>//</code> and end at the end of the line:</p>
|
||||
<div class="codehilite"><pre><span class="c1">// This is a comment.</span>
|
||||
@ -78,17 +78,15 @@ or be within a single one. Unlike C, block comments can nest in Wren:</p>
|
||||
<h2>Reserved words <a href="#reserved-words" name="reserved-words" class="header-anchor">#</a></h2>
|
||||
<p>Some people like to see all of the reserved words in a programming language in
|
||||
one lump. If you're one of those folks, here you go:</p>
|
||||
<div class="codehilite"><pre><span class="k">break</span> <span class="kd">class</span> <span class="nc">else</span> <span class="k">for</span> <span class="k">if</span> <span class="k">in</span> <span class="k">is</span> <span class="k">return</span> <span class="kd">static</span> <span class="kd">var</span> <span class="k">while</span>
|
||||
<div class="codehilite"><pre><span class="k">break</span> <span class="kd">class</span> <span class="nc">else</span> <span class="kc">false</span> <span class="k">for</span> <span class="k">if</span> <span class="k">in</span> <span class="k">is</span> <span class="k">new</span> <span class="kc">null</span>
|
||||
<span class="k">return</span> <span class="kd">static</span> <span class="k">super</span> <span class="k">this</span> <span class="kc">true</span> <span class="kd">var</span> <span class="k">while</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Wren also has a few predefined identifiers:</p>
|
||||
<div class="codehilite"><pre><span class="kc">false</span> <span class="kc">null</span> <span class="k">this</span> <span class="kc">true</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<h2>Names <a href="#names" name="names" class="header-anchor">#</a></h2>
|
||||
<p>Identifiers are similar to other programming languages. They start with a letter or underscore and may contain letters, digits, and underscores. Case is sensitive.</p>
|
||||
<h2>Identifiers <a href="#identifiers" name="identifiers" class="header-anchor">#</a></h2>
|
||||
<p>Naming rules are similar to other programming languages. Identifiers start with
|
||||
a letter or underscore and may contain letters, digits, and underscores. Case
|
||||
is sensitive.</p>
|
||||
<div class="codehilite"><pre><span class="n">hi</span>
|
||||
<span class="n">camelCase</span>
|
||||
<span class="n">PascalCase</span>
|
||||
@ -98,34 +96,40 @@ one lump. If you're one of those folks, here you go:</p>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Identifiers that start with underscore (<code>_</code>) are special in Wren. They are used to indicate fields in <a href="classes.html">classes</a>.</p>
|
||||
<h2>Statement terminators <a href="#statement-terminators" name="statement-terminators" class="header-anchor">#</a></h2>
|
||||
<p>Officially, statements are terminated by a semicolon (<code>;</code>) like in other
|
||||
languages in the C tradition. However, Wren treats newlines as equivalent
|
||||
to a semicolon whenever it makes sense. In practice, this means you almost
|
||||
never write <code>;</code> unless you want to cram a bunch of statements on one line.</p>
|
||||
<p>Identifiers that start with underscore (<code>_</code>) are special in Wren. They are used
|
||||
to indicate <a href="classes.html#fields">fields</a> in classes.</p>
|
||||
<h2>Newlines <a href="#newlines" name="newlines" class="header-anchor">#</a></h2>
|
||||
<p>Newlines (<code>\n</code>) are meaningful in Wren. They are used to separate statements:</p>
|
||||
<div class="codehilite"><pre><span class="c1">// Two statements:</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"hi"</span><span class="p">)</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"hi"</span><span class="p">)</span> <span class="c1">// Newline.</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"bye"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Sometimes, though, a statement doesn't fit on a single line and treating the
|
||||
newline as a semicolon would trip things up. To handle that, Wren has a very
|
||||
simple rule: It ignores a newline following any token that can't end a
|
||||
statement.</p>
|
||||
<p>Everywhere else, a newline is treated just like a <code>;</code>. Note that this is a very
|
||||
different system from how JavaScript handles semicolons. If you've been burned
|
||||
there, don't worry, you should be fine here.</p>
|
||||
<p>Sometimes, though, a statement doesn't fit on a single line and jamming a
|
||||
newline in the middle would trip it up. To handle that, Wren has a very simple
|
||||
rule: It ignores a newline following any token that can't end a statement.</p>
|
||||
<div class="codehilite"><pre><span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span> <span class="c1">// Newline here is ignored.</span>
|
||||
<span class="s2">"hi"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>In practice, this means you can put each statement on its own line and wrap
|
||||
them across lines as needed without too much trouble.</p>
|
||||
<h2>Blocks <a href="#blocks" name="blocks" class="header-anchor">#</a></h2>
|
||||
<p>Wren uses curly braces to define <em>blocks</em>. Things like <a href="branching.html">control flow</a> and <a href="looping.html">looping</a> allow block bodies. <a href="method-calls.html">Method</a> and <a href="functions.html">function</a> bodies are also blocks. For example:</p>
|
||||
<p>Wren uses curly braces to define <em>blocks</em>. You can use a block anywhere a
|
||||
statement is allowed, like in <a href="control-flow.html">control flow</a> statements.
|
||||
<a href="classes.html#methods">Method</a> and <a href="functions.html">function</a> bodies are also
|
||||
blocks. For example, here we have a block for the then case, and a single
|
||||
statement for the else:</p>
|
||||
<div class="codehilite"><pre><span class="k">if</span> <span class="p">(</span><span class="n">happy</span> <span class="o">&&</span> <span class="n">knowIt</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">hands</span><span class="p">.</span><span class="n">clap</span>
|
||||
<span class="p">}</span> <span class="k">else</span> <span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"sad"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Here we have a block for the then case, and just a single expression for the else. Blocks have two similar but not identical forms. If a there is a newline after the opening <code>{</code>, then the body contains a series of statements:</p>
|
||||
<p>Blocks have two similar but not identical forms. Typically, blocks contain a
|
||||
series of statements like:</p>
|
||||
<div class="codehilite"><pre><span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"one"</span><span class="p">)</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"two"</span><span class="p">)</span>
|
||||
@ -134,20 +138,24 @@ there, don't worry, you should be fine here.</p>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>If there is no newline, the block may only contain a single expression:</p>
|
||||
<div class="codehilite"><pre><span class="p">{</span> <span class="s2">"this is fine"</span> <span class="p">}</span>
|
||||
<span class="p">{</span> <span class="k">while</span> <span class="p">(</span><span class="k">this</span><span class="p">)</span> <span class="s2">"is an error"</span> <span class="p">}</span>
|
||||
<p>Blocks of this form when used for method and function bodies automatically
|
||||
return <code>null</code> after the block has completed. If you want to return a different
|
||||
value, you need an explicit <code>return</code> statement.</p>
|
||||
<p>However, it's pretty common to have a method or function that just evaluates
|
||||
and returns the result of a single expression. For that, Wren has a more
|
||||
compact notation:</p>
|
||||
<div class="codehilite"><pre><span class="p">{</span> <span class="s2">"single expression"</span> <span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>These are useful when defining method and function bodies. A normal block body implicitly returns <code>null</code>. If you want your method or function to return something different, you need an explicit <code>return</code> statement. However, a single-expression block with no newline after the <code>{</code> implicitly returns the result of that expression. This is a nice convenience for short methods and functions that just evaluate and return an expression.</p>
|
||||
<p><strong>TODO: Move this somewhere else:</strong></p>
|
||||
<h2>The <code>is</code> operator <a href="#the-<code>is</code>-operator" name="the-<code>is</code>-operator" class="header-anchor">#</a></h2>
|
||||
<p>The <code>is</code> keyword can be used as an infix operator in expression. It performs a
|
||||
type test. The left operand is an object and the right operand is a class. It
|
||||
evaluates to <code>true</code> if the object is an instance of the class (or one of its
|
||||
subclasses).</p>
|
||||
<p><strong>TODO: blocks, assignment, maps</strong></p>
|
||||
<p>If there is no newline after the <code>{</code> (or after the parameter list in a of
|
||||
<a href="functions.html">function</a>), then the block may only contain a single
|
||||
expression, and it automatically returns the result of it. It's exactly the
|
||||
same as doing:</p>
|
||||
<div class="codehilite"><pre><span class="p">{</span>
|
||||
<span class="k">return</span> <span class="s2">"single expression"</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</main>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
51
values.html
51
values.html
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -59,12 +58,17 @@
|
||||
<main>
|
||||
<h1>Values</h1>
|
||||
<p>Values are the built-in object types that all other objects are composed of.
|
||||
They can be created through <em>literals</em>, expressions that evaluate to a value.</p>
|
||||
They can be created through <em>literals</em>, expressions that evaluate to a value.
|
||||
All values are <em>immutable</em>—once created, they do not change. The number
|
||||
<code>3</code> is always the number <code>3</code>. The string <code>"frozen"</code> can never have its
|
||||
character array modified in place.</p>
|
||||
<h2>Booleans <a href="#booleans" name="booleans" class="header-anchor">#</a></h2>
|
||||
<p>A boolean value represents truth or falsehood. There are two boolean literals,
|
||||
<code>true</code> and <code>false</code>. Its class is <code>Bool</code>.</p>
|
||||
<code>true</code> and <code>false</code>. Their class is <code>Bool</code>.</p>
|
||||
<h2>Numbers <a href="#numbers" name="numbers" class="header-anchor">#</a></h2>
|
||||
<p>Like other scripting languages, Wren has a single numeric type: double-precision floating point. Number literals look like you expect coming from other languages:</p>
|
||||
<p>Like other scripting languages, Wren has a single numeric type:
|
||||
double-precision floating point. Number literals look like you expect coming
|
||||
from other languages:</p>
|
||||
<div class="codehilite"><pre><span class="m">0</span>
|
||||
<span class="m">1234</span>
|
||||
<span class="o">-</span><span class="m">5678</span>
|
||||
@ -76,31 +80,46 @@ They can be created through <em>literals</em>, expressions that evaluate to a va
|
||||
|
||||
<p>Numbers are instances of the <code>Num</code> class.</p>
|
||||
<h2>Strings <a href="#strings" name="strings" class="header-anchor">#</a></h2>
|
||||
<p>Strings are chunks of text. String literals are surrounded in double quotes:</p>
|
||||
<p>Strings are chunks of text stored as UTF-8. Their class is <code>String</code>. String
|
||||
literals are surrounded in double quotes:</p>
|
||||
<div class="codehilite"><pre><span class="s2">"hi there"</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>A couple of escape characters are supported:</p>
|
||||
<div class="codehilite"><pre><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span> <span class="c1">// Newline.</span>
|
||||
<span class="s2">"</span><span class="se">\"</span><span class="s2">"</span> <span class="c1">// A double quote character.</span>
|
||||
<p>A handful of escape characters are supported:</p>
|
||||
<div class="codehilite"><pre><span class="s2">"</span><span class="se">\"</span><span class="s2">"</span> <span class="c1">// A double quote character.</span>
|
||||
<span class="s2">"</span><span class="se">\\</span><span class="s2">"</span> <span class="c1">// A backslash.</span>
|
||||
<span class="s2">"</span><span class="se">\a</span><span class="s2">"</span> <span class="c1">// Alarm beep. (Who uses this?)</span>
|
||||
<span class="s2">"</span><span class="se">\b</span><span class="s2">"</span> <span class="c1">// Backspace.</span>
|
||||
<span class="s2">"</span><span class="se">\f</span><span class="s2">"</span> <span class="c1">// Formfeed.</span>
|
||||
<span class="s2">"</span><span class="se">\n</span><span class="s2">"</span> <span class="c1">// Newline.</span>
|
||||
<span class="s2">"</span><span class="se">\r</span><span class="s2">"</span> <span class="c1">// Carriage return.</span>
|
||||
<span class="s2">"</span><span class="se">\t</span><span class="s2">"</span> <span class="c1">// Tab.</span>
|
||||
<span class="s2">"</span><span class="se">\v</span><span class="s2">"</span> <span class="c1">// Vertical tab.</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Their class is <code>String</code>.</p>
|
||||
<p>A <code>\u</code> followed by four hex digits can be used to specify a Unicode code point.</p>
|
||||
<h2>Ranges <a href="#ranges" name="ranges" class="header-anchor">#</a></h2>
|
||||
<p>A range is a little object that represents a consecutive range of numbers. They don't have their own dedicated literal syntax. Instead, the number class implements <code>..</code> and <code>...</code> operators to create them:</p>
|
||||
<p>A range is a little object that represents a consecutive range of integers.
|
||||
They don't have their own dedicated literal syntax. Instead, the number class
|
||||
implements the <code>..</code> and <code>...</code> <a href="expressions.html#operators">operators</a> to create
|
||||
them:</p>
|
||||
<div class="codehilite"><pre><span class="m">3.</span><span class="p">.</span><span class="m">8</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>This creates a range from three two eight, including eight itself. If you want a half-inclusive range, use <code>...</code>:</p>
|
||||
<p>This creates a range from three to eight, including eight itself. If you want a
|
||||
half-inclusive range, use <code>...</code>:</p>
|
||||
<div class="codehilite"><pre><span class="m">4.</span><span class="p">..</span><span class="m">6</span>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>This creates a range from four to six <em>not</em> including six itself. Ranges are commonly used for <a href="looping.html">looping</a> over a sequences of numbers, but are useful in other places too. You can pass them to a <a href="lists.html">list</a>'s subscript operator to return a subset of the list, for example:</p>
|
||||
<p>This creates a range from four to six <em>not</em> including six itself. Ranges are
|
||||
commonly used for <a href="control-flow.html#for-statements">iterating</a> over a
|
||||
sequences of numbers, but are useful in other places too. You can pass them to
|
||||
a <a href="lists.html">list</a>'s subscript operator to return a subset of the list, for
|
||||
example:</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">list</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">,</span> <span class="s2">"d"</span><span class="p">,</span> <span class="s2">"e"</span><span class="p">]</span>
|
||||
<span class="kd">var</span> <span class="n">slice</span> <span class="o">=</span> <span class="n">list</span><span class="p">[</span><span class="m">1.</span><span class="p">.</span><span class="m">3</span><span class="p">]</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">slice</span><span class="p">)</span> <span class="c1">// ["b", "c", "d"]</span>
|
||||
@ -108,8 +127,8 @@ They can be created through <em>literals</em>, expressions that evaluate to a va
|
||||
|
||||
|
||||
<h2>Null <a href="#null" name="null" class="header-anchor">#</a></h2>
|
||||
<p>Wren has a special value <code>null</code>, which is the only instance of the class <code>Null</code>.
|
||||
(Note the difference in case.) It functions a bit like <code>void</code> in some
|
||||
<p>Wren has a special value <code>null</code>, which is the only instance of the class
|
||||
<code>Null</code>. (Note the difference in case.) It functions a bit like <code>void</code> in some
|
||||
languages: it indicates the absence of a value. If you call a method that
|
||||
doesn't return anything and get its returned value, you get <code>null</code> back.</p>
|
||||
</main>
|
||||
|
||||
@ -27,10 +27,9 @@
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method Calls</a></li>
|
||||
<li><a href="expressions.html">Expressions</a></li>
|
||||
<li><a href="variables.html">Variables</a></li>
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
<li><a href="control-flow.html">Control Flow</a></li>
|
||||
<li><a href="error-handling.html">Error Handling</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
@ -73,8 +72,8 @@ defined, it can be accessed by name as you would expect.</p>
|
||||
|
||||
|
||||
<h2>Scope <a href="#scope" name="scope" class="header-anchor">#</a></h2>
|
||||
<p>Wren has true block scope: a variable exists from the point where it is
|
||||
defined until the end of the block where that definition appears.</p>
|
||||
<p>Wren has true block scope: a variable exists from the point where it is defined
|
||||
until the end of the <a href="syntax.html#blocks">block</a> where that definition appears.</p>
|
||||
<div class="codehilite"><pre><span class="p">{</span>
|
||||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="c1">// ERROR! a doesn't exist yet.</span>
|
||||
<span class="kd">var</span> <span class="n">a</span> <span class="o">=</span> <span class="m">123</span>
|
||||
@ -84,10 +83,10 @@ defined until the end of the block where that definition appears.</p>
|
||||
</pre></div>
|
||||
|
||||
|
||||
<p>Variables defined at the top level of a script are <em>global</em>. All other variables
|
||||
are <em>local</em>. Declaring a variable in an inner scope with the same name as an
|
||||
outer one is called <em>shadowing</em> and is not an error (although it's not
|
||||
something you likely intend to do much).</p>
|
||||
<p>Variables defined at the top level of a script are <em>global</em>. All other
|
||||
variables are <em>local</em>. Declaring a variable in an inner scope with the same
|
||||
name as an outer one is called <em>shadowing</em> and is not an error (although it's
|
||||
not something you likely intend to do much).</p>
|
||||
<div class="codehilite"><pre><span class="kd">var</span> <span class="n">a</span> <span class="o">=</span> <span class="s2">"outer"</span>
|
||||
<span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="n">a</span> <span class="o">=</span> <span class="s2">"inner"</span>
|
||||
|
||||
Reference in New Issue
Block a user