sagev.space/posts/c

68 lines
3.0 KiB
Plaintext
Raw Normal View History

2020-12-29 15:03:54 -05:00
What is it with pointers?
Listen, if I had to pick a language to write a decent program in, I'd want to
use something like Rust. It behaves in more or less all the sane ways I want a
language to behave. Python's nice and quick for Python-y stuff, and Javascript
is Javascript, etc. But for some reason, I just <i>like</i> C.
I've written something of an implementation of Lisp for my Pebble smartwatch,
which I named PebbLisp. I'd love to have written it in Rust, to get some more
practice with it, but it was a real pain in the tookus to get compiling for the
watch, and I gave up. So, C.
I'll never act like C is a perfect language. Many, many, stupid memory leaks
could've been avoided with something smarter. For some reason, though, it's
just fun to work with. PebbLisp involves some dancing about with pointers, and
includes a homegrown tagged-union setup. There are parts that are probably very
ugly to more practiced eyes, and correcting unexpected behavior is a nightmare,
but coding it leaves me downright giggly sometimes.
The Object struct in PebbLisp has three parts:
<code class="codeblock">struct Object {<br>
Type type;<br>
union {<br>
...<br>
};<br>
Object *forward;<br>
}</code>
<h2>The Tag</h2>
The first part is the `Type` of the `Object`. This is just an enumeration with
all the possible types that a PebbLisp object can be. It's the tag of our
tagged union. Already I like it far more than is warranted. One number is a
front for every possible type? Incredible!
<h2>The Union</h2>
The second part is, of course, the union itself. I've cut it out here, but
there are members of the union for integers, pointers to strings, function
pointers, etc. Unions are also something I treasure. The famous issue with
unions is trying to keep track of what state any given union is actually in,
and god help you should it ever be interpreted incorrectly. That's why it's
fun, though. Coding a consistent way to access a union feels like cracking open
the secret door of programming. The Pointer
Finally, `Object *forward`: something that traditionally might be named `cdr`
(which I had to look up, because I'm really not enough of a Lisp guy). In Lisp,
everything is a list. An object with `forward == NULL` is a list of length 1.
An object that points to another object is a list of length `1 +
listLength(forward)`, aka itself plus the rest of the list.
So much code in PebbLisp is dedicated to making sure that this value is never
incorrect, duplicate, or useless. A `cloneObject()` function exists largely
because copies of individual objects can't keep this address. I'd love to use
our friendly neighborhood assignment operator: `=`, but C doesn't allow operator
overloading. But `cloneObject()` was fun to write, somehow!
<h2>C</h2>
Anyway, this has already run too long. Point is, C doesn't care what you do
with data. And for some reason, it's fun to redo decades of other people's work
in a project no one asked for. I highly recommend it.
#100DaysToOffload
2020-09-01