logoalt Hacker News

The C3 Programming Language

357 pointsby y1n0last Saturday at 4:41 PM229 commentsview on HN

Comments

Fivepluslast Saturday at 5:34 PM

I've been following C3 for sometime now, and I really appreciate the discipline in the design philosophy here.

Neither does it force a new memory model on you, nor does it try to be C++. The killer feature for me is the full ABI compatibility. The fact that I no longer have to write bindings and can just mix C3 files into my existing C build system reduces the friction to near zero.

Kudos to the maintainer for sticking to the evolution, not revolution vision. If you are looking for a weekend language to learn that doesn't require resetting your brain but feels more modern than C99, I highly recommend giving this a shot. Great work by the team.

show 2 replies
Fraterkeslast Saturday at 6:51 PM

Dumb question about contracts: I was reading the docs (https://c3-lang.org/language-common/contracts/) and this jumped out

"Contracts are optional pre- and post-condition checks that the compiler may use for static analysis, runtime checks and optimization. Note that conforming C3 compilers are not obliged to use pre- and post-conditions at all.

However, violating either pre- or post-conditions is unspecified behaviour, and a compiler may optimize code as if they are always true – even if a potential bug may cause them to be violated.

In safe mode, pre- and post-conditions are checked using runtime asserts."

So I'm probably missing something, but it reads to me like you're adding checks to your code, except there's no guarantee that they will run and whether it's at compile or runtime. And sometimes instead of catching a mistake, these checks will instead silently introduce undefined behaviour into your program. Isn't that kinda bad? How are you supposed to use this stuff reliably?

(otherwise C3 seems really cool!)

show 7 replies
throwfaraway135last Saturday at 6:02 PM

The GitHub project has more details: https://github.com/c3lang/c3c

Some ways C3 differs from C:

- No mandatory header files

- New semantic macro system

- Module-based namespacing

- Slices

- Operator overloading

- Compile-time reflection

- Enhanced compile-time execution

- Generics via generic modules

- "Result"-based zero-overhead error handling

- Defer

- Value methods

- Associated enum data

- No preprocessor

- Less undefined behavior, with added runtime checks in "safe" mode

- Limited operator overloading (to enable userland dynamic arrays)

- Optional pre- and post-conditions

show 1 reply
loeglast Saturday at 6:36 PM

They named Result (or Expected) Optional? No, no, "optional" means "T or empty." Not "T or E."

https://c3-lang.org/language-fundamentals/functions/#functio...

show 4 replies
xprniolast Saturday at 5:03 PM

Tsoding did a bunch of livestreams using C3. Over 30h worth if anyone’s interested.

https://youtube.com/playlist?list=PLpM-Dvs8t0VYwdrsI_O-7wpo-...

impoppylast Saturday at 5:26 PM

I haven’t tried C3 myself, but I happened to interact a lot with Christopher Lerno, Ginger Bill and multiple Zig maintainers before. Was great to learn that C3, Odin and Zig weren’t competing with each other but instead learn from each other and discuss various trade-offs they made when designing their languages. Generally was a very pleasant experience to learn from them on how and why they implemented building differently or what itch they were scratching when choosing or refusing to implement certain features.

show 2 replies
rixedlast Saturday at 6:13 PM

Just browsed the doc to get the answers to two burning questions, which I will dump here in case it saves some time to others:

  - uses LLVM (so: as portable as LLVM)
  - sadly, does not support tagged enums
Apart from that it adds a few very desirable things, such as introspection and macros.
show 2 replies
gritzkolast Saturday at 5:24 PM

I wonder, at which point it is worth it to make a language? I personally implemented generics, slices and error propagation in C… that takes some work, but doable. Obviously, C stdlib goes to the trash bin, but there is not much value in it anyway. Not much code, and very obsolete.

Meanwhile, a compiler is an enormously complicated story. I personally never ever want to write a compiler, cause I already had more fun than I ever wanted working with distributed systems. While idiomatic C was not the way forward, my choice was a C dialect and Go for higher-level things.

How can we estimate these things? Or let's have fun, yolo?

show 4 replies
chuckadamslast Saturday at 6:01 PM

I was expecting something very bare-bones, but was pleasantly surprised to see a rich list of new and useful features. And maybe it's not the deepest of things to highlight, but what really made me giggle is how C3's analogue to exceptions are called Excuses.

antfarmlast Saturday at 5:13 PM

This is what a website for a programming language should look like.

show 1 reply
syn-ninelast Saturday at 7:48 PM

I've enjoyed using the C3 language to make some simple games [0] and found it really easy to pick up. The only thing that I got hung up on at first was the temporary memory arenas which I didn't know existed and ultimately really liked.

[0] https://github.com/Syn-Nine/c3-mini-games

show 1 reply
cb321last Saturday at 5:45 PM

I see from `test/test_suite/compile_time_introspection/paramsof.c3t` that there is a way to get names & types of function parameters [1]. The language also seems to support default values { e.g. `int foo(int a, int b = 2) {...}` } and even call with keyword arguments/named parameters [2], but I couldn't find any `defaultof` or similar thing in the code. Does anyone know if this is just an oversight / temporary omission?

[1] https://github.com/c3lang/c3c/blob/master/test/test_suite/co...

[2] https://c3-lang.org/language-fundamentals/functions/

show 1 reply
maxlohlast Saturday at 6:49 PM

Google is making a similar attempt with C++ called Carbon Language: https://github.com/carbon-language/carbon-lang

show 1 reply
chadcmulliganlast Saturday at 11:43 PM

It's funny seeing the problems with C Niklaus Wirth pointed out originally still trying to be solved. He solved them with pascal and its OO successors, though for some reason it's not cool still.

I suppose it has less of the ability to blow your foot off and so isn't a very dangerous way to code, therefore not cool. If any of you younger folk haven't looked at it, I'd suggest having a look, there is Delphi - a cross platform dev environment that addresses all these problems and compiles in less than a second, or there's the free, open source alternative Lazarus. They also compile to mobile platforms and even the raspberry pi (Lazarus) or Arduino.

If you like contracts then ADA is the way to go, but I haven't used this for many years, so not sure what is the state of the compilers.

[1] https://www.embarcadero.com/products/delphi

[2] https://www.lazarus-ide.org

givemeethekeyslast Saturday at 5:42 PM

This looks like Zig. What problems does this solve that Zig doesn't? Potato - potaato?

show 4 replies
jadboxlast Saturday at 7:20 PM

Does anyone who has actually used C3, Odin, and Zig talk about how to think of these three?

show 1 reply
sea-goldlast Saturday at 5:03 PM

Previous discussions:

July 2025 (159 comments, 143 points): https://news.ycombinator.com/item?id=44532527

lalitmagantilast Saturday at 7:12 PM

Was an interesting ready but sad to see that there is nothing special for matching or restructuring tagged unions (beyond the special cased optional type). That's one of the things from Rust I miss the most in my day to day work with C/C++.

show 1 reply
logicproglast Saturday at 6:55 PM

This seems pretty neat! Still holding out for a language with Go's runtime and compilation and performance characteristics, but language syntax and semantics like Gleam... Maybe one day

show 5 replies
netbioserrorlast Saturday at 5:14 PM

This is neat and I wish C3 well. But using Nim has shown me the light on maybe the most important innovation I've seen in a native-compiled systems language: Everything, even heap-allocated data, having value semantics by default.

In Nim, strings and seqs exist on the heap, but are managed by simple value-semantic wrappers on the stack, where the pointer's lifetime is easy to statically analyze. Moves and destroys can be automatic by default. All string ops return string, there are no special derivative types. Seq ops return seq, there are no special derivative types. Do you pay the price of the occasional copy? Yes. But there are opt-in trapdoors to allocate RC- or manually-managed strings and seqs. Otherwise, the default mode of interacting with heap data is an absolute breeze.

For the life of me, I don't know why other languages haven't leaned harder into such a transformative feature.

show 1 reply
shevy-javayesterday at 9:17 AM

Its successor will be C4!

WalterBrightlast Saturday at 8:07 PM

The front page reads like a D language checklist :-)

show 1 reply
maybewhenthesunlast Saturday at 10:03 PM

I see 'fn void main()'. There's probably a good reasson but why the 'fn'? It doesn't really add anything because 'void main()' already communicates it's a function.

The main draw of C (to me) is it's terseness and it's avoidance of 'filler' syntax words.

I admit I didn't (yet) look much further into it, but this first thing jumped out to me and slightly diminished my desire to look further into C3...

show 2 replies
ulimnlast Saturday at 6:51 PM

I am not a C programmer but I always find these low level languages intriguing.

I am wondering though: when does one pick C3 for a task/problem?

show 1 reply
mr_00ff00last Saturday at 8:49 PM

Anyone use zig vs C3? Seems like a lot of overlap, curious about people’s experiences with both

show 1 reply
stacktraceyolast Saturday at 6:46 PM

My university had us program in c++ with resolve. Which looks very similar to the contract stuff here.

epagelast Saturday at 5:58 PM

I think the switch statement design is a foot gun: defaults to fall-through when empty and break when there is a body.

https://c3-lang.org/language-overview/examples/#enum-and-swi...

show 3 replies
theflyinghorselast Saturday at 5:11 PM

I keep thinking about perhaps LLMs would make writing code in these lower-level-but-far-better-performing languages in vogue. Why have claude generate a python service when you could write a rust or C3 service with compiler doing a lot of heavy lifting around memory bugs?

show 6 replies
masavikyesterday at 4:02 AM

Does c3 use llvm?

jksmithlast Saturday at 6:00 PM

Windows is a horse that is becoming less and less rideable. Be great to get this to build on ReactOS as just a hobby or side effort.

peloratlast Saturday at 11:30 PM

Delete "fn" and I might get onboard

show 2 replies
gigatexallast Saturday at 10:58 PM

Why have features but then the compiler doesn’t make programs that enforce it…

I’m seeing a lot of this in the docs:

“However, just like for const the compiler might not detect whether the annotation is correct or not! This program might compile, but will behave strangely:”

turnsoutlast Saturday at 8:42 PM

Looks interesting, but operator overloading is an anti-pattern. Leading with that is like leading with "full support for null pointers."

oulipo2last Saturday at 8:27 PM

Interesting! If today I wanted to start a project in a C-like language, I'd have chosen Zig. Would you tell a rough overview of how C3 differs from something like Zig?

bluecalmlast Saturday at 8:11 PM

I like the idea of strict improvements to C without taking anything away or making any controversial (as far as language design goes) choices.

One thing I am wondering is why new low level languages remove goto (Zig, C3, Nim). I think it's sometimes the cleanest, most readable and most maintainable solution. I get that's rare but especially when you are expressing low level algorithm operating on arrays/blocks/bit streams it can be useful. It's not that you can't express it with "structured" constructs but sometimes it's just not the best way. I get removing backwards goto when you provide alternative constructs for state machines but forward one is useful in other contexts.

Is it a purely ideological choice or does it make the compiler simpler/faster?

show 1 reply
CyberDildonicslast Saturday at 7:20 PM

It seems great to have something that is C but cleaned up, although clay had all that with templates and move semantics.

I think leaving out move semantics and destructors is inexcusable at this point. It is not only fundamental, but doesn't affect things like standard libraries, runtimes, or ABIs.

zephenlast Saturday at 6:42 PM

" the C-like for programmers who like C."

Sounds intriguing. But then, the first thing I noticed in their example is a double-colon scope operator.

I understand that it's part of the culture (and Rust, C#, and many other languages), but I find the syntax itself ugly.

I dunno. Maybe I have the visual equivalent of misophonia, in addition to the auditory version, but :: and x << y << z << whatever and things like that just grate.

I like C. But I abhor C++ with a passion, partly because of what, to me, is jarring syntax. A lot of languages have subsequently adopted this sort of syntax, but it really didn't have that much thought put into it at the beginning, other than that Stroustrup went out of his way to use different symbols for different kinds of hierarchies, because some people were confused.

Source: https://medium.com/@alexander.michaud/the-double-colon-opera...

Think about that. The designer of a language that is practically focused on polymorphism went out of his way to _not_ overload the '.' operator for two things that are about as close semantically as things ever get (hierarchical relationships), simply because some of his customers found that overloading to be confusing. (And yet, '<<' is used for completely disparate things in the same language, but, of course, apparently, that is not at all confusing.)

I saw in another comment here just now that one of the differentiators between zig and C3 is that C3 allows operator overloading.

Honestly, that's in C3's favor (in my book), so why don't they start by overloading '.' and get rid of '::' ?

show 3 replies
WhereIsTheTruthlast Saturday at 6:03 PM

We have solved the better C issue, but nobody seems keen on solving the better compiler issue

Why do we still have to recompile the whole program everytime we make a change, the only project i am aware of who wants to tackle this is Zig with binary patching, and that's imo where we should focus our effort on..

C3 does look interesting tho, the idea of ABI compatibility with C is pretty ingenious, you get to tap into C's ecosystem for free

show 6 replies
fatty_patty89last Saturday at 7:06 PM

not being able to do alias i32 = int; was the biggest turn off for me

Rohansiyesterday at 5:25 AM

c3 is as easy as 1,2,3

maximgeorgelast Saturday at 5:22 PM

[dead]

bigbadfelinelast Saturday at 6:14 PM

[flagged]

gdsdfelast Saturday at 6:32 PM

Honestly if your programming language does not compile to wasm I don't care for it. That's my new rule.

show 2 replies
TZubirilast Saturday at 5:19 PM

If I had a dollar for every C successor...

bofialast Saturday at 5:38 PM

Does this compile to Rust with an LLVM?

show 1 reply