tech

[English] [Japanese]

10. Functions

This time, I will explain the function of LuneScript.

Function definition

LuneScript functions are defined like this:

// @lnsFront: ok
fn add_sub( val1:int, val2:int ): int, int {
   return val1 + val2, val1 - val2;
}
print( add_sub( 1, 2 ) ); // 3, -1

The example above defines the following functions:

definition
function name add_sub
First argument name val1
First argument type int
Second argument name val2
Second argument type int
primary return type int
Secondary return type int

LuneScript can return multiple return values.

Return value

Function return values use the return statement.

Functions can return multiple values.

See below for multi-value return values.

../multipleretval

Functions that do not return

Some functions do not return.

For example:

// @lnsFront: error
fn func(): __ {
   while true {
   }
}
func();
print( 1 ); // error

In this example, func() is an infinite loop. Therefore, func() will not return processing.

To make this explicit, the return type of func() is __. __ indicates that the function does not return.

This will tell us that the print() statement following func() is not processed and will result in an error.

Note that functions with a return type of __ must not return.

For example, if you break as follows, the loop will be exited, so the process will return from func(). An error will occur in such cases.

// @lnsFront: error
fn func(val:int): __ {
   while true {
      if val == 1 {
         break;
      }
   }
}

variable length arguments, return value

Variable length arguments and return values are available.

See the following article for details.

../arg

definition location

Functions can be defined anywhere a statement can be written. Specifically, you can define it inside a block like this:

// @lnsFront: ok
fn sub():int {
   let mut val = 0;
   {
      {
         fn func(): int {
            return 1;
         }
         val = val + func();
      }
      fn func(): int {
         return 2;
      }
      val = val + func();
   }
   fn func(): int {
      return 3;
   }
   return val + func();
}
print( sub() ); // 6

Functions with the same name can be defined in different scopes.

public function

Functions, like variables, can be exposed externally using pub.

// @lnsFront: ok
pub fn func(): int {
   return 1;
}

Specifying pub makes the function accessible from the outside.

global is also available.

// @lnsFront: ok
global fn func(): int {
   return 1;
}

Global declarations of functions have the same restrictions as global declarations of variables.

"A function declared global becomes effective when the module that declares it is imported."

Exposing functions externally has the following restrictions:

"Functions exposed to the outside world must be declared at the topmost scope of the script"

form type

LuneScript can treat function objects as values. You can use form as a special function object type.

Here's an example of using form:

// @lnsFront: ok
fn test() {
   print( "hoge" );
}
fn sub( func:form ) {
  func();
}
sub( test ); // hoge

This example has the following configuration:

  • Define a function test
  • The function sub has an argument of type form
  • Execute sub with test as argument

This will run test inside sub and print hoge .

In addition, the form type is treated as the following functions.

// @lnsFront: skip
fn func(...):... {}

A function type that can be assigned to a form type

As above, form is synonymous with fn func(...):... {}.

Also, ... represents zero or more stem!.

This means that functions with arguments of type stem! are assignable to type form , and functions with arguments of non-stem! are unassignable.

If it can be assigned, the next call to func2( nil ) will call func( nil ), resulting in incorrect behavior.

// @lnsFront: error
fn func( val:int ) {
   print( val + 1 );
}
let func2:form = func;
func2( nil );

Here are examples of substitutable and non-substitutable cases.

// @lnsFront: error
let form1:form = fn ( val1:stem! ) { };
let form2:form = fn ( val1:stem ) { };  // error
let form3:form = fn ( val1:stem!, val2:stem! ) { };
let form4:form = fn ( val1:stem!, val2:stem ) { }; // error

The above form1 and form3 are assignable, but form2 and form4 are not assignable.

form declaration

As mentioned above, only some types of functions can be handled by form.

To handle functions that cannot be handled by form, declare form as follows.

// @lnsFront: ok
form funcform( val:int ):int;
fn sub( func:funcform ) {
   print( func( 1 ) + 1 );
}
sub( fn ( val:int ):int { return val + 1; } ); // 3

This example declares funcform as a form .

The form declaration makes funcform a function type with an int type val as an argument and an int type return value.

anonymous function

An anonymous function defines a function without a name.

Here is an example of an anonymous function:

// @lnsFront: ok
fn sub( func:form ) {
  func( 1 );
}
sub( fn ( val:stem! ) { print( val ); } );  // 1

This example defines the anonymous function fn ( val:int ) { print( val ); }.

By passing this anonymous function to the argument of sub(), the anonymous function will be executed in sub().

An anonymous function declaration is an expression.

function call

Attaching () to a function object causes that function to be executed.

The types of function formal and actual arguments must match. Note that omitted actual arguments are treated as nil. It is an error if the dummy argument corresponding to the omitted actual argument is not nilable.

Omitting Arguments

Please check the following article about omitting arguments.

../defaultarg

Function limits

LuneScript functions cannot be overloaded with different arguments.

summary

Summarizing the functions in LuneScript,

  • Declare with fn
  • can have multiple return values
  • Can have variable length arguments and return values
  • Publish functions to external modules with pub, global
  • Function object type uses form type and form declaration
  • have anonymous functions
  • Omitted actual argument contains nil
  • no function overloads

Next time, I will explain nilable.