Scar

A compiled, statically typed programming language, offering high-level syntax with low-level control.

v0.0.1

what it is

Scar is a RAD-centred programming language that includes defensive programming as part of the language grammar, while still being flexible enough to iterate and prototype upon ideas.

why it exists

Existing options were either garbage collected (pauses, slowness), plagued with numerous footguns, or cryptic and unreadable due to their overly loose and flexible conventions. This language aims to strike a balance between safety and iterability.

explicit over implicit

No hidden allocations. This does not hinder readability, in fact it greatly helps to have complete explicitness under a Ruby-style, readable syntax.

interfaces & generics

Generics and interface rely on static dispatch, thus there is zero runtime overhead associated with them. This means, rich, dynamic language features, without losing runtime performance.

extern def strcmp(x ref(u8), y ref(u8)) i32 :: "strcmp"
extern def strlen(x ref(u8)) usize :: "strlen"

pub def eql(x ref(u8), y ref(u8)) bool
    guard (y != none && x != none) else
        return false
    end
    return strcmp(x, y) == 0
end

pub def len(x ref(u8)) usize
    guard (x != none) else
        return 0
    end
    return strlen(x)
end

test "equals works"
    assert eql("hello", "hello")
    assert !eql("hello", "something else")
end
type Complex
    re i64
    im i64
end

def c_add(a Complex, b Complex) Complex
    return Complex(
        re: a.re + b.re,
        im: a.im + b.im
    )
end

def mandelbrot_iter(c Complex, max_iter i32) i32
    var z = make_complex(0, 0)
    for var i = 0 .. max_iter
        if c_mag2(z) > 4
            return i
        end
        z = c_add(c_mul(z, z), c)
    end
    return max_iter
end
pub interface BumpAllocator
    pub def alloc(a ref(BumpAllocator), size usize) ref(void)|error
    pub def reset(a ref(BumpAllocator))
    pub def destroy(a ref(BumpAllocator))
end

pub type Arena : BumpAllocator
    ptr ref(u8)
    cap usize
    off usize
end

pub def Arena.new(cap usize) Arena|error
    ## Create a new arena given some cap.
    var mem ref(u8) = @alloc(cap) as mut(ref(u8))
    if mem == none
        return error("arena allocation failed")
    end
    return Arena(ptr: mem, cap: cap, off: 0)
end

test "alloc with unwrap works"
    var arena = Arena.new(1024 as usize)?
    var mem = Arena.alloc(@addr(arena), 500)?
    Arena.destroy(@addr(arena))
end
type Grid
    width  i32
    height i32
    cells  list[list[i32]]
end

def step(grid ref(Grid)) Grid
    val next = make_grid(grid.width, grid.height)
    for var y = 0 .. grid.height
        for var x = 0 .. grid.width
            val alive     = get_cell(grid, x, y)
            val neighbors = count_neighbors(grid, x, y)
            if alive == 1
                if neighbors == 2 || neighbors == 3
                    set_cell(@addr(next), x, y, 1)
                end
            else
                if neighbors == 3
                    set_cell(@addr(next), x, y, 1)
                end
            end
        end
    end
    return next
end

2025

Initial design. Pythonic syntax. First compiler prototype.

early 2026

Syntax redesign. Moved from Pythonic to Ruby-style structure.

now

Looking towards making the standard library more feature complete, and the language itself more batteries included