F/fn keyword



F <name>(<arguments>) [-> <return_type>]
   <body>

<name>

Name of the function. Can be empty if it is a constructor (when function defined inside type definition, example: {}) or this is a module nameless function, e.g.
os:(command_string)
(see module os documentation).

<arguments>

Comma- or semicolon-separated list of function arguments. Can be empty.
Each argument is defined as:
[<argument type>] [<qualifier>]<argument name> [= <default value>]

By default all arguments passed to a function are constant and can not be changed inside a function, but this behaviour can be altered via qualifiers.
Qualifiers

<return_type>

Void
can be used as a return type name to denote that function does not return anything.


Named arguments


F sqlen(x = 0, y = 0, z = 0)
   R x*x + y*y + z*z

print(sqlen(z' 3)) // equivalent to print(sqlen(0, 0, 3))


Named-only [or keyword-only] arguments


F to_html(instr, ohd = 0B, ', habr_html = 0B)
   ...

to_html(s, 0B, 1B) // this is wrong
to_html(s, 0B, habr_html' 1B) // this is correct
to_html(s, habr_html' 1B) // and this is correct


Matching named arguments elision


This call:
my_function(
  my_first_variable' my_first_variable,
  my_second_variable' my_second_variable
)
can be shortened to:
my_function(
  ' my_first_variable,
  ' my_second_variable
)
[Inspired by this thread.]


F/fn subkeywords



F.destructor
/
fn.destructor
is used to define a destructor:
T TypeName
   F.destructor
      print(‘TypeName destructor called’)

Subkeywords
virtual.new
,
virtual.override
,
virtual.final
,
virtual.abstract
and
virtual.assign
indicate that this functions is virtual and they specify a "type of virtuality" of this function.
virtual.new
means that this is a new virtual function.
virtual.override
ensures that the function is virtual and is overriding a virtual function from a base type. The program is ill-formed (a compile-time error is generated) if this is not true.
virtual.final
specifies that a virtual function cannot be overridden in a derived type.
virtual.abstract
subkeyword enables you to create type functions that are incomplete and must be implemented in a derived type (this implementation should be marked with
virtual.assign
).
Small example:
T Shape
   F.virtual.abstract square() -> Float

T Circle(Shape)
   Float radious
   F.virtual.assign square() -> Float
      R math:pi * .radious^2

F.args
/
fn.args
is intended to provide access to the arguments passed to the current function, but it is not implemented yet.

F.result
/
fn.result
is a special variable that serves as an implicit return variable.
Why `fn.result`?