I'm building a clarity-first language (compiles to C++)

(github.com)

24 points | by hedayet 4 days ago ago

24 comments

  • amluto 2 hours ago

    > 3. Values follow a strict rule: primitives pass by value, containers pass by read-only reference. This prevents accidental aliasing/mutation across scopes and keeps ownership implicit but predictable.

    There are plenty of languages where functions cannot mutate their parameters or anything their parameters reference — Haskell is one example. But these languages tend to have the ability to (reasonably) efficiently make copies of most of a data structure so that you can, for example, take a list as a parameter and return that list with one element changed. These are called persistent data structures.

    Are you planning to add this as a first-class feature? This might be complex to implement efficiently on top of C++’s object model — there’s usually a very specialized GC involved.

    • hedayet 44 minutes ago

      [author here] ROX avoids implicit structural sharing and persistent data structures. Allocation and mutation are explicit - if I want a modified container, I construct one.

      This is intentionally more resource-intensive. ROX trades some efficiency for simplicity and predictability.

      The goal is clarity of logic and clarity of behavior, even at slightly higher cost. And future optimizations should preserve that model rather than hide it.

    • cyber_kinetist an hour ago

      I've seen some C++ libraries that implement persistent data structures like immer (https://github.com/arximboldi/immer) - but seems it requires the use of the Boehm GC (which is notorious to be slow, since it is a conservative GC and cannot exploit any of the specific semantics/runtime characteristics of the language you're making).

    • eager_learner 2 hours ago

      Comments like amluto's above, are the reason my time spent on HN is not wasted.

    • paulddraper an hour ago

      I don’t see the relevance of special GC.

      But yes you need immutable data structures designed for amortized efficient copy.

  • nynx an hour ago

    This is an interesting line in the readme:

    > The language forces clarity — not ceremony.

    I find this statement curious because a language, like this, without ability to build abstractions forces exactly the opposite.

    • hedayet 14 minutes ago

      [author here] That’s a very good point - "not ceremony" was poorly phrased.

      ROX does introduce more explicitness, which indeed introduces more ceremony. The goal isn’t to reduce keystrokes; it’s to reduce hidden behaviour.

      A better framing would be: ROX prioritizes clarity over convenience. Explicitness may cost more keystrokes, but it eliminates hidden behavior. [README updated]

  • sesm 2 hours ago

    > Lists are accessed only via .at()

    If clarity is the goal, then data structures that support access by index should be called `arrays` or `vectors`

    • hedayet an hour ago

      [author here] What @joshuamorton said + my rationale was - for natural language users too, a "list" should be more intuitive than `array` or `vector`

      I'm more than happy to be corrected though.

      • anon291 10 minutes ago

        The idea of being inspired by natural language is completely at odds with also desiring clarity first

    • rkeene2 an hour ago

      Also why num/num32 for Integer types, and no floating point type

      • hedayet an hour ago

        [author here] Very good questions; I definitely would like to revisit num32 very shortly. I'd say the initial rational of having num32 is not coherent right now, but I'll have to verify removing the support.

        we have floating point type(It was missing from the type list in readme. I have just updated that seeing this comment. thank you!)

    • joshuamorton an hour ago

      This is very language dependent. People coming from python or Java would call them lists.

      Vectors are a mathematical concept unless you use c++.

      • vlovich123 3 minutes ago

        In Java it’s called Vector / list refers to linked list. Python doesn’t have a linked list type so it’s kinda irrelevant. But also not every language has to be Algol centric even though Algol has largely dominated the design space of popular languages due to familiarity.

  • leecommamichael an hour ago

    I’d be curious to hear the author’s thoughts on Odin. Odin seems to have meet many of the same goals as ROX. I am not implying the author shouldn’t keep going with their language.

  • anon291 11 minutes ago

    The best imperative language is Haskell do notation which offers everything you support here.

  • dusanstanojevic 4 days ago

    Very interesting, I've read your readme and your core principles really resonate with me. How is memory managed?

    • hedayet 4 days ago

      Great question - we keep memory management intentionally simple.

      1. There’s no manual memory management exposed at the language level (no pointers, no allocation APIs). I intend to keep it this way as long as possible.

      2. Containers (list[T], dictionary[K,V]) compile directly to C++ STL types (std::vector, std::unordered_map).

      3. Values follow a strict rule: primitives pass by value, containers pass by read-only reference. This prevents accidental aliasing/mutation across scopes and keeps ownership implicit but predictable.

      Anything created in a scope is destroyed when that scope ends (standard C++ RAII). So in practice, memory management in Rox is C++ lifetime semantics underneath, but with a stricter surface language to reduce accidental complexity.

      • teraflop 3 hours ago

        That sounds like it's basically impossible to implement your own non-trivial data structures. You can only use the ones that are already in the standard library.

        For instance, how would you represent a binary tree? What would the type of a node be? How would I write an "insert node" function, which requires that the newly-created node continues to exist after the function returns?

        I'm not necessarily saying that this makes your language bad, but it seems to me that the scope of things that can be implemented is much much smaller than C++.

  • OsrsNeedsf2P 2 hours ago

    This is great. I look forwards to more "strict" languages whose deterministic compilers will give LLMs a tight feedback loop to catch bugs.

  • Panzerschrek 2 hours ago

    Does it have destructors?

    • hedayet an hour ago

      [author here] as of today - no. I'm super keen to keep the concept of destructors and GC hidden from this language interface.

      • boothby 4 minutes ago

        I'm confused by this. What you've written on this page says that nothing is hidden. I'm curious how you square this with your stated goal.

  • tovej 19 minutes ago

    You have to unwrap every array access? That does not feel clear to me at all. Also this would make every hot loop slower.

    The amount of safety features here seems excessive. The language is stricter than Rust. It's not very "clear" either. For some reason the author has decided to rename concepts that are familiar to programmers, making it more didficult to switch to for experienced programmers (repeat instead of for, num instead of... float I assume?), but the langauge isn't really beginner-friendly either, due to the strict semantics.

    This feels like vibe-coded slop. Why is this on the front page? HN has fallen off.