2015-01-01 21:04:14 -08:00
<!DOCTYPE html>
< html >
< head >
< meta http-equiv = "Content-type" content = "text/html;charset=UTF-8" / >
2015-11-09 08:01:19 -08:00
< title > Control Flow – Wren< / title >
2015-01-01 21:04:14 -08:00
< link rel = "stylesheet" type = "text/css" href = "style.css" / >
2015-01-15 21:18:18 -08:00
< link href = '//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel = 'stylesheet' type = 'text/css' >
2015-01-01 21:04:14 -08:00
<!-- 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" >
2015-01-18 15:37:50 -08:00
< h1 > < a href = "./" > wren< / a > < / h1 >
2019-02-06 02:52:27 +00:00
< h2 > a classy little scripting language< / h2 >
2015-01-01 21:04:14 -08:00
< / div >
< / div >
< / header >
< div class = "page" >
2015-11-09 08:01:19 -08:00
< nav class = "big" >
2019-02-06 02:52:27 +00:00
< a href = "./" > < img src = "./wren.svg" class = "logo" > < / a >
2015-01-01 21:04:14 -08:00
< ul >
< li > < a href = "getting-started.html" > Getting Started< / a > < / li >
2015-11-09 08:01:19 -08:00
< li > < a href = "contributing.html" > Contributing< / a > < / li >
2019-02-06 02:52:27 +00:00
< li > < a href = "blog" > Blog< / a > < / li >
2015-01-01 21:04:14 -08:00
< / ul >
< section >
2019-02-06 02:52:27 +00:00
< h2 > guides< / h2 >
2015-01-01 21:04:14 -08:00
< ul >
< li > < a href = "syntax.html" > Syntax< / a > < / li >
< li > < a href = "values.html" > Values< / a > < / li >
< li > < a href = "lists.html" > Lists< / a > < / li >
< li > < a href = "maps.html" > Maps< / a > < / li >
2015-11-09 08:01:19 -08:00
< li > < a href = "method-calls.html" > Method Calls< / a > < / li >
< li > < a href = "control-flow.html" > Control Flow< / a > < / li >
< li > < a href = "variables.html" > Variables< / a > < / li >
< li > < a href = "functions.html" > Functions< / a > < / li >
< li > < a href = "classes.html" > Classes< / a > < / li >
< li > < a href = "concurrency.html" > Concurrency< / a > < / li >
< li > < a href = "error-handling.html" > Error Handling< / a > < / li >
< li > < a href = "modularity.html" > Modularity< / a > < / li >
2015-01-01 21:04:14 -08:00
< / ul >
< / section >
< section >
< h2 > reference< / h2 >
< ul >
2015-11-09 08:01:19 -08:00
< li > < a href = "modules" > Modules< / a > < / li >
2017-10-19 07:05:45 -07:00
< li > < a href = "embedding" > Embedding< / a > < / li >
2015-01-01 21:04:14 -08:00
< li > < a href = "performance.html" > Performance< / a > < / li >
< li > < a href = "qa.html" > Q & A< / a > < / li >
< / ul >
< / section >
< / nav >
2015-11-09 08:01:19 -08:00
< nav class = "small" >
< table >
< tr >
2019-10-03 06:50:59 +00:00
< div > < a href = "getting-started.html" > Getting Started< / a > < / div >
< div > < a href = "contributing.html" > Contributing< / a > < / div >
< div > < a href = "blog" > Blog< / a > < / div >
2015-11-09 08:01:19 -08:00
< / tr >
< tr >
2019-02-06 02:52:27 +00:00
< td colspan = "2" > < h2 > guides< / h2 > < / td >
2015-11-09 08:01:19 -08:00
< td > < h2 > reference< / h2 > < / td >
< / tr >
< tr >
< td >
< ul >
< li > < a href = "syntax.html" > Syntax< / a > < / li >
< li > < a href = "values.html" > Values< / a > < / li >
< li > < a href = "lists.html" > Lists< / a > < / li >
< li > < a href = "maps.html" > Maps< / a > < / li >
< li > < a href = "method-calls.html" > Method Calls< / a > < / li >
< li > < a href = "control-flow.html" > Control Flow< / a > < / li >
< / ul >
< / td >
< td >
< ul >
< li > < a href = "variables.html" > Variables< / a > < / li >
< li > < a href = "functions.html" > Functions< / a > < / li >
< li > < a href = "classes.html" > Classes< / a > < / li >
< li > < a href = "concurrency.html" > Concurrency< / a > < / li >
< li > < a href = "error-handling.html" > Error Handling< / a > < / li >
< li > < a href = "modularity.html" > Modularity< / a > < / li >
< / ul >
< / td >
< td >
< ul >
< li > < a href = "modules" > Modules< / a > < / li >
2017-10-19 07:05:45 -07:00
< li > < a href = "embedding" > Embedding< / a > < / li >
2015-11-09 08:01:19 -08:00
< li > < a href = "performance.html" > Performance< / a > < / li >
< li > < a href = "qa.html" > Q & A< / a > < / li >
< / ul >
< / td >
< / tr >
< / table >
< / nav >
2015-01-01 21:04:14 -08:00
< main >
2019-02-06 02:52:27 +00:00
< h2 > Control Flow< / h2 >
2015-11-09 08:01:19 -08:00
< p > Control flow is used to determine which chunks of code are executed and how many
times. < em > Branching< / em > statements and expressions decide whether or not to execute
some code and < em > looping< / em > ones execute something more than once. < / p >
2015-01-03 23:27:54 -08:00
< h2 > Truth < a href = "#truth" name = "truth" class = "header-anchor" > #< / a > < / h2 >
2015-11-09 08:01:19 -08:00
< p > All control flow is based on < em > deciding< / em > whether or not to do something. This
decision depends on some expression’ s value. We take the entire universe of
possible objects 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 >
2015-01-03 23:27:54 -08:00
< ul >
2015-11-09 08:01:19 -08:00
< 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 >
2015-01-03 23:27:54 -08:00
< / ul >
2015-11-09 08:01:19 -08:00
< p > This means < code > 0< / code > , empty strings, and empty collections are all considered “ true”
values. < / p >
2015-01-03 23:27:54 -08:00
< h2 > If statements < a href = "#if-statements" name = "if-statements" class = "header-anchor" > #< / a > < / h2 >
2015-11-09 08:01:19 -08:00
< p > The simplest branching statement, < code > if< / code > lets you conditionally skip a chunk of
code. It looks like this: < / p >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "n" > ready< / span > < span class = "p" > )< / span > < span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s" > " go!" < / span > < span class = "p" > )< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-03 23:27:54 -08:00
2015-11-09 08:01:19 -08:00
< 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 >
2018-07-15 04:42:00 +00:00
< 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 = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s" > " getSet" < / span > < span class = "p" > )< / span >
< span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s" > " go!" < / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-03 23:27:54 -08:00
2015-11-09 08:01:19 -08:00
< p > You may also provide an < code > else< / code > branch. It will be executed if the condition is
false: < / p >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "n" > ready< / span > < span class = "p" > )< / span > < span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s" > " go!" < / span > < span class = "p" > )< / span > < span class = "k" > else< / span > < span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s" > " not ready!" < / span > < span class = "p" > )< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-03 23:27:54 -08:00
2015-11-09 08:01:19 -08:00
< p > And, of course, it can take a block too: < / p >
2018-07-15 04:42:00 +00:00
< 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 = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s" > " go!" < / span > < span class = "p" > )< / span >
< span class = "p" > }< / span > < span class = "k" > else< / span > < span class = "p" > {< / span >
< span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s" > " not ready!" < / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-03 23:27:54 -08:00
2015-11-09 08:01:19 -08:00
< h2 > Logical operators < a href = "#logical-operators" name = "logical-operators" class = "header-anchor" > #< / a > < / h2 >
< p > Unlike most other < a href = "method-calls.html#operators" > operators< / a > in Wren which are just a special syntax for
< a href = "method-calls.html" > method calls< / a > , the < code > & & < / code > and < code > ||< / code > operators are special. This is because they
only conditionally evaluate right operand— they short-circuit. < / p >
< p > A < 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 >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "kc" > false< / span > < span class = "o" > & & < / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "output" > false< / span >
< span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "mi" > 1< / span > < span class = "o" > & & < / span > < span class = "mi" > 2< / span > < span class = "p" > )< / span > < span class = "output" > 2< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-11-09 08:01:19 -08:00
2017-10-19 07:05:45 -07:00
< p > A < code > ||< / code > (“ logical or” ) expression is reversed. If the left-hand argument is
< em > true< / em > , it’ s returned, otherwise the right-hand argument is evaluated and
2015-11-09 08:01:19 -08:00
returned: < / p >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "kc" > false< / span > < span class = "o" > ||< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "output" > 1< / span >
< span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "mi" > 1< / span > < span class = "o" > ||< / span > < span class = "mi" > 2< / span > < span class = "p" > )< / span > < span class = "output" > 1< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-11-09 08:01:19 -08:00
< h2 > The conditional operator < code > ?:< / code > < a href = "#the-conditional-operator-" name = "the-conditional-operator-" 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 brethren. < / p >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "mi" > 1< / span > < span class = "o" > !=< / span > < span class = "mi" > 2< / span > < span class = "o" > ?< / span > < span class = "s" > " math is sane" < / span > < span class = "o" > :< / span > < span class = "s" > " math is not sane!" < / span > < span class = "p" > )< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-11-09 08:01:19 -08:00
< 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 >
2015-01-01 21:04:14 -08:00
< h2 > While statements < a href = "#while-statements" name = "while-statements" class = "header-anchor" > #< / a > < / h2 >
2015-11-09 08:01:19 -08:00
< 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 >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "c1" > // Hailstone sequence.< / span >
< span class = "k" > var< / span > < span class = "err" > n< / span > < span class = "o" > =< / span > < span class = "mi" > 27< / span >
< span class = "k" > while< / span > < span class = "p" > (< / span > < span class = "err" > n< / span > < span class = "o" > !=< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "p" > {< / span >
< span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "err" > n< / span > < span class = "o" > %< / span > < span class = "mi" > 2< / span > < span class = "o" > ==< / span > < span class = "mi" > 0< / span > < span class = "p" > )< / span > < span class = "p" > {< / span >
< span class = "err" > n< / span > < span class = "o" > =< / span > < span class = "err" > n< / span > < span class = "o" > /< / span > < span class = "mi" > 2< / span >
< span class = "p" > }< / span > < span class = "k" > else< / span > < span class = "p" > {< / span >
< span class = "err" > n< / span > < span class = "o" > =< / span > < span class = "mi" > 3< / span > < span class = "o" > *< / span > < span class = "err" > n< / span > < span class = "o" > +< / span > < span class = "mi" > 1< / span >
< span class = "p" > }< / span >
< span class = "p" > }< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-01 21:04:14 -08:00
2015-11-09 08:01:19 -08:00
< 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 >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "k" > var< / span > < span class = "err" > n< / span > < span class = "o" > =< / span > < span class = "mi" > 27< / span >
< span class = "k" > while< / span > < span class = "p" > (< / span > < span class = "err" > n< / span > < span class = "o" > !=< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "err" > n< / span > < span class = "o" > %< / span > < span class = "mi" > 2< / span > < span class = "o" > ==< / span > < span class = "mi" > 0< / span > < span class = "p" > )< / span > < span class = "err" > n< / span > < span class = "o" > =< / span > < span class = "err" > n< / span > < span class = "o" > /< / span > < span class = "mi" > 2< / span > < span class = "k" > else< / span > < span class = "err" > n< / span > < span class = "o" > =< / span > < span class = "mi" > 3< / span > < span class = "o" > *< / span > < span class = "err" > n< / span > < span class = "o" > +< / span > < span class = "mi" > 1< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-01 21:04:14 -08:00
< h2 > For statements < a href = "#for-statements" name = "for-statements" class = "header-anchor" > #< / a > < / h2 >
2015-11-09 08:01:19 -08:00
< 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, uh, for. It looks like this: < / p >
2018-07-15 04:42:00 +00:00
< 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 = "s" > " george" < / span > < span class = "p" > ,< / span > < span class = "s" > " john" < / span > < span class = "p" > ,< / span > < span class = "s" > " paul" < / span > < span class = "p" > ,< / span > < span class = "s" > " ringo" < / span > < span class = "p" > ])< / span > < span class = "p" > {< / span >
< span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "n" > beatle< / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-01 21:04:14 -08:00
2015-11-09 08:01:19 -08:00
< p > A < code > for< / code > loop has three components: < / p >
2015-01-01 21:04:14 -08:00
< ol >
< li >
2015-11-09 08:01:19 -08:00
< 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 >
2015-01-01 21:04:14 -08:00
< / li >
< li >
2015-11-09 08:01:19 -08:00
< 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 >
2015-01-01 21:04:14 -08:00
< / li >
< li >
2015-11-09 08:01:19 -08:00
< 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 >
2015-01-01 21:04:14 -08:00
< / li >
< / ol >
< h2 > Break statements < a href = "#break-statements" name = "break-statements" class = "header-anchor" > #< / a > < / h2 >
2015-11-09 08:01:19 -08:00
< 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 immediately exits out of the nearest enclosing
< code > while< / code > or < code > for< / code > loop. < / p >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "k" > for< / span > < span class = "p" > (< / span > < span class = "err" > i< / span > < span class = "k" > in< / span > < span class = "p" > [< / span > < span class = "mi" > 1< / span > < span class = "p" > ,< / span > < span class = "mi" > 2< / span > < span class = "p" > ,< / span > < span class = "mi" > 3< / span > < span class = "p" > ,< / span > < span class = "mi" > 4< / span > < span class = "p" > ])< / span > < span class = "p" > {< / span >
< span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "err" > i< / span > < span class = "p" > )< / span > < span class = "output" > 1< / span >
< span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "err" > i< / span > < span class = "o" > ==< / span > < span class = "mi" > 3< / span > < span class = "p" > )< / span > < span class = "k" > break< / span > < span class = "output" > 2< / span >
< span class = "p" > }< / span > < span class = "output" > 3< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-01 21:04:14 -08:00
< h2 > Numeric ranges < a href = "#numeric-ranges" name = "numeric-ranges" class = "header-anchor" > #< / a > < / h2 >
2015-11-09 08:01:19 -08:00
< 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 >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "k" > for< / span > < span class = "p" > (< / span > < span class = "err" > i< / span > < span class = "k" > in< / span > < span class = "mi" > 1< / span > < span class = "o" > ..< / span > < span class = "mi" > 100< / span > < span class = "p" > )< / span > < span class = "p" > {< / span >
< span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "err" > i< / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-01 21:04:14 -08:00
2015-11-09 08:01:19 -08:00
< 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 >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "k" > for< / span > < span class = "p" > (< / span > < span class = "err" > i< / span > < span class = "k" > in< / span > < span class = "mi" > 1< / span > < span class = "o" > ...< / span > < span class = "mi" > 100< / span > < span class = "p" > )< / span > < span class = "p" > {< / span >
< span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "err" > i< / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-01 21:04:14 -08:00
2015-11-09 08:01:19 -08:00
< 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#operators" > other operators< / a > , they are 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 >
2015-01-01 21:04:14 -08:00
< h2 > The iterator protocol < a href = "#the-iterator-protocol" name = "the-iterator-protocol" class = "header-anchor" > #< / a > < / h2 >
2015-11-09 08:01:19 -08:00
< 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 < 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 >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "k" > for< / span > < span class = "p" > (< / span > < span class = "err" > i< / span > < span class = "k" > in< / span > < span class = "mi" > 1< / span > < span class = "o" > ..< / span > < span class = "mi" > 100< / span > < span class = "p" > )< / span > < span class = "p" > {< / span >
< span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "err" > i< / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-01 21:04:14 -08:00
2015-11-09 08:01:19 -08:00
< p > Wren sees it something like this: < / p >
2018-07-15 04:42:00 +00:00
< div class = "codehilite" > < pre > < span class = "k" > var< / span > < span class = "n" > iter_< / span > < span class = "o" > =< / span > < span class = "kc" > null< / span >
< span class = "k" > var< / span > < span class = "n" > seq_< / span > < span class = "o" > =< / span > < span class = "mi" > 1< / span > < span class = "o" > ..< / span > < span class = "mi" > 100< / span >
< span class = "k" > while< / span > < span class = "p" > (< / span > < span class = "n" > iter_< / span > < span class = "o" > =< / span > < span class = "n" > seq_< / span > < span class = "o" > .< / span > < span class = "n" > iterate< / span > < span class = "p" > (< / span > < span class = "n" > iter_< / span > < span class = "p" > ))< / span > < span class = "p" > {< / span >
< span class = "k" > var< / span > < span class = "err" > i< / span > < span class = "o" > =< / span > < span class = "n" > seq_< / span > < span class = "o" > .< / span > < span class = "n" > iteratorValue< / span > < span class = "p" > (< / span > < span class = "n" > iter_< / span > < span class = "p" > )< / span >
< span class = "vg" > System< / span > < span class = "o" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "err" > i< / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
2018-07-13 09:03:56 -07:00
< / pre > < / div >
2015-01-01 21:04:14 -08:00
2015-11-09 08:01:19 -08:00
< 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 >
2019-02-06 02:52:27 +00:00
< p > < br > < hr >
< a class = "right" href = "variables.html" > Variables → < / a >
2015-11-09 08:01:19 -08:00
< a href = "method-calls.html" > ← Method Calls< / a > < / p >
2015-01-01 21:04:14 -08:00
< / main >
< / div >
< footer >
< div class = "page" >
< div class = "main-column" >
2015-11-09 08:01:19 -08:00
< p > Wren lives
2019-02-06 02:52:27 +00:00
< a href = "https://github.com/wren-lang/wren" > on GitHub< / a >
2015-11-09 08:01:19 -08:00
— Made with ❤ by
< a href = "http://journal.stuffwithstuff.com/" > Bob Nystrom< / a > and
2019-02-06 02:52:27 +00:00
< a href = "https://github.com/wren-lang/wren/blob/master/AUTHORS" > friends< / a > .
2015-11-09 08:01:19 -08:00
< / p >
2015-01-01 21:04:14 -08:00
< div class = "main-column" >
< / div >
< / footer >
< / body >
2015-04-25 08:50:08 -07:00
< / html >