Skip to content

Philosophy

Why design another programming language?

Languages like Nim, Swift, and many others often leave concurrency and high-performance numeric computing to libraries or ad-hoc patterns. That forces users to stitch together: a language with ergonomic syntax + a heavy external lib (Arraymancer), and runtime/ABI mismatches.

The key point is this: A language that bakes in structured parallelism and numeric-first value semantics reduces that friction and enables far cleaner, higher-performance code by default.

Structured concurrency as primary model. parallel: and parallel for are essentially structured fork-join. This is simple to reason about, maps well to work-stealing runtimes, and composes easily with nested loops. It also allows the compiler to generate efficient join points.

Justifications

Designing a language with concurrency and parallelism as a core construct

Compiler-first synchronization is a highly important design goal in Scar. Rather than forcing manual mutexes everywhere, the compiler performs static analysis (and when needed, emits runtime synchronization). But crucially you must combine static checks + opt-in/opt-out mechanisms:

  • Static detection of obvious races: if a variable is accessed from multiple concurrent tasks without synchronization, the compiler warns/error.
  • Automatic safe transforms: for a pattern like independent loop iterations updating a per-iteration slot, compiler can use thread-local buffers and a final merge to avoid locks.
  • Explicit annotations for intent: atomic, shared, reduction, or unique qualifiers let the compiler emit low-overhead atomics or lock-free code when you mean it.

Data-race-free and Sequential-consistency semantics

DRF / SC semantics are employed for usability. Adopting an easily-understood memory model. Sequential Consistency for Data-Race-Free (SC-for-DRF) by default (if program is data-race-free, it behaves like SC), while providing atomics and fences for low-level control. SC-for-DRF is easier for users and can be enforced via compile-time checks and sanitizer/runtime options.

Value-semantics, stack allocation, and escape analysis. To avoid "ref object everywhere" boxing:

  • Strong static typing with first-class value types (structs, arrays) that default to stack/inline allocation.
  • Escape analysis to determine when heap allocation is necessary.
  • Cheap move/borrow semantics (borrow or move, not implicit ref) to avoid copies while remaining safe.
  • Optional small-boxing for polymorphism/heterogeneous containers.

Compilation model

C backend for practical reasons.

Pros:

  • easy bootstrap
  • ubiquitous toolchain
  • interop with C libs (BLAS, pthreads)
  • simple debugging.

An LLVM backend will be adopted at a later stage of development.