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