Cello – Higher Level Programming in C
libcello.org
libcello.org
1. Why? 2. Is anyone using it for anything serious?
The second one is easiest to answer: no. And most people are suprised to hear that I probably wouldn't use it for anything serious either.
If you hadn't noticed from my github page I love C, and while I am also very interested in the things Cello adds such as duck typing and interfaces, and all the syntactic sugar that makes thing really nice and literate; it doesn't interest me enough to choose it over C. Additionally who is going to want to use my project if it uses this weird hacky C library! People are (for good reason) very suspect of dependancies.
That isn't to say I don't like programming in Cello. I'm almost definitely the person who has written the most in it and some things are just a joy to write in it, and look so clear and functional and algorithmic. At some point in the distant future when I find the time I really will attempt something serious such as a web framework. If that takes off we seriously can decide if it really is a good project (hur hur hur).
To be fair, "why" can also be pretty easy to answer depending on who is asking: because I could. Because I thought it was kinda cool and that people would be interested. There seems to be some default position in programming that unless your project is silly or sarcastic people assume you are "advocating" something by doing it, or making some kind of political statement on software development. I didn't work on this project to try and change the world. Nor to create something better than the alternatives. It doesn't change my life if people use Cello or not. I wasn't frustrated with C++, and I wasn't looking for a cylindrical rolly thing for my cart. I just made it for fun.
Why? If it's as fast as C but has the benefit of sugar, why not use it?
> People are (for good reason) very suspect of dependancies.
Not web developers. :D Although we should be.
> And most people are suprised to hear that I probably wouldn't use it for anything serious either.
Again, why not? C performance but easier to read code sounds like a good reason to use it for something serious. What are the downsides?
This has tons of sugar; if you're just interested in how this stuff is possible in C it would probably be more instructive to look at the GNU library libffcall[0] which implements trampolines. The code is simpler and there's less syntactic sugar obscuring what's going on. Of course, the linked articles on the Cello home page are instructive too.
I've yet to actually use Cello myself since I feel like if you hack C up that much, you might as well just use something like C++, C#, Rust or what have you and gain even more benefits, like a mature ecosystem that's highly compatible with the features you're using while I worry Cello, when relying on normal C libraries, might require you to slip back into some C-isms that Cello desires to avoid due to your dependencies not caring.
Since the early 90's I never understood why some programmers insist in using what is basically a portable macro assembler for higher level programming.
It was already primitive when compared with the likes of Modula-2 and Turbo/Apple Pascal, not to mention all the other alternatives even higher level.
Another, unfixable problem was that the size of an array was part of the type of the array. This meant that you couldn't ever access past the end of an array, which was good. It also meant that you could never have a variable-sized array - you couldn't even talk about the type of such a thing.
This meant that Pascal was completely unusable for writing, say, a memory manager (what type would you give to the return from an allocation)? But that's a low level problem. It also meant that Pascal couldn't be used for a numeric simulation where the size of your grid was a user-supplied runtime value.
Note that I am only talking about the original (Wirth/UCSD) Pascal. I believe that Turbo Pascal fixed the variable-sized array problem.
The largely ignored Extended Pascal ISO standard also had those issues fixed.
The first Mac OS versions were written in Apple Pascal.
When implementing an OS avoiding Assembly is impossible. Even if intrisics are used instead, they are just another way of using Assembly like instructions.
There are lots of informations in this book, "Revolution in The Valley: The Insanely Great Story of How the Mac Was Made".
"But most of the Lisa code was written in the Pascal programming language. Since the Macintosh had much tighter memory constraints, we needed to write most of our system-oriented code in the most efficient way possible, using the native language of the processor, 68000 assembly language. Even so, we could still use Lisa code by hand translating the Pascal into assembly language.
"We directly incorporated Quickdraw, Bill Atkinson's amazing bit-mapped graphics package, since it was already written mostly in assembly language. We also used the Lisa window and menu managers, which we recoded in assembly language from Bill's original Pascal, reducing the code size by a factor of two or so. Bill's lovely Pascal code was a model of clarity, so that was relatively easy to accomplish."
Also, about half the LOC in MacPaint were assembly.
Of course anything related to graphics programming would be written in pure Assembly code, so excuse me if I misused "Some".
None of the Pascal dialects that extended it with features for professional programming suffered from it.
Not putting down the other languages - I use Python whenever I can, as it is such a joy to use. Anything other than C/C++ for most of my production code? Not in the foreseeable future.
If you feel the urge to quibble about that last sentence, recall how much existing code I (and by extension, the world) already have. Never, ever, can we afford to throw that away. Shall we write some horror show of Haskell, Erlang, Javascript, and Clojure interfacing into 'legacy' code that in fact would need to be updated all the time? No thanks. For all the hand wringing about memory management, between smart pointers (rolled my own before there were library versions) and RAII I can't remember the last time I spent a serious amount of time chasing down a resource leak. Maybe early 90's? I dunno, but it seems that I spend more time debugging Python code where I am passing in a variable of the wrong type and Python just silently spits out the wrong thing in response.
Would I like a 'better' language than C? Absolutely! Do I see one in my future? Not really. Because it is actually awesome at doing the kinds of things that need to be done.
I would love to use this library but as C programs often requires third-party libraries I could see many instances of having to use normal C types. Is there a way, for example, to easily convert a float to and from a var (with a Real key/value)? How would I use your library to take hash table values and assign them back into standard struct members? Would I just use traditional casting? Something tells me normal casting is not an option, or at least not so easy.
int cValue = 5; // because I randomly feel like that's a good number
var celloValue = $(Int, cValue); // I'm pretty sure this works, but I haven't proven it
Coming back from Cello to C, it appears that you can do this: long anotherCValue = as_long(celloValue);I think the most apt would be a comparison to Vala, which is compiled to C and also adds higher level languages features.
That said, Vala is much heavier, and requires manual writing of interface files to use C libraries.
I can see this being a useful tool if kept lightweight. It's certainly prettier than GObjects!
In fact, it fails to compile with -std=c99, it seems to require GNU extenstions, that's why they have -std=gnu99 in their Makefile. They use ##__VA_ARGS__, which is not in the C99 and AFAIK there is no portable way to make a workaround.
A note about the __VA_ARGS__ detail - You can portably avoid it in a lot of cases if you plan ahead and allow __VA_ARGS__ to suck-up one extra always-provided argument, but it's not as clean as the GNU extension and can't always be done.
EDIT: AFAIK "$" is not valid ANSI-C, however I would love it... For example in a reference counting system could be cool to have $() and _() to incr/decr references.
I think it's more like a framework than a library, based solely on the principle that it basically encourages a completely different syntax and code style that someone else would have to learn in addition to C in order to work with code written using it.
I feel that calling it a framework is really pushing it. C is such a simple language, and things like the GNU C extensions and the macros the Linux kernel provide offer some similar semantics, particularly when dealing with linear data structures. Not to mention, when dealing with POSIX, your coding style completely changes to fit what it gives you.
By that measure, maybe Brainfuck is a simple language too. But I wouldn't want to actually program in it when there are so many sane alternatives available.
Yes, and no. If you're sticking with just raw C and the standard libraries, it's a simple language. That doesn't mean your program will be simple, however - security concerns alone ramp up the complexity by orders of magnitude. But at its core, it is a simple language with mostly simple rules.
But, C can be improved a lot without violating its nature with better libs. Libc is very unreasonable on what it offers. It should have data structures, dynamic strings, a few buffers that are easy to consume both sides, and so forth. This is what people keep reimplementing again and again and again.
[0]: https://github.com/eudoxia0/cmacro [1]: https://github.com/eudoxia0/magma
[0] https://github.com/eatonphil/ViolaGo does provide collections and iterators and such, so Cello is similar on that front. But, every modern language provide those things, and Cello collections don't seem any more Go-like than they seem Python or ObjC like.
Well written C is consistently faster than well-written Go. There are some dynamic runtime elements to Cello that could potentially hurt performance but I doubt it's a major factor.
I think Rust is probably the better modern language to compare Cello to, and I suspect they'll have similar performance. ObjC would also be a reasonable thing to compare.
But, for most things, they're all Fast Enough. Performance is probably not a useful metric. The reason I could see for using this would be modernizing an existing C codebase (though I'd be cautious about relying on something like this until it has a healthy uptake among developers), or when working in environments where only C compilers and libraries are available. If I were starting a new systems project, I would start with Rust or Go (or maybe ObjC if I ever had to work on Mac/iOS).
Mostly though, I think it's just a cool experiment, and educational.
And, lots of benchmarks between C and Go have already been done. Likewise, Rust and Go, and Rust and C.
(Serious question)
(Serious answer.)
But I think you're really asking a different question than the one your words say. I suspect you're asking why someone should bother to write this. There are several possible reasons. "Just because they felt like it" is a perfectly fine reason. "Because they thought it was interesting" is pretty close to the same reason. "Because they thought the world needed this language" is probably not as good a reason, because it seems somewhat unlikely to be correct.
> delete(items);
This part is funny: "Higher Level" but still no garbage collection.