ksi

Язык программирования

Пример hello world

@main .do ( 'Hello' write_line@std{} )

Результат:

Hello

Комментарии

-- В начале файла желательно -- прокомментировать его назначение @main -- Главный модуль /* Пространство модуля */ .do ( -- Локальное пространво -- Раздел .do не обязателен для каждого модуля ) /* Продолжение пространства модуля -- Комментарии не выполняются системой /* Они для облегчения понимания */ */

Пространство модуля

@shop fruit := 'Apple' -- Константа price = 5 -- Переменная

Раздел .do

@main dice = range@std(1 6) .do ( .local ( result = dice random@std{} ) result write_line@std{} )

Возможный результат:

5

Виды значений

Конструкторы видов - это команды, которые создают новые типы данных. Типы и функции в ksi являются значениями ячейки.

Команды:
.fn
.struct
.enum

Функция

@main squared := .fn (x) .seq ( ret = x * x ) .do ( -- Обычный вызов функции: squared(3) write_line@std{} -- Цепной вызов функции: 5 squared{} write_line@std{} )

Результат:

9 25

squared ~ константа, хранящая указатель на функцию

x ~ параметр функции

.seq ~ список действий (sequence)

ret ~ ячейка результата

Подробнее о функциях

Структура данных

@sample coords := .struct (x y) origin = coords(0 0) .do ( point = coords(3 4) point distance{} write_line@std{} ) distance := .fn (from, to = origin) .seq ( ret = (to.x - from.x) ^ 2 ret += (to.y - from.y) ^ 2 ret = root@std(ret, 2) )

Результат:

5

Команда .struct

Встраивание структур, перегрузка функций

@main coords = .struct ( x y ) square = .struct ( .insert ( coords ) width ) -- x y width rectangle = .struct ( .insert ( square ) height ) -- x y width height scale[square] = .fn (ret, factor) .seq ( ret.width *= factor ) scale[rectangle] = .fn (ret, factor) .seq ( -- scale only width property first: ret->square scale{factor} -- scale the height too: ret.height *= factor ) .do ( .local ( shape = rectangle(0 0, 10 20) ) shape scale{0.5} shape area{} write_line@std{} -- 50 -- Площадь фигуры, если бы это был квадрат: shape->square area{} write_line@std{} -- 25 ) area[square] = .fn (shape) .seq ( ret = shape.width ^ 2 ) area[rectangle] = .fn (shape) .seq ( ret = shape.width * shape.height )

Результат:

50 25

В языке ksi нет наследования структур.

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

Оператор стрелка -> служит для создания срезов объекта. Справа от этого оператора указывается встроенный тип - составляющая структура, по которой делается срез объекта.

Функция scale() является функцией‑модификатором. Она возвращает свой первый параметр с именем ret

Функция area() вычисляет площадь фигуры, и она перегружена для типов square и rectangle.

Упрощённо говоря перегрузка функции - это переменная, хранящая ассоциативный массив $map, где ключом служит тип первого параметра функции, а значением - сама функция конкретной перегрузки.

Перечисление

@sample align_type := .enum ( left center right ) .do ( node_align = align_type.left write_line@std(node_align.name) -- Печать элементов перечисления align_type elements@std .each it ( it write_line@std{ key_separator: ': ' separator: "\n" } write_line@std() ) ) @std /* enum_element := .struct ( index name ) */

Результат:

left index: 0 name: left index: 1 name: center index: 2 name: right

Команда .enum

Циклы

Цикл .each для массива

@main numbers = [3 2 1] -- array .do ( numbers reverse@std{} .each item ( item write_line@std{} ) )

Результат:

1 2 3

reverse@std ~ Генератор выдачи новой последовательности.

reverse_it@std ~ Функция, которая меняет исходную последовательность.

Цикл .each для диапазона

@main range = range@std(1 3) .do ( .local (row cell) -- Таблица умножения чисел от 1 до 3 range .for .each row ( range .for .each cell ( .seq (" ", row * cell) write@std{} ) write_line@std() ) )

Результат:

1 2 3 2 4 6 3 6 9

У команды .for есть параметр шага.

.for(step: 0.5)

.leave_scope ~ Выход из цикла

.leave_scope[depth: 2]

Top