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 capacity N
  • b = (s1, s2, ...) streams elements via record notation without string concat
  • b = (13, 10) appends raw CRLF byte records directly
  • +b freezes 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 to i == target)
  • --> breaks innermost cycle; -->N jumps 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::open opens native POSIX file descriptors
  • b = {4096} allocates an in-place Builder buffer
  • &b passes the writable buffer pointer directly
  • ?b = n updates length; +b freezes 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
  • %dot and %sum for hardware SIMD reductions
  • %clamp and %usub_sat for 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{} or T{N} initializes dynamic arrays with optional capacity hints
  • arr += item appends elements in-place with amortized resizing
  • ?arr queries element length; ++arr performs an explicit deep copy
  • arr(i)!! reads with unwrap; arr(i) | _ | fallback handles 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 Addr represents 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 @pkg imports versioned dependencies from the package import map
  • #use(import) str brings module symbols into current scope unqualified
  • #public blocks define export APIs; unlisted symbols stay module-private
  • src/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 = '⚡'