Block type literals
Block literals are a form of type literal. Use a block literal to reference a specific block type. The block literal specifies the kinds of arguments that the block takes and the type of the return value.
Block types BNF notation
The formal BNF notation of a block literal is:
blockliteral -> block_literal_1 | block_literal_2
block_literal_1 -> block ( type_list ) : type
block_literal_2 -> parameter_name ( type_list ) : return_type
type_list -> type | type_list , | nullBlock types in declarations
To declare a variable to contain a block, the preferred syntax is:
var variableName( list_of_argument_types ) : return_typeFor example, to
declare that strBlock
is a variable that can contain a block that takes a single String argument and returns a
String value, use this
code:
var strBlock( String ) : StringIn declarations, you can also
optionally use the block
keyword, although this is discouraged in declarations:
var variableName : block( list_of_types ) : return_typeFor example, this code declares the same block type as described earlier:
var x : block( String ) : StringUsage of block types not in declarations
For a block type literal that is not part
of a declaration, the block
keyword is strictly required:
block( list_of_types ) : return_typeFor example:
return b as block( String ) : intThe b variable is assigned a value
that is a block type. Because the block type literal is not directly
part of the declaration, Gosu requires the block keyword.
Block types in argument lists
A function definition can specify a function argument as a block. As you define the block argument, provide a name for that block parameter so that you can use the block within the function. Use the following syntax for block types in argument lists:
parameter_variable_name( list_of_types ) : return_typeFor example, suppose
you want to declare a function that takes one argument, which is a block.
Suppose the block takes a single String
argument and returns no value. To refer to this block by name as myCallback, define the argument
using the syntax:
myCallBack( String ) : voidExample of a block type in an argument list
The following Gosu class includes a function
that takes a callback block. The argument is called myCallBack, which is a block that
takes a single string argument and returns no value. The outer function
calls that callback function with a String
argument.
package mytest
class test1 {
function myMethod( myCallBack( String ) : void ) {
// Call your callback block and pass it a String argument
myCallBack("Hello World")
}
}
After creating the class, you can test the following code in the Gosu Scratchpad:
var a = new mytest.test1()
a.myMethod( \ s : String -> print("<contents>" + s + "</contents>") )
For more concise code, you can omit the argument type
“: String” in the
in-line block. The block is defined in-line as an argument to a method
whose argument types are already defined. In other words, you can use
the following code:
var a = new mytest.test1()
a.myMethod( \ s -> print("<contents>" + s + "</contents>") )
Both versions print the following:
<contents>Hello World</contents>Usage of block types for recursion
Gosu blocks support recursion, in which the block calls itself until reaching an end condition. To use recursion in blocks, you must name and define the block signature before you define the block code. For example, the following code defines a block that returns the factorial of an integer:
var bFactorial: block(int): int
bFactorial = \ x -> x > 12 or x < 1 ? -1 : (x == 1 ? 1 : x * bFactorial(x-1))
This code has two end conditions. The first end condition
ensures that the block terminates if the result would be greater than
Integer.MAX_VALUE or if
the parameter value is less than 1. The second end condition terminates
the recursion when the argument value is 1. To test this block, use code
like the following:
print(bFactorial(6))This code prints:
720