Hacker News new | past | comments | ask | show | jobs | submit login

I'm not sure if you're leading this or not, but to be clear... this is exactly a type system.

(Edit: read your blog; it's clear you're leading it. Poe's Law is in effect sometimes here, sorry 'bout that!)

It's a good type system. Many programming languages don't support this kind of type information, notably C.

I'm always curious how far a sufficiently motivated masochist could go with C... I guess it's just C++ ;)

You can write very safe code by using structs (even 1-element structs) for everything. But there's no generics system and very little in the way of safe tools for making one; writing a safe "generics runtime" and macros to use it puts you halfway to writing a new language.

>structs (even 1-element structs) for everything.

Are there any large C projects written in this style?

I don't recall the LOC, but I used this style at a recent position. Basically, the idea is not to use bare primitive types anywhere - instead wrapping them in something semantic. Probably the two biggest wins from this approach were distinguishing types of indexes and (in the particular project) distinguishing price from quantity.

It does add a bit of boilerplate. For the indexes in particular, foo_lookup(foo, idx) is substantially safer than foo[idx.value] - but then you've gotta write the lookup functions (which may just be a macro but is still a bit of cruft). Locally, if using var.value everywhere in math is getting ugly, you can of course pull things out into temporary primitive variables - enforcing things at the boundaries between functions provides almost all of the benefit.

All I'm aware of is a friend's private project of around 20KLOC.

I would love to see even small examples of this.

I intend to write a blog post on this at some point... but I recently colored functions in C by passing an empty struct as the first argument, with a standard name and annotated with __attribute__((unused)). The propagation was manual, but trivially easy, and it proved a major help in refactoring when I had to move some functionality to a differently colored context. I was even able to get some (extremely limited) polymorphism using unions to express "any of these colors". It could even be marginally nicer if C allowed passing one union as another if the first was a subset of the second - which I think would be correct - but really parametric polymorphism would be the bigger win...

The Linux kernel is a good example of just how far you can push C (plus GCC and Sparse extensions), including type system enhancements (__user and __kernel), pseudo-OO (kobject, many structs of function pointers), and other safety features.

Applications are open for YC Winter 2020

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact