This project has moved. For the latest updates, please go here.
Function is a one of type of object that can be called by '(' and ')' paired operator.

Define

Function can be defined using following syntax:
    function identifier(argument-list) {
        statements
    }

where argument-list is
    identifier[, identifier]*

See Language Specification.

For example:
    function hello() {
        console.log('hello world!');
    }

Call

Syntax to call a defined function:
    hello()

Arguments

To pass arguments into function, the syntax of definition is:
    function show(a, b) {
        console.log(a + b);
    }

Then call this function with arguments:
    show(10, 5);

The result is:
    15

Function Overload

Like JavaScript, function overload is not supported by ReoScript too. However, it's possible to simulate the same effect by using argument array, it also work in JavaScript. See Variable Number of Arguments below.

Variable Number of Arguments

ReoScript finds and calls a function by specified function name, even given arguments does not matched to that function. For example:
    function plus(a, b, c) {
        return a + b + c;
    }

Call this function:
    var z = plus(1, 2, 3);        // 'z' is 6

This function can also be called with different number of arguments:
    var z = plus(1, 2);           // calling is OK, but 'z' is NaN since 'c' is null

Arguments that not specified in calling statement will be set to null automatically. The `a b c` will returns `NaN` because `c` is null(+ operation does not work with numbers and null). To solve this issue, you could:

1. Check whether or not the arguments are specified
2. Use `args` system variable

For example:
    function plus(a, b, c) {
        return c == null ? (a + b) : (a + b + c);
    }

Or you could use an argument array `args`, it is an array contains all of variables:
    function plus(a, b, c) {
        return __args__.length == 3 ? (a + b + c) : (a + b);
    }

Another example that joins all of arguments into one string using `args`.
    function join() {
        var output = '';
        for (str in __args__) {
            if (output.length > 0) output += '-';
            output += str;
        }
        return output;
    }

Use this function:
    var result = join('The', 'Earth', 'and', 'Sun');

The result is:
    The-Earth-and-Sun

> `args` is called `arguments` in JavaScript.

Access Scope

Available to inner scope

Since function is also an object which be stored as variable or property to another object. The variable scope rule to call functions is same as Variables references. All functions defined in outer scope can be called in inner scope. Functions can also defined in local call-scope. For example:
    function outer() {
    }

`outer` is global object(defined as property to global object) is available to all of call-scopes:
    function fun_b() {
      outer();              // OK
    }

Nested Function

It is possible to define a function inside another function, for example:
    function outer() {
        function inner() {
        }
    }

Actually it is same as:
    function outer() {
        var inner = function() {
        };
    }

Inner function can only be called inside inner scope:
    function outer() {
        var inner = function() {
        };

        inner();               // OK
    }

    inner();                   // error: Function is not defined: 'inner' 

Notice that `inner` is not a property of `outer`:
    outer.inner();             // error

Since `outer.inner` is null so you will get an error `function outer() {...} has no method 'inner'`.
There is no way to call an inner function from outside scope, the inner function is only available to the scope where contains itself.

Recursive

You could call a function in itself to implement recursive calling:
    function findMore(path) {
        if (path.hasMore()) {
             return find_more(path.getMore());
        }
    }

Anonymous Function

A function defined without a specified name is an anonymous function. For example:
    var hello = function() { };

Anonymous function must be defined, assigned to a variable or property, or called immediately.
    var hello = function() { };       // OK
    function() { };                   // error: is not a valid expression-statement, it needs left-hand
    function() { } ();                // OK: call an anonymous function immediately

Lambda Expression is a simplified syntax to declare anonymous function.
    var plus = (a, b) => a + b;

See Lambda Expression.

Method to object

Anonymous function defined as property to an object can be used like method to an object. For example:
    var obj = new Object();

    obj.hello = function() { 
         console.log('hello world');
    };

After calling this method, the `hello world` will be printed out in console.
    obj.hello();

Method is also a function and a variable so you could pass the function to another object:
    var obj2 = new Object();
    obj2.sayHello = obj.hello;

Then call this method:
    obj2.sayHello();

The `hello world` will be printed out in console.

this keyword

The this keyword used in function (also global scope) always points to the owner object of the function. For example:
    var obj = new Object();
    obj.name = 'guest';         // set property 'name' to 'guest'
    obj.whoami = function() {
        console.log("I am " + this.name);
    };

Then call this method:
    obj.whoami();

The output is:
    I am guest

Self-Executing Anonymous Function

Self-Executing Anonymous Function allows to define an anonymous function and call it immediately. For example:
    function() { 
        var a = 10, b = 20;
        console.log('c = ' + (a + b));
    } ();

The code runs in self-executing anonymous function will force the variables to be defined in inner function scope, the variables will do not effect the variables defined in outer function scope.

Function wrapper object

There is a function named Function existed in global object. The Function is the wrapper object to all of functions.
    function Function() {
    }

All of functions are the instance of Function:
    function fun1() { }
    var fun2 = function() { };

    debug.assert(fun1 instanceof Function);     // true
    debug.assert(fun2 instanceof Function);     // true

Method added into prototype of `Function` are available to all the functions:
    Function.prototype.do = function() {
        this();
    };

    var fun1 = function() {
        console.log('hello world');
    };

    fun1.do();

The output is:
    hello world

call method

call method used to call a function and change its this by specified object. For example:
    function whoami() {
        console.log('I am ' + this.name);    // use 'this' keyword to get name property from owner object
    }

    // we have two objects
    var obj1 = {name: 'Alfred', whoami: whoami};
    var obj2 = {name: 'Ken'};
    var obj3 = {name: 'Ryu'};

Call this function by following attempts:
    obj1.whoami();          // 'I am Alfred'    (normal method)
    whoami.call(obj2);      // 'I am Ken'       (set owner by call method)
    whoami.call(obj3);      // 'I am Ryu'       (set owner by call method)

call method supports to pass arguments:
    whoami.call(obj2, arg1, arg2, ..., argn);

apply method

apply method is same as call method, only the arguments will be passed by an array:
    func.apply(owner, [arg1, arg2, ..., argn]);

Last edited Dec 17, 2014 at 1:42 AM by unvell, version 4