Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

Blocks

We can embed a sequence of statements inside "try", called a "block". Defined variables are only visible within that block, not outside:

Using the "def" keyword is optional because we are inside a script:

But variables without "def" are visible outside the block:

We can't define a variable (using "def") with the same name as another already visible (ie, another "in scope"):

We can nest blocks:

Closures

We can take a sequence of statements that refers to its external context and assign it to a variable, then execute it later. It's technically called a "closable block", commonly called a "closure":

The closure assigned to the variable (here, c) will remember its context (here, including a) even if that context is not in scope when the closure is called:

A closure always returns a value, the result of its last statement:

By putting a closure within another, we can create two instances of it:

Closure Parameters

We can put parameters at the beginning of a closure definition, and pass values in when we call the closure:

We can also pass information out using the parameters:

One parameter is always available, called "it", if no explicit parameters are named:

If parameters aren't specified, "it" will still be implicitly defined, but be null:

Parameters can't have the same name as another variable in scope, except for the implicit parameter 'it':

If there's already a variable called 'it' in scope, we can access it using owner.it:

We can pass one closure into another as a parameter:

We can return a closure from another:

There's a shortcut syntax when explicitly defining a closure within another closure call, where that closure is the last or only parameter:

Arguments in a closure call can be named. They are interpreted as the keys in a map passed in as the first parameter:

We can enquire the number of parameters for a closure, both from inside and outside the closure:

A closure may have its last parameter/s assigned default value/s:

A closure can take a varying number of arguments by prefixing its last parameter with Object[], and accessing them using 'each':

We can also prefix the last parameter of a closure with Closure[] to pass in a varying number of other closures, even using the shortcut syntax:

When we call a closure with a list argument, if there's no closure defined with a list parameter, the arguments are passed in as separate parameters:

A closure may be copied with its first parameter/s fixed to a constant value/s, using curry:

In closures, we can use currying and parameter-count-varying together:

We can make closures recursive:

Functions

A function is similar to a closure, though a function can't access defined variables in its surrounding context:

The def keyword is compulsory when defining functions:

We use a special syntax to assign a function to another variable when using the original definition name:

Unlike blocks and closures, we can't nest functions:

Function Parameters

A function can have parameters, with which we can pass information both in and out:

We can have more than one function of the same name if they each have different numbers of (untyped) parameters.

A function returns a value, unless prefixed by void instead of def, when it always returns null:

When there's a method and closure with the same name and parameters, the method is chosen instead of the closure:

Some Similarities with Closures

We can use the shortcut invocation syntax for closure parameters:

A function may have its last parameter/s assigned default value/s:

Arguments in a function call can be named, interpreted as keys in a map passed in as first parameter:

A function can take a varying number of arguments by prefixing its last argument by Object[], and accessing them using each:

When we call a function with a list argument, if there's none defined with a list parameter, the arguments are passed in separately:

We can call a function recursively by referencing its own name:

  • No labels