
Cello – Higher Level Programming in C - denysonique
http://libcello.org/
======
orangeduck
Author here. I always get asked two questions about libCello.

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.

~~~
MrDom
> it doesn't interest me enough to choose it over C.

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?

~~~
comex
It is not as fast as normally written C due to the dynamic typing.

~~~
musername
that's not necessary for the API, is it?

~~~
comex
The API allows 'var's to be treated as dynamically typed, so sure it is. More
to the point, if you tried to change it to be statically typed, it wouldn't be
expressible in the same nice-looking way in C.

------
TheDong
Previous discussion:
[https://news.ycombinator.com/item?id=6047576](https://news.ycombinator.com/item?id=6047576)

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.

[0]:
[https://www.gnu.org/software/libffcall/](https://www.gnu.org/software/libffcall/)

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

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.

~~~
agumonkey
Wasn't there some issue with Pascal type system being too restricting
sometimes (the unfortunate lack of cast) ?

~~~
AnimalMuppet
It wasn't just the lack of a cast. (IIRC, you could work around that with
variant records if you really had to, though it was really clumsy.)

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.

~~~
pjmlp
Those problems were not part of the Pascal dialects.

The largely ignored Extended Pascal ISO standard also had those issues fixed.

The first Mac OS versions were written in Apple Pascal.

~~~
agumonkey
I knew about Apple programs being in Pascal, but the whole OS ? did they
resort to inline asm ?

~~~
pjmlp
Yes, they did use Assembly.

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

~~~
saretired
They used more than some assembly. Andy Hertzfeld:

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

~~~
pjmlp
Basic, Forth, C and Pascal were the Ruby and Python of the 80's home
computers, both in compiler code quality and memory usage.

Of course anything related to graphics programming would be written in pure
Assembly code, so excuse me if I misused "Some".

------
runewell
I really love this. Are there convenience functions to convert existing values
to and from your new data types?

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.

~~~
AnimalMuppet
Converting a C value to a Cello value is 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);

------
seabrookmx
I see lots of weird comparisons here.

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!

------
pavanky
Has the development moved away from github[1] or has it completely stalled ?
The last commit I see is from 8 months ago.

[1]
[https://github.com/orangeduck/libCello/](https://github.com/orangeduck/libCello/)

------
zserge
> To compile Cello requires a C99 compatible C compiler.

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.

~~~
DSMan195276
You're completely right, this definitely uses GNU extensions.

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.

------
antirez
Too high level IMHO... $(Int,5) is not reasonable, also everything is too
opaque for it to be a C library. You can go a long way without creating such a
layer of abstraction with just a set of libs implementing data structures,
dynamic strings, with simple object-alike structures that are reference
counted so that it is trivial to have lists of hashes or alike, but where you
can also store raw stuff trivially just changing the "method" to free or dup
the objects.

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.

------
userbinator
The syntax is rather reminiscent of jQuery... and just like how that has
created jQuery developers who know next to no JavaScript, I could envision
many Cello developers who know almost no C which given the characteristics of
the language would probably be an even bigger problem. It's good that they
have a disclaimer saying that this isn't for those who don't already know C.

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.

~~~
edgyswingset
I'd say it's more reminiscent of Python, sans the dollar signs.

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.

~~~
pmoriarty
C is a simple language if you ignore all the traps, pitfalls, gotcha's, corner
cases, and exceptions to the rules.

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.

~~~
edgyswingset
> C is a simple language if you ignore all the traps, pitfalls, gotcha's,
> corner cases, and exceptions to the rules.

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.

------
api
It would be very interesting to pair this with a very well designed
minimalistic web framework, drivers for things like Redis, etc., for some
_VERY_ high-performance web backends.

------
otis_inf
Let C be C. For the people who don't like C for one reason or another, there
are a ton of alternatives available, from x64/x86 targeting languages to
manages stacks. Adding these libraries to C might look nice, but if you want
to experience the things it brings to the table use a language where it's been
borrowed from.

~~~
eudox
I wrote cmacro[0] and magma[1] with the goal of a augmenting C while keeping
it C-like.

[0]: [https://github.com/eudoxia0/cmacro](https://github.com/eudoxia0/cmacro)
[1]: [https://github.com/eudoxia0/magma](https://github.com/eudoxia0/magma)

~~~
ori_b
And I wrote Myrddin[0] for the goal of seeing what C would be if I was
reimagining it with the benefit of hindsight.

[0][http://eigenstate.org/myrddin](http://eigenstate.org/myrddin)

------
eatonphil
After seeing this I started work on a simplification of libCello called Viola
[0]. It has a slightly lighter syntax and takes away some (IMO) needless
typing...

    
    
        [0] https://github.com/eatonphil/Viola

------
_RPM
How are you implementing the dynamic type interface? Discriminated union?

~~~
orangeduck
It uses raw pointers (void*) and something a little like a vtable:
[http://libcello.org/documentation/hacking](http://libcello.org/documentation/hacking)

------
aosmith
I'd love to know how this compares to GoLang... Conceptually similar, which is
faster?

~~~
SwellJoe
I don't know that I would call it conceptually similar to Go. At least, not if
we're looking at the Big Pictures concepts, where Go has concurrency as one of
its major departures from C. I don't see any mention of concurrency primitives
in Cello (maybe they're there and I didn't notice, but I would think the
author would have put that on the front page, if it were a thing Cello tried
to solve).

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

~~~
Cyther606
Nim, with its Pythonic syntax and native code generation via C, compares as
well [1].

[http://goran.krampe.se/2014/10/20/i-missed-
nim/](http://goran.krampe.se/2014/10/20/i-missed-nim/)

~~~
aosmith
TY!

------
halayli
Just use C++11

------
chris_va
Why does this exist?

(Serious question)

~~~
AnimalMuppet
Because someone cared enough to make it.

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

~~~
fayyazkl
The last part might not be true. Though i won't generalize, let's just say
that i have been writing industry code for almost a decade, 90% C (because of
domain) and at least a quick review tells me, porting this to a couple of
major platforms could be very practical and useful IF IF, it does not
sacrifice the performance.

------
diego_moita
> /* Heap objects destroyed with "delete" */

> delete(items);

This part is funny: "Higher Level" but still no garbage collection.

~~~
vowelless
Why would higher level necessarily imply garbage collection?

