Not abandonned though, just no features to be added, and C doesn't evolve a whole lot, so no need for updates. This is a pretty desirable state for a project to be in, actually.
What's wrong with that? Rust seems to be fully capable of doing low level things like drivers and kernels, so why would you choose less abstraction and safety instead of more?
In a time where C++ exists, C still gets used. C interop is even easier in C++ than Rust IIRC, so given the choice, C++ would get the nod much earlier I'd imagine.
That said, people use C because it forgoes abstractions and complications. Neither C++ nor Rust provide that experience. I think Go comes the closest, while being a bit nicer to work with overall.
C++ has more features than Rust but you can limit yourself pretty severely and use "simple" features to get far more safety and convenience than C without having to wrap your mind around Rust.
True for your new project from scratch when you already sucked up C++ such that you know what&when.
But at this point you know C++ pretty well (including all what you don't want to use, take a look at the CPP Core Guidelines), and using Rust is almost trivial, since Rust doesn't really introduce anything really new you wouldn't be already familiar with.
I agree, and much easier than Rust to get going and then some. Other than playing with Nannou in Rust to 'get' the language, and the Rust book, I started a toy game in Zig without more than the skeleton put together here:
I like Raylib, and there are bindings for most popular languages, but I like the minimalism I can start with fairly quickly in Zig. I tried Bevy for Rust, but it is a lot more involved, and Rust, so Zig it is for now.
For safety, and high-integrity software, I am sticking with SPARK2014. Rust will get there soon, but Ada/SPARK2014 have such a lead, maturity, and industry take up that I am putting Rust down for another year or more.
I kinda wish SPARK were mainstream. Ada kind of aims for the same things as Rust, but it's been around such a long time. It's amazing how long C has stayed around.
That's a bit debatable. Vlang is right there too. This would all be relative to what people are trying to do. Many people might really be looking for a C and C++ replacement, of which there are a number of viable alternatives (including good old Object Pascal), but then preferences and other factors makes things cloudy.
Rust is the one Torvalds seems most interested in, and I suspect that's a deciding factor.
Zig might be the most direct upgrade from C, but it seems like rust can mostly replace the entire concept of portable assembly, since it has zero cost abstractions.
The question is whether they should be foregoing those abstractions and complications.
C is not a language known for high security or reliability, nor is it known for being fast or easy to develop in, so by my guess based on vague anecdotal evidence, it seems that defaulting to the highest level of abstraction unless forced to do otherwise by some specific requirement is a better plan.
C and direct C replacements advertise simplicity, but if the simplicity doesn't buy you any reliability in practice, why bother with it?
I tried multiple times to grok rust, but it's still too difficult for me to understand and be comfortable. In contrary go other than the struggle of unused variable compile error, I can use it within hours.
Rob Pike is 66 and the average male life expectancy in America is 76 years. Of course I wish him to live happily for many more years, but it would be presumptuous to expect him to work on Go for the rest of his life.
But although google has killed 264 projects so far [1], I believe that Go has too many dependents at Google and in industry to cancel. And even if it should happen anyway, the community will fork it.
Yeah... Exactly. Look at all the stuff Bell Labs came out with in the 60s and 70s that still survives today, without their involvement. Go will live on regardless.
You can't literally kill a FOSS project like you can with proprietary, but it can go away if nobody else wants to maintain it.
FOSS projects die all the time. You might want to write a patch here and there, but do you want to do all the DevOps, pay for hosting, manage testing, etc?
Sure, but there are enough huge companies using Go (including organisations like banks for whom a couple of developer salaries are small change) that I’m sure someone would step up to maintain it.
That article completely misses the point - assembly (or machine code) might not be how the "metal" works on a modern desktop(-like) CPU, but that is irrelevant when that is the lowest level that said CPUs are exposing. On such CPUs C is at the lower levels possible.
But also C isn't just for Intel, x86 and (some) ARM CPUs, there are other targets it has.
Nothing of that is exclusive to C, please provide an example of a CPU where C is the only compiler toolchain available, and exposes CPU capabilities without using language extensions.
Any example with language extensions to ISO C, allows me to provide a counter example with language extensions.
Any example where only a subset of ISO C is allowed, allows me to provide a counter example with a language subset.
Are you replying to the correct comment? I never claimed anything that would be exclusive to C. What i wrote applies equally to something like, e.g., most Pascal dialects that are around the same "level" as C.
For some cases that's fine, but go has terrible FFI, which make it unsuitable for some use cases, and being garbage collected makes it unsuitable for others.
This shows up periodically and it looks pretty nightmarish (~15 years reading and writing C). If you want this kind of abstraction, I think you're better served by any of the dynamically-typed scripting languages.
One of the advantages of a language is that you can get someone with experience in that language and they'll be able to understand it (with some work for code style and libraries used etc).
This seems to be different enough you may as well just use another language.
It is definitely worth pointing out that this isn’t new, the idea itself is truely fascinating and the author clearly articulates this is code as art. It is definitely eye opening once you read into the details.
I stumbled across this when a new chapter of crafting interpreters came out, and I ended up doing a deep dive into how to speed up CPython. My conclusion was that it wouldn’t be possible without rearchitecture of the fundamental types, and hence unpalatable, but a fun exercise none the lesser
If you’d be wrong to so quick to dismiss Cello. Cello is an order of magnitude quicker than python, even cython can only achieve 3x on CPython without annotation. The ideas behind Cello put it somewhere around JavaScript speed, but far more extendable, and definitely worthy of further investigation.
To expand further, fat pointers (void type, void data) could be superior to NaN boxing, and I’m not aware of any interpreted languages that have seriously implemented fat pointers, but it seems to be going well for Rust.
> any interpreted languages that have seriously implemented fat pointers
Have a look at PicoLisp. It has less than a handful of data types but i uses "Tag Bits". Julia is not really interpreted but it uses pointer tags for union types to save on boxing?
Are you seriously proposing banning posts about an experimental programming language because you think it is harmful? This radicalization is one of the most concerning issues with today’s society.
"Experimental programming language" is a huge stretch for this thing.
I think you need to understand a bit of some C subcultures to get this reaction. C more than other communities is about best practices to achieve certain goals like portability, stability, security, maintainability, etc. These best practices are often restrictive, or advocate cautious use of language features. Cello breaks a lot of these rules, sometimes haphazardly, and no experienced C person would advocate for some of those hacks.
But what ends up in the HN comment thread is a largely unfamiliar-with-C-culture looks at the README and comes away with the impression that this is an accessible way to learn C, which it is not.
I'm explaining why people would say this is a poor, even irresponsible introduction to the topic. "Nothing to understand", "censorship" are extreme reactions. It's a good idea to understand criticism before dismissing it.
To take an extreme example... If a medical textbook had some strange and nonstandard information, and doctors said it should not be published because it advocates poor health outcomes... Is that "censorship"?
I'm suprised that there are so many comments advising to not use it, when even FAQ of this library basically says that it's not production ready. It always was just cool project to show off how someone can hack C to it's limits.
People keep saying not to use this, and I think that's pretty wrong-headed.
Sure, if you're going to do greenfield software development, and you don't absolutely need to kind of closeness to the metal (not just performance, but direct access) that C offers, then use something else (Rust, Zig, Go ... if you need to compile to native binaries, Java, C# & their myriad of variants if you don't).
But if you have to use C, to extend an existing project, use a specific library, or hook some other system... why not use Cello?
For sure, this is not a tight black-box abstraction, so you should strive to understand the semantics of how it works. Once you do though, it'll make your life a whole lot simpler.
If you have to use C to extend an existing system, or hook into one, or leverage C code and so on, I found Nim to be brilliant. Because it is C once compiled.
I’m using it right now at work to build our firmware for our custom embedded board. It’s been brilliant: ESP-IDF is all C (mostly, some C++ but it all has C interfaces too) and wrapping, extending, calling and integrating into those has been a breeze.
I always get a bit sad when a nice library I come across in the wild is C++, as FFI to C++ is so much more... fiddly, in all languages, compared to a C library. The latter is a breeze.
In fact, today, I needed to be able to call the `esp_pthreads.h` functions (which describe some ESP32-specific extensions to it's pthread layer) and it took me, no joke, 5 minutes to wrap.
Pass the header through c2nim, add `{.importc, header: "esp_pthreads.h".}` pragmas to the proc definition, and done. Now I can call them without issue. Its liberating for sure!
That said, you can even wrap C++ if need be, though it's less elegant at times.
Seems to me, Cello would be more for those C programmers that didn't want to try the various alternative languages that are now out, and happen to agree with its developer's interpretation of preferred higher level abstractions and what they should look like. The point of these alternative languages is to offer features that C doesn't have or to implement them in easier or clearer ways.
This is a good point, and definitely worth considering. I would however weigh the benefits of these languages with the cost of complexifying the toolchain, adding another language into the mix, & future maintainability (I'm pretty sure I can still run `make` on the C codebase in 10 years. I'm not so sure about these others.)
I wish there was some dialect of C, with a complexity between C and C++, with simple things such as string, vector, dict...
I like V, nim, Zig, etc, but I just want a language that use the same idioms of C, with the same syntax flavor, without all the complexities of C++ (templates, inheritance, etc). I don't want complex, new features that new languages offer.
That's what I do, but it doesn't change the fact that compiling C++ is pretty heavy and slow, and C++ still suffers from a lot of backward compatibility.
Looks interesting, but it seems to be missing something that would allow you to deal with arbitrary binary data that has nulls in it. Looking at the types[1], there's a String, but it's mapped to null-terminated C strings. And I don't see a mapping to char or a pointer to some allocated memory.
I like some of the ideas here, but I think it goes too far. What I want is a modern replacement for libc, that has less global state, always treats arrays as a pointer and length instead of null terminated pointers (maybe with a macro to define a struct of pointer and length), has consistent error handling, standardizes on utf-8 for strings, either handles locale in a sane way, or doesn't worry about locale and leaves it up to the application/other libraries, instead if having a broken locale system, is designed with working in a multithreded environment in mind, etc.
But, I think all the macro magic in libcelli is a bit much.
I mean, it's still an interesting project, and it's cool that it's pushing the limits of c. But a more conservative replacement for libc would be more likely to see widespread use
90 comments
[ 2.6 ms ] story [ 103 ms ] threadhttps://github.com/orangeduck/Cello/issues/135
That said, people use C because it forgoes abstractions and complications. Neither C++ nor Rust provide that experience. I think Go comes the closest, while being a bit nicer to work with overall.
But at this point you know C++ pretty well (including all what you don't want to use, take a look at the CPP Core Guidelines), and using Rust is almost trivial, since Rust doesn't really introduce anything really new you wouldn't be already familiar with.
At least that was my experience.
https://github.com/michal-z/zig-gamedev
I like Raylib, and there are bindings for most popular languages, but I like the minimalism I can start with fairly quickly in Zig. I tried Bevy for Rust, but it is a lot more involved, and Rust, so Zig it is for now.
For safety, and high-integrity software, I am sticking with SPARK2014. Rust will get there soon, but Ada/SPARK2014 have such a lead, maturity, and industry take up that I am putting Rust down for another year or more.
Zig might be the most direct upgrade from C, but it seems like rust can mostly replace the entire concept of portable assembly, since it has zero cost abstractions.
C is not a language known for high security or reliability, nor is it known for being fast or easy to develop in, so by my guess based on vague anecdotal evidence, it seems that defaulting to the highest level of abstraction unless forced to do otherwise by some specific requirement is a better plan.
C and direct C replacements advertise simplicity, but if the simplicity doesn't buy you any reliability in practice, why bother with it?
There's almost no C code you could write in an effort to "forego abstractions and complications" that isn't also C++.
But although google has killed 264 projects so far [1], I believe that Go has too many dependents at Google and in industry to cancel. And even if it should happen anyway, the community will fork it.
[1] https://killedbygoogle.com/
FOSS projects die all the time. You might want to write a patch here and there, but do you want to do all the DevOps, pay for hosting, manage testing, etc?
Maintaining a project kinda sucks.
https://queue.acm.org/detail.cfm?id=3212479
https://www.f-secure.com/en/consulting/foundry
https://developer.arm.com/solutions/internet-of-things/langu...
But also C isn't just for Intel, x86 and (some) ARM CPUs, there are other targets it has.
Any example with language extensions to ISO C, allows me to provide a counter example with language extensions.
Any example where only a subset of ISO C is allowed, allows me to provide a counter example with a language subset.
Sorry if I misunderstood it.
https://news.ycombinator.com/item?id=6047576
https://news.ycombinator.com/item?id=14091630
https://news.ycombinator.com/item?id=8799070
https://news.ycombinator.com/item?id=22102533
https://news.ycombinator.com/item?id=10526159
https://news.ycombinator.com/item?id=19665596
https://news.ycombinator.com/item?id=11912427
This shows up periodically and it looks pretty nightmarish (~15 years reading and writing C). If you want this kind of abstraction, I think you're better served by any of the dynamically-typed scripting languages.
This seems to be different enough you may as well just use another language.
I stumbled across this when a new chapter of crafting interpreters came out, and I ended up doing a deep dive into how to speed up CPython. My conclusion was that it wouldn’t be possible without rearchitecture of the fundamental types, and hence unpalatable, but a fun exercise none the lesser
If you’d be wrong to so quick to dismiss Cello. Cello is an order of magnitude quicker than python, even cython can only achieve 3x on CPython without annotation. The ideas behind Cello put it somewhere around JavaScript speed, but far more extendable, and definitely worthy of further investigation.
To expand further, fat pointers (void type, void data) could be superior to NaN boxing, and I’m not aware of any interpreted languages that have seriously implemented fat pointers, but it seems to be going well for Rust.
Have a look at PicoLisp. It has less than a handful of data types but i uses "Tag Bits". Julia is not really interpreted but it uses pointer tags for union types to save on boxing?
Could it possibly be useful there?
I suspect just using a tiny Lua/JS/Python would be better but maybe in some super niche case this could have a use. Probably not though.
To my knowledge it's been demonstrated on AVR, ARM Cortex-M and ESP32.
It's macro system comes in handy for embedded, too, as you can precompute so much stuff at compile time.
I think Nim has quite nice standard library and production-ready. Zig, on the other side, is still highly experimental.
I think you need to understand a bit of some C subcultures to get this reaction. C more than other communities is about best practices to achieve certain goals like portability, stability, security, maintainability, etc. These best practices are often restrictive, or advocate cautious use of language features. Cello breaks a lot of these rules, sometimes haphazardly, and no experienced C person would advocate for some of those hacks.
But what ends up in the HN comment thread is a largely unfamiliar-with-C-culture looks at the README and comes away with the impression that this is an accessible way to learn C, which it is not.
To take an extreme example... If a medical textbook had some strange and nonstandard information, and doctors said it should not be published because it advocates poor health outcomes... Is that "censorship"?
Sure, if you're going to do greenfield software development, and you don't absolutely need to kind of closeness to the metal (not just performance, but direct access) that C offers, then use something else (Rust, Zig, Go ... if you need to compile to native binaries, Java, C# & their myriad of variants if you don't).
But if you have to use C, to extend an existing project, use a specific library, or hook some other system... why not use Cello?
For sure, this is not a tight black-box abstraction, so you should strive to understand the semantics of how it works. Once you do though, it'll make your life a whole lot simpler.
I’m using it right now at work to build our firmware for our custom embedded board. It’s been brilliant: ESP-IDF is all C (mostly, some C++ but it all has C interfaces too) and wrapping, extending, calling and integrating into those has been a breeze.
In fact, today, I needed to be able to call the `esp_pthreads.h` functions (which describe some ESP32-specific extensions to it's pthread layer) and it took me, no joke, 5 minutes to wrap.
Pass the header through c2nim, add `{.importc, header: "esp_pthreads.h".}` pragmas to the proc definition, and done. Now I can call them without issue. Its liberating for sure!
That said, you can even wrap C++ if need be, though it's less elegant at times.
Seems to me, Cello would be more for those C programmers that didn't want to try the various alternative languages that are now out, and happen to agree with its developer's interpretation of preferred higher level abstractions and what they should look like. The point of these alternative languages is to offer features that C doesn't have or to implement them in easier or clearer ways.
I like V, nim, Zig, etc, but I just want a language that use the same idioms of C, with the same syntax flavor, without all the complexities of C++ (templates, inheritance, etc). I don't want complex, new features that new languages offer.
Vlang is the most simple in your list – it is a different syntax, but not much more complex than C.
From the next release you will be even able to import C into D. https://dlang.org/changelog/2.099.0.html#__import
[1] https://libcello.org/learn
But, I think all the macro magic in libcelli is a bit much.
The article shows it with syntax highlighting, that I could only guess wouldn’t actually work.