Разделы сайта находятся в разработке.
Материалы могут быть неполными или содержать ошибки. Содержимое сайта будет синхронизировано с реализацией при выходе следующей версии, тогда как текущая (0.6.0) предназначена для прототипирования синтаксиса и создания песочницы.
Условия и циклы
В TrustLang нет ключевого слова if: условие проверяется конструкцией, которая по смыслу соответствует
математическому «следует» — два тире и угловая скобка -->. Запись легко объединяется в цепочки для
проверки нескольких условий вида «else if». Ниже конструкция показана обеими формами — DSL-макросом
и базовым синтаксисом (о двух формах записи см. Макросы и DSL):
| Макросы DSL | Базовый синтаксис |
|---|---|
| |
Для записи циклов используется оператор <-> (в базовой записи) или макросы @while/@dowhile
(в DSL). Условие записывается в квадратных скобках; в зависимости от взаимного расположения условия и
тела цикл бывает с предусловием (while) или с постусловием (do while). Эквивалентные формы:
| Макросы DSL | Базовый синтаксис |
|---|---|
| |
| |
| |
Цикл с предусловием (while) поддерживает ветку else, которая выполняется, если условие входа в цикл
не было выполнено ни разу.
Внимание: это отличается от аналогичной конструкции в Python, где секция
elseвыполняется всегда, кроме прерывания цикла поbreak.
Перебор коллекций (foreach)
У цикла foreach нет отдельного ключа DSL — он реализуется циклом с деструктуризацией элемента и
мутацией источника (оператор раскрытия списка). Пример суммирования элементов словаря:
summa := 0;
dict := (1,2,3,4,5,);
[ dict ] <-> { # условие цикла — пока в dict есть данные
# распаковка: первый элемент переходит в item, суффикс dict... — оставшиеся
item, dict... := ... dict;
summa += item; # накопление суммы
};
Сопоставление с образцом (match)
Оператор оценки выражения (match) — приблизительный аналог операторов switch/match в других
языках. Он задаётся конструкцией [ выражение ] ==> { ... } (базовый синтаксис) или макросом @match
(DSL), в теле которых перечисляются ветки-условия. Эквивалентные формы:
| Макросы DSL | Базовый синтаксис |
|---|---|
| |
Хотя оператор внешне похож на сопоставление с образцом (pattern matching), по сути это краткая запись множественного оператора сравнения: в качестве оператора оценки можно использовать любой оператор сравнения:
==>— равенство с приведением типов;===>— точное равенство;~>— проверка типа (имени класса);~~>— утиная типизация;~~~>— строгая утиная типизация.
Если в качестве оператора сравнения используется утиная типизация, оценка превращается в классическое
сопоставление с образцом по полям (пример приведён на форме @match):
$value := (f1=1, f2='2',);
@match( $value ) ~~> {
@case((f1=_,), (f1=_, f2=0,)) { ... }; # поле f2 отсутствует или является числом
@case((f1=_, f2="",), (f1=_, f2='',)) { ... }; # поле f2 — строка
@default { ... };
};
Переопределение функции сравнения (атрибут @[matcher("fn")])
Если сравнение по значению не сводится к == (например, сопоставление строки с регулярным выражением),
функцию сравнения match можно переопределить атрибутом @[matcher("fn")], где fn — объявленная
ранее функция-предикат с сигнатурой bool fn(T_value, T_pattern). В каждой ветке вместо сравнения
(value == pattern) вызывается предикат fn(value, pattern); проверяемое выражение (scrutinee)
вычисляется один раз во временную переменную. При заданном матчере ветки всегда порождаются как
if/else-цепочка (оператор switch неприменим — шаблон не обязан быть константой).
Атрибут ставится между значением и оператором (на «сырой» форме, так как макрос @match требует оператор
сразу после себя):
@func matches_regex(value:StrChar, pattern:StrChar):Bool { ... };
$s := 'foobar';
[ $s ] @[matcher("matches_regex")@] ==> {
@case('^foo') { ... };
@case('bar$', 'baz') { ... };
@default { ... };
};
Семантика проверяет, что fn — объявленная функция-предикат ровно с двумя параметрами и логическим
(булевским) возвратом. Атрибут @[matcher] несовместим с сопоставлением по типу (~>/~~>/~~~>).