logoalt Hacker News

Zen-C: Write like a high-level language, run like C

147 pointsby simonpureyesterday at 12:57 PM90 commentsview on HN

Comments

Joker_vDyesterday at 5:49 PM

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:

    var f = fopen("file.txt", "r");
    defer fclose(f);

    if fread(&ch, 1, 1, f) <= 0 { return -1; }
    return 0;
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.
show 1 reply
Lucasoatoyesterday at 3:30 PM

> 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.

show 3 replies
seabrookmxyesterday at 4:27 PM

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.

show 1 reply
giancarlostoroyesterday at 2:27 PM

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.

show 3 replies
morcusyesterday at 2:35 PM

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?

show 2 replies
Gysyesterday at 2:20 PM

Initial commit was 24h ago, 363 stars, 20 forks already. Man, this goes fast.

show 2 replies
forgotpwd16yesterday at 4:02 PM

Basically C2/C3 but Rust influenced. Missed chance to call it C4.

Archit3chyesterday at 11:29 PM

Answering the title, why not Julia?

Dwedityesterday at 9:40 PM

I wonder how this compares to the Beef programming language.

https://www.beeflang.org/

The Beef programming language was used to write Penny's Big Breakaway.

v_iteryesterday at 2:47 PM

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.

show 5 replies
stevefoltayesterday at 7:45 PM

Nice! Compiles in 2s on my unexceptional hardware. But it lacks my other main desiderata in a new language: string interpolation and kebab-case.

Zambyteyesterday at 10:19 PM

The tagline also applies to C :-)

taolsonyesterday at 8:49 PM

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...

krecoyesterday at 2:55 PM

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.

aapplebyyesterday at 10:28 PM

Example at the top of the readme!

alfonsodevyesterday at 2:56 PM

Is this the Typescript of C ?

blacksqryesterday at 3:24 PM

What's the performance hit?

alexpadulayesterday at 2:54 PM

18 commits! I hope you keep up with the project, it’s really cool, great work.

ramses0yesterday at 3:20 PM

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.

show 1 reply
ethinyesterday at 2:12 PM

Am I the only one who saw this syntax and immediately though "Man, this looks almost identical to Rust with a few slight variations"?

show 4 replies
GrowingSidewaysyesterday at 2:33 PM

Why not compile to rust or assembly? C seems like an odd choice.

In fact why not simply write rust to begin with?

show 4 replies