Словари и наборы (перечисления)

Словарь

Словарь (:Dictionary) — набор данных произвольного типа с доступом к отдельным элементам по целочисленному индексу или по имени элемента при его наличии (это похоже и на tuple и на структуру одновременно).

Словари отличаются от тензоров тем, что всегда имеют только одно измерение, но каждый элемент может содержать произвольное количество элементов любого типа, в том числе и другие словари.

Доступ к элементам словаря происходит по имени элемента, которое записывается через точку от имени переменной, либо по целочисленному индексу. Индекс начинается с 0 и как у тензоров, тоже может быть отрицательным (индекс элемента от “конца”).

Литерал с типом «словарь» в тексте программы записывается в круглых скобках с обязательной завершающей запятой, т. е. (,) — пустой словарь, (1, 2= «2», name=3,). Для указания конкретного типа объекта у литерала, его необходимо указать после закрывающей скобки, т.е. (1, two= «2», name=3,):Dict.

# Новый тип (класс) :NewClass
:Dict := :Dictionary() {
    _ := 1; # У поля данных имя отсутствует
    two := 2;
    name := 3; 
};
dict := :Dict(); # Экземпляр класса (1, two=2, name=3,):Dict
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,)

Набор (перечисление)

Набор или перечисление (:Set) — тип данных, в котором множество возможных значений представляет собой ограниченный список идентификаторов. Тип данных каждого индентификатора может быть указан индивидуально или для всех идентификаторов сразу.

Литерал с типом «Набор/перечисление» в тексте программы записывается в угловых скобках с обязательной завершающей запятой, т. е. <,> — пустой набор, перечисление из трех элементов: <SET, CUR, END , >.

По умолчанию типы идентификаторов рассматриваются как целое число, значения которых начинаются с 0 и увеличиваются на единицу в соответствии с их порядком. В этом случае набор (перечисление) становится аналогичен типу enum. Но в отличии от последнего, набор (перечисление) может содержать данные разных типов и тогда он становится аналогичен типу std::optional.

    # Use set as optional result
    func(): < :Error, :Int32, :String, > ::= {
        ...
    };

Указать конкретный тип сразу для всех элементов перечисления, можно для имени переменной (типа) или сразу после закрывающей угловой скобки, т.е. :seek :Int32 ::= <SET=0, CUR, END,> или :seek ::= <SET=0, CUR=1, END=2,> :Int32.

Обращение к элементам перечислениия, например для сравнения, выполняется как к идентификатору в области имен, т.е. seek::SET, seek::CUR или seek::END, которым он по сути и является.

Данная особеность позволяет расширять перечисления даже после его определения, но для этого набор (перечисление) нужно создавать изменяемым (мутабельным), т.е. seek ^ ::= <SET=0, CUR=1, END=2,>:Int32;

    # Check enum at compile
    seek^ ::= <SET=0, CUR=1, END=2,>:Int32;

    # Add new value after definition
    seek::OTHER ::= -1;

Набор (перечисление) типов данных (классов)

Без завершающей заяатой указывается перечисление типов (классов). Можно указать сразу несколько типов, перечислив их в угловых скобрах через знак +. Если в угловых скобках перед именем типа будет стоять знак минус -, это означает, что данные тип исключен из списка разрешенных, например <:Arithmetic - :Rational - :Complex> означает любые числа, кроме рациональьных и комплексных.