examples/ репозитория и запускаются через CLI:
dotnet run --project src/RealV.Cli/RealV.Cli.fsproj -- examples/<файл>.rv
Управление и операторы
1. Тернарный оператор
В RealV нет громоздкого if/then/else. Его заменяет компактный тернарный оператор ?:, который напрямую разворачивается в AST-узел If.
{
x = 10
result = (x > 5) ? 100 : 200
return result
}
let x = 10
let result =
if x > 5 then 100 else 200
Функции и рекурсия
2. Факториал и рекурсия
Классическая рекурсия поддерживается из коробки — любая объявленная функция видит саму себя внутри тела без дополнительных ключевых слов.
factorial(n) = {
n == 0 ? return 1 : return n * factorial(n - 1)
}
factorial(5) // 120
let rec factorial n =
if n = 0 then 1
else n * factorial (n - 1)
factorial 5
3. Цикл через диапазоны (ArrowLoop)
Конструкция start -> end -> (i) => body реализует итерационный цикл. Тело — лямбда, что сохраняет функциональный стиль без потери читаемости.
factorial(n) = {
result = 1
1 -> n -> (i) => result = result * i
return result
}
factorial(6) // 720
let factorial n =
let mutable result = 1
for i in 1..n do
result <- result * i
result
4. Лямбда-функции и замыкания
Функции первого класса: можно создавать анонимные функции и возвращать их как значения. Они запомнят своё лексическое окружение.
makeAdder(x) = {
return (y) => x + y
}
{
add5 = makeAdder(5)
return add5(10) // 15
}
let makeAdder x =
fun y -> x + y
let add5 = makeAdder 5
add5 10 // 15
Структуры данных
5. Массивы и списки
Массивы объявляются через [...]. Встроенное окружение предоставляет методы для их обработки в Lisp-стиле (голова / хвост) и функционального преобразования. Идентификаторы могут быть на кириллице — RealV поддерживает Unicode в именах переменных.
{
lst = [1, 2, 3]
lst = append(lst, 4) // [1, 2, 3, 4]
первый = head(lst) // 1
хвост = tail(lst) // [2, 3, 4]
return (первый == 1) ? true : false
}
let lst = [1; 2; 3]
let lst2 = lst @ [4]
let fst = List.head lst2
let tail = List.tail lst2
6. Ленивые вычисления (Delay / Force)
delay замораживает выражение в Thunk, не вычисляя его. force раскрывает thunk и кэширует результат — повторный вызов мгновенен.
{
t = delay(100 / 0) // не упадёт — выражение заморожено
lazyTask = delay(40 + 2)
val1 = force(lazyTask) // вычисляется (42)
val2 = force(lazyTask) // из кэша (42)
return val1
}
let t = lazy(100 / 0)
let lazyTask = lazy(40 + 2)
let val1 = lazyTask.Force()
let val2 = lazyTask.Force() // из кэша
Системные возможности
7. Выброс исключений (Raise)
Оператор ! прерывает выполнение с пользовательской ошибкой. Формально превращается в AST-узел Raise.
{
ошибка = "Что-то пошло не так"
! ошибка
// LangError("Что-то пошло не так")
}
let ошибка = "Что-то пошло не так"
failwith ошибка
8. Файловый ввод-вывод
Встроенные функции readFile, writeFile, appendFile позволяют работать с файловой системой напрямую из кода на RealV.
{
path = "output.txt"
writeFile(path, "Строка 1\n")
appendFile(path, "Строка 2\n")
text = readFile(path)
return text
}
let path = "output.txt"
File.WriteAllText(path, "Строка 1\n")
File.AppendAllText(path, "Строка 2\n")
let text = File.ReadAllText(path)
Сводная таблица конструкций
| Конструкция | RealV | F# |
|---|---|---|
| Объявление / мутация | имя = ... | let мут = / мут <- |
| Объявление функции | f(x) = { ... } | let f x = ... |
| Условие | cond ? a : b | if ... then ... else ... |
| Лямбда | (x) => x * 2 | fun x -> x * 2 |
| Массивы | [1, 2, 3] | [1; 2; 3] |
| Цикл | 1 -> 5 -> (i) => ... | for i in 1..5 do ... |
| Ленивые вычисления | delay(...) / force(...) | lazy(...) / .Force() |
| Генерация ошибки | ! "Ошибка" | failwith "Ошибка" |
| Блок инструкций | { инстр1; инстр2 } | отступы (indentation) |