2015-01-01 21:04:14 -08:00
<!DOCTYPE html>
< html >
< head >
< meta http-equiv = "Content-type" content = "text/html;charset=UTF-8" / >
< title > Functions – Wren< / title >
< 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" >
< h1 > < a href = "index.html" > wren< / a > < / h1 >
< h2 > a classy little scripting language< / h2 >
< / div >
< / div >
< / header >
< div class = "page" >
< nav >
< ul >
< li > < a href = "getting-started.html" > Getting Started< / a > < / li >
< / ul >
< section >
< h2 > language< / h2 >
< ul >
< li > < a href = "syntax.html" > Syntax< / a > < / li >
2015-01-03 23:27:54 -08:00
< li > < a href = "expressions.html" > Expressions< / a > < / li >
2015-01-01 21:04:14 -08:00
< li > < a href = "variables.html" > Variables< / a > < / li >
2015-01-03 23:27:54 -08:00
< li > < a href = "control-flow.html" > Control Flow< / a > < / li >
2015-01-01 21:04:14 -08:00
< li > < a href = "error-handling.html" > Error Handling< / a > < / li >
< / ul >
< / section >
< section >
< h2 > types< / h2 >
< ul >
< li > < a href = "values.html" > Values< / a > < / li >
< li > < a href = "classes.html" > Classes< / a > < / li >
< li > < a href = "fibers.html" > Fibers< / a > < / li >
< li > < a href = "functions.html" > Functions< / a > < / li >
< li > < a href = "lists.html" > Lists< / a > < / li >
< li > < a href = "maps.html" > Maps< / a > < / li >
< / ul >
< / section >
< section >
< h2 > reference< / h2 >
< ul >
< li > < a href = "core-library.html" > Core Library< / a > < / li >
< li > < a href = "embedding-api.html" > Embedding API< / a > < / li >
< li > < a href = "performance.html" > Performance< / a > < / li >
< li > < a href = "contributing.html" > Contributing< / a > < / li >
< li > < a href = "qa.html" > Q & A< / a > < / li >
< / ul >
< / section >
< / nav >
< main >
< h1 > Functions< / h1 >
2015-01-03 23:27:54 -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 >
< h2 > Block arguments < a href = "#block-arguments" name = "block-arguments" class = "header-anchor" > #< / a > < / h2 >
< p > Most of the time you create a function just to pass it to some method. For
example, if you want to filter a < a href = "lists.html" > list< / a > by some criteria, you'll
call its < code > where< / code > method, passing in a function that defines the predicate
you're filtering on.< / p >
< p > Since that's the most common usage pattern, Wren's syntax optimizes for that.
Taking a page from Ruby, a function is created by passing a < em > block argument< / em > to
a method. At its simplest, it looks like this:< / p >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "n" > blondie< / span > < span class = "p" > .< / span > < span class = "n" > callMe< / span > < span class = "p" > {< / span >
< span class = "n" > IO< / span > < span class = "p" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s2" > " This is the body!" < / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
< / pre > < / div >
2015-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "kd" > class< / span > < span class = "nc" > Blondie< / span > < span class = "p" > {< / span >
< span class = "n" > callMe< / span > < span class = "p" > (< / span > < span class = "n" > fn< / span > < span class = "p" > )< / span > < span class = "p" > {< / span >
< span class = "c1" > // Call it...< / span >
< span class = "p" > }< / span >
< span class = "p" > }< / span >
< / pre > < / div >
2015-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "n" > blondie< / span > < span class = "p" > .< / span > < span class = "n" > callMeAt< / span > < span class = "p" > (< / span > < span class = "m" > 867< / span > < span class = "p" > ,< / span > < span class = "m" > 5309< / span > < span class = "p" > )< / span > < span class = "p" > {< / span >
< span class = "n" > IO< / span > < span class = "p" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s2" > " This is the body!" < / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
< / pre > < / div >
2015-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "kd" > var< / span > < span class = "n" > someFn< / span > < span class = "o" > =< / span > < span class = "c1" > // Get a function...< / span >
< span class = "n" > blondie< / span > < span class = "p" > .< / span > < span class = "n" > callMe< / span > < span class = "p" > (< / span > < span class = "n" > someFn< / span > < span class = "p" > )< / span >
< / pre > < / div >
2015-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "kd" > var< / span > < span class = "n" > someFn< / span > < span class = "o" > =< / span > < span class = "k" > new< / span > < span class = "n" > Fn< / span > < span class = "p" > {< / span >
< span class = "n" > IO< / span > < span class = "p" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s2" > " Hi!" < / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
< / pre > < / div >
2015-01-03 23:27:54 -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-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "kd" > class< / span > < span class = "nc" > Blondie< / span > < span class = "p" > {< / span >
< span class = "n" > callMe< / span > < span class = "p" > (< / span > < span class = "n" > fn< / span > < span class = "p" > )< / span > < span class = "p" > {< / span >
< span class = "n" > fn< / span > < span class = "p" > .< / span > < span class = "n" > call< / span >
< span class = "p" > }< / span >
< span class = "p" > }< / span >
< / pre > < / div >
2015-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "kd" > class< / span > < span class = "nc" > FakeFn< / span > < span class = "p" > {< / span >
< span class = "n" > call< / span > < span class = "p" > {< / span >
< span class = "n" > IO< / span > < span class = "p" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s2" > " I' m feeling functional!" < / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
< span class = "p" > }< / span >
< span class = "n" > blondie< / span > < span class = "p" > .< / span > < span class = "n" > callMe< / span > < span class = "p" > (< / span > < span class = "k" > new< / span > < span class = "n" > FakeFn< / span > < span class = "p" > )< / span >
< / pre > < / div >
< h2 > Function parameters < a href = "#function-parameters" name = "function-parameters" class = "header-anchor" > #< / a > < / h2 >
2015-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "n" > blondie< / span > < span class = "p" > .< / span > < span class = "n" > callMe< / span > < span class = "p" > {< / span > < span class = "o" > |< / span > < span class = "n" > first< / span > < span class = "p" > ,< / span > < span class = "n" > last< / span > < span class = "o" > |< / span >
< span class = "n" > IO< / span > < span class = "p" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "s2" > " Hi, " < / span > < span class = "o" > +< / span > < span class = "n" > first< / span > < span class = "o" > +< / span > < span class = "s2" > " " < / span > < span class = "o" > +< / span > < span class = "n" > last< / span > < span class = "o" > +< / span > < span class = "s2" > " !" < / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
< / pre > < / div >
2015-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "kd" > class< / span > < span class = "nc" > Blondie< / span > < span class = "p" > {< / span >
< span class = "n" > callMe< / span > < span class = "p" > (< / span > < span class = "n" > fn< / span > < span class = "p" > )< / span > < span class = "p" > {< / span >
< span class = "n" > fn< / span > < span class = "p" > .< / span > < span class = "n" > call< / span > < span class = "p" > (< / span > < span class = "s2" > " Debbie" < / span > < span class = "p" > ,< / span > < span class = "s2" > " Harry" < / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
< span class = "p" > }< / span >
< / pre > < / div >
2015-01-03 23:27:54 -08:00
< p > It's an error to call a function with fewer or more arguments than its
parameter list expects.< / 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-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "k" > new< / span > < span class = "n" > Fn< / span > < span class = "p" > {< / span > < span class = "s2" > " return value" < / span > < span class = "p" > }< / span >
< span class = "k" > new< / span > < span class = "n" > Fn< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "s2" > " return value" < / span >
< span class = "p" > }< / span >
< / pre > < / div >
< h2 > Closures < a href = "#closures" name = "closures" class = "header-anchor" > #< / a > < / h2 >
2015-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "kd" > class< / span > < span class = "nc" > Counter< / span > < span class = "p" > {< / span >
< span class = "kd" > static< / span > < span class = "n" > create< / span > < span class = "p" > {< / span >
< span class = "kd" > var< / span > < span class = "n" > i< / span > < span class = "o" > =< / span > < span class = "m" > 0< / span >
< span class = "k" > return< / span > < span class = "k" > new< / span > < span class = "n" > Fn< / span > < span class = "p" > {< / span > < span class = "n" > i< / span > < span class = "o" > =< / span > < span class = "n" > i< / span > < span class = "o" > +< / span > < span class = "m" > 1< / span > < span class = "p" > }< / span >
< span class = "p" > }< / span >
< span class = "p" > }< / span >
< / pre > < / div >
2015-01-03 23:27:54 -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 >
2015-01-01 21:04:14 -08:00
< div class = "codehilite" > < pre > < span class = "kd" > var< / span > < span class = "n" > counter< / span > < span class = "o" > =< / span > < span class = "n" > Counter< / span > < span class = "p" > .< / span > < span class = "n" > create< / span >
< span class = "n" > IO< / span > < span class = "p" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "n" > counter< / span > < span class = "p" > .< / span > < span class = "n" > call< / span > < span class = "p" > )< / span > < span class = "c1" > // Prints " 1" .< / span >
< span class = "n" > IO< / span > < span class = "p" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "n" > counter< / span > < span class = "p" > .< / span > < span class = "n" > call< / span > < span class = "p" > )< / span > < span class = "c1" > // Prints " 2" .< / span >
< span class = "n" > IO< / span > < span class = "p" > .< / span > < span class = "n" > print< / span > < span class = "p" > (< / span > < span class = "n" > counter< / span > < span class = "p" > .< / span > < span class = "n" > call< / span > < span class = "p" > )< / span > < span class = "c1" > // Prints " 3" .< / span >
< / pre > < / div >
< / main >
< / div >
< footer >
< div class = "page" >
< div class = "main-column" >
< p > Wren lives < a href = "https://github.com/munificent/wren" > on GitHub< / a > — Made with ❤ by < a href = "http://journal.stuffwithstuff.com/" > Bob Nystrom< / a > .< / p >
< div class = "main-column" >
< / div >
< / footer >
< / body >
< / html >