Note: information on this page refers to Ceylon 1.1, not to the current release.
Function and method declarations
A function accepts arguments and returns a value.
When a function is a member of a type is it called a method.
Usage
A trivial function declaration using a block looks like this:
void trivialBlock() {
/* method block: statements */
}
Alternatively it's possible to declare a function using
fat arrow, =>
, like this:
void trivialSpecifier() => anotherMethod();
The general form of a function declaration looks like either of these:
ANNOTATIONS
TYPE exampleBlock
<TYPE-PARAMETERS>
PARAMETER-LISTS
given TYPE-PARAMETER-CONSTRAINTS {
FUNCTION-BODY
}
// or
ANNOTATIONS
TYPE exampleSpecifier
<TYPE-PARAMETERS>
PARAMETER-LISTS
given TYPE-PARAMETER-CONSTRAINTS
=> EXPRESSION;
Where:
-
ANNOTATIONS
is a list of function annotations -
TYPE
is a type expression for the reference returned from the function when it is invoked (orvoid
). -
TYPE-PARAMETERS
is a,
-separated list of type parameters -
PARAMETER-LISTS
is one or more,
-separated list of value parameters, each list enclosed in parenthesis -
TYPE-PARAMETER-CONSTRAINTS
is a list of constraints on type parameters declared in the type parameter list -
FUNCTION-BODY
is block of statements -
EXPRESSION
is specified result of the function
Description
Method receiver
Method invocations have a 'receiver', an instance of the type that declares
the method. Within the method body, the expression
this
refers to this receiving instance.
A top level function does not have a receiver.
Return type
A non-local function declaration always specifies the return type of the function,
or the keyword void
if the function has no specific return value.
The type system considers a void
function identical to a function declared
to return Anything
.
In particular, a void
method may be refined by a subtype to return a more
specific type. The value actually returned from an unrefined void
function
is always null
:
class Top() {
shared default void m() {}
}
class Sub() extends Top() {
shared actual Boolean m() => true
}
void example() {
Anything topM = Top().m(); // topM is null
Boolean subM = Sub().m();
}
Type inference
Local function declarations often don't need to explictly declare a type,
but can instead use type inference via the function
keyword.
class C() {
function f() => 0; //inferred type Integer
}
If the local function doesn't return a value void
is used instead of function
.
Type parameters
A function declaration may have a list of type parameters
enclosed in angle brackets (<
and >
) after the function name.
void generic<Foo, Bar>(){
/* method block: statements
type parameter Foo and Bar are treated as a type */
}
Of course, methods may be members of types which themselves have type parameters:
class Generic<Foo>() {
void method(Foo z) {
}
}
A function declaration with type parameters may have a given
clause
for each declared type parameter to
constrain the argument types.
Parameter list
A function declaration must have one or more parameter lists.
Most commonly just one parameter list is required, but higher order functions can use two or more:
String url(String host)(String path) => "http://``host````path``";
String(String) ceylonUrl = url("ceylon-lang.org");
String ceylonBlog = ceylonUrl("/blog);
Function blocks
The body of a function may be composed of statements in a brace-delimited block.
The body of a non-void
function must definitely return a value
using the return statement. The
following code will be rejected by the compiler:
String fun(Boolean bool) {
if (bool) {
return "hello";
}
// error: missing return
}
Similarly a void
function must only use the form of return
which lacks
an expression.
Function specifiers
A block with a return statement is unnecessarily verbose for a function that
just evaluates a single expression and returns its result.
In this case, we prefer to use the fat arrow
(=>
) syntax:
Integer addTen(Integer i) => i+10;
Note that you can use this to partially apply a function (or any Callable
):
function zeroTo(Integer n) => Range(0, n);
Callable type
The callable type of a function expresses, in terms of the
Callable
interface, is the
function's return type and parameter types. For example, the callable type
of:
String stringExample(Integer i, Boolean b) => "";
is String(Integer, Boolean)
, and the callable type of:
void voidExample() {}
is Anything()
.
Exceptions
Ceylon doesn't have checked exceptions, so it's never necessary to declare what exceptions a method can throw.
The throws
annotation may be used to document
thrown exceptions.
Different kinds of method
formal
and default
methods
A method declaration may be annotated formal
or default
. A formal or default method must
also be annotated shared
.
A formal method does not specify an implementation. A formal method must be refined by concrete classes which inherit the containing class or interface.
A default
method may be refined by types which inherit the containing
class or interface.
shared
functions
A toplevel function declaration, or a function declaration nested inside the
body of a containing class or interface, may be annotated
shared
.
- A toplevel
shared
function is visible wherever the package that contains it is visible. - A
shared
function nested inside a class or interface is visible wherever the containing class or interface is visible.
Metamodel
Function declarations can be manipulated at runtime via their representation as
FunctionDeclaration
instances. An applied function (i.e. with all type parameters specified) corresponds to
either a
Function
or
Method
model instance.
See also
- Method invocation
- Compilation unit
class
declarationinterface
declarationobject
declaration- Functions in the Ceylon language spec