> Mutability
> By default, variables are mutable. You can enable Immutable by Default mode using a directive.
> //> immutable-by-default
> var x = 10; > // x = 20; // Error: x is immutable
> var mut y = 10; > y = 20; // OK
Wait, but this means that if I’m reading somebody’s code, I won’t know if variables are mutable or not unless I read the whole file looking for such directive. Imagine if someone even defined custom directives, that doesn’t make it readable.
It's odd that the async/await syntax _exclusively_ uses threads under the hood. I guess it makes for a straightforward implementation, but in every language I've seen the point of async/await is to use an event loop/cooperative multitasking.
Syntax aside, how does this compare to Nim? Nim does similar, I think Crystal does as well? Not entirely sure about Crystal tbh. I guess Nim and Vala, since I believe both transpile to C, so you really get "like C" output from both.
An interesting bit to me is that it compiles to (apparently) readable C, I'm not sure how one would use that to their advantage
I am not too familiar with C - is the idea that it's easier to incrementally have some parts of your codebase in this language, with other parts being in regular C?
Initial commit was 24h ago, 363 stars, 20 forks already. Man, this goes fast.
Basically C2/C3 but Rust influenced. Missed chance to call it C4.
Answering the title, why not Julia?
I wonder how this compares to the Beef programming language.
The Beef programming language was used to write Penny's Big Breakaway.
So, the point of this language is to be able to write code with high productivity, but with the benefit of compiling it to a low level language? Overall it seems like the language repeats what ZIG does, including the C ABI support, manual memory management with additional ergonomics, comptime feature. The biggest difference that comes to mind quickly is that the creator of Zen-C states that it can allow for the productivity of a high level language.
Nice! Compiles in 2s on my unexceptional hardware. But it lacks my other main desiderata in a new language: string interpolation and kebab-case.
The tagline also applies to C :-)
The author includes some easter-eggs (printing random facts about Zen and various C constructs) which trigger randomly -- check out the file src/zen/zen_facts.c in the repository...
That's a very nice project.
List of remarks:
> var ints: int[5] = {1, 2, 3, 4, 5};
> var zeros: [int; 5]; // Zero-initialized
The zero initialized array is not intuitive IMO.
> // Bitfields
If it's deterministically packed.
> Tagged unions
Same, is the memory layout deterministic (and optimized)?
> 2 | 3 => print("Two or Three")
Any reason not to use "2 || 3"?
> Traits
What if I want to remove or override the "trait Drawing for Circle" because the original implementation doesn't fit my constraints? As long as traits are not required to be in a totally different module than the struct I will likely never welcome them in a programming language.
Example at the top of the readme!
Is this the Typescript of C ?
What's the performance hit?
18 commits! I hope you keep up with the project, it’s really cool, great work.
The whole language examples seem pretty rational, and I'm especially pleased / shocked by the `loop / repeat 5` examples. I love the idea of having syntax support for "maximum number of iterations", eg:
repeat 3 {
try { curl(...) && break }
except { continue }
}
...obviously not trying to start any holy wars around exceptions (which don't seem supported) or exponential backoff (or whatever), but I guess I'm kindof shocked that I haven't seen any other languages support what seems like an obvious syntax feature.I guess you could easily emulate it with `for x in range(3): ...break`, but `repeat 3: ...break` feels a bit more like that `print("-"*80)` feature but for loops.
Am I the only one who saw this syntax and immediately though "Man, this looks almost identical to Rust with a few slight variations"?
Why not compile to rust or assembly? C seems like an odd choice.
In fact why not simply write rust to begin with?
From what I can see in the codegen, defer is not implemented "properly": the deferred statements are only executed when the block exits normally; leaving the block via "return", "break", "continue" (including their labelled variants! those interact subtly with outer defers), or "goto" skips them entirely. Which, arguably, should not happen:
would not close file if it was empty. In fact, I am not sure how it works even for normal "return 0": it looks like the deferred statements are emitted after the "return", textually, so they only properly work in void-returning function and internal blocks.