Быстрый старт
Эта страница доведёт вас от скачанного zip-архива до работающей программы на
Nova за несколько минут, а затем до чуть более крупного примера, показывающего
две вещи, которые отличают Nova: эффекты в сигнатурах функций и
структурированную конкурентность без async/await.
Nova — компилируемый язык: nova build превращает .nv-файл в C, а затем в
нативный бинарник через системный C-компилятор. Интерпретатора нет (nova run
намеренно не поддерживается) — nova build и nova test это две команды,
которыми вы будете пользоваться.
Установка (Windows x64)
-
Скачайте
nova-v0.1.0-windows-x64.zipсо страницы GitHub Releases и распакуйте куда угодно, например вC:\nova. -
В сессии PowerShell, из папки, куда вы распаковали архив, выполните dot-source скрипта настройки (ведущее
.важно — без него переменные окружения исчезнут при выходе скрипта):. .\setup-env.ps1Скрипт устанавливает пять переменных окружения (
NOVA_STD_PATH,NOVA_CG_INCLUDE,NOVA_RT_DIR,NOVA_GC_LIB_DIR,NOVA_GC_INCLUDE_DIR), которые говорятnova.exe, где искать стандартную библиотеку и C-рантайм, когда он запускается не изнутри монорепозитория Nova, а также добавляет папку вPATHдля текущей сессии. Чтобы закрепить это навсегда, добавьте папку в вашPATHи задайте те же пять переменных через Параметры → Переменные среды (илиsetx). -
Проверьте, что всё сработало:
nova --version # nova 0.1.0 -
Вам также понадобится C-компилятор на машине — Nova компилирует в C, а не напрямую в машинный код. MSVC (Visual Studio Build Tools) определяется автоматически через
vcvars64.bat; Clang или GCC тоже работают через--toolchain.
Установка (Linux)
Готового Linux-архива для v0.1.0 пока нет — собирайте из исходников. Полный
рецепт (пакеты Debian/Ubuntu, Rust-тулчейн, git submodule update, сборка,
smoke-тест) — в docs/guide/linux-build.md; наверху той
страницы есть пятиминутный TL;DR.
Привет, Nova
Каждому проекту Nova нужен свой nova.toml, чтобы компилятор знал корень
пакета. Создайте папку с двумя файлами:
nova.toml:
[package]
name = "hello"
version = "0.1.0"
hello.nv:
module hello
fn main() {
println("Hello, Nova!")
}
Имя модуля (hello) должно совпадать с именем пакета для .nv-файла, лежащего
прямо в корне проекта — это конвенция Nova, а не опечатка.
Соберите и запустите:
nova build hello.nv
.\hello.exe
# Hello, Nova!
nova build компилирует hello.nv до hello.exe за один шаг (Nova → C →
нативный бинарник). Есть также nova check (только type-check, без
C-компилятора) и nova test (запускает файловые блоки test { ... }).
Пример побольше: эффекты + конкурентность
Однострочник выше не показывает, что делает Nova интересной. Вот это
показывает — это настоящий файл examples/mini_aggregator.nv из репозитория
Nova, ~30 строк, без сети, без UI:
module nova_examples.mini_aggregator
import std.time.duration
const BUDGET_MS int = 120 // total budget for the whole run, ms
// One "source": waits its own latency (simulated network call) and
// reports on a channel. A spawn that misses the shared deadline is
// genuinely cancelled — not left running in the background with its
// result thrown away.
fn probe(latency_ms int, deadline Monotonic) Time -> str {
ro { tx, rx } = Channel[bool].new(1)
// A `with Fail[T]` handler runs IN THE FIBER of the failing operation,
// not the installing scope's fiber (see spec/decisions/06-concurrency.md
// D441) — a bare `mut` flag captured there is a data race under M:N.
// `AtomicBool` is the synchronized alternative.
mut timed_out = AtomicBool.new(false)
with Fail[TimeoutError] = |_e| { timed_out.store(true) } {
supervised(deadline: deadline) {
spawn {
Time.sleep(latency_ms)
ro _ = tx.try_send(true)
}
}
}
if timed_out.load() {
"cancelled"
} else {
match rx.try_recv() {
Some(_) => "done"
None => "cancelled"
}
}
}
// Fan-out: all sources start AT ONCE, results collected into []str.
fn fan_out(latencies []int, deadline Monotonic) Time -> []str {
ro outcomes = parallel for i int in 0..latencies.len() {
probe(latencies[i], deadline)
}
outcomes
}
fn main() Time {
ro latencies []int = [20, 40, 60, 80, 300, 800] // ms; last two miss the budget
ro t0 Monotonic = Monotonic.now()
ro deadline Monotonic = t0 + BUDGET_MS.to_millis()
ro outcomes = fan_out(latencies, deadline)
mut done = 0
mut cancelled = 0
for i int in 0..outcomes.len() {
if outcomes[i] == "done" { done = done + 1 } else { cancelled = cancelled + 1 }
}
ro now Monotonic = Monotonic.now()
ro wall = now.elapsed_since(t0)
println("done=${done} cancelled=${cancelled} wall=${wall.millis()}ms")
}
Соберите и запустите из клона репозитория Nova (файл лежит в examples/,
рядом с nova.toml, который уже объявляет рабочее пространство):
cd examples
nova build mini_aggregator.nv -o mini_agg
.\mini_agg
# done=3 cancelled=3 wall=155ms
(Примечание: с явным -o name выходной файл называется ровно name — .exe
не добавляется, даже несмотря на то, что это обычный PE-бинарник на Windows.
Без -o команда nova build hello.nv называет выход hello.exe по имени
входного файла.)
Точное распределение done/cancelled и время wall зависят от тайминга —
важно структурное: шесть источников стартуют вместе, два самых медленных
(300ms, 800ms) не успевают завершиться, потому что превышают общий бюджет
120ms, и они реально отменяются (supervised(deadline:)), а не остаются
работать после отбрасывания их результата. Обратите внимание на то, чего здесь
нет: ни async fn, ни .await, ни Future<T> в типе возврата — Time в
сигнатуре функции это единственный маркер того, что код трогает часы, а
spawn/parallel for/supervised дают структурированную конкурентность без
отдельного «async»-диалекта языка.
Куда дальше
- spec/overview.ru.md — основные идеи, что у кого заимствовано, обзор тулинга.
- examples/flagship/aggregator —
полноразмерная версия примера выше: настоящий HTTP-сервер (через пакет
http), веб-UI с визуализацией waterfall и та же сигнатура эффектовNet Time Emit, проверяемая компилятором (--strict-effects). Поставляется со своим Dockerfile. - spec/decisions/ — журнал проектных решений (D-номера), авторитетный источник по синтаксису и семантике Nova — каждая языковая возможность восходит к решению здесь.
- docs/dev/test-conventions.md — как работает
nova test, маркерыEXPECT_*, флаги CLI. - docs/guide/linux-build.md — сборка из исходников на Linux/WSL2.