Call a function: Difference between revisions
Content added Content deleted
(adding a contribution with lambdatalk) |
(Added Wren) |
||
Line 5,306: | Line 5,306: | ||
# function. |
# function. |
||
(+ 3) 7 -- print;</lang> |
(+ 3) 7 -- print;</lang> |
||
=={{header|Wren}}== |
|||
Wren distinguishes between functions and methods. |
|||
The former are first-class standalone objects which cannot be overloaded whereas the latter are always members of a class and can be overloaded by ''arity'' (i.e. the number of arguments they require). As Wren is dynamically typed and doesn't support type annotations, methods cannot be overloaded by parameter type. Methods can either be instance or static members of their class. |
|||
As well as 'ordinary' methods which always have a (possibly empty) parameter list, Wren also has the following types of methods: |
|||
1. 'constructors' which always have a parameter list and are really a pair of methods - a static method which creates a new instance of the class and then invokes an initializer on that instance. |
|||
2. 'getters' which leave off the parameter list. |
|||
3. 'setters' which have '=' after the name followed by a parameter list with just a single parameter. |
|||
4. 'operators' which, if they're infix operators, always have a parameter list with a single parameter. However, if they're prefix operators, they have no parameter list. |
|||
Wren does not support optional arguments, a variable number of arguments or named arguments though these can be respectively simulated by overloading, passing lists or passing maps. |
|||
Arguments are always passed by value though, if they're mutable reference types, it's the reference which gets copied so the function or method can mutate the object itself. |
|||
There are no built-in functions but all built-in classes have methods. Unless you know what they are, there is no way to distinguish between them and methods of user-defined classes. |
|||
The only way to distinguish between sub-routines and functions it to check whether they return a concrete value. The former always return null by default. |
|||
Partial function application is not supported ''per se'' but can be simulated as in the task of that name. |
|||
Here are some examples: |
|||
<lang ecmascript>var f1 = Fn.new { System.print("Function 'f1' with no arguments called.") } |
|||
var f2 = Fn.new { |a, b| |
|||
System.print("Function 'f2' with 2 arguments called and passed %(a) & %(b).") |
|||
} |
|||
var f3 = Fn.new { 42 } // function which returns a concrete value |
|||
f1.call() // statement context |
|||
f2.call(2, 3) // ditto |
|||
var v1 = 8 + f3.call() // calling function within an expression |
|||
var v2 = f3.call() // obtaining return value |
|||
System.print([v1, v2]) // print last two results as a list |
|||
class MyClass { |
|||
static m() { System.print("Static method 'm' called.") } |
|||
construct new(x) { _x = x } // stores 'x' in a field |
|||
x { _x } // gets the field |
|||
x=(y) { _x = y } // sets the field to 'y' |
|||
- { MyClass.new(-_x) } // prefix operator |
|||
+(o) { MyClass.new(_x + o.x) } // infix operator |
|||
toString { _x.toString } // instance method |
|||
} |
|||
MyClass.m() // call static method 'm' |
|||
var mc1 = MyClass.new(40) // construct 'mc1' |
|||
var mc2 = MyClass.new(8) // construct 'mc2' |
|||
System.print(mc1.x) // print mc1's field using getter |
|||
mc1.x = 42 // change mc1's field using setter |
|||
System.print(-mc1.x) // invoke prefix operator - |
|||
System.print(mc1 + mc2) // invoke infix operator +</lang> |
|||
{{out}} |
|||
<pre> |
|||
Function 'f1' with no arguments called. |
|||
Function 'f2' with 2 arguments called and passed 2 & 3. |
|||
[50, 42] |
|||
Static method 'm' called. |
|||
40 |
|||
-42 |
|||
50 |
|||
</pre> |
|||
=={{header|XLISP}}== |
=={{header|XLISP}}== |