Project

General

Profile

Actions

Function object in Scol

To call a function, we write the function name followed by parameters, if any.

fun <function_name_1> ( <args> )=
    instructions
;;

fun <function_name_2> ( <args> )=
    instructions;
    <function_name_1> <parameters>;
    instructions
;;

However, we can use a function as an object. A such object could be useful for a subsequent operation. This is common with the reflex (callbacks) : call a function when an event occurs. You can need these objects in other cases. The function object can be passed as an argument what is important for us.

To create it, add a "@" before the name of function : <function_name_1>

Here is a very basic example (adpated from the Scol tutoriel by Sylvain huet) :
Three ways to add two numbers.

The classic way :

a function is called from another function.

fun add (x, y)=
    x+y;;

fun main ()=
    _showconsole;
    _fooId add 1 2;    // displays 3 in the console
    0;;

Using exec ... with [...] :

We create a function object. We call it with exec.
exec <function_object> with [<arguments>]

fun add (x, y)=
    x+y;;    // displays 3 in the console

fun main ()=
    _showconsole;
    _fooId exec @add with [1 2];    // object created by a @ before the function name
    0;;

exec <function_name> with <tuple> apply to an object some arguments and return the result. Note that the arguments are passed in a tuple. exec returns the same type than the <function_name>.

exec @add with [1 2]; : calculate the function in the object @add with two arguments in the tuple [1 2]

Passing an object in parameter :

fun add (x, y)=
    x+y;;    // displays 3 in the console

fun fooadd (x, y, objFun)=
    exec objFun with [x y];;

fun main ()=
    _showconsole;
    _fooId fooadd 1 2 @add;    // call fooadd with an function object @add as parameter
    0;;

Of course, in these different manners, you must keep a typing correct.

A fourth way !

There is a fourth answer : create a node from a function from another function and an argument.
In fact, we "add" an argument to a subsequent use. A function with N-1 argument "becomes" a function with N arguments. This is commonly used in the callbacks.
To use this, we have mkfunN functions (N : 2 -> 8)

Here, we get again the previous and very basic example.

fun add (x, y)=
    x+y;;    // displays 3 in the console

fun fooadd (x)=
    let mkfun2 @add 1 -> foofun in // we fix the second argument to 1
    exec foofun with [x];;

fun main ()=
    _showconsole;
    _fooId fooadd 2;;

Now, another example using callback with this last way.
We create a window object and when the user closes it a message is displayed in the console and a value is returned.
The function called when the user closes a window has two arguments. In this example, we want three arguments, we use thus mkfun3.

/* mkfun_parameter is the third argument added when the callback has been defined */
fun endWin (objwin, user_parameter, mkfun_parameter)=
    _fooS mkfun_parameter;
    user_parameter;;

fun crWin ()=
    // create a simple window
    let _CRwindow _channel nil 0 0 250 50 WN_NORMAL "function objects" -> window in
    let "THE END" -> string in
    /* define a callback when the user closes the window creating a function object.
    This callback takes two arguments normally (the object window and an user parameter).
    With mkfun3, we "add" a third argument */
    _CBwinDestroy window mkfun3 @endWin string 0;
    0;;

fun main ()=
    _showconsole;
    crWin;;

Of course, this example is simply. We get the same result passing a tuple as our user_parameter ...

License : CC-BY-SA-2.0
Tutorial by iri
Updated by /

Updated by iri over 11 years ago · 4 revisions