The C Object System (2010)
arxiv.org
arxiv.org
Not that it's not worth doing again for fun or to explore different techniques and purposes. But the ones that are in use in the real world are incredibly clumsy and complex, require a lot of boilerplate and yak shaving, and you have to buy into a big toolchain and religion.
"The guy who invented the wheel was an idiot. The real genius was the guy who invented the other three." -Sid Caesar
¯\_(ツ)_/¯
The whole point of writing C is to keep it simple and only build exactly what's needed. No other language I've tried comes close to supporting the same level of custom fitting. This is also the reason it's potentially really fast; more because it encourages simple, direct solutions than anything else.
Virtual dispatch is a function pointer, either embedded directly in the value or together with others in a shared vtable. A type id may be added to the vtable if needed. Avoid inheritance tricks, composition is mostly the right answer in C. Downcasting is a solved [0] problem [1].
[0] https://gitlab.com/sifoo/snigl/blob/master/src/snigl/type.c#...
[1] https://gitlab.com/sifoo/snigl/blob/master/src/snigl/util.h#...
" a small C library which implements high-level concepts available in Clos, Objc"
Well, Objective-C is "a small C library" which implements the high-level concepts available in Objective-C. Mostly. At some point, the creators found out that they needed a "compiler" to gather up and unique selectors, and at that point adding a small amount of syntactic sugar was easy and useful.
An object is a struct with pointer to a class as its firs element. (A class is another struct, it is also an object) And 'id' is a pointer to such an object.
A selector (SEL) is a uniqued C-String.
A method is a C function that takes an object and a selector as its first arguments:
-hi:there {
}
is roughly the same as id hi( id self, SEL _cmd, id there ) {
}
(The naming is slightly different)Sending a message is calling the function objc_msgSend(). And if you don't like the syntactic additions, just call objc_msgSend() yourself.
Those who don't understand Objective-C are doomed to reinvent it?
To destruct -- to collect.
To collect -- perchance to tenure: ay there's the rub!
For in that collection of destruction what cycles may come
When we have shuffled off this mortal core,
Must give us callbacks.
Finally, as far as I understand Cfront was a proper C++ compiler that simply targeted C instead of ASM (like many compilers for other languages do ), not some sort of C preprocessor (Cfront was initially bootstrapped with a c-with-classes preprocessor though).
sgl_baseof uses offsetof with a valid struct type and a valid field name, so where is the UB? Unless you feed it an invalid pointer, but then all bets are off.
If an implementation provides offsetof and it doesn't work, that implementation would go out of fashion in a heart beat.
Where is the practical use of this information?
How is this even an argument?
The patent's expired (I like to think of this as a Mercy Patent, that benefits society by keeping people from doing this for 20 years):
Method for apparatus for implementing a class hierarchy of objects in a hierarchical file system
https://patents.google.com/patent/US5187786
Abstract
A method and apparatus for implementing a class hierarchy of objects in a hierarchical file system is disclosed, which does not require the support of additional file attributes by the hierarchical file system, and has particular application to object oriented programming in window-based computer systems. The class hierarchy comprises a root class, a plurality of classes and a plurality of class instances. The root class is implemented with a hierarchy of root class directory and root class files. Each class is implemented with a hierarchy of class directories and class files comprising the class methods, and the initial values of the class instance variables. Each class instance is implemented with a hierarchy of class instance directory and class instance files comprising the class instance variables. Each hierarchy of directories and files also comprises a path file. The content of these path files are logically related to each other, based on their class' relationships. By controlling the invocation of class methods, using these path files, inheritance is achieved. By accessing the class instance variables through the class methods, data abstraction is also achieved. Additionally, the method and apparatus also supports the pseudo class instance/class "Self" and "Super" when invoking another class method by a class method.
You focus on CLOS in isolation and you not only end up missing the point completely but also end up with a frankenstein monstrosity that can be very destructive. This also reminds me of Alan Kay talking about how most OO languages completely missed the point unlike Lisp that got it: Late binding.