Ключевое слово F/fn



F <имя функции>(<аргументы>) [-> <тип возвращаемого значения>]
   <тело функции>

<имя функции>

Имя функции. Может быть пустым в случае если это конструктор (когда функция определяется внутри определения типа, пример: {}) или когда это безымянная функция модуля, например
os:(command_string)
(см. документацию модуля os).

<аргументы>

Список аргументов, разделённых запятой или точкой с запятой. Может быть пустым.
Каждый аргумент определяется как:
[<тип аргумента>] [<квалификатор>]<имя аргумента> [= <значение по умолчанию>]

Все передаваемые в функцию аргументы по умолчанию константны и не могут модифицироваться внутри функции, но это можно изменить посредством квалификаторов.
Квалификаторы


Именованные аргументы


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

print(sqlen(z' 3)) // эквивалентно print(sqlen(0, 0, 3))


"Только-именованные" аргументы


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

to_html(s, 0B, 1B) // ошибка
to_html(s, 0B, habr_html' 1B) // правильно
to_html(s, habr_html' 1B) // так тоже правильно


Сокращение совпадающих именованных аргументов


Такой вызов:
my_function(
  my_first_variable' my_first_variable,
  my_second_variable' my_second_variable
)
можно сократить до:
my_function(
  ' my_first_variable,
  ' my_second_variable
)
[Идея навеяна этим тредом.]


Ключевые подслова F/fn



F.destructor
/
fn.destructor
используется для объявления деструктора:
T TypeName
   F.destructor
      print(‘TypeName destructor called’)

Подслова
virtual.new
,
virtual.override
,
virtual.final
,
virtual.abstract
и
virtual.assign
означают, что эта функция виртуальная, и они задают "тип виртуальности" этой функции.
virtual.new
обозначает, что это новая виртуальная функция (наличие виртуальной функции с этим же именем в базовом типе является ошибкой компиляции).
virtual.override
используется для указания того, что данная функция переопределяет виртуальную функцию из базового типа (отсутствие виртуальной функции с этим же именем в базовом типе является ошибкой компиляции).
virtual.final
указывает, что виртуальная функция не может быть переопределена в производном типе.
Подслово
virtual.abstract
предоставляет возможность создавать функции типов, которые должны быть реализованы в производном типе (при этом реализация должна быть помечена
virtual.assign
).
Небольшой пример:
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
предназначено для обеспечения доступа к аргументам, переданным в текущую функцию, но на данный момент оно не реализовано.

F.result
/
fn.result
— это специальная переменная, которая служит в качестве неявной переменной возврата.
Почему `fn.result`?