> 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.
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.
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.
If the only loop is `repeat i in range(start, end, step)` , how do you do a loop like "Keep reading from a buffer until it's empty"? I.e. any loop when you can't know the number of iterations needed when the loop starts?
If this is to be a real, (relatively) widely-used language, I would make some tough choices on where to innovate, and where to just leave things the same.
One thing I noticed in the example is `num target`, especially because the focus is on "clarity". When I read the example, I was sure that `num` would be something like the JavaScript `Number` type. But to my surprise, it's just a 64-bit integer.
For an extremely long time, languages have had "int", "integer", "int64", and similar. If you aim for clarity, I would strongly advise to just keep those names and don't try to invent new words for them just because. Both because of familiarity (most programmers coming to your language will already be familiar other languages which have "int(eger)"), and because of clarity ("int(eger)" is unambiguous, it is a well defined term to mean a round number; "num" is ambiguous and "number" can mean any type of number, e.g. integer, decimal, imaginary, complex, etc).
The most clear are when the data types are fully explicit, eg. `int64` (signed), `uint64` (unsigned), `int32`, etc.
one thing ive always wondered about these type of projects is how do you debug them? gdb at runtime? printf statements? i mean when im debugging python i mainly rely on print() and log files so i guess that would work. its been a long time since i used an ide to step through a program anyway, i think way back with borland turbo c/c++ i used to step through statements to see how it all worked but things are much too complex for that now.
> In ROX: <...> Nothing implicit happens behind your back.
> You write the logic. The language stays out of the way.
Writing business logic and everything being explicit are polar opposite. For the programming language to stay out of the way it should more resemble concise version on English with little to no language constructs.
sidenote : are we going to still see new languages appear after AI becomes the one that writes the code ?
I'd say that for a new language to appear in that new world, it would need to offer new compile-time properties that AI could benefit from. Something like expressing general program properties / invariants that the compiler could check and the AI could iterate on.
Most of what the section "Why ROX exists" reminds me of Rust and Zig, where both are more explicit (but Zig even more where there aren't hidden allocations, while Rust hides it).
Said that I really miss all the i{8|16|32|64|128|size}, u{8|16|32|64|128|size} and f{32|64} in other languages, I think having num and num32 is a mistake (IMHO) and naming like them like Rust/Zig provides more clarity (and it's also more concise).
For the "repeat" keyword I find it odd, because most other languages uses "for" but I can understand the reason and might be able to get used to it.
Otherwise I find always interesting new programming languages, what new they bring to the table and the lessons learned from other PLs.
with an implicit “i = i + n”, followed by an implicit comparison.
Also, range(0, n, 1) looks like a function call, but isn’t one, is it? Or an i write
evenDigits = range(0, 10, 2)
I think introducing a range type would be cleanest, but I think clarity would improve even more by giving up more on “Nothing implicit happens behind your back”. Allowing
for num in nums {…}
has quite a bit of magic, but IMO is clearer than iterating over indexes, followed by superfluous checks whether indexing succeeded.
If the goal is truly "clarity", then I fail to see how this leads to more readable programs than Knuth's Web (or cweb for a more practical implementation).
If you really mean "C/C++, but with the sharp pointy bits filed down," then I fail to see what it adds over MISRA.
The bottom line is that we've had "clarity-first" languages for decades; the reason they're not more widely used is not simply that no one has tried this, nor that programmers appreciate murky code.
19 comments
[ 2.8 ms ] story [ 50.8 ms ] threadIf clarity is the goal, then data structures that support access by index should be called `arrays` or `vectors`
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.
> 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.
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.
One thing I noticed in the example is `num target`, especially because the focus is on "clarity". When I read the example, I was sure that `num` would be something like the JavaScript `Number` type. But to my surprise, it's just a 64-bit integer.
For an extremely long time, languages have had "int", "integer", "int64", and similar. If you aim for clarity, I would strongly advise to just keep those names and don't try to invent new words for them just because. Both because of familiarity (most programmers coming to your language will already be familiar other languages which have "int(eger)"), and because of clarity ("int(eger)" is unambiguous, it is a well defined term to mean a round number; "num" is ambiguous and "number" can mean any type of number, e.g. integer, decimal, imaginary, complex, etc).
The most clear are when the data types are fully explicit, eg. `int64` (signed), `uint64` (unsigned), `int32`, etc.
> You write the logic. The language stays out of the way.
Writing business logic and everything being explicit are polar opposite. For the programming language to stay out of the way it should more resemble concise version on English with little to no language constructs.
I'd say that for a new language to appear in that new world, it would need to offer new compile-time properties that AI could benefit from. Something like expressing general program properties / invariants that the compiler could check and the AI could iterate on.
Said that I really miss all the i{8|16|32|64|128|size}, u{8|16|32|64|128|size} and f{32|64} in other languages, I think having num and num32 is a mistake (IMHO) and naming like them like Rust/Zig provides more clarity (and it's also more concise).
For the "repeat" keyword I find it odd, because most other languages uses "for" but I can understand the reason and might be able to get used to it.
Otherwise I find always interesting new programming languages, what new they bring to the table and the lessons learned from other PLs.
And then, we have
with an implicit “i = i + n”, followed by an implicit comparison.Also, range(0, n, 1) looks like a function call, but isn’t one, is it? Or an i write
I think introducing a range type would be cleanest, but I think clarity would improve even more by giving up more on “Nothing implicit happens behind your back”. Allowing has quite a bit of magic, but IMO is clearer than iterating over indexes, followed by superfluous checks whether indexing succeeded.If you really mean "C/C++, but with the sharp pointy bits filed down," then I fail to see what it adds over MISRA.
The bottom line is that we've had "clarity-first" languages for decades; the reason they're not more widely used is not simply that no one has tried this, nor that programmers appreciate murky code.