Словари и наборы (перечисления)
Словарь
Словарь (:Dictionary) — набор данных произвольного типа с доступом к отдельным элементам по целочисленному индексу или по имени элемента при его наличии (это похоже и на tuple и на структуру одновременно).
Словари отличаются от тензоров тем, что всегда имеют только одно измерение, но каждый элемент может содержать произвольное количество элементов любого типа, в том числе и другие словари.
Доступ к элементам словаря происходит по имени элемента, которое записывается через точку от имени переменной, либо по целочисленному индексу. Индекс начинается с 0 и как у тензоров, тоже может быть отрицательным (индекс элемента от “конца”).
Литерал с типом «словарь» в тексте программы записывается в круглых скобках с обязательной завершающей запятой, т. е. (,) — пустой словарь, (1, 2= «2», name=3,). Для указания конкретного типа объекта у литерала, его необходимо указать после закрывающей скобки, т.е. (1, two= «2», name=3,):Dict.
Позиционный литерал без указания типа, например (1, 2, 3,), всегда является словарём (:Dictionary). Словарь — единственный универсальный тип, который может быть приведён к любому другому типу: для создания значения конкретного типа достаточно передать словарь аргументом в приведение/конструктор типа, например :Tensor[...]( (1,2,3,) ).
⚠️ НЕ РЕАЛИЗОВАНО: данный способ создания типа-словаря через `:Dict := :Dictionary() (...)` и обращения `:Dict()`/`:Dict(two=42)` в текущей версии НЕ работает. Реализован литерал `(1, two=2, name='3',)` → trust::Dict с доступом d.name / d[0] / d[i], оператором `[]=`, методом size() (см. playground/dict.src)
# Новый тип (класс) :NewClass
:Dict := :Dictionary() {
_ := 1; # У поля данных имя отсутствует
two := 2;
name := 3;
};
dict := :Dict(); # Экземпляр класса (1, two=2, name=3,):Dict
Позиционный литерал без указания типа, например `(1, 2, 3,)`, всегда является словарём (`:Dictionary`). Словарь — единственный универсальный тип, который может быть приведён к любому другому типу: для создания значения конкретного типа достаточно передать словарь аргументом в приведение/конструктор типа, например `:Tensor[...]( (1,2,3,) )`.
dict2 := :Dict(two=42); # Экземпляр класса (1, two=42, name=100,):Dict
dict3 := dict2(99, name=0); # Копия объекта dict2 (99, two=42, name=0,):Dict
В будущем можно будет добавить возможность указывать индексы элементов словаря с помощь диапазонов
$dict = :Dict[10](first=1, 4..4 = 29, 2..3 = 15, , 2..3 = 15, 7..9..2 = 7); #(first=1, 0, 15, 15, 29, 0, 0, 7, 0, 7,)
Перечисление (Enum)
Enum — тип данных с ограниченным списком членов, у каждого из которых есть имя и значение. Все члены перечисления имеют единый тип значений (valueType), который выводится по общим правилам (из значений членов либо из явной аннотации типа).
Литерал-объявление записывается в постфиксной форме (члены,):Enum или префиксной
:Enum(члены) (как у типизированного кортежа). Обязательная завершающая запятая — как у словаря.
# Члены с явными значениями; тип значений — Int64 (по общим правилам)
Status ::= (OK=0, ERROR=1, BUSY=2,):Enum;
# Безнарные члены — автоинкремент от 0: RED=0, GREEN=1, BLUE=2
Color ::= (RED, GREEN, BLUE,):Enum;
# Явный тип члена задаёт единый тип значений — Int8 (безнарные → автоинкремент)
Flag ::= (LOW:Int8, HIGH,):Enum;
⚠️ НЕ РЕАЛИЗОВАНО: оператор `::=` здесь используется корректно (объявление типа Enum); проверено компилятором. Однако доступ к членам через `Status.OK` и методы `count()`/`fromName()`/`fromValue()` в текущей версии реализованы не полностью (например `Status.count()` даёт ошибку 'type Enum has no method count')
По умолчанию тип значений выводится из явных значений членов (resolvedType + join по общим
правилам); если явных значений нет — минимальный знаковый целый по числу членов. Явная
аннотация типа члена (name:Type) задаёт тип значений принудительно (у всех членов он должен
быть одинаковым). Сравнение членов идёт по значению (value), а не по позиции (IntEnum-семантика).
Классические методы (работают через имя типа):
count()— число членов;fromName(name)— член по имени;fromValue(value)— член по значению.
Обращение к члену — через имя типа: Status.OK.
Вариант (Variant)
Variant — гетерогенный тип: каждый член имеет свой тип данных (аналог std::variant).
Тип члена задаётся явной аннотацией (name:Type) либо выводится из его значения; для
безнарного члена без типа — минимальный знаковый целый по позиции.
Data ::= (i=42, s='text', r=1\2,):Variant; # типы членов: Int8, StrChar, Rational
V ::= (X:Int64=7, Y:Rational,):Variant; # явные типы членов
⚠️ НЕ РЕАЛИЗОВАНО: оператор `::=` здесь используется корректно (объявление типа Variant); проверено компилятором
Классический метод: count() — число членов. Обращение к члену: Data.i (тип — тип
конкретного члена, гетерогенный).