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

This very much sounds like a type inference with hinting version of the C type system with a minor extension. It also seems to have many parallels to the Objective C type system with id, but again in a type inference variant.

The three rules to apply to quite directly to standard OO C:

1. If t1 is a subclass of t2, t1 is also consistent with t2. (But not the other way around.)

Using the standard OO C method of subclassing structs, ie.

struct t2 {...}; struct t1 {struct t2 t2; ...};

This is obviously true and the normal subclass relationship, though the C syntax to use this is a bit awkward:

t2_method(&t1->t2, arg1, arg2);

2. Any is consistent with every type. (But Any is not a subclass of every type.)

In C the Any type is void. Using the class definitions above this is entirely valid and produces no warnings:

void v;

struct t1 = v;

So if you have an object of void type you can use it wherever you might require a stricter type. If you pass in something which is not consistent you'll get a runtime error (usually a segfault in the case of C).

3. Every type is a subclass of Any. (Which also makes every type consistent with Any, via rule 1.)

This just says that you can do the following without getting any warnings: struct t1 t1; void v = t1;

And this works quite well in C.

The extension to the C type system, beyond the type inference, is to make these rules recursive, especially in function types. For example, this produces a warning under GCC, though it will compile and run fine:

void f(int* func(int b, int c)) {}

void* g(void b, void c) {return b;}

f(g);

That might just be a limitation of GCC's type checking though.

I think this is quite a good direction to take. C's type system has proven sufficiently powerful over the decades to build large systems and at the same time is trivially bypassed when you paint yourself into a typed corner or you want flexibility strict static type checking finds cumbersome to provide.




> In C the Any type is void. Using the class definitions above this is entirely valid and produces no warnings: > void v; > struct t1 = v;

I assume you mean a pointer to void here. You explicitly cannot have a void value, as void is an incomplete type (it has no size).

  $ gcc -x c - <<<"int main(void) {void a; return 0;}"
  <stdin>: In function ‘main’:
  <stdin>:1:22: error: variable or field ‘a’ declared void
You can have a pointer to void, which works as you describe, though you must also use a pointer to the struct.

  void *v;
  struct t1 *b = v;


>For example, this produces a warning under GCC, though it will compile and run fine:

All function pointer types are convertible to any other function pointer type, and since 'func' is never called as the wrong type there is nothing wrong with your example. It's not a limitation of GCC, it's the intended behavior according to the standard.


Right, the standard allows it, but GCC hasn't yet extended its type checker to give you the help you'd want in this case. The warning effectively says "The standard says this is fine, but in most cases this isn't what you want". Which, in nearly all cases, is correct.

If I pass "void g(int a)" to "f(int func(struct foo f))" the standard says everything is fine, but it's almost certainly going to blow up. GCC helpfully notifies me of this.

The only case where this warning isn't what I want is where some of the pointer types have been replaced with void. That is, passing "void g(void a)" to "f(int func(struct foo f))" should work just like "struct foo f = (void *a);" and output no warning.

The proposal from the article supports this case and other similar recursive cases.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: