CINXE.COM
Control flow | Raku Documentation
<!DOCTYPE html> <html lang="en" class="fontawesome-i2svg-active fontawesome-i2svg-complete" style="scroll-padding-top:60px"> <head> <title>Control flow | Raku Documentation</title> <meta charset="UTF-8" /> <link href="/assets/images/Camelia.ico" rel="icon" type="image/x-icon"/> <link rel="stylesheet" href="/assets/css/Website.css"/> <link rel="stylesheet" href="/assets/css/css/page-styling-main.css"/> <link rel="stylesheet" href="/assets/css/css/page-styling-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/page-styling-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/chyronToggle-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/chyronToggle-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/centreToggle-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/centreToggle-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/listf-styling-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/listf-styling-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/options-search-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/options-search-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/all.min.css"/> <link rel="stylesheet" href="/assets/css/css/rainbow-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/rainbow-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/filtered-toc-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/filtered-toc-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/tm-styling.css"/> <link rel="stylesheet" href="/assets/css/tm-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/tm-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/css/announce-light.css" title="light"/> <link rel="stylesheet" href="/assets/css/css/announce-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/typegraph-styling.css"/> <link rel="stylesheet" href="/assets/css/typegraph-dark.css" title="dark"/> <link rel="stylesheet" href="/assets/css/typegraph-light.css" title="light"/> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tarekraafat/autocomplete.js@10.2.7/dist/css/autoComplete.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-light.min.css" title="light" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css" title="dark" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="/assets/scripts/all.min.js"></script><script src="/assets/scripts/filter-script.js"></script><script src="/assets/scripts/tableManager.js"></script><script src="https://cdn.jsdelivr.net/npm/@tarekraafat/autocomplete.js@10.2.7/dist/autoComplete.min.js"></script><script src="https://cdn.jsdelivr.net/npm/fuzzysort@2.0.4/fuzzysort.min.js"></script><script src="/assets/scripts/options-search.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/haskell.min.js"></script><script src="/assets/scripts/filtered-toc.js"></script><script src="/assets/scripts/page-styling.js"></script><script src="/assets/scripts/rainbow.js"></script><script src="/assets/scripts/announcements.js"></script> </head> <body class="has-navbar-fixed-top"> <div id="Control_flow" class="top-of-page"></div> <nav class="navbar is-fixed-top is-flex-touch" role="navigation" aria-label="main navigation"> <div class="navbar-item" style="margin-left: auto;"> <div class="left-bar-toggle" title="Toggle Table of Contents & Index"> <label class="chyronToggle left"> <input id="navbar-left-toggle" type="checkbox"> <span class="text">Contents</span> </label> </div> </div> <div class="container is-justify-content-space-around"> <div class="navbar-brand"> <div class="navbar-logo"> <a class="navbar-item" href="/"> <img src="/assets/images/camelia-recoloured.png" alt="Raku" width="52.83" height="38"> </a> <span class="navbar-logo-tm">tm</span> </div> <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navMenu"> <span aria-hidden="true"></span> <span aria-hidden="true"></span> <span aria-hidden="true"></span> </a> </div> <div id="navMenu" class="navbar-menu"> <div class="navbar-start"> <a class="navbar-item" href="/introduction" title="Getting started, Tutorials, Migration guides"> Introduction </a> <a class="navbar-item" href="/reference" title="Fundamentals, General reference"> Reference </a> <a class="navbar-item" href="/miscellaneous" title="Programs, Experimental"> Miscellaneous </a> <a class="navbar-item" href="/types" title="The core types (classes) available"> Types </a> <a class="navbar-item" href="/routines" title="Searchable table of routines"> Routines </a> <a class="navbar-item" href="https://raku.org" title="Home page for community"> Raku<sup>®</sup> </a> <a class="navbar-item" href="https://web.libera.chat/#raku" title="IRC live chat"> Chat </a> <div class="navbar-item has-dropdown is-hoverable"> <a class="navbar-link"> More </a> <div class="navbar-dropdown is-right is-rounded"> <hr class="navbar-divider"> <a class="navbar-item js-modal-trigger" data-target="download-ebook"> Download E-Book (epub) </a> <hr class="navbar-divider"> <a class="navbar-item" href="/about"> About </a> <hr class="navbar-divider"> <a class="navbar-item has-text-red" href="https://github.com/raku/doc-website/issues"> Report an issue with this site </a> <hr class="navbar-divider"> <a class="navbar-item" href="https://github.com/raku/doc/issues"> Report an issue with the documentation content </a> <hr class="navbar-divider"> <label class="navbar-item centreToggle" title="Enable/Disable Announcements" style="--switch-width: 18"> <input id="cancelAnnouncements" type="checkbox"> <span class="text">Announcements</span> <span class="on">suppressed</span> <span class="off">allowed</span> </label> </div> </div> </div> <div class="navbar-end navbar-search-wrapper"> <div class="navbar-item"> <div class="field has-addons"> <div class="autoComplete_options"> <input class="control input" id="autoComplete" type="search" dir="ltr" spellcheck=false autocorrect="off" autocomplete="off" autocapitalize="off" placeholder="🔍 Type f to search for ..."> </div> <div class="control" title="Search options"> <a class="button is-primary js-modal-trigger" data-target="options-search-info"> <span class="icon"> <i class="fas fa-cogs"></i> </span> </a> </div> </div> </div> </div> <div id="options-search-info" class="modal"> <div class="modal-background"></div> <div class="modal-content"> <div class="box"> <p>The last search was: <span id="selected-candidate" class="ss-selected"></span></p> <div class="control is-grouped is-grouped-centered options-search-controls"> <label class="centreToggle" title="Include extra information (Alt-E)" style="--switch-width: 10.5"> <input id="options-search-extra" type="checkbox"> <span class="text">Extra info</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>The search response can be shortened by excluding the extra information line (Alt-E)</p> <label class="centreToggle" title="Search engine type Strict/Loose (Alt-L)" style="--switch-width: 10.5"> <input id="options-search-loose" type="checkbox"> <span class="text">Search type</span> <span class="on">loose</span> <span class="off">strict</span> </label> <p> The search engine can perform a strict search (only the characters in the search box) or a loose search (Alt-L)</p> <label class="centreToggle" title="Search in headings (Alt-H)" style="--switch-width: 10.5"> <input id="options-search-headings" type="checkbox"> <span class="text">Headings</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>Search through headings in all web-pages (Alt-H)</p> <label class="centreToggle" title="Search indexed items (Alt-I)" style="--switch-width: 10.5"> <input id="options-search-indexed" type="checkbox"> <span class="text">Indexed</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>Search through all indexed items (Alt-I)</p> <label class="centreToggle" title="Search composite pages (Alt-C)" style="--switch-width: 10.5"> <input id="options-search-composite" type="checkbox"> <span class="text">Composite</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>Search in the names of composite pages, which combine similar information from the main web pages (Alt-C)</p> <label class="centreToggle" title="Search primary sources (Alt-P)" style="--switch-width: 10.5"> <input id="options-search-primary" type="checkbox"> <span class="text">Primary</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>Search through the names of the main web pages (Alt-P)</p> <label class="centreToggle" title="Open in new tab (Alt-Q)" style="--switch-width: 10.5"> <input id="options-search-newtab" type="checkbox"> <span class="text">New tab</span> <span class="on">yes</span> <span class="off">no</span> </label> <p>Once a search candidate has been chosen, it can be opened in a new tab or in the current tab (Alt-Q)</p> <p>If all else fails, an item is added to use the Google search engine on the whole site</p> <button class="button is-warning" id="options-search-reset-defaults">Clear options, reset to defaults</button> <p>Exit this page by pressing <Escape>, or clicking on X or on the background.</p> </div> </div> </div> <button class="modal-close is-large" aria-label="close"></button> </div> </div> <div id="download-ebook" class="modal"> <div class="modal-background"></div> <div class="modal-content"> <div class="box"> <p><a href="/RakuDocumentation.epub" download>RakuDocumentation.epub</a> is a work in progress e-book. It targets the <a href="https://www.w3.org/publishing/epub3/">EPUB v3 specification</a>. It needs testing on a variety of ereaders (some of which may still implicitly expect compliance with EPUB v2). The CSS definitely needs enhancing (especially for code snippets). The Ebook opens in a Calibre reader, which is available on all operating systems.</p> <p>Suggestions are welcome and should be addressed by opening an issue on the Raku/doc-website repository</p> <p>Exit this popup by pressing <Escape>, or clicking on X or on the background.</p> </div> </div> <button class="modal-close is-large" aria-label="close"></button> </div> <div id="announcement-modal" class="modal"> <div class="modal-background"></div> <div class="modal-content"> <div class="box"> <div id="raku-doc-announcement"></div> <p>For more see <a href="/announcements">Announcements page</a>.</p> <p>Exit this popup by pressing <Escape>, or clicking on X or on the background.</p> </div> </div> <button class="modal-close is-large" aria-label="close"></button> </div> </div> </nav> <div class="tile is-ancestor section"> <div class="page-edit"> <a class="button page-edit-button" href="https://github.com/Raku/doc/edit/main/doc/Language/control.rakudoc" title="Edit this page. Commit: 8e397fdce 2024-12-26"> <span class="icon is-right"> <i class="fas fa-pen-alt is-medium"></i> </span> </a> </div> <div id="left-column" class="tile is-parent is-2 is-hidden"> <div id="left-col-inner"> <div class="tabs" id="tabs"> <ul> <li class="is-active" id="toc-tab"> <a>Table of Contents</a> </li> <li id="index-tab"> <a>Index</a> </li> </ul> </div> <div class="field"> <div class="control has-icons-right"> <input id="toc-filter" class="input" type="text" placeholder="Filter"> <span class="icon is-right has-text-grey"> <i class="fas fa-search is-medium"></i> </span> </div> </div> <div class="raku-sidebar"> <aside id="toc-menu" class="menu"> <ul class="menu-list"> <li><a href="#Statements">Statements</a></li> <li><a href="#Blocks">Blocks</a></li> <li><a href="#Phasers">Phasers</a></li> <li><a href="#do">do</a></li> <li><a href="#start">start</a></li> <li><a href="#if">if</a></li> <ul> <li><a href="#else/elsif">else/elsif</a></li> </ul> <li><a href="#unless">unless</a></li> <li><a href="#with_orwith_without">with orwith without</a></li> <li><a href="#when">when</a></li> <li><a href="#for">for</a></li> <li><a href="#gather/take">gather/take</a></li> <li><a href="#supply/emit">supply/emit</a></li> <li><a href="#given">given</a></li> <ul> <li><a href="#default_and_when">default and when</a></li> <li><a href="#proceed_and_succeed">proceed and succeed</a></li> <li><a href="#given_as_a_statement">given as a statement</a></li> </ul> <li><a href="#loop">loop</a></li> <li><a href="#while,_until">while, until</a></li> <li><a href="#repeat/while,_repeat/until">repeat/while, repeat/until</a></li> <li><a href="#return">return</a></li> <li><a href="#return-rw">return-rw</a></li> <li><a href="#fail">fail</a></li> <li><a href="#once">once</a></li> <li><a href="#LABELs">LABELs</a></li> <li><a href="#next">next</a></li> <li><a href="#last">last</a></li> <li><a href="#redo">redo</a></li> </ul> </aside> <aside id="index-menu" class="menu is-hidden"> <ul class="menu-list"> <li>Control flow<ul> </ul></li> <li>Other languages<ul> <li><a href="#index-entry-case_statements_(given)">case statements </a></li> <li><a href="#index-entry-switch_(given)">switch </a></li> </ul></li> </ul> </aside> </div> </div> </div> <div id="main-column" class="tile is-parent" style="overflow-x: hidden;"> <div id="main-col-inner"> <section class="raku page-header"> <div class="container px-4"> <div class="raku page-title has-text-centered"> Control flow </div> <div class="raku page-subtitle has-text-centered"> <p>Statements used to control the flow of execution</p> </div> </div> </section> <section class="raku page-content"><div class="container px-4"><div class="columns one-col"> <h1 id="Statements" class="raku-h1"><a name="index-entry-statements-Statements" data-indexedheader="Control flow;statements"></a><a href="#Control_flow" title="go to top of document">Statements<a class="raku-anchor" title="direct link" href="#Statements">§</a></a></h1> <!-- defnmark Statements 1 --> <p>Raku programs consist of one or more statements. Simple statements are separated by semicolons. The following program will print "Hello" and then "World" on the next line.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Hello</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">World</span><span class="highlite-STRING_DELIMITER">"</span>;</pre> </div> </div> <p>In most places where spaces appear in a statement, and before the semicolon, they may be split up over many lines. Also, multiple statements may appear on the same line. It would be awkward, but the above example could also be written as:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Hello</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">World</span><span class="highlite-STRING_DELIMITER">"</span>;</pre> </div> </div> <h1 id="Blocks" class="raku-h1"><a name="index-entry-blocks-Blocks" data-indexedheader="Control flow;blocks"></a><a href="#Control_flow" title="go to top of document">Blocks<a class="raku-anchor" title="direct link" href="#Blocks">§</a></a></h1> <!-- defnmark Blocks 1 --> <p>Like many other languages, Raku uses <code>blocks</code> enclosed by <code>{</code> and <code>}</code> to turn a sequence of statements into a <a href="/type/Block"><code>Block</code></a> that acts as a single one. It is OK to omit the semicolon between the last statement in a block and the closing <code>}</code>.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">{ <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Hello</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">World</span><span class="highlite-STRING_DELIMITER">"</span> }</pre> </div> </div> <p>When a block stands alone as a statement, it will be entered immediately after the previous statement finishes, and the statements inside it will be executed.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">say</span> 1; <span class="highlite-COMMENT"># OUTPUT: «1» </span>{ <span class="highlite-ROUTINE">say</span> 2; <span class="highlite-ROUTINE">say</span> 3 }; <span class="highlite-COMMENT"># OUTPUT: «23» </span><span class="highlite-ROUTINE">say</span> 4; <span class="highlite-COMMENT"># OUTPUT: «4»</span></pre> </div> </div> <p>Unless it stands alone as a statement, a block simply creates a closure. The statements inside are not executed immediately. Closures are another topic and how they are used is explained <a href="/language/functions#Blocks_and_lambdas">elsewhere</a>. For now it is just important to understand when blocks run and when they do not:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">We get here</span><span class="highlite-STRING_DELIMITER">"</span>; { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">then here.</span><span class="highlite-STRING_DELIMITER">"</span> }; { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">not here</span><span class="highlite-STRING_DELIMITER">"</span>; 0; } <span class="highlite-OPERATOR">or</span> <span class="highlite-ROUTINE">die</span>; </pre> </div> </div> <p>In the above example, after running the first statement, the first block stands alone as a second statement, so we run the statement inside it. The second block is a closure, so instead, it makes an object of type <a href="/type/Block"><code>Block</code></a> but does not run it. Object instances are usually considered to be true, so the code does not die, even though that block would evaluate to 0, were it to be executed. The example does not say what to do with the <a href="/type/Block"><code>Block</code></a> object, so it just gets thrown away.</p><p>Most of the flow control constructs covered below are just ways to tell Raku when, how, and how many times, to enter blocks like that second block.</p><p>Before we go into those, an important side-note on syntax: If there is nothing (or nothing but comments) on a line after a closing curly brace where you would normally put semicolon, then you do not need the semicolon:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-COMMENT"># All three of these lines can appear as a group, as is, in a program </span>{ 42.<span class="highlite-ROUTINE">say</span> } <span class="highlite-COMMENT"># OUTPUT: «42» </span>{ 43.<span class="highlite-ROUTINE">say</span> } <span class="highlite-COMMENT"># OUTPUT: «43» </span>{ 42.<span class="highlite-ROUTINE">say</span> }; { 43.<span class="highlite-ROUTINE">say</span> } <span class="highlite-COMMENT"># OUTPUT: «4243»</span></pre> </div> </div> <p>...but:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">{ 42.<span class="highlite-ROUTINE">say</span> } { 43.<span class="highlite-ROUTINE">say</span> } <span class="highlite-COMMENT"># Syntax error </span>{ 42.<span class="highlite-ROUTINE">say</span>; } { 43.<span class="highlite-ROUTINE">say</span> } <span class="highlite-COMMENT"># Also a syntax error, of course </span></pre> </div> </div> <p>So, be careful when you backspace in a line-wrapping editor:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">{ <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Without semicolons line-wrapping can be a bit treacherous.</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> } \ { 43.<span class="highlite-ROUTINE">say</span> } <span class="highlite-COMMENT"># Syntax error </span></pre> </div> </div> <p>You have to watch out for this in most languages anyway to prevent things from getting accidentally commented out. Many of the examples below may have unnecessary semicolons for clarity.</p><p>Class bodies behave like simple blocks for any top level expression; same goes to roles and other packages, like grammars (which are actually classes) or modules.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">class</span> C { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">I live</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-ROUTINE">die</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">I will never live!</span><span class="highlite-STRING_DELIMITER">"</span> }; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$c</span> <span class="highlite-OPERATOR">=</span> C.<span class="highlite-ROUTINE">new</span>; │ <span class="highlite-COMMENT"># OUTPUT: Fails and writes «I liveI will never live! </span></pre> </div> </div> <p>This block will first run the first statement, and then <code>die</code> printing the second statement. <code>$c</code> will never get a value.</p> <h1 id="Phasers" class="raku-h1"><a name="index-entry-Phasers-Phasers" data-indexedheader="Control flow;Phasers"></a><a href="#Control_flow" title="go to top of document">Phasers<a class="raku-anchor" title="direct link" href="#Phasers">§</a></a></h1> <!-- defnmark Phasers 1 --> <p>Blocks may have <em>phasers</em>: special labeled blocks that break their execution into phases that run in particular phases. See the page <a href="/language/phasers">phasers</a> for the details.</p> <h1 id="do" class="raku-h1"><a name="index-entry-do-do" data-indexedheader="Control flow;do"></a><a href="#Control_flow" title="go to top of document">do<a class="raku-anchor" title="direct link" href="#do">§</a></a></h1> <!-- defnmark do 1 --> <p>The simplest way to run a block where it cannot be a stand-alone statement is by writing <code>do</code> before it:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-COMMENT"># This dies half of the time </span><span class="highlite-ROUTINE">do</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Heads I win, tails I die.</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-TYPE">Bool</span>.<span class="highlite-ROUTINE">pick</span> } <span class="highlite-OPERATOR">or</span> <span class="highlite-ROUTINE">die</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">I win.</span><span class="highlite-STRING_DELIMITER">"</span>; </pre> </div> </div> <p>Note that you need a space between the <code>do</code> and the block.</p><p>The whole <code>do {...}</code> evaluates to the final value of the block. The block will be run when that value is needed in order to evaluate the rest of the expression. So:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-TYPE">False</span> <span class="highlite-OPERATOR">and</span> <span class="highlite-ROUTINE">do</span> { 42.<span class="highlite-ROUTINE">say</span> };</pre> </div> </div> <p>...will not say 42. However, the block is only evaluated once each time the expression it is contained in is evaluated:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-COMMENT"># This says "(..1 ..2 ..3)" not "(..1 ...2 ....3)" </span><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$f</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">.</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-ROUTINE">do</span> { <span class="highlite-NAME_SCALAR">$f</span> <span class="highlite-OPERATOR">~</span><span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">.</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-OPERATOR">X</span>~ 1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 3;</pre> </div> </div> <p>In other words, it follows the same <a href="/language/glossary#Reify">reification</a> rules as everything else.</p><p>Technically, <code>do</code> is a loop which runs exactly one iteration.</p><p>A <code>do</code> may also be used on a bare statement (without curly braces) but this is mainly just useful for avoiding the syntactical need to parenthesize a statement if it is the last thing in an expression:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">3<span class="highlite-OPERATOR">,</span> <span class="highlite-ROUTINE">do</span> <span class="highlite-KEYWORD">if</span> 1 { 2 } ; <span class="highlite-COMMENT"># OUTPUT: «(3, 2)» </span>3<span class="highlite-OPERATOR">,</span> (<span class="highlite-KEYWORD">if</span> 1 { 2 }) ; <span class="highlite-COMMENT"># OUTPUT: «(3, 2)» </span></pre> </div> </div> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">3<span class="highlite-OPERATOR">,</span> <span class="highlite-KEYWORD">if</span> 1 { 2 } ; <span class="highlite-COMMENT"># Syntax error </span></pre> </div> </div> <p>As a consequence, <code>do</code> does not run blocks that, by their syntax, must be functions. For example, if <code>-></code> is used to specify a <a href="/language/syntax#Block_declaration">signature</a>, <code>do</code> treats these as single-expression statements.</p><p>Thus, adding <code>-></code> to our first example prevents the closure from being evaluated:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-COMMENT"># This never dies and never prints "Heads I win, tails I die." </span><span class="highlite-ROUTINE">do</span> <span class="highlite-KEYWORD">-></span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Heads I win, tails I die.</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-TYPE">Bool</span>.<span class="highlite-ROUTINE">pick</span> } <span class="highlite-OPERATOR">or</span> <span class="highlite-ROUTINE">die</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">I win.</span><span class="highlite-STRING_DELIMITER">"</span>; </pre> </div> </div> <h1 id="start" class="raku-h1"><a name="index-entry-start-start" data-indexedheader="Control flow;start"></a><a href="#Control_flow" title="go to top of document">start<a class="raku-anchor" title="direct link" href="#start">§</a></a></h1> <!-- defnmark start 1 --> <p>The simplest way to run a statement or block <strong>asynchronously</strong> is by writing <code>start</code> before it:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">start</span> { <span class="highlite-ROUTINE">sleep</span> 1; <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">done</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">working</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-COMMENT"># working, done </span></pre> </div> </div> <p>Note that you need a space between the <code>start</code> and the block. In the example above, the <code>start</code> block is in sink context since it's not assigned to a variable. From version 6.d, these sunk blocks have an exception handler attached:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">start</span> { <span class="highlite-ROUTINE">die</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">We're dead</span><span class="highlite-STRING_DELIMITER">"</span>; } <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">working</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-ROUTINE">sleep</span> 10; </pre> </div> </div> <p>This code will print <code>Unhandled exception in code scheduled on thread 4 We're dead</code> in version 6.d, while it will simply get out after waiting for 10 seconds in version 6.c.</p><p>The <code>start {...}</code> immediately returns a <a href="/type/Promise"><code>Promise</code></a> that can be safely ignored if you are not interested in the result of the block. If you <strong>are</strong> interested in the final value of the block, you can call the <code>.result</code> method on the returned promise. So:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$promise</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-KEYWORD">start</span> { <span class="highlite-ROUTINE">sleep</span> 10; 42 } <span class="highlite-COMMENT"># ... do other stuff </span><span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">The result is </span><span class="highlite-NAME_SCALAR">$promise</span><span class="highlite-STRING">.result()</span><span class="highlite-STRING_DELIMITER">"</span>;</pre> </div> </div> <p>If the code inside the block has not finished, the call to <code>.result</code> will wait until it is done.</p><p>A <code>start</code> used on a bare statement is useful when the only thing to do asynchronously is a subroutine or method:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">sub</span> get42 { 42 } <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$promise</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-KEYWORD">start</span> get42; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$promise</span>.<span class="highlite-ROUTINE">result</span>; <span class="highlite-COMMENT"># OUTPUT: «42»</span></pre> </div> </div> <p>Note that start code does not have access to the special variables <a href="/syntax/$!"><code>$!</code></a> and <a href="/syntax/$$SOLIDUS"><code>$/</code></a> of its outer block, but receives new ones, so every asynchronous task has its per-task state.</p><p>Thus, <code>try</code> expressions and regex matches executed in the asynchronous task have their per-task state.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">a</span><span class="highlite-STRING_DELIMITER">'</span> <span class="highlite-OPERATOR">~~</span> <span class="highlite-REGEX_DELIMITER">/</span><span class="highlite-REGEX_LITERAL">a</span><span class="highlite-REGEX_DELIMITER">/</span>; <span class="highlite-COMMENT"># $/ is set to 「a」 </span><span class="highlite-KEYWORD">try</span> <span class="highlite-ROUTINE">die</span>; <span class="highlite-COMMENT"># $! is defined now with an anonymous AdHoc exception </span><span class="highlite-COMMENT"># as a code block </span><span class="highlite-ROUTINE">await</span> <span class="highlite-KEYWORD">start</span> { <span class="highlite-ROUTINE">say</span> $<span class="highlite-OPERATOR">!</span> }; <span class="highlite-COMMENT"># OUTPUT: «Nil» </span><span class="highlite-ROUTINE">await</span> <span class="highlite-KEYWORD">start</span> { <span class="highlite-ROUTINE">say</span> $<span class="highlite-OPERATOR">/</span> }; <span class="highlite-COMMENT"># OUTPUT: «Nil» </span><span class="highlite-COMMENT"># as a single statement </span><span class="highlite-ROUTINE">await</span> <span class="highlite-KEYWORD">start</span> $<span class="highlite-OPERATOR">!</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «Nil» </span><span class="highlite-ROUTINE">await</span> <span class="highlite-KEYWORD">start</span> $<span class="highlite-OPERATOR">/</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «Nil»</span></pre> </div> </div> <h1 id="if" class="raku-h1"><a name="index-entry-if-if" data-indexedheader="Control flow;if"></a><a href="#Control_flow" title="go to top of document">if<a class="raku-anchor" title="direct link" href="#if">§</a></a></h1> <!-- defnmark if 1 --> <p>To conditionally run a block of code, use an <code>if</code> followed by a condition. The condition, an expression, will be evaluated immediately after the statement before the <code>if</code> finishes. The block attached to the condition will only be evaluated if the condition means <code>True</code> when coerced to <a href="/type/Bool"><code>Bool</code></a>. Unlike some languages the condition does not have to be parenthesized, instead the <code>{</code> and <code>}</code> around the block are mandatory:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 1 { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">1 is true</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "1 is true" </span></pre> </div> </div> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 1 <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">1 is true</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> ; <span class="highlite-COMMENT"># syntax error, missing block </span></pre> </div> </div> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">0 is true</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># does not say anything, because 0 is false </span></pre> </div> </div> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 42.<span class="highlite-ROUTINE">say</span> <span class="highlite-OPERATOR">and</span> 0 { 43.<span class="highlite-ROUTINE">say</span> }; <span class="highlite-COMMENT"># says "42" but does not say "43" </span></pre> </div> </div> <p>There is also a form of <code>if</code> called a "statement modifier" form. In this case, the <code>if</code> and the condition come after the code you want to run conditionally. Do note that the condition is still always evaluated first:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">43.<span class="highlite-ROUTINE">say</span> <span class="highlite-KEYWORD">if</span> 42.<span class="highlite-ROUTINE">say</span> <span class="highlite-OPERATOR">and</span> 0; <span class="highlite-COMMENT"># says "42" but does not say "43" </span>43.<span class="highlite-ROUTINE">say</span> <span class="highlite-KEYWORD">if</span> 42.<span class="highlite-ROUTINE">say</span> <span class="highlite-OPERATOR">and</span> 1; <span class="highlite-COMMENT"># says "42" and then says "43" </span><span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">It is easier to read code when 'if's are kept on left of screen</span><span class="highlite-STRING_DELIMITER">"</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-TYPE">True</span>; <span class="highlite-COMMENT"># says the above, because it is true </span>{ 43.<span class="highlite-ROUTINE">say</span> } <span class="highlite-KEYWORD">if</span> <span class="highlite-TYPE">True</span>; <span class="highlite-COMMENT"># says "43" as well</span></pre> </div> </div> <p>The statement modifier form is probably best used sparingly.</p><p>The <code>if</code> statement itself will either <a href="/type/Slip"><code>Slip</code></a> us an empty list, if it does not run the block, or it will return the value which the block produces:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$d</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-ROUTINE">say</span> (1<span class="highlite-OPERATOR">,</span> (<span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-NAME_SCALAR">$d</span> <span class="highlite-OPERATOR">+</span><span class="highlite-OPERATOR">=</span> 42; 2; })<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$d</span>); <span class="highlite-COMMENT"># says "(1 3 0)" </span><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$c</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-ROUTINE">say</span> (1<span class="highlite-OPERATOR">,</span> (<span class="highlite-KEYWORD">if</span> 1 { <span class="highlite-NAME_SCALAR">$c</span> <span class="highlite-OPERATOR">+</span><span class="highlite-OPERATOR">=</span> 42; 2; })<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$c</span>); <span class="highlite-COMMENT"># says "(1 2 3 42)" </span><span class="highlite-ROUTINE">say</span> (1<span class="highlite-OPERATOR">,</span> (<span class="highlite-KEYWORD">if</span> 1 { 2<span class="highlite-OPERATOR">,</span> 2 })<span class="highlite-OPERATOR">,</span> 3); <span class="highlite-COMMENT"># does not slip, says "(1 (2 2) 3)"</span></pre> </div> </div> <p>For the statement modifier it is the same, except you have the value of the statement instead of a block:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">say</span> (1<span class="highlite-OPERATOR">,</span> (42 <span class="highlite-KEYWORD">if</span> <span class="highlite-TYPE">True</span>) <span class="highlite-OPERATOR">,</span> 2); <span class="highlite-COMMENT"># says "(1 42 2)" </span><span class="highlite-ROUTINE">say</span> (1<span class="highlite-OPERATOR">,</span> (42 <span class="highlite-KEYWORD">if</span> <span class="highlite-TYPE">False</span>)<span class="highlite-OPERATOR">,</span> 2); <span class="highlite-COMMENT"># says "(1 2)" </span><span class="highlite-ROUTINE">say</span> (1<span class="highlite-OPERATOR">,</span> 42 <span class="highlite-KEYWORD">if</span> <span class="highlite-TYPE">False</span> <span class="highlite-OPERATOR">,</span> 2); <span class="highlite-COMMENT"># says "(1 42)" because "if False, 2" is true</span></pre> </div> </div> <p>The <code>if</code> does not change the topic (<code>$_</code>) by default. In order to access the value which the conditional expression produced, you have to ask for it more strongly:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">if</span> 42 { <span class="highlite-NAME_SCALAR">$_</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "1" </span><span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">if</span> 42 <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$_</span> { <span class="highlite-NAME_SCALAR">$_</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "42" </span><span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">if</span> 42 <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$a</span> { <span class="highlite-NAME_SCALAR">$_</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-NAME_SCALAR">$a</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "1" then says "42" </span><span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">if</span> 42 { <span class="highlite-NAME_SCALAR">$_</span>.<span class="highlite-ROUTINE">say</span>; $^a.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "1" then says "42"</span></pre> </div> </div> <h2 id="else/elsif" class="raku-h2"><a name="index-entry-else_elsif-else/elsif" data-indexedheader="Control flow;else elsif"></a><a href="#Control_flow" title="go to top of document"><code>else/elsif</code><a class="raku-anchor" title="direct link" href="#else/elsif">§</a></a></h2> <!-- defnmark else/elsif 2 --> <p>A compound conditional may be produced by following an <code>if</code> conditional with <code>else</code> to provide an alternative block to run when the conditional expression is false:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">no</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">yes</span><span class="highlite-STRING_DELIMITER">"</span> } ; <span class="highlite-COMMENT"># says "yes" </span><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">no</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">else</span>{ <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">yes</span><span class="highlite-STRING_DELIMITER">"</span> } ; <span class="highlite-COMMENT"># says "yes", space is not required </span></pre> </div> </div> <p>The <code>else</code> cannot be separated from the conditional statement by a semicolon, but as a special case, it is OK to have a newline.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">no</span><span class="highlite-STRING_DELIMITER">"</span> }; <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">yes</span><span class="highlite-STRING_DELIMITER">"</span> } ; <span class="highlite-COMMENT"># syntax error </span></pre> </div> </div> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">no</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">yes</span><span class="highlite-STRING_DELIMITER">"</span> } ; <span class="highlite-COMMENT"># says "yes" </span></pre> </div> </div> <p>Additional conditions may be sandwiched between the <code>if</code> and the <code>else</code> using <code>elsif</code>. An extra condition will only be evaluated if all the conditions before it were false, and only the block next to the first true condition will be run. You can end with an <code>elsif</code> instead of an <code>else</code> if you want.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">no</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">elsif</span> <span class="highlite-TYPE">False</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">NO</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">yes</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-COMMENT"># says "yes" </span><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">no</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">elsif</span> <span class="highlite-TYPE">True</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">YES</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">yes</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-COMMENT"># says "YES" </span> <span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">no</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">elsif</span> <span class="highlite-TYPE">False</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">NO</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-COMMENT"># does not say anything </span> <span class="highlite-KEYWORD">sub</span> <span class="highlite-ROUTINE">right</span> { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Right!</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-TYPE">True</span> } <span class="highlite-KEYWORD">sub</span> wrong { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Wrong!</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-TYPE">False</span> } <span class="highlite-KEYWORD">if</span> wrong() { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">no</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">elsif</span> <span class="highlite-ROUTINE">right</span>() { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">yes</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">maybe</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-COMMENT"># The above says "Wrong!" then says "Right!" then says "yes"</span></pre> </div> </div> <p>You cannot use the statement modifier form with <code>else</code> or <code>elsif</code>:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">42.<span class="highlite-ROUTINE">say</span> <span class="highlite-KEYWORD">if</span> 0 <span class="highlite-KEYWORD">else</span> { 43.<span class="highlite-ROUTINE">say</span> } <span class="highlite-COMMENT"># syntax error </span></pre> </div> </div> <p>All the same rules for semicolons and newlines apply, consistently</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> 0 }; <span class="highlite-KEYWORD">elsif</span> 1 { <span class="highlite-ROUTINE">say</span> 1 } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">how?</span><span class="highlite-STRING_DELIMITER">"</span> } ; <span class="highlite-COMMENT"># syntax error </span><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> 0 } <span class="highlite-KEYWORD">elsif</span> 1 { <span class="highlite-ROUTINE">say</span> 1 }; <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">how?</span><span class="highlite-STRING_DELIMITER">"</span> } ; <span class="highlite-COMMENT"># syntax error </span></pre> </div> </div> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> 0 } <span class="highlite-KEYWORD">elsif</span> 1 { <span class="highlite-ROUTINE">say</span> 1 } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">how?</span><span class="highlite-STRING_DELIMITER">"</span> } ; <span class="highlite-COMMENT"># says "1" </span></pre> </div> </div> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> 0 } <span class="highlite-KEYWORD">elsif</span> 1 { <span class="highlite-ROUTINE">say</span> 1 } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">how?</span><span class="highlite-STRING_DELIMITER">"</span> } ; <span class="highlite-COMMENT"># says "1" </span> <span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> 0 } <span class="highlite-KEYWORD">elsif</span> 1 { <span class="highlite-ROUTINE">say</span> 1 } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">how?</span><span class="highlite-STRING_DELIMITER">"</span> } ; <span class="highlite-COMMENT"># says "1" </span> <span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">no</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">elsif</span> <span class="highlite-TYPE">False</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">NO</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">yes</span><span class="highlite-STRING_DELIMITER">"</span> } ; <span class="highlite-COMMENT"># says "yes"</span></pre> </div> </div> <p>The whole thing either <a href="/type/Slip"><code>Slip</code></a>s us an empty list (if no blocks were run) or returns the value produced by the block that did run:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$d</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-ROUTINE">say</span> (1<span class="highlite-OPERATOR">,</span> (<span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-NAME_SCALAR">$d</span> <span class="highlite-OPERATOR">+</span><span class="highlite-OPERATOR">=</span> 42; <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">two</span><span class="highlite-STRING_DELIMITER">"</span>; } <span class="highlite-KEYWORD">elsif</span> <span class="highlite-TYPE">False</span> { <span class="highlite-NAME_SCALAR">$d</span> <span class="highlite-OPERATOR">+</span><span class="highlite-OPERATOR">=</span> 43; 2; })<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$d</span>); <span class="highlite-COMMENT"># says "(1 3 0)" </span><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$c</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-ROUTINE">say</span> (1<span class="highlite-OPERATOR">,</span> (<span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-NAME_SCALAR">$c</span> <span class="highlite-OPERATOR">+</span><span class="highlite-OPERATOR">=</span> 42; <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">two</span><span class="highlite-STRING_DELIMITER">"</span>; } <span class="highlite-KEYWORD">else</span> { <span class="highlite-NAME_SCALAR">$c</span> <span class="highlite-OPERATOR">+</span><span class="highlite-OPERATOR">=</span> 43; 2; })<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$c</span>); <span class="highlite-COMMENT"># says "(1 2 3 43)"</span></pre> </div> </div> <p>It's possible to obtain the value of the previous expression inside an <code>else</code>, which could be from <code>if</code> or the last <code>elsif</code> if any are present:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">if</span> 0 { } <span class="highlite-KEYWORD">else</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$a</span> { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-NAME_SCALAR">$_</span><span class="highlite-STRING"> </span><span class="highlite-NAME_SCALAR">$a</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "1 0" </span><span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">if</span> <span class="highlite-TYPE">False</span> { } <span class="highlite-KEYWORD">else</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$a</span> { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-NAME_SCALAR">$_</span><span class="highlite-STRING"> </span><span class="highlite-NAME_SCALAR">$a</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "1 False" </span> <span class="highlite-KEYWORD">if</span> <span class="highlite-TYPE">False</span> { } <span class="highlite-KEYWORD">elsif</span> 0 { } <span class="highlite-KEYWORD">else</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$a</span> { <span class="highlite-NAME_SCALAR">$a</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "0"</span></pre> </div> </div> <h1 id="unless" class="raku-h1"><a name="index-entry-unless-unless" data-indexedheader="Control flow;unless"></a><a href="#Control_flow" title="go to top of document"><code>unless</code><a class="raku-anchor" title="direct link" href="#unless">§</a></a></h1> <!-- defnmark unless 1 --> <p>When you get sick of typing "if not (X)" you may use <code>unless</code> to invert the sense of a conditional statement. You cannot use <code>else</code> or <code>elsif</code> with <code>unless</code> because that ends up getting confusing. Other than those two differences <code>unless</code> works the same as <a href="#if">if</a>:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">unless</span> 1 { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">1 is false</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># does not say anything, since 1 is true </span></pre> </div> </div> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">unless</span> 1 <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">1 is false</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> ; <span class="highlite-COMMENT"># syntax error, missing block </span></pre> </div> </div> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">unless</span> 0 { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">0 is false</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "0 is false" </span></pre> </div> </div> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">unless</span> 42.<span class="highlite-ROUTINE">say</span> <span class="highlite-OPERATOR">and</span> 1 { 43.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "42" but does not say "43" </span>43.<span class="highlite-ROUTINE">say</span> <span class="highlite-KEYWORD">unless</span> 42.<span class="highlite-ROUTINE">say</span> <span class="highlite-OPERATOR">and</span> 0; <span class="highlite-COMMENT"># says "42" and then says "43" </span>43.<span class="highlite-ROUTINE">say</span> <span class="highlite-KEYWORD">unless</span> 42.<span class="highlite-ROUTINE">say</span> <span class="highlite-OPERATOR">and</span> 1; <span class="highlite-COMMENT"># says "42" but does not say "43" </span> <span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">unless</span> 0 { <span class="highlite-NAME_SCALAR">$_</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "1" </span><span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">unless</span> 0 <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$_</span> { <span class="highlite-NAME_SCALAR">$_</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "0" </span><span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">unless</span> <span class="highlite-TYPE">False</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$a</span> { <span class="highlite-NAME_SCALAR">$a</span>.<span class="highlite-ROUTINE">say</span> } ; <span class="highlite-COMMENT"># says "False" </span> <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$c</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-ROUTINE">say</span> (1<span class="highlite-OPERATOR">,</span> (<span class="highlite-KEYWORD">unless</span> 0 { <span class="highlite-NAME_SCALAR">$c</span> <span class="highlite-OPERATOR">+</span><span class="highlite-OPERATOR">=</span> 42; 2; })<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$c</span>); <span class="highlite-COMMENT"># says "(1 2 3 42)" </span><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$d</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-ROUTINE">say</span> (1<span class="highlite-OPERATOR">,</span> (<span class="highlite-KEYWORD">unless</span> 1 { <span class="highlite-NAME_SCALAR">$d</span> <span class="highlite-OPERATOR">+</span><span class="highlite-OPERATOR">=</span> 42; 2; })<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$d</span>); <span class="highlite-COMMENT"># says "(1 3 0)"</span></pre> </div> </div> <h1 id="with_orwith_without" class="raku-h1"><a name="index-entry-with_orwith_without-with_orwith_without" data-indexedheader="Control flow;with orwith without"></a><a href="#Control_flow" title="go to top of document"><code>with orwith without</code><a class="raku-anchor" title="direct link" href="#with_orwith_without">§</a></a></h1> <!-- defnmark with_orwith_without 1 --> <p>The <code>with</code> statement is like <code>if</code>, but tests for definedness rather than truth, and it topicalizes on the condition, much like <code>given</code>:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">with</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">abc</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">index</span>(<span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">a</span><span class="highlite-STRING_DELIMITER">"</span>) { .<span class="highlite-ROUTINE">say</span> } <span class="highlite-COMMENT"># prints 0</span></pre> </div> </div> <p>Similarly to <code>elsif</code>, <code>orwith</code> may be used to chain definedness tests:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-COMMENT"># The below code says "Found 'a' at 0" </span><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$s</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">abc</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-KEYWORD">with</span> <span class="highlite-NAME_SCALAR">$s</span>.<span class="highlite-ROUTINE">index</span>(<span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">a</span><span class="highlite-STRING_DELIMITER">"</span>) { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Found 'a' at </span><span class="highlite-NAME_SCALAR">$_</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">orwith</span> <span class="highlite-NAME_SCALAR">$s</span>.<span class="highlite-ROUTINE">index</span>(<span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">b</span><span class="highlite-STRING_DELIMITER">"</span>) { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Found 'b' at </span><span class="highlite-NAME_SCALAR">$_</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">orwith</span> <span class="highlite-NAME_SCALAR">$s</span>.<span class="highlite-ROUTINE">index</span>(<span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">c</span><span class="highlite-STRING_DELIMITER">"</span>) { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Found 'c' at </span><span class="highlite-NAME_SCALAR">$_</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">else</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Didn't find 'a', 'b' or 'c'</span><span class="highlite-STRING_DELIMITER">"</span> }</pre> </div> </div> <p>You may intermix <code>if</code>-based and <code>with</code>-based clauses.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-COMMENT"># This says "Yes" </span><span class="highlite-KEYWORD">if</span> 0 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">No</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">orwith</span> <span class="highlite-TYPE">Nil</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">No</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">orwith</span> 0 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Yes</span><span class="highlite-STRING_DELIMITER">"</span> };</pre> </div> </div> <p>As with <code>unless</code>, you may use <code>without</code> to check for undefinedness, but you may not add an <code>else</code> clause:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$answer</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">Any</span>; <span class="highlite-KEYWORD">without</span> <span class="highlite-NAME_SCALAR">$answer</span> { <span class="highlite-ROUTINE">warn</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Got: </span><span class="highlite-ESCAPE">{</span><span class="highlite-NAME_SCALAR">$_</span>.<span class="highlite-ROUTINE">raku</span><span class="highlite-ESCAPE">}</span><span class="highlite-STRING_DELIMITER">"</span> }</pre> </div> </div> <p>There are also <code>with</code> and <code>without</code> statement modifiers:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$answer</span> <span class="highlite-OPERATOR">=</span> (<span class="highlite-TYPE">Any</span><span class="highlite-OPERATOR">,</span> <span class="highlite-TYPE">True</span>).<span class="highlite-ROUTINE">roll</span>; <span class="highlite-ROUTINE">say</span> 42 <span class="highlite-KEYWORD">with</span> <span class="highlite-NAME_SCALAR">$answer</span>; <span class="highlite-ROUTINE">warn</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">undefined answer</span><span class="highlite-STRING_DELIMITER">"</span> <span class="highlite-KEYWORD">without</span> <span class="highlite-NAME_SCALAR">$answer</span>;</pre> </div> </div> <p>As with the other chainable constructs, an <code>else</code> completing a <code>with/if</code>..<code>orwith/elsif</code> chain will itself topicalize to the value of the prior (failed) condition's topic (either the topic of <code>with</code> or the final <code>orwith</code> or <code>elsif</code>).</p><p>In the case of an <code>else</code> following a <code>with</code> or <code>orwith</code>, topicalizing a value guaranteed to be undefined may seem useless. But it makes for a useful idiom when used in conjunction with operations that may fail, because <a href="/type/Failure"><code>Failure</code></a> values are always undefined:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">sub</span> may_fail( <span class="highlite-KEYWORD">--></span> Numeric:D ) { <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$value</span> <span class="highlite-OPERATOR">=</span> (^10).<span class="highlite-ROUTINE">pick</span> <span class="highlite-OPERATOR">||</span> <span class="highlite-ROUTINE">fail</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Zero is unacceptable</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-ROUTINE">fail</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Odd is also not okay</span><span class="highlite-STRING_DELIMITER">"</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$value</span> <span class="highlite-OPERATOR">%</span> 2; <span class="highlite-KEYWORD">return</span> <span class="highlite-NAME_SCALAR">$value</span>; } <span class="highlite-KEYWORD">with</span> may_fail() <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$value</span> { <span class="highlite-COMMENT"># defined, so didn't fail </span> <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">I know </span><span class="highlite-NAME_SCALAR">$value</span><span class="highlite-STRING"> isn't zero or odd.</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">else</span> { <span class="highlite-COMMENT"># undefined, so failed, and the Failure is the topic </span> <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Uh-oh: </span><span class="highlite-ESCAPE">{</span>.<span class="highlite-ROUTINE">exception</span>.<span class="highlite-ROUTINE">message</span><span class="highlite-ESCAPE">}</span><span class="highlite-STRING">.</span><span class="highlite-STRING_DELIMITER">"</span> } </pre> </div> </div> <p>Note that while topicalizing a <a href="/type/Failure"><code>Failure</code></a> marks it <a href="/type/Failure#method_handled"><code>handled</code></a>—so you can use the <code>with</code>/<code>else</code> to proceed safely with execution—it doesn't make the <em>Failure value itself</em> safe. Even within the <code>else</code> clause, if you try to use the value directly, it will result in your <code>else</code> clause itself failing (or, in Rakudo, "promoting" the Failure into a thrown exception).</p><p>But as seen above, you <em>can</em> use the methods of a handled <a href="/type/Failure"><code>Failure</code></a> object the <code>else</code> topicalizes, such as <a href="/type/Failure#method_exception"><code>exception</code></a>, if you wish to provide diagnostics or interrogate the underlying <a href="/type/Exception"><code>Exception</code></a>.</p> <h1 id="when" class="raku-h1"><a name="index-entry-when-when" data-indexedheader="Control flow;when"></a><a href="#Control_flow" title="go to top of document">when<a class="raku-anchor" title="direct link" href="#when">§</a></a></h1> <!-- defnmark when 1 --> <p>The <code>when</code> block is similar to an <code>if</code> block and either or both can be used in an outer block; they also both have a "statement modifier" form. But there is a difference in how following code in the same, outer block is handled: When the <code>when</code> block is executed, control is passed to the enclosing block and following statements are ignored; but when the <code>if</code> block is executed, following statements are executed. <sup class="content-footnote"><a name="fnret1" href="#fn1">[1]</a></sup> The following examples should illustrate the <code>if</code> or <code>when</code> block's default behavior assuming no special exit or other side effect statements are included in the <code>if</code> or <code>when</code> blocks:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">{ <span class="highlite-KEYWORD">if</span> <span class="highlite-OPERATOR">X</span> {<span class="highlite-OPERATOR">...</span>} <span class="highlite-COMMENT"># if X is true in Boolean context, block is executed </span> <span class="highlite-COMMENT"># following statements are executed regardless </span>} { <span class="highlite-KEYWORD">when</span> <span class="highlite-OPERATOR">X</span> {<span class="highlite-OPERATOR">...</span>} <span class="highlite-COMMENT"># if X is true in Boolean context, block is executed </span> <span class="highlite-COMMENT"># and control passes to the outer block </span> <span class="highlite-COMMENT"># following statements are NOT executed </span>} </pre> </div> </div> <p>Should the <code>if</code> and <code>when</code> blocks above appear at file scope, following statements would be executed in each case.</p><p>There is one other feature <code>when</code> has that <code>if</code> doesn't: the <code>when</code>'s Boolean context test defaults to <code>$_ ~~</code> while the <code>if</code>'s does not. That has an effect on how one uses the X in the <code>when</code> block without a value for <code>$_</code> (it's <a href="/type/Any"><code>Any</code></a> in that case and <a href="/type/Any"><code>Any</code></a> smartmatches on <code>True</code>: <code>Any ~~ True</code> yields <code>True</code>). Consider the following:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">{ <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$a</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$b</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">True</span>; <span class="highlite-KEYWORD">when</span> <span class="highlite-NAME_SCALAR">$a</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">a</span><span class="highlite-STRING_DELIMITER">'</span> }; <span class="highlite-COMMENT"># no output </span> <span class="highlite-KEYWORD">when</span> <span class="highlite-OPERATOR">so</span> <span class="highlite-NAME_SCALAR">$a</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">a</span><span class="highlite-STRING_DELIMITER">'</span> } <span class="highlite-COMMENT"># a ("so $a" 'so' coerces $a to Boolean context True </span> <span class="highlite-COMMENT"># which matches with Any) </span> <span class="highlite-KEYWORD">when</span> <span class="highlite-NAME_SCALAR">$b</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">b</span><span class="highlite-STRING_DELIMITER">'</span> }; <span class="highlite-COMMENT"># no output (this statement won't be run) </span>} </pre> </div> </div> <p>Finally, <code>when</code>'s statement modifier form does not affect execution of following statements either inside or outside of another block:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">foo</span><span class="highlite-STRING_DELIMITER">"</span> <span class="highlite-KEYWORD">when</span> <span class="highlite-OPERATOR">X</span>; <span class="highlite-COMMENT"># if X is true statement is executed </span> <span class="highlite-COMMENT"># following statements are not affected </span></pre> </div> </div> <p>Since a successful match will exit the block, the behavior of this piece of code:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">True</span>; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$a</span>; { <span class="highlite-NAME_SCALAR">$a</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">do</span> <span class="highlite-KEYWORD">when</span> .<span class="highlite-OPERATOR">so</span> { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">foo</span><span class="highlite-STRING_DELIMITER">"</span> } }; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$a</span>; <span class="highlite-COMMENT"># OUTPUT: «(Any)» </span></pre> </div> </div> <p>is explained since the <code>do</code> block is abandoned before any value is stored or processed. However, in this case:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-TYPE">False</span>; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$a</span>; { <span class="highlite-NAME_SCALAR">$a</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">do</span> <span class="highlite-KEYWORD">when</span> .<span class="highlite-OPERATOR">so</span> { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">foo</span><span class="highlite-STRING_DELIMITER">"</span> } }; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$a</span>; <span class="highlite-COMMENT"># OUTPUT: «False» </span></pre> </div> </div> <p>the block is not abandoned since the comparison is false, so <code>$a</code> will actually get a value.</p> <h1 id="for" class="raku-h1"><a name="index-entry-for-for" data-indexedheader="Control flow;for"></a><a href="#Control_flow" title="go to top of document">for<a class="raku-anchor" title="direct link" href="#for">§</a></a></h1> <!-- defnmark for 1 --> <p>The <code>for</code> loop iterates over a list, running the statements inside a <a href="/type/Block"><code>Block</code></a> once on each iteration. If the block takes parameters, the elements of the list are provided as arguments. By default, the block takes one parameter, <code>$_</code>:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-OPERATOR">=</span> 1..3; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span> { <span class="highlite-NAME_SCALAR">$_</span>.<span class="highlite-ROUTINE">print</span> } <span class="highlite-COMMENT"># prints each value contained in @foo </span><span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span> { .<span class="highlite-ROUTINE">print</span> } <span class="highlite-COMMENT"># same thing, because .print implies a $_ argument </span><span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span> { 42.<span class="highlite-ROUTINE">print</span> } <span class="highlite-COMMENT"># prints 42 as many times as @foo has elements</span></pre> </div> </div> <p>Pointy block syntax or a <a href="/language/variables#The_^_twigil">placeholder</a> may be used to name the parameter:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-OPERATOR">=</span> 1..3; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$item</span> { <span class="highlite-ROUTINE">print</span> <span class="highlite-NAME_SCALAR">$item</span> } <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span> { <span class="highlite-ROUTINE">print</span> $^<span class="highlite-ROUTINE">item</span> } <span class="highlite-COMMENT"># same thing</span></pre> </div> </div> <p>Multiple parameters can be declared, in which case the iterator takes as many elements from the list as needed before running the block.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-OPERATOR">=</span> 1..3; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span>.<span class="highlite-ROUTINE">kv</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$idx</span><span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$val</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-NAME_SCALAR">$idx:</span><span class="highlite-STRING"> </span><span class="highlite-NAME_SCALAR">$val</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_HASH">%hash</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER"><</span><span class="highlite-STRING">a b c</span><span class="highlite-STRING_DELIMITER">></span> <span class="highlite-OPERATOR">Z</span>=<span class="highlite-OPERATOR">></span> 1,2,3; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_HASH">%hash</span>.<span class="highlite-ROUTINE">kv</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$key</span><span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$val</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-NAME_SCALAR">$key</span><span class="highlite-STRING"> => </span><span class="highlite-NAME_SCALAR">$val</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">for</span> 1<span class="highlite-OPERATOR">,</span> 1.1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 2.1 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">$^x < $^y</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-COMMENT"># OUTPUT: «1 < 1.12 < 2.1»</span></pre> </div> </div> <p>Parameters of a pointy block can have default values, allowing the code to handle lists with missing elements.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@list</span> <span class="highlite-OPERATOR">=</span> 1,2,3,4; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@list</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$a</span><span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$b</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">N/A</span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$c</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">N/A</span><span class="highlite-STRING_DELIMITER">'</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-NAME_SCALAR">$a</span><span class="highlite-STRING"> </span><span class="highlite-NAME_SCALAR">$b</span><span class="highlite-STRING"> </span><span class="highlite-NAME_SCALAR">$c</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-COMMENT"># OUTPUT: «1 2 34 N/A N/A»</span></pre> </div> </div> <p>When no parameters are specified for a <code>for</code> loop's block, <code>when</code> can be used within it similarly to how it's used in a <code>given</code> block:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-COMMENT"># A solution for FizzBuzz: </span><span class="highlite-KEYWORD">for</span> 1..100 { <span class="highlite-KEYWORD">when</span> <span class="highlite-OPERATOR">*</span> <span class="highlite-OPERATOR">%%</span> 15 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">FizzBuzz</span><span class="highlite-STRING_DELIMITER">'</span> } <span class="highlite-KEYWORD">when</span> <span class="highlite-OPERATOR">*</span> <span class="highlite-OPERATOR">%%</span> 3 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">Fizz</span><span class="highlite-STRING_DELIMITER">'</span> } <span class="highlite-KEYWORD">when</span> <span class="highlite-OPERATOR">*</span> <span class="highlite-OPERATOR">%%</span> 5 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">Buzz</span><span class="highlite-STRING_DELIMITER">'</span> } <span class="highlite-KEYWORD">default</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$_</span> } }</pre> </div> </div> <p>If the postfix form of <code>for</code> is used, a block is not required and the topic is set for the statement list.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">say</span> „I <span class="highlite-NAME_SCALAR">$_</span> butterflies!“ <span class="highlite-KEYWORD">for</span> <span class="highlite-OPERATOR"><</span>♥ ♥ ♥<span class="highlite-OPERATOR">></span>; <span class="highlite-COMMENT"># OUTPUT: «I ♥ butterflies!I ♥ butterflies!I ♥ butterflies!»</span></pre> </div> </div> <p>A <code>for</code> may be used on lazy lists – it will only take elements from the list when they are needed, so to read a file line by line, you could use:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_SCALAR">$*IN</span>.<span class="highlite-ROUTINE">lines</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$line</span> { .<span class="highlite-ROUTINE">say</span> } </pre> </div> </div> <p>Iteration variables are always lexical, so you don't need to use <code>my</code> to give them the appropriate scope. Also, they are read-only aliases. If you need them to be writable, use <code><-></code> instead of <code>-></code>. Alternatively, you can add the <a href="/language/signatures#Parameter_traits_and_modifiers"><code>is rw</code></a> trait; this performs a binding operation so assigning to the parameter changes the value of the variable at the caller side. If instead you want to modify copies of the arguments within the block, add <a href="/language/signatures#Parameter_traits_and_modifiers"><code>is copy</code></a>.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-OPERATOR">=</span> 1..3; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span> <<span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$value</span> { <span class="highlite-NAME_SCALAR">$value</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_SCALAR">$value</span> <span class="highlite-OPERATOR">%%</span> 2 <span class="highlite-OPERATOR">??</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Even</span><span class="highlite-STRING_DELIMITER">"</span> <span class="highlite-OPERATOR">!!</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Odd</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_ARRAY">@foo</span>; <span class="highlite-COMMENT"># OUTPUT: «[Odd Even Odd]» </span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-OPERATOR">=</span> 1..3; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$value</span> <span class="highlite-KEYWORD">is</span> <span class="highlite-KEYWORD">rw</span> { <span class="highlite-NAME_SCALAR">$value</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_SCALAR">$value</span> <span class="highlite-OPERATOR">%%</span> 2 <span class="highlite-OPERATOR">??</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Even</span><span class="highlite-STRING_DELIMITER">"</span> <span class="highlite-OPERATOR">!!</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Odd</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_ARRAY">@foo</span>; <span class="highlite-COMMENT"># OUTPUT: «[Odd Even Odd]» </span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-OPERATOR">=</span> 1..3; <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@bar</span>; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$value</span> <span class="highlite-KEYWORD">is</span> <span class="highlite-ROUTINE">copy</span> { <span class="highlite-NAME_SCALAR">$value</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-NAME_SCALAR">$value</span> <span class="highlite-OPERATOR">%%</span> 2 <span class="highlite-OPERATOR">??</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Even</span><span class="highlite-STRING_DELIMITER">"</span> <span class="highlite-OPERATOR">!!</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Odd</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-NAME_ARRAY">@bar</span>.push: <span class="highlite-NAME_SCALAR">$value</span> } <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_ARRAY">@foo</span>; <span class="highlite-COMMENT"># OUTPUT: «[1 2 3]» </span><span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_ARRAY">@bar</span>; <span class="highlite-COMMENT"># OUTPUT: «[Odd Even Odd]» </span></pre> </div> </div> <p>This rule also applies to the topic variable <code>$_</code>, which by default is a read-write alias; it will become read-only if it's used in a <code>-></code> loop.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-OPERATOR">=</span> 1..3; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$_</span> { <span class="highlite-NAME_SCALAR">$_</span>.<span class="highlite-ROUTINE">say</span> } <span class="highlite-COMMENT"># Error: ...require mutable arguments </span><span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@foo</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$_</span> { <span class="highlite-NAME_SCALAR">$_</span>+<span class="highlite-OPERATOR">+</span> }</pre> </div> </div> <p>A <code>for</code> loop can produce a <a href="/type/List"><code>List</code></a> of the values produced by each run of the attached block. To capture these values, put the for loop in parenthesis or assign them to an array:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">(<span class="highlite-KEYWORD">for</span> 1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 3 { <span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">*</span> 2 }).<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «(2 4 6)» </span><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@a</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">do</span> <span class="highlite-KEYWORD">for</span> 1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 3 { <span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">*</span> 2 }; <span class="highlite-NAME_ARRAY">@a</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «[2 4 6]» </span><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@b</span> <span class="highlite-OPERATOR">=</span> (<span class="highlite-KEYWORD">for</span> 1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 3 { <span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">*</span> 2 }); <span class="highlite-NAME_ARRAY">@b</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «[2 4 6]»</span></pre> </div> </div> <p>This implies that, if the results of the loop are not assigned, they will be in a <a href="/language/contexts#Sink">sink context</a>:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">class</span> Sunk { <span class="highlite-KEYWORD">has</span> <span class="highlite-NAME_SCALAR">$.titanic</span>; <span class="highlite-KEYWORD">method</span> <span class="highlite-ROUTINE">sink</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Sinking </span><span class="highlite-NAME_SCALAR">$!titanic</span><span class="highlite-STRING_DELIMITER">"</span>; } } Sunk.<span class="highlite-ROUTINE">new</span>( :titanic(<span class="highlite-NAME_SCALAR">$_</span>) ) <span class="highlite-KEYWORD">for</span> ^3; <span class="highlite-KEYWORD">for</span> 1 { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">About to sink</span><span class="highlite-STRING_DELIMITER">"</span>; Sunk.<span class="highlite-ROUTINE">new</span>( :titanic(<span class="highlite-NAME_SCALAR">$_</span>) ); } <span class="highlite-COMMENT"># OUTPUT: </span><span class="highlite-COMMENT"># Sinking 0 </span><span class="highlite-COMMENT"># Sinking 1 </span><span class="highlite-COMMENT"># Sinking 2 </span><span class="highlite-COMMENT"># About to sink </span><span class="highlite-COMMENT"># Sinking 1 </span></pre> </div> </div> <p>The first loop creates three elements but they are in a sink context, so its <code>sink</code> method is called. In the second loop, its last statement will be in a sink context, so it will be also sunk (from version 6.d).</p><p>The <code>Empty</code> constant will act as a no-op for a loop:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Not here</span><span class="highlite-STRING_DELIMITER">"</span> <span class="highlite-KEYWORD">for</span> <span class="highlite-TYPE">Empty</span>; </pre> </div> </div> <p>Will not do anything. This constant is <a href="/syntax/Empty">equivalent to an empty Slip or List</a>.</p><p>Undefined values will behave in the same way:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@array</span> <span class="highlite-OPERATOR">:=</span> <span class="highlite-TYPE">Empty</span>; .<span class="highlite-ROUTINE">say</span> <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@array</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_ARRAY">@array</span>; <span class="highlite-COMMENT"># OUTPUT: «()» </span></pre> </div> </div> <p>Assigning <code>Empty</code> will effectively undefine an <a href="/type/Array"><code>Array</code></a>, using <code>for</code> over an undefined array will not even enter the loop, as shown, effectively behaving in the same way as above when <code>Empty</code> was used directly.</p><p>With <code>hyper</code> and <code>race</code>, the <code>for</code> loop is potentially iterated in parallel. See also the documentation for <code>hyper</code> and <code>race</code> in class <a href="/type/Map"><code>Map</code></a>.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$primes_h</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">hyper</span> <span class="highlite-KEYWORD">for</span> ^10_000 <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$number</span> { <span class="highlite-NAME_SCALAR">$number</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$number</span>.<span class="highlite-ROUTINE">is-prime</span> }; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$primes_h</span>.<span class="highlite-ROUTINE">elems</span>; <span class="highlite-COMMENT"># OUTPUT: «1229» </span><span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$primes_h</span>.tail: 5; <span class="highlite-COMMENT"># OUTPUT: «(9931 9941 9949 9967 9973)» </span></pre> </div> </div> <p>with <code>hyper</code> the order of elements is preserved.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$primes_r</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">race</span> <span class="highlite-KEYWORD">for</span> ^10_000 <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$number</span> { <span class="highlite-NAME_SCALAR">$number</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$number</span>.<span class="highlite-ROUTINE">is-prime</span> }; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$primes_r</span>.<span class="highlite-ROUTINE">elems</span>; <span class="highlite-COMMENT"># OUTPUT: «1229» </span></pre> </div> </div> <p>Unlike <code>hyper</code>, <code>race</code> does not preserve the order of elements.</p> <h1 id="gather/take" class="raku-h1"><a name="index-entry-gather_take-gather/take" data-indexedheader="Control flow;gather take"></a><a href="#Control_flow" title="go to top of document">gather/take<a class="raku-anchor" title="direct link" href="#gather/take">§</a></a></h1> <!-- defnmark gather/take 1 --> <p><code>gather</code> is a statement or block prefix that returns a <a href="/type/Seq">sequence</a> of values. The values come from calls to <a href="/type/Mu#routine_take">take</a> in the dynamic scope of the <code>gather</code> code. In the following example, we implement a subroutine to compute the factors of an integer with <code>gather</code> (note that the factors are not generated in order):</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">sub</span> factors( Int:D \n ) { <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$k</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">gather</span> { <span class="highlite-KEYWORD">while</span> <span class="highlite-NAME_SCALAR">$k</span>**2 <span class="highlite-OPERATOR"><</span> n { <span class="highlite-KEYWORD">if</span> n <span class="highlite-OPERATOR">%%</span> <span class="highlite-NAME_SCALAR">$k</span> { <span class="highlite-ROUTINE">take</span> <span class="highlite-NAME_SCALAR">$k</span>; <span class="highlite-ROUTINE">take</span> n <span class="highlite-OPERATOR">div</span> <span class="highlite-NAME_SCALAR">$k</span>; } <span class="highlite-NAME_SCALAR">$k</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-ROUTINE">take</span> <span class="highlite-NAME_SCALAR">$k</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$k</span>**2 <span class="highlite-OPERATOR">==</span> n; } } <span class="highlite-ROUTINE">say</span> factors(36); <span class="highlite-COMMENT"># OUTPUT: «1, 36, 2, 18, 3, 12, 4, 9, 6»</span></pre> </div> </div> <p>The <code>gather/take</code> combination can generate values lazily, depending on context. Binding to a scalar or sigilless container will force laziness. If you want to force lazy evaluation use the <a href="/type/Iterable#method_lazy">lazy</a> subroutine or method. For example:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@vals</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">lazy</span> <span class="highlite-KEYWORD">gather</span> { <span class="highlite-ROUTINE">take</span> 1; <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Produced a value</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-ROUTINE">take</span> 2; } <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_ARRAY">@vals</span>[0]; <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">between consumption of two values</span><span class="highlite-STRING_DELIMITER">'</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_ARRAY">@vals</span>[1]; <span class="highlite-COMMENT"># OUTPUT: </span><span class="highlite-COMMENT"># 1 </span><span class="highlite-COMMENT"># between consumption of two values </span><span class="highlite-COMMENT"># Produced a value </span><span class="highlite-COMMENT"># 2</span></pre> </div> </div> <p><code>gather/take</code> is scoped dynamically, so you can call <code>take</code> from subs or methods that are called from within <code>gather</code>:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">sub</span> weird(<span class="highlite-NAME_ARRAY">@elems</span><span class="highlite-OPERATOR">,</span> <span class="highlite-OPERATOR">:</span><span class="highlite-NAME_SCALAR">$direction</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">forward</span><span class="highlite-STRING_DELIMITER">'</span>) { <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_HASH">%direction</span> <span class="highlite-OPERATOR">=</span> ( forward <span class="highlite-OPERATOR">=></span> <span class="highlite-KEYWORD">sub</span> { <span class="highlite-ROUTINE">take</span> <span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@elems</span> }<span class="highlite-OPERATOR">,</span> backward <span class="highlite-OPERATOR">=></span> <span class="highlite-KEYWORD">sub</span> { <span class="highlite-ROUTINE">take</span> <span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@elems</span>.<span class="highlite-ROUTINE">reverse</span> }<span class="highlite-OPERATOR">,</span> random <span class="highlite-OPERATOR">=></span> <span class="highlite-KEYWORD">sub</span> { <span class="highlite-ROUTINE">take</span> <span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@elems</span>.<span class="highlite-ROUTINE">pick</span>(<span class="highlite-OPERATOR">*</span>) }<span class="highlite-OPERATOR">,</span> ); <span class="highlite-KEYWORD">return</span> <span class="highlite-KEYWORD">gather</span> <span class="highlite-NAME_HASH">%direction</span>{<span class="highlite-NAME_SCALAR">$direction</span>}(); } <span class="highlite-ROUTINE">say</span> weird(<span class="highlite-STRING_DELIMITER"><</span><span class="highlite-STRING">a b c</span><span class="highlite-STRING_DELIMITER">></span><span class="highlite-OPERATOR">,</span> :direction<backward> ); <span class="highlite-COMMENT"># OUTPUT: «(c b a)»</span></pre> </div> </div> <p>If values need to be mutable on the caller side, use <a href="/type/Mu#routine_take-rw">take-rw</a>.</p><p>Note that the <a href="/type/Seq"><code>Seq</code></a> created by <code>gather/take</code> may be coerced to another type. An example with assignment to a hash:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_HASH">%h</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-KEYWORD">gather</span> { <span class="highlite-ROUTINE">take</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">foo</span><span class="highlite-STRING_DELIMITER">"</span> <span class="highlite-OPERATOR">=></span> 1; <span class="highlite-ROUTINE">take</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">bar</span><span class="highlite-STRING_DELIMITER">"</span> <span class="highlite-OPERATOR">=></span> 2}; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_HASH">%h</span>; <span class="highlite-COMMENT"># OUTPUT: «{bar => 2, foo => 1}»</span></pre> </div> </div> <p><strong>Note</strong>: <code>gather/take</code> must not be used to collect results from <code>react/whenever</code>. The <code>whenever</code> block is not run from the thread that runs the <code>gather/react</code>, but the thread that runs the <code>emit</code>. On this thread, there is no handler for the control exception thrown by <code>take</code>, causing it to error out.</p> <h1 id="supply/emit" class="raku-h1"><a name="index-entry-supply_emit-supply/emit" data-indexedheader="Control flow;supply emit"></a><a href="#Control_flow" title="go to top of document">supply/emit<a class="raku-anchor" title="direct link" href="#supply/emit">§</a></a></h1> <!-- defnmark supply/emit 1 --> <p>The keyword <code>supply</code> creates a <a href="/type/Supply">Supply object</a> which is an <a href="/language/concurrency#index-entry-supply_(on-demand)">on-demand supply</a> that you can tap. It pairs with <code>emit</code>, which can be used anywhere from within <code>supply</code> prefixed code.</p><p>Using the <a href="/type/Mu#method_emit"><code>emit method</code></a> or the <a href="/type/independent-routines#sub_emit"><code>emit routine</code></a> passes the invocant to the enclosing <a href="/language/concurrency#index-entry-supply_(on-demand)">supply</a>:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$supply</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-KEYWORD">supply</span> { .<span class="highlite-ROUTINE">emit</span> <span class="highlite-KEYWORD">for</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">foo</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> 42<span class="highlite-OPERATOR">,</span> .5; } <span class="highlite-NAME_SCALAR">$supply</span>.tap: { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">received </span><span class="highlite-ESCAPE">{</span>.^<span class="highlite-ROUTINE">name</span><span class="highlite-ESCAPE">}</span><span class="highlite-STRING"> (</span><span class="highlite-NAME_SCALAR">$_</span><span class="highlite-STRING">)</span><span class="highlite-STRING_DELIMITER">"</span>; } <span class="highlite-COMMENT"># OUTPUT: </span><span class="highlite-COMMENT"># received Str (foo) </span><span class="highlite-COMMENT"># received Int (42) </span><span class="highlite-COMMENT"># received Rat (0.5)</span></pre> </div> </div> <p>See also: <a href="/routine/tap"><code>tap</code></a> and <a href="/type/Supplier"><code>Supplier</code></a>.</p><p><a name="index-entry-switch_(given)" class="index-entry"></a> <a name="index-entry-case_statements_(given)" class="index-entry"></a></p> <h1 id="given" class="raku-h1"><a name="index-entry-given-given" data-indexedheader="Control flow;given"></a><a href="#Control_flow" title="go to top of document">given<a class="raku-anchor" title="direct link" href="#given">§</a></a></h1> <!-- defnmark given 1 --> <p>The <code>given</code> statement is Raku's topicalizing keyword in a similar way that <code>switch</code> topicalizes in languages such as C. In other words, <code>given</code> sets <code>$_</code> inside the following block. The keywords for individual cases are <code>when</code> and <code>default</code>. The usual idiom looks like this:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$var</span> <span class="highlite-OPERATOR">=</span> (<span class="highlite-TYPE">Any</span><span class="highlite-OPERATOR">,</span> 21<span class="highlite-OPERATOR">,</span> <span class="highlite-ROUTINE">any</span> <answer lie>).<span class="highlite-ROUTINE">pick</span>; <span class="highlite-KEYWORD">given</span> <span class="highlite-NAME_SCALAR">$var</span> { <span class="highlite-KEYWORD">when</span> 21 { <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">*</span> 2 } <span class="highlite-KEYWORD">when</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">lie</span><span class="highlite-STRING_DELIMITER">'</span> { .<span class="highlite-ROUTINE">say</span> } <span class="highlite-KEYWORD">default</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">default</span><span class="highlite-STRING_DELIMITER">'</span> } }</pre> </div> </div> <p>The <code>given</code> statement is often used alone:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">given</span> 42 { .<span class="highlite-ROUTINE">say</span>; .<span class="highlite-TYPE">Numeric</span>; }</pre> </div> </div> <p>This is a lot more understandable than:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">{ .<span class="highlite-ROUTINE">say</span>; .<span class="highlite-TYPE">Numeric</span>; }(42)</pre> </div> </div> <h2 id="default_and_when" class="raku-h2"><a name="index-entry-default_when-default_and_when" data-indexedheader="Control flow;default when"></a><a href="#Control_flow" title="go to top of document">default and when<a class="raku-anchor" title="direct link" href="#default_and_when">§</a></a></h2> <!-- defnmark default_and_when 2 --> <p>A block containing a <code>default</code> statement will be left immediately when the sub-block after the <code>default</code> statement is left. It is as though the rest of the statements in the block were skipped.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">given</span> 42 { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">This says</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">==</span> 42 <span class="highlite-OPERATOR">and</span> ( <span class="highlite-KEYWORD">default</span> { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">This says, too</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; 43; } ); <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">This never says</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; } <span class="highlite-COMMENT"># The above block evaluates to 43</span></pre> </div> </div> <p>A <code>when</code> statement will also do this (but a <code>when</code> statement modifier will <em>not</em>.)</p><p>In addition, <code>when</code> statements <code>smartmatch</code> the topic (<code>$_</code>) against a supplied expression such that it is possible to check against values, regular expressions, and types when specifying a match.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">for</span> 42<span class="highlite-OPERATOR">,</span> 43<span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">foo</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> 44<span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">bar</span><span class="highlite-STRING_DELIMITER">"</span> { <span class="highlite-KEYWORD">when</span> <span class="highlite-TYPE">Int</span> { .<span class="highlite-ROUTINE">say</span> } <span class="highlite-KEYWORD">when</span> /:i ^Bar/ { .<span class="highlite-ROUTINE">say</span> } <span class="highlite-KEYWORD">default</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Not an Int or a Bar</span><span class="highlite-STRING_DELIMITER">"</span> } } <span class="highlite-COMMENT"># OUTPUT: «4243Not an Int or a Bar44Bar»</span></pre> </div> </div> <p>In this form, the <code>given</code>/<code>when</code> construct acts much like a set of <code>if</code>/<code>elsif</code>/<code>else</code> statements. Be careful with the order of the <code>when</code> statements. The following code says <code>"Int"</code> not <code>42</code>.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">given</span> 42 { <span class="highlite-KEYWORD">when</span> <span class="highlite-TYPE">Int</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Int</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">when</span> 42 { <span class="highlite-ROUTINE">say</span> 42 } <span class="highlite-KEYWORD">default</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">huh?</span><span class="highlite-STRING_DELIMITER">"</span> } } <span class="highlite-COMMENT"># OUTPUT: «Int»</span></pre> </div> </div> <p>When a <code>when</code> statement or <code>default</code> statement causes the outer block to return, nesting <code>when</code> or <code>default</code> blocks do not count as the outer block, so you can nest these statements and still be in the same "switch" just so long as you do not open a new block:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">given</span> 42 { <span class="highlite-KEYWORD">when</span> <span class="highlite-TYPE">Int</span> { <span class="highlite-KEYWORD">when</span> 42 { <span class="highlite-ROUTINE">say</span> 42 } <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Int</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">default</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">huh?</span><span class="highlite-STRING_DELIMITER">"</span> } } <span class="highlite-COMMENT"># OUTPUT: «42»</span></pre> </div> </div> <p><code>when</code> statements can smartmatch against <a href="/language/syntax#Signature_literals">Signatures</a>.</p> <h2 id="proceed_and_succeed" class="raku-h2"><a name="index-entry-proceed-proceed" data-indexedheader="Control flow;proceed"></a><a href="#Control_flow" title="go to top of document">proceed<a class="raku-anchor" title="direct link" href="#proceed_and_succeed">§</a></a></h2> <!-- defnmark proceed_and_succeed 2 --> <p>Both <code>proceed</code> and <code>succeed</code> are meant to be used only from inside <code>when</code> or <code>default</code> blocks.</p><p>The <code>proceed</code> statement will immediately leave the <code>when</code> or <code>default</code> block, skipping the rest of the statements, and resuming after the block. This prevents the <code>when</code> or <code>default</code> from exiting the outer block.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">given</span> <span class="highlite-OPERATOR">*</span> { <span class="highlite-KEYWORD">default</span> { <span class="highlite-KEYWORD">proceed</span>; <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">This never says</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> } } <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">This says</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; </pre> </div> </div> <p>This is most often used to enter multiple <code>when</code> blocks. <code>proceed</code> will resume matching after a successful match, like so:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">given</span> 42 { <span class="highlite-KEYWORD">when</span> <span class="highlite-TYPE">Int</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Int</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-KEYWORD">proceed</span> } <span class="highlite-KEYWORD">when</span> 42 { <span class="highlite-ROUTINE">say</span> 42 } <span class="highlite-KEYWORD">when</span> 40.<span class="highlite-OPERATOR">.*</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">greater than 40</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">default</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">huh?</span><span class="highlite-STRING_DELIMITER">"</span> } } <span class="highlite-COMMENT"># OUTPUT: «Int» </span><span class="highlite-COMMENT"># OUTPUT: «42»</span></pre> </div> </div> <p>Note that the <code>when 40..*</code> match didn't occur. For this to match such cases as well, one would need a <code>proceed</code> in the <code>when 42</code> block.</p><p>This is not like a <code>C</code> <code>switch</code> statement, because the <code>proceed</code> does not merely enter the directly following block, it attempts to match the <code>given</code> value once more, consider this code:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">given</span> 42 { <span class="highlite-KEYWORD">when</span> <span class="highlite-TYPE">Int</span> { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Int</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-KEYWORD">proceed</span> } <span class="highlite-KEYWORD">when</span> 43 { 43.<span class="highlite-ROUTINE">say</span> } <span class="highlite-KEYWORD">when</span> 42 { 42.<span class="highlite-ROUTINE">say</span> } <span class="highlite-KEYWORD">default</span> { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">got change for an existential answer?</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> } } <span class="highlite-COMMENT"># OUTPUT: «Int» </span><span class="highlite-COMMENT"># OUTPUT: «42»</span></pre> </div> </div> <p>...which matches the <a href="/type/Int"><code>Int</code></a>, skips <code>43</code> since the value doesn't match, matches <code>42</code> since this is the next positive match, but doesn't enter the <code>default</code> block since the <code>when 42</code> block doesn't contain a <code>proceed</code>.</p><p>By contrast, the <code>succeed</code> keyword short-circuits execution and exits the entire <code>given</code> block at that point. It may also take an argument to specify a final value for the block.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-ROUTINE">say</span> <span class="highlite-ROUTINE">do</span> <span class="highlite-KEYWORD">given</span> 42 { <span class="highlite-KEYWORD">when</span> <span class="highlite-TYPE">Int</span> { <span class="highlite-KEYWORD">succeed</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Found</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">never this!</span><span class="highlite-STRING_DELIMITER">"</span>; } <span class="highlite-KEYWORD">when</span> 42 { <span class="highlite-ROUTINE">say</span> 42 } <span class="highlite-KEYWORD">default</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">dunno?</span><span class="highlite-STRING_DELIMITER">"</span> } } <span class="highlite-COMMENT"># OUTPUT: «Found»</span></pre> </div> </div> <p>If you are not inside a when or default block, it is an error to try to use <code>proceed</code> or <code>succeed</code>.Also remember, the <code>when</code> statement modifier form does not cause any blocks to be left, and any <code>succeed</code> or <code>proceed</code> in such a statement applies to the surrounding clause, if there is one:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">given</span> 42 { { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">This says</span><span class="highlite-STRING_DELIMITER">"</span> } <span class="highlite-KEYWORD">when</span> <span class="highlite-TYPE">Int</span>; <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">This says too</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-KEYWORD">when</span> <span class="highlite-OPERATOR">*</span> <span class="highlite-OPERATOR">></span> 41 { { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">And this says</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-KEYWORD">proceed</span> } <span class="highlite-KEYWORD">when</span> <span class="highlite-OPERATOR">*</span> <span class="highlite-OPERATOR">></span> 41; <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">This never says</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; } <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">This also says</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span>; } <span class="highlite-COMMENT"># OUTPUT: «This saysThis says tooAnd this saysThis also says»</span></pre> </div> </div> <h2 id="given_as_a_statement" class="raku-h2"><a name="index-entry-given_statement-given_as_a_statement" data-indexedheader="Control flow;given statement"></a><a href="#Control_flow" title="go to top of document">given as a statement<a class="raku-anchor" title="direct link" href="#given_as_a_statement">§</a></a></h2> <!-- defnmark given_as_a_statement 2 --> <p><code>given</code> can follow a statement to set the topic in the statement it follows.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">.<span class="highlite-ROUTINE">say</span> <span class="highlite-KEYWORD">given</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">foo</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-COMMENT"># OUTPUT: «foo» </span> <span class="highlite-ROUTINE">printf</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-NAME_HASH">%s</span><span class="highlite-STRING"> </span><span class="highlite-NAME_HASH">%02i</span><span class="highlite-STRING">.</span><span class="highlite-NAME_HASH">%02i</span><span class="highlite-STRING">.</span><span class="highlite-NAME_HASH">%i</span><span class="highlite-STRING_DELIMITER">"</span><span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER"><</span><span class="highlite-STRING">Mo Tu We Th Fr Sa Su</span><span class="highlite-STRING_DELIMITER">></span>[.<span class="highlite-ROUTINE">day-of-week</span> <span class="highlite-OPERATOR">-</span> 1]<span class="highlite-OPERATOR">,</span> .<span class="highlite-ROUTINE">day</span><span class="highlite-OPERATOR">,</span> .<span class="highlite-ROUTINE">month</span><span class="highlite-OPERATOR">,</span> .<span class="highlite-ROUTINE">year</span> <span class="highlite-KEYWORD">given</span> <span class="highlite-TYPE">DateTime</span>.<span class="highlite-ROUTINE">now</span>; <span class="highlite-COMMENT"># OUTPUT: «Sa 03.06.2016»</span></pre> </div> </div> <h1 id="loop" class="raku-h1"><a name="index-entry-loop-loop" data-indexedheader="Control flow;loop"></a><a href="#Control_flow" title="go to top of document">loop<a class="raku-anchor" title="direct link" href="#loop">§</a></a></h1> <!-- defnmark loop 1 --> <p>The <code>loop</code> statement takes three statements in parentheses separated by <code>;</code> that take the roles of initializer, conditional and incrementer, respectively. The initializer is executed once before the conditional is first tested. In case the initializer involves a variable declaration, the variable is declared as a lexical variable in the loop's <em>outer or containing</em> scope so that it can be used in code following the loop statement. The conditional is executed before each iteration and coerced to <a href="/type/Bool"><code>Bool</code></a>; if <code>False</code> the loop is stopped. The incrementer is executed after each iteration, and before the conditional is tested again.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">loop</span> (<span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR"><</span> 10; <span class="highlite-NAME_SCALAR">$i</span>+<span class="highlite-OPERATOR">+</span>) { <span class="highlite-COMMENT"># A typical loop </span> <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$i</span>; } <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@str</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">However Long</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">comb</span>; <span class="highlite-COMMENT"># Our very own .char routine: </span><span class="highlite-KEYWORD">loop</span> (<span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$l</span> <span class="highlite-OPERATOR">=</span> 0;;) { <span class="highlite-COMMENT"># Declare $l in outer scope </span> <span class="highlite-ROUTINE">last</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-OPERATOR">!</span><span class="highlite-NAME_ARRAY">@str</span>[<span class="highlite-NAME_SCALAR">$l</span>+<span class="highlite-OPERATOR">+</span>] <span class="highlite-COMMENT"># and count chars until we hit </span>} <span class="highlite-COMMENT"># an undefined element (Any) </span><span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">The string is </span><span class="highlite-ESCAPE">{</span><span class="highlite-OPERATOR">--</span><span class="highlite-NAME_SCALAR">$l</span><span class="highlite-ESCAPE">}</span><span class="highlite-STRING"> chars long.</span><span class="highlite-STRING_DELIMITER">"</span>;</pre> </div> </div> <p>The infinite loop does not require parentheses.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">loop</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">forever</span><span class="highlite-STRING_DELIMITER">'</span> } </pre> </div> </div> <p>The <code>loop</code> statement may be used to produce values from the result of each run of the attached block if it appears in lists:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">(<span class="highlite-KEYWORD">loop</span> ( <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-NAME_SCALAR">$i</span>+<span class="highlite-OPERATOR">+</span> <span class="highlite-OPERATOR"><</span> 3;) { <span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR">*</span> 2 }).<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «(2 4 6)» </span><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@a</span> <span class="highlite-OPERATOR">=</span> (<span class="highlite-KEYWORD">loop</span> ( <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$j</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-NAME_SCALAR">$j</span>+<span class="highlite-OPERATOR">+</span> <span class="highlite-OPERATOR"><</span> 3;) { <span class="highlite-NAME_SCALAR">$j</span> <span class="highlite-OPERATOR">*</span> 2 }); <span class="highlite-NAME_ARRAY">@a</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «[2 4 6]» </span><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@b</span> <span class="highlite-OPERATOR">=</span> <span class="highlite-ROUTINE">do</span> <span class="highlite-KEYWORD">loop</span> ( <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$k</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-NAME_SCALAR">$k</span>+<span class="highlite-OPERATOR">+</span> <span class="highlite-OPERATOR"><</span> 3;) { <span class="highlite-NAME_SCALAR">$k</span> <span class="highlite-OPERATOR">*</span> 2 }; <span class="highlite-NAME_ARRAY">@b</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># same thing</span></pre> </div> </div> <p>Unlike a <code>for</code> loop, one should not rely on whether returned values are produced lazily. It would probably be best to use <code>eager</code> to guarantee that a loop whose return value may be used actually runs:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">sub</span> heads-in-a-row { (<span class="highlite-ROUTINE">eager</span> <span class="highlite-KEYWORD">loop</span> (; 2.<span class="highlite-ROUTINE">rand</span> <span class="highlite-OPERATOR"><</span> 1;) { <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">heads</span><span class="highlite-STRING_DELIMITER">"</span>.<span class="highlite-ROUTINE">say</span> }) }</pre> </div> </div> <h1 id="while,_until" class="raku-h1"><a name="index-entry-while_until-while,_until" data-indexedheader="Control flow;while until"></a><a href="#Control_flow" title="go to top of document">while, until<a class="raku-anchor" title="direct link" href="#while,_until">§</a></a></h1> <!-- defnmark while,_until 1 --> <p>The <code>while</code> statement executes the block as long as its condition is true. So</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">while</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR"><</span> 4 { <span class="highlite-ROUTINE">print</span> <span class="highlite-NAME_SCALAR">$x</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-ROUTINE">print</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-ESCAPE">\n</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-COMMENT"># OUTPUT: «123»</span></pre> </div> </div> <p>Similarly, the <code>until</code> statement executes the block as long as the expression is false.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">until</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">></span> 3 { <span class="highlite-ROUTINE">print</span> <span class="highlite-NAME_SCALAR">$x</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-ROUTINE">print</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-ESCAPE">\n</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-COMMENT"># OUTPUT: «123»</span></pre> </div> </div> <p>The condition for <code>while</code> or <code>until</code> can be parenthesized, but there must be a space between the keyword and the opening parenthesis of the condition.</p><p>Both <code>while</code> and <code>until</code> can be used as statement modifiers. E. g.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">=</span> 42; <span class="highlite-NAME_SCALAR">$x--</span> <span class="highlite-KEYWORD">while</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">></span> 12</pre> </div> </div> <p>Also see <code>repeat/while</code> and <code>repeat/until</code> below.</p><p>All these forms may produce a return value the same way <code>loop</code> does.</p> <h1 id="repeat/while,_repeat/until" class="raku-h1"><a name="index-entry-repeat-repeat/while,_repeat/until" data-indexedheader="Control flow;repeat"></a><a href="#Control_flow" title="go to top of document">repeat/while, repeat/until<a class="raku-anchor" title="direct link" href="#repeat/while,_repeat/until">§</a></a></h1> <!-- defnmark repeat/while,_repeat/until 1 --> <p>Executes the block <em>at least once</em> and, if the condition allows, repeats that execution. This differs from <code>while</code>/<code>until</code> in that the condition is evaluated at the end of the loop, even if it appears at the front.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">=</span> -42; <span class="highlite-KEYWORD">repeat</span> { <span class="highlite-NAME_SCALAR">$x</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-KEYWORD">while</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR"><</span> 5; <span class="highlite-NAME_SCALAR">$x</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «5» </span> <span class="highlite-KEYWORD">repeat</span> { <span class="highlite-NAME_SCALAR">$x</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-KEYWORD">while</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR"><</span> 5; <span class="highlite-NAME_SCALAR">$x</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «6» </span> <span class="highlite-KEYWORD">repeat</span> <span class="highlite-KEYWORD">while</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR"><</span> 10 { <span class="highlite-NAME_SCALAR">$x</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-NAME_SCALAR">$x</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «10» </span> <span class="highlite-KEYWORD">repeat</span> <span class="highlite-KEYWORD">while</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR"><</span> 10 { <span class="highlite-NAME_SCALAR">$x</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-NAME_SCALAR">$x</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «11» </span> <span class="highlite-KEYWORD">repeat</span> { <span class="highlite-NAME_SCALAR">$x</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-KEYWORD">until</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">>=</span> 15; <span class="highlite-NAME_SCALAR">$x</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «15» </span> <span class="highlite-KEYWORD">repeat</span> { <span class="highlite-NAME_SCALAR">$x</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-KEYWORD">until</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">>=</span> 15; <span class="highlite-NAME_SCALAR">$x</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «16» </span> <span class="highlite-KEYWORD">repeat</span> <span class="highlite-KEYWORD">until</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">>=</span> 20 { <span class="highlite-NAME_SCALAR">$x</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-NAME_SCALAR">$x</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «20» </span> <span class="highlite-KEYWORD">repeat</span> <span class="highlite-KEYWORD">until</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">>=</span> 20 { <span class="highlite-NAME_SCALAR">$x</span>+<span class="highlite-OPERATOR">+</span>; } <span class="highlite-NAME_SCALAR">$x</span>.<span class="highlite-ROUTINE">say</span>; <span class="highlite-COMMENT"># OUTPUT: «21»</span></pre> </div> </div> <p>All these forms may produce a return value the same way <code>loop</code> does.</p> <h1 id="return" class="raku-h1"><a name="index-entry-return-return" data-indexedheader="Control flow;return"></a><a href="#Control_flow" title="go to top of document">return<a class="raku-anchor" title="direct link" href="#return">§</a></a></h1> <!-- defnmark return 1 --> <p>The sub <code>return</code> will stop execution of a subroutine or method, run all relevant <a href="/language/phasers#Block_phasers">phasers</a> and provide the given return value to the caller. The default return value is <a href="/type/Nil"><code>Nil</code></a>. If a return <a href="/language/signatures#Constraining_return_types">type constraint</a> is provided it will be checked unless the return value is <a href="/type/Nil"><code>Nil</code></a>. If the type check fails the exception <a href="/type/X/TypeCheck/Return"><code>X::TypeCheck::Return</code></a> is thrown. If it passes a control exception is raised and can be caught with <a href="/language/phasers#CONTROL">CONTROL</a>.</p><p>Any <code>return</code> in a block is tied to the first <a href="/type/Routine"><code>Routine</code></a> in the outer lexical scope of that block, no matter how deeply nested. Please note that a <code>return</code> in the root of a package will fail at runtime. A <code>return</code> in a block that is evaluated lazily (e.g. inside <code>map</code>) may find the outer lexical routine gone by the time the block is executed. In almost any case <code>last</code> is the better alternative. Please check <a href="/language/functions#Return_values">the functions documentation</a> for more information on how return values are handled and produced.</p> <h1 id="return-rw" class="raku-h1"><a name="index-entry-return-rw-return-rw" data-indexedheader="Control flow;return-rw"></a><a href="#Control_flow" title="go to top of document">return-rw<a class="raku-anchor" title="direct link" href="#return-rw">§</a></a></h1> <!-- defnmark return-rw 1 --> <p>The sub <code>return</code> will return values, not containers. Those are immutable and will lead to runtime errors when attempted to be mutated.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">sub</span> <span class="highlite-ROUTINE">s</span>(){ <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$a</span> <span class="highlite-OPERATOR">=</span> 41; <span class="highlite-KEYWORD">return</span> <span class="highlite-NAME_SCALAR">$a</span> }; <span class="highlite-ROUTINE">say</span> ++<span class="highlite-ROUTINE">s</span>(); <span class="highlite-KEYWORD">CATCH</span> { <span class="highlite-KEYWORD">default</span> { <span class="highlite-ROUTINE">say</span> .^<span class="highlite-ROUTINE">name</span><span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">: </span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> .<span class="highlite-TYPE">Str</span> } }; <span class="highlite-COMMENT"># OUTPUT: «X::Multi::NoMatch.new(dispatcher …</span></pre> </div> </div> <p>To return a mutable container, use <code>return-rw</code>.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">sub</span> <span class="highlite-ROUTINE">s</span>(){ <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$a</span> <span class="highlite-OPERATOR">=</span> 41; <span class="highlite-KEYWORD">return-rw</span> <span class="highlite-NAME_SCALAR">$a</span> }; <span class="highlite-ROUTINE">say</span> ++<span class="highlite-ROUTINE">s</span>(); <span class="highlite-COMMENT"># OUTPUT: «42»</span></pre> </div> </div> <p>The same rules as for <code>return</code> regarding phasers and control exceptions apply.</p> <h1 id="fail" class="raku-h1"><a name="index-entry-fail-fail" data-indexedheader="Control flow;fail"></a><a href="#Control_flow" title="go to top of document">fail<a class="raku-anchor" title="direct link" href="#fail">§</a></a></h1> <!-- defnmark fail 1 --> <p>Leaves the current routine and returns the provided <a href="/type/Exception"><code>Exception</code></a> or <a href="/type/Str"><code>Str</code></a> wrapped inside a <a href="/type/Failure"><code>Failure</code></a>, after all relevant <a href="/language/phasers#Block_phasers">phasers</a> are executed. If the caller activated fatal exceptions via the pragma <code>use fatal;</code>, the exception is thrown instead of being returned as a <a href="/type/Failure"><code>Failure</code></a>.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">sub</span> <span class="highlite-ROUTINE">f</span> { <span class="highlite-ROUTINE">fail</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">WELP!</span><span class="highlite-STRING_DELIMITER">"</span> }; <span class="highlite-ROUTINE">say</span> <span class="highlite-ROUTINE">f</span>; <span class="highlite-KEYWORD">CATCH</span> { <span class="highlite-KEYWORD">default</span> { <span class="highlite-ROUTINE">say</span> .^<span class="highlite-ROUTINE">name</span><span class="highlite-OPERATOR">,</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">: </span><span class="highlite-STRING_DELIMITER">'</span><span class="highlite-OPERATOR">,</span> .<span class="highlite-TYPE">Str</span> } } <span class="highlite-COMMENT"># OUTPUT: «X::AdHoc: WELP!»</span></pre> </div> </div> <h1 id="once" class="raku-h1"><a name="index-entry-once-once" data-indexedheader="Control flow;once"></a><a href="#Control_flow" title="go to top of document">once<a class="raku-anchor" title="direct link" href="#once">§</a></a></h1> <!-- defnmark once 1 --> <p>A block or statement prefixed with <code>once</code> will be executed exactly once, even if placed inside a loop or a recursive routine.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$guard</span>; <span class="highlite-KEYWORD">loop</span> { once <span class="highlite-NAME_SCALAR">$guard</span> <span class="highlite-OPERATOR">=</span> 3; <span class="highlite-ROUTINE">last</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$guard--</span> <span class="highlite-OPERATOR"><=</span> 0; once { <span class="highlite-ROUTINE">put</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">once</span><span class="highlite-STRING_DELIMITER">'</span> }; <span class="highlite-ROUTINE">print</span> <span class="highlite-STRING_DELIMITER">'</span><span class="highlite-STRING">many</span><span class="highlite-STRING_DELIMITER">'</span> } <span class="highlite-COMMENT"># OUTPUT: «oncemanymanymany»</span></pre> </div> </div> <p>This works per "clone" of the containing code object, so:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">({ once 42.<span class="highlite-ROUTINE">say</span> } <span class="highlite-OPERATOR">xx</span> 3).map: {<span class="highlite-NAME_SCALAR">$_</span>()<span class="highlite-OPERATOR">,</span> <span class="highlite-NAME_SCALAR">$_</span>()}; <span class="highlite-COMMENT"># says 42 thrice</span></pre> </div> </div> <p>Note that this is <strong>not</strong> a thread-safe construct when the same clone of the same block is run by multiple threads. Also remember that methods only have one clone per class, not per object.</p> <h1 id="LABELs" class="raku-h1"><a href="#Control_flow" title="go to top of document">LABELs<a class="raku-anchor" title="direct link" href="#LABELs">§</a></a></h1> <p><code>while</code>, <code>until</code>, <code>loop</code> and <code>for</code> loops can all take a label, which can be used to identify them for <code>next</code>, <code>last</code>, and <code>redo</code>. Nested loops are supported, for instance:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">OUTAHERE: <span class="highlite-KEYWORD">while</span> <span class="highlite-TYPE">True</span> { <span class="highlite-KEYWORD">for</span> 1,2,3 <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$n</span> { <span class="highlite-ROUTINE">last</span> OUTAHERE <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$n</span> <span class="highlite-OPERATOR">==</span> 2; } }</pre> </div> </div> <p>Labels can be used also within nested loops to name each loop, for instance:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights">OUTAHERE: <span class="highlite-KEYWORD">loop</span> ( <span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-TYPE">True</span>; <span class="highlite-NAME_SCALAR">$i</span>+<span class="highlite-OPERATOR">+</span> ) { OUTFOR: <span class="highlite-KEYWORD">for</span> 1,2,3 <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$n</span> { <span class="highlite-COMMENT"># exits the for loop before its natural end </span> <span class="highlite-ROUTINE">last</span> OUTFOR <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$n</span> <span class="highlite-OPERATOR">==</span> 2; } <span class="highlite-COMMENT"># exits the infinite loop </span> <span class="highlite-ROUTINE">last</span> OUTAHERE <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR">>=</span> 2; } </pre> </div> </div> <h1 id="next" class="raku-h1"><a name="index-entry-next-next" data-indexedheader="Control flow;next"></a><a href="#Control_flow" title="go to top of document">next<a class="raku-anchor" title="direct link" href="#next">§</a></a></h1> <!-- defnmark next 1 --> <p>The <code>next</code> command starts the next iteration of the loop. So the code</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@x</span> <span class="highlite-OPERATOR">=</span> 1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> 4<span class="highlite-OPERATOR">,</span> 5; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@x</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$x</span> { <span class="highlite-ROUTINE">next</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">==</span> 3; <span class="highlite-ROUTINE">print</span> <span class="highlite-NAME_SCALAR">$x</span>; } </pre> </div> </div> <p>prints "1245".</p><p>You can also use <code>next</code> in a <code>map</code>: the above example then looks like:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@x</span> <span class="highlite-OPERATOR">=</span> 1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> 4<span class="highlite-OPERATOR">,</span> 5; <span class="highlite-ROUTINE">print</span> <span class="highlite-NAME_ARRAY">@x</span>.map: <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$x</span> { <span class="highlite-ROUTINE">next</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">==</span> 3; <span class="highlite-NAME_SCALAR">$x</span> } </pre> </div> </div> <p>prints "1 2 4 5" because a space is added between entries of a <a href="/type/Seq"><code>Seq</code></a> when it is stringified. Note that that <code>print</code> was not put inside the block of the <code>map</code>, as it generally considered bad practice to run a <code>map</code> for its side-effects (in this case, the <code>print</code>.</p><p>If the <a href="/language/phasers#NEXT"><code>NEXT</code> phaser</a> is present, it runs before the next iteration:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-TYPE">Int</span> <span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-KEYWORD">while</span> (<span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR"><</span> 10) { <span class="highlite-KEYWORD">if</span> (<span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR">%</span> 2 <span class="highlite-OPERATOR">==</span> 0) { <span class="highlite-ROUTINE">next</span>; } <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-NAME_SCALAR">$i</span><span class="highlite-STRING"> is odd.</span><span class="highlite-STRING_DELIMITER">"</span>; <span class="highlite-KEYWORD">NEXT</span> { <span class="highlite-NAME_SCALAR">$i</span>+<span class="highlite-OPERATOR">+</span>; } } <span class="highlite-COMMENT"># OUTPUT: «1 is odd.3 is odd.5 is odd.7 is odd.9 is odd.» </span></pre> </div> </div> <p>In version 6.e.PREVIEW (available as of the 2021.07 Rakudo compiler release), it is also possible to return a value with the <code>next</code> statement. This is particularly useful when using it in a <code>map</code>:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@x</span> <span class="highlite-OPERATOR">=</span> 1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> 4<span class="highlite-OPERATOR">,</span> 5; <span class="highlite-ROUTINE">print</span> <span class="highlite-NAME_ARRAY">@x</span>.map: <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$x</span> { <span class="highlite-ROUTINE">next</span> 42 <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">==</span> 3; <span class="highlite-NAME_SCALAR">$x</span> } </pre> </div> </div> <p>prints "1 2 42 4 5".</p><p>In a <a href="/language/concurrency#whenever">whenever</a> block, <code>next</code> immediately exits the block for the current value:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">react</span> { <span class="highlite-KEYWORD">whenever</span> <span class="highlite-TYPE">Supply</span>.<span class="highlite-ROUTINE">interval</span>(1) { <span class="highlite-ROUTINE">next</span> <span class="highlite-KEYWORD">if</span> .<span class="highlite-ROUTINE">is-prime</span>; <span class="highlite-ROUTINE">say</span> <span class="highlite-NAME_SCALAR">$_</span>; <span class="highlite-ROUTINE">done</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$_</span> <span class="highlite-OPERATOR">==</span> 4; } }</pre> </div> </div> <p>prints "0", "1" and "4" - integers from 0 to 4 with primes skipped.</p><p>*Since version 6.d, the <code>next</code> command in a loop that collects its last statement values returns <code>Empty</code> for the iterations they run on.*</p> <h1 id="last" class="raku-h1"><a name="index-entry-last-last" data-indexedheader="Control flow;last"></a><a href="#Control_flow" title="go to top of document">last<a class="raku-anchor" title="direct link" href="#last">§</a></a></h1> <!-- defnmark last 1 --> <p>The <code>last</code> command immediately exits the loop in question.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@x</span> <span class="highlite-OPERATOR">=</span> 1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> 4<span class="highlite-OPERATOR">,</span> 5; <span class="highlite-KEYWORD">for</span> <span class="highlite-NAME_ARRAY">@x</span> <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$x</span> { <span class="highlite-ROUTINE">last</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">==</span> 3; <span class="highlite-ROUTINE">print</span> <span class="highlite-NAME_SCALAR">$x</span>; } </pre> </div> </div> <p>prints "12".</p><p>You can also use <code>last</code> in a <code>map</code>: the above example then looks like:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@x</span> <span class="highlite-OPERATOR">=</span> 1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> 4<span class="highlite-OPERATOR">,</span> 5; <span class="highlite-ROUTINE">print</span> <span class="highlite-NAME_ARRAY">@x</span>.map: <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$x</span> { <span class="highlite-ROUTINE">last</span> <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">==</span> 3; <span class="highlite-NAME_SCALAR">$x</span> } </pre> </div> </div> <p>prints "1 2" because a space is added between entries of a <a href="/type/Seq"><code>Seq</code></a> when it is stringified. Note that that <code>print</code> was not put inside the block of the <code>map</code>, as it generally considered bad practice to run a <code>map</code> for its side-effects (in this case, the <code>print</code>.</p><p>If the <a href="/language/phasers#LAST"><code>LAST</code> phaser</a> is present, it runs before exiting the loop:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-TYPE">Int</span> <span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR">=</span> 1; <span class="highlite-KEYWORD">while</span> (<span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR"><</span> 10) { <span class="highlite-KEYWORD">if</span> (<span class="highlite-NAME_SCALAR">$i</span> <span class="highlite-OPERATOR">%</span> 5 <span class="highlite-OPERATOR">==</span> 0) { <span class="highlite-ROUTINE">last</span>; } <span class="highlite-KEYWORD">LAST</span> { <span class="highlite-ROUTINE">say</span> <span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">The last number was </span><span class="highlite-NAME_SCALAR">$i</span><span class="highlite-STRING">.</span><span class="highlite-STRING_DELIMITER">"</span>; } <span class="highlite-KEYWORD">NEXT</span> { <span class="highlite-NAME_SCALAR">$i</span>+<span class="highlite-OPERATOR">+</span>; } } <span class="highlite-COMMENT"># OUTPUT: «The last number was 5.» </span></pre> </div> </div> <p>Since version 6.d, the <code>last</code> command in a loop that collects its last statement values returns <code>Empty</code> for the iterations they run on.</p><p>In version 6.e.PREVIEW (available as of the 2021.07 Rakudo compiler release), it is also possible to return a value with the <code>last</code> statement. This is particularly useful when using it in a <code>map</code>:</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">my</span> <span class="highlite-NAME_ARRAY">@x</span> <span class="highlite-OPERATOR">=</span> 1<span class="highlite-OPERATOR">,</span> 2<span class="highlite-OPERATOR">,</span> 3<span class="highlite-OPERATOR">,</span> 4<span class="highlite-OPERATOR">,</span> 5; <span class="highlite-ROUTINE">print</span> <span class="highlite-NAME_ARRAY">@x</span>.map: <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$x</span> { <span class="highlite-ROUTINE">last</span> 42 <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$x</span> <span class="highlite-OPERATOR">==</span> 3; <span class="highlite-NAME_SCALAR">$x</span> } </pre> </div> </div> <p>print "1 2 42".</p> <h1 id="redo" class="raku-h1"><a name="index-entry-redo-redo" data-indexedheader="Control flow;redo"></a><a href="#Control_flow" title="go to top of document">redo<a class="raku-anchor" title="direct link" href="#redo">§</a></a></h1> <!-- defnmark redo 1 --> <p>The <code>redo</code> command restarts the loop block without evaluating the conditional again.</p> <div class="raku-code raku-lang"> <button class="copy-code" title="Copy code"><i class="far fa-clipboard"></i></button> <label>Raku highlighting</label> <div> <pre class="nohighlights"><span class="highlite-KEYWORD">for</span> 1..5 <span class="highlite-KEYWORD">-></span> <span class="highlite-NAME_SCALAR">$current-level</span> { <span class="highlite-KEYWORD">state</span> <span class="highlite-NAME_SCALAR">$total-attempts</span> <span class="highlite-OPERATOR">=</span> 0; <span class="highlite-NAME_SCALAR">$total-attempts</span>+<span class="highlite-OPERATOR">+</span>; <span class="highlite-ROUTINE">print</span>(<span class="highlite-STRING_DELIMITER">"</span><span class="highlite-STRING">Entering #</span><span class="highlite-NAME_SCALAR">$current-level</span><span class="highlite-STRING">. </span><span class="highlite-STRING_DELIMITER">"</span>); <span class="highlite-KEYWORD">if</span> <span class="highlite-NAME_SCALAR">$total-attempts</span> <span class="highlite-OPERATOR">%%</span> 3 { <span class="highlite-ROUTINE">redo</span>; } } <span class="highlite-COMMENT"># OUTPUT: «Entering #1... Entering #2... Entering #3... Entering #3... Entering #4... Entering #5... Entering #5... » </span></pre> </div> </div> </div></div></section> <section class="page-footnotes"> <div class="container"> <div id="_Footnotes" class="footnotes"> <div class="footnote" id="fn1"><span class="footnote-number">1</span><a class="footnote-linkback" href="#fnret1"> [↑] </a>There are other ways to modify their default behavior; they are discussed in other sections.</div> </div> </div> </section> </div> </div> </div> <footer class="footer main-footer"> <div class="container px-4"> <nav class="level"> <div class="level-left"> <div class="level-item"> <a href="/about">About</a> </div> <div class="level-item"> <a id="toggle-theme">Toggle theme</a> </div> <div class="level-item" title="8e397fdce 2024-12-26"> <a>Commit</a> </div> </div> <div class="level-right"> <div class="level-item"> <a href="/license">License</a> </div> </div> </nav> </div> </footer> </body> </html>