edva
an implementation of dva
A zero-keyword, expression-oriented systems language.
Language by Example
Explore syntax, symbolic control flow, algebraic types, and performance.
Symbolic Control Flow
Edva has zero keywords. Conditional branches, pattern matching, and cycles are unified into expressions.
|introduces choices and fallback branches[guard]supports value, predicate (e.g.[!< 90]), or variant guards@iterates over ranges, arrays, or streams-->and--^provide symbolic break and continue
// Conditionals & multi-guard pattern matching
classify = score =>
score [100] "perfect"
[!< 90] "distinction"
[!< 50] "pass"
| "fail"
// Iteration with @ and symbolic cycle control
count = 10
0..count @ i =>
i [7] --> // --> breaks the cycle
print $ classify(i * 10)
Algebraic Ramifications
Rams represent binary outcomes (presence/absence, success/failure) with unboxed { i1, i64 } storage.
- Four shapes:
<>,<T|>,<|E>,<T|E> - Positional matching: first branch is positive, second negative
- Monadic propagation via
$>> - Inline unwrap and error bubbling via
--!
// Monadic bind ($>>) chains fallible operations
find_user: String => < User | Error >
find_user = id =>
query_db(id) $>> validate $>> (u => <+ u +>)
// Postfix error propagation (--!) unwraps or early-returns
load_config: String => < Config | Error >
load_config = path =>
raw = io::read_file(path)--!
cfg = json::parse(raw)--!
<+ cfg +>
In-Place Builders & Strings
Strings are immutable fat pointers. Builders provide high-throughput in-place buffering with zero-copy freeze.
b = {N}allocates an initial buffer with capacityNb = (s1, s2, ...)streams elements via record notation without string concatb = (13, 10)appends raw CRLF byte records directly+bfreezes the buffer into an immutable String with zero allocation
// Pure strings & in-place builders
build_report: (String[]) => String
build_report = items =>
b = {128} // initial capacity hint
b = ("# Report Summary", "\n\n") // record streaming
items @ item =>
b = (" - ", item, "\n") // zero-alloc append
b = (13, 10) // CRLF byte record
+b // freeze to String
Native Networking
A production-ready micro HTTP service built purely on Edva's standard library with zero runtime overhead.
- Native non-blocking sockets and poll integration
- Raw string literals
(= ... =)for inline JSON/templates - No tracing garbage collector or thread runtime
- Direct LLVM compilation and native link
#use net
#use net/http
handle_req: Int, String => Int
handle_req = c_fd, r =>
path = http::path_of(r)
path ["/"]
http::respond(c_fd, 200, "text/plain", "Hello!")
["/health"]
body = (={"status": "ok"}=)
http::respond(c_fd, 200, "application/json", body)
|
http::respond(c_fd, 404, "text/plain", "Not Found")
Expressive Power & Low-Level Precision
Modern ergonomics paired with mechanical sympathy
Pipelines & Sections
Chain functions with multi-argument feed and point-free operator sections.
$>feeds the LHS as the first argument to RHS$applies multi-argument functions with infix precedence(2 * _)desugars to a clean inline lambda- Zero wrapper closures generated at runtime
// Multi-argument feed ($>) and sections
clamp: Int, Int, Int => Int
clamp = val, lo, hi =>
val [< lo] lo [> hi] hi | val
raw = 150
// Feeds raw into clamp, then applies section
result = raw $> clamp(0, 100) $> (2 * _)
print_int $ result
Cycle Escapes & Jumps
Cycles evaluate as expressions returning binary ramifications.
i [target]value guard checks equality (equivalent toi == target)-->breaks innermost cycle;-->Njumps N outer levels--^continues innermost iteration>--turns cycles into expressions yielding< T | >- Produces
<+ val +>on break,<-->on completion
// Cycle-escape (>--) returns < T | >
find_target: Int, Int => < Int | >
find_target = count, target =>
0..count @ i =>
i [target] --> // matches i == target; breaks
>--
target
res = find_target(10, 7)
res | print_int(_) | print $ "Not found"
SIMD & Vector Math
Hardware-accelerated element-wise operations with zero glue code.
- Homogeneous records map directly to LLVM vector registers
- Element-wise arithmetic:
+,-,*,/ - Scalar broadcasting across vector operands
0 {N}postfix repetition creates flat records
// LLVM SIMD operations on homogeneous records
pos = (10, 20, 30, 40)
vel = (1, 2, 3, 4)
// Element-wise addition and scalar broadcast multiply
next_pos = pos + vel * 2
print_int $ next_pos(0) // 12
print_int $ next_pos(3) // 48
Explicit Mutability
Deterministic immutability by default, with clear visual mutation boundaries.
- Bindings are immutable by default;
=is used uniformly - Rebindable variables require trailing primes:
x',x'' - Function parameters are permanently immutable
- Interior record mutations (
pt.x = ...) require no primes
#type Point (x: Int, y: Int)
// Unprimed bindings allow interior field mutation
pt = Point(10, 20)
pt.x = 42
// Rebindable local variables declare with a prime (')
total' = 0
0..5 @ i =>
total' = total' + i
print_int $ total' + pt.x // 52
Systems Programming & Direct Hardware Access
Zero-cost abstractions with bare-metal control
File I/O & Memory
Direct POSIX file descriptor handling with zero-copy buffer transfers.
libc::openopens native POSIX file descriptorsb = {4096}allocates an in-place Builder buffer&bpasses the writable buffer pointer directly?b = nupdates length;+bfreezes without copying
#use libc
// Zero-copy file read using Builder buffer
read_file: String => < String | >
read_file = path =>
fd = libc::open(path, 0)
fd [< 0] <-->
|
b = {4096}
n = libc::read(fd, &b, 4096)
libc::close(fd)
n > 0 | (?b = n; <+ +b +>) | <-->
LLVM Intrinsics
Compiler-level intrinsics lowered directly to target processor instructions.
%-prefixed intrinsics lower to LLVM IR without calls%dotand%sumfor hardware SIMD reductions%clampand%usub_satfor saturating math- Zero runtime overhead or library dependency
// Hardware-accelerated LLVM intrinsics
a = (1, 2, 3)
b = (4, 5, 6)
// Vector reductions & dot products
dot_prod = %dot(a, b) // llvm.fmuladd / SIMD
total = %sum(a) // llvm.vector.reduce.add
// Bounding & saturating arithmetic
clamped = %clamp(120, 0, 100) // 100
sat_sub = %usub_sat(5, 10) // 0 (unsigned sat)
Tagged Enums
Type-safe algebraic data types with compact unboxed payloads.
#type Name <Variants>defines closed algebraic types- Variant guards
[Tag(payload)]bind fields directly - Deep structural equality with
==compares tag and payload - Unboxed register storage for single-scalar variants
#type Shape < Circle(Float), Rect((Float, Float)) >
// Variant pattern matching binds payloads directly
area: Shape => Float
area = s =>
s [Circle(r)] 3.14 * r * r
[Rect(dim)] dim(0) * dim(1)
c = Shape(Circle, 10.0)
print_float $ area(c) // 314.0
Bitwise Operators
Predictable low-level binary manipulation with UB-safe bit shifts.
.<.and.>.zero-fill shifts masked to operand width.&.bitwise AND and.|.bitwise OR.!.unary bitwise negation (integers and runes only)- Explicit type suffixes:
0xFFu8,0b1010u16,1i64
// Bitwise operators & UB-safe bit shifts
mask' = 0x01 .|. 0x04 // bitwise OR: 5
// Test bitmask flags
has_flag = mask' .&. 0x04 != 0
// Logical shift left with masked operand width
offset = 1 .<. 8 // 256
Collections, Interop & Architecture
Growable collections, C ABI interop, hermetic packaging, and compile-time evaluation
Growable Arrays
Dynamically sized collections with unboxed layouts, zero hidden overhead, and bounds-checked safety.
T{}orT{N}initializes dynamic arrays with optional capacity hintsarr += itemappends elements in-place with amortized resizing?arrqueries element length;++arrperforms an explicit deep copyarr(i)!!reads with unwrap;arr(i) | _ | fallbackhandles bounds safely
// Initialize growable array with capacity hint (64)
scores: Int{64}
// In-place append using +=
scores += 95
scores += 88
scores += 100
// Query count (?) and perform deep clone (++)
total = ?scores
backup = ++scores
// Bounds-checked unwrap (!!) and safe fallback choice
first = scores(0)!! // unwraps 95
safe = scores(5) | _ | 0 // handles out-of-bounds
Foreign Function Interface
Zero-overhead native interoperability calling C functions directly with LLVM ABI linkage.
#foreign "c"declares typed foreign signatures without header wrappers- First-class
Addrrepresents raw pointers and opaque OS handles - Pass immutable string data and mutable builder buffers (
&b) directly - Zero runtime bridge overhead, marshaling layers, or garbage collection stalls
// Declare foreign C ABI functions directly
#foreign "c"
puts: (s: String) => Int
getpid: () => Int
isatty: (fd: Int) => Int
// Invoke native POSIX symbols seamlessly
pid = getpid()
is_term = isatty(1) != 0
is_term | puts("Interactive terminal detected")
| puts("Standard output redirected to pipe")
Packages & Modules
Hermetic package resolution, clean encapsulation, and zero global namespace pollution.
#use @pkgimports versioned dependencies from the package import map#use(import) strbrings module symbols into current scope unqualified#publicblocks define export APIs; unlisted symbols stay module-privatesrc/internal/submodules enforce strict package-private boundary visibility
// Package dependency and unqualified stdlib import
#use @crypto/sha256
#use(import) str
#public
sign_payload: String => String
sign_payload = data =>
salt = "edva-secret-salt"
data + salt $> sha256::digest $> to_hex
// Unexported functions remain private to this module
validate: String => < | String >
validate = token =>
?token > 32 | <++> | <- "Token too short" ->
Compile-Time & Here-Docs
First-class compile-time evaluation, Unicode runes, repetition, and multiline here-documents.
#!evaluates expressions at compile time and folds static constants"""..."""here-docs with baseline margin stripping and${expr}interpolation- Unescaped
"and""work as-is; direct in-place lowering into Builders expr {N}repetition constructs flat, register-allocated records
// Compile-time constant folding with #!
#! #type Version (major: Int, minor: Int, patch: Int)
#! build_ver = Version(1, 4, 0)
// Triple-quoted here-doc with margin stripping & interpolation
user = "Alice"
count = 3
report = """
Hello, ${user}!
Items remaining: ${count}
Note: unescaped "quotes" and ""double quotes"" work as-is.
"""
// Repetition literal (0 {8}) and 64-bit Unicode Rune
zero_block = 0 {8}
badge = '⚡'