RealV
RealV

RealV — функциональный язык с читаемым синтаксисом на основе фигурных скобок, вдохновлённым C и JavaScript. Под капотом он использует AST на основе лямбда-исчисления, поддерживает рекурсию, замыкания, ленивые вычисления и встроенный файловый I/O. Файлы программ имеют расширение .rv.

1. Структура программы

Программа на RealV состоит из инструкций. Основная структурная единица — блок { ... }. Выражения внутри блока разделяются переносом строки. Блок возвращает значение последнего вычисленного выражения или то, что передано через return.

{
  x = 10
  y = 20
  return x + y
}

2. Комментарии

RealV поддерживает однострочные комментарии, начинающиеся с //:

// Это комментарий
x = 5 // переменная x равна 5

3. Базовые типы и литералы

ТипФормат / ЛитералПример
Целые числачисла без точки0, 42, -7
Логическийtrue, falsetrue
Строкитекст в двойных кавычках"Привет!"
Массивыквадратные скобки [...][1, 2, 3]

4. Переменные и присваивание

Конструкция имя = выражение используется и для объявления, и для изменения значения. При первом появлении имени в блоке это объявление, при последующих — мутация.

{
  x = 10      // объявление
  x = x + 5   // присваивание нового значения
  return x     // вернёт 15
}

5. Объявление функций и рекурсия

Функции объявляются по шаблону имя(аргумент) = тело. Все функции унарны (принимают один аргумент). Тело может быть выражением или блоком { ... }. Рекурсия поддерживается неявно — функция «видит» себя внутри своего тела.

factorial(n) = {
  n == 0 ? return 1 : return n * factorial(n - 1)
}

factorial(5) // 120

Вызов функции использует круглые скобки: factorial(5) или factorial (5).

Все функции принимают один аргумент. Для нескольких аргументов используется каррирование — вложенные лямбды: add(x) = (y) => x + y. Вызов: add(3)(4)7.

6. Лямбда-функции и замыкания

Анонимные функции создаются стрелочным синтаксисом =>:

(x) => выражение
(x) => { ... }

Лямбды запоминают лексическое окружение (замыкания):

makeAdder(x) = {
  return (y) => x + y
}

add5 = makeAdder(5)
add5(10) // 15

7. Условные выражения

Роль if/else выполняет тернарный оператор:

условие ? выражение_если_true : выражение_если_false
x = 10
result = (x > 5) ? 100 : 200 // 100

Ветви могут содержать любые выражения, в том числе блоки { ... }.

8. Обработка ошибок

Оператор ! останавливает программу с ошибкой времени выполнения, передавая вычисленное значение как полезную нагрузку:

! "Что-то пошло не так"
! 404
Оператор ! часто используется внутри тернарного оператора для валидации аргументов функции перед вычислением.

9. Массивы и встроенные операции

Массив объявляется через перечисление элементов в [...]. Доступен широкий набор встроенных функций:

lst = [1, 2, 3, 4, 5]

// Получение свойств
len  = length(lst)       // 5
fst  = head(lst)         // 1
rst  = tail(lst)         // [2, 3, 4, 5]
el   = get(lst, 0)       // 1

// Создание новых списков
lst  = append(lst, 6)    // [1, 2, 3, 4, 5, 6]
lst  = remove(lst, 2)    // удаляет элемент с индексом 2
part = slice(lst, 1, 3)  // срез от 1 до 3

// Проверки
ok = contains(lst, 10)   // false

10. Цикл и диапазоны

RealV реализует цикл с неявным счётчиком через конструкцию ArrowLoop:

старт -> конец -> (индекс) => тело_цикла

Диапазон включает обе границы: 1 -> 5 итерирует i = 1, 2, 3, 4, 5. Каждое тело — лямбда, что сохраняет функциональный стиль:

factorial(n) = {
  result = 1
  1 -> n -> (i) => result = result * i
  return result
}

11. Ленивые вычисления

RealV поддерживает отложенные вычисления через delay (создание thunk'а) и force (форсированное вычисление). Результат мемоизируется — повторный вызов force возвращает кэшированное значение.

t = delay(!123)         // не упадёт — ошибка заморожена (t намеренно не форсируется)

lazyTask = delay(40 + 2)
val1 = force(lazyTask)  // вычисляется (42)
val2 = force(lazyTask)  // берётся из кэша (42)
Вызов force() на уже вычисленном значении просто возвращает его без повторных вычислений.

12. Файловый ввод-вывод

RealV имеет встроенные функции для работы с файловой системой:

path = "output.txt"

writeFile(path, "Начало логирования\n")   // запись с заменой
appendFile(path, "Новая запись\n")        // дозапись в конец

content = readFile(path)                  // чтение всего файла

13. Запуск программ

Программы RealV имеют расширение .rv. Запуск через .NET CLI из корня репозитория:

Требуется установленный .NET 8 SDK. Проверить: dotnet --version должна вернуть 8.x или выше.
dotnet run --project src/RealV.Cli/RealV.Cli.fsproj -- путь/к/скрипту.rv

Пример запуска файла из директории examples/:

dotnet run --project src/RealV.Cli/RealV.Cli.fsproj -- examples/factorial.rv