Philosophy on Simplicity, Safety, and Elegance

Philosophy on Simplicity, Safety, and Elegance

Every design decision in Luma is guided by three principles: simplicity, safety, and elegance. This page explains what these mean in practice and how they shape the language.

Simplicity

If a feature requires a paragraph to explain, it’s too complex.

Luma deliberately stays small. The entire language can be learned in a weekend. This isn’t a limitation; it’s a feature.

Simplicity in practice:

  • One way to iterate: .walk() works on lists, sets, maps, ranges, and files. No for, while, do, foreach, or loop keywords to choose between.
  • One way to declare variables: name: type = value. Always the same pattern.
  • No hidden behavior: What you write is what happens. No implicit conversions (except safe int-to-float promotion), no magic methods, no operator overloading.
  • Small keyword set: The entire language uses fewer than 20 keywords.

The goal is not to limit what you can do, but to make sure everything you do is immediately understandable.

Safety

The compiler should catch mistakes before the program runs.

Luma’s type system exists to protect you, not to burden you.

Safety in practice:

  • Optional types (?T) make nil explicit. You can’t accidentally use a nil value because regular types cannot be nil.
  • No truthiness: if count doesn’t work. You must write if count > 0. This eliminates an entire class of bugs where values are accidentally treated as booleans.
  • Explicit type annotations: Every variable declaration states its type. You always know what you’re working with.
  • Safe conversions: "abc".to_int() returns nil, not a crash. "abc".to_int(0) returns a safe default.
  • Immutability with lock: When a value shouldn’t change, say so: lock pi: float = 3.14159.

Safety doesn’t mean ceremony. It means fewer surprises at runtime.

Elegance

Code should be pleasant to read and pleasant to write.

Elegance is the hardest principle to define, but you recognize it when you see it. Elegant code communicates its intent clearly without wasted syntax.

Elegance in practice:

  • String interpolation: "Hello ${name}" instead of format functions or concatenation.
  • Expression bodies: fn double(x: int) -> int => x * 2 for simple functions.
  • Inline walk: nums.walk(n) -> print(n) for one-line iterations.
  • Clean struct syntax: Fields are declared simply, constructors are automatic.
  • Composable APIs: json.decode(file("config.json").read()) reads naturally as a sentence.

Luma avoids the temptation to add features just because they’re popular. Every addition must earn its place by making code clearer, not just shorter.

These principles in tension

Sometimes these principles pull in different directions:

  • Adding type annotations is less simple but more safe
  • Optional types add complexity but prevent crashes
  • Requiring explicit comparisons is more verbose but eliminates ambiguity

When principles conflict, Luma chooses the option that helps the programmer understand their code better. A few extra characters are worth it if they prevent confusion.

The result

A Luma program reads almost like pseudocode. A beginner can look at it and understand what it does. An experienced programmer can write it quickly without fighting the language. That’s the goal: a language where simplicity, safety, and elegance work together instead of against each other.

Last updated on