Objective-C is just, like, a leaky abstraction over C
blog.metaobject.com
blog.metaobject.com
Brad Cox's above book and Bertrand Meyer's Object-Oriented Software Construction (using the Eiffel language) were my guides to Object-Oriented Design/Programming and Software Engineering in general and i am eternally grateful to them.
C++? Not so much because, in essence, that is also a leaky abstraction where you have to care about even more issues. Static versus dynamic methods to give an example: code looks the same but works subtly very differently depending on whether the methods used are static or dynamic. So you cannot ignore how the mechanics of the language works underneath and there is a continuous high mental load.
IMO Objective C is simpler - the OO side of it is all dynamic. For performance optimisations you can drop to C and you can really know where you are and what to expect.
To be fair I haven't used Objective-C enough so perhaps there are things about it which would turn me off it in the end. I liked Go for example but the way modules work eventually wore me down.
(not the OP)
https://www.mail-archive.com/discuss-gnustep@gnu.org/msg2550...
As you guys know, Algoriddim makes use of GNUstep on Windows. It has just been released in beta: https://www.algoriddim.com/store/djay-windows-beta
When I'm doing something on my own it's usually so small that it's not really worth it - something like a python C module where there's already a kind of OO model built in. I think my last C program was a set of functions for GNU Make that you can load up - a collection of tiny functions to do simple things that GNU Make should have been able to do 15 years ago but is too constipated to get on with.
Once or twice I've had the perfect sized mini-project but have been in a team where using Objective-C would get me into trouble because the rest of the team love C++ or whatever and would immediately demand that I use that instead. For some reason using C didn't bother them.
But I think it's no longer quite correct to describe ObjC as plain syntax sugar over the ObjC runtime C API (same as it is no longer correct to say that C++ is simply a preprocessor for C - AFAIK both ObjC and C++ started as such preprocessors), especially when it comes to features like ARC where the compiler does static lifetime tracking on ObjC object references. I don't think this can be replicated in plain C (and in C++ only less efficiently, since smart pointers are a stdlib feature and oblivious to the compiler).
PS: I actually do like the ObjC syntax. One great feature is that ObjC leaves the C syntax and semantics alone, which means that ObjC automatically supports the latest C standard. C++ would be a much better option today if it went the same route, but instead the 'C subset' in C++ is stuck somewhere ca 1995.
That would be possible for static binaries, but I don't see how that would work for dynamic libraries. Two libraries or a library and the executable would need the strings around in order to ensure they both got the same global address. You could mangle the strings to dynamic symbols so that it's just regular dynamic symbol resolution to get multiple loaded entities to agree on an address, but in that case, the selector string is still present in the binary in mangled form.
See https://www.sealiesoftware.com/blog/archive/2009/09/01/objc_... and https://www.mulle-kybernetik.com/weblog/2015/mulle_objc_sele...
I actually can't find much authoritative discussion about this on the internet, just those two posts. But since the objc-runtime is open source, you can probably find it there. I think it might be this method?
https://github.com/opensource-apple/objc4/blob/cd5e62a5597ea...
--
But I'm not sure what GP meant by "at compilation". I suppose the compiler could be smart by reading the selectors of any shared libraries you link against and avoid duplicates in _your_ binary, but that wouldn't work for two shared libraries that know nothing about each other nor anything mapped in via dlopen.
Once they had the need for the pre-processor, they decided they might as well make some usable, Smalltalk-derived syntax.
Exactly! :-)
And that's a good thing!
Even the keyword syntax in general and Smalltalk syntax specifically...no wonder it gets reinvented.
https://blog.metaobject.com/2020/06/the-curious-case-of-swif...
This isn’t always the case with Swift, unfortunately.
The older I get, the more and more I think ObjC had many things right.
That’s not really true of all Lisps! Common Lisp may be compiled straight down to assembly (that’s what SBCL does). It can call straight out to the host OS, just like a C program. Now, due to things like garbage collection you have to manage things a bit at the edges, but that’s no different from a language like Go, and I think that no-one would say that Go is its own machine.
It’s true of some Lisps, such as Emacs Lisp. Emacs is really a virtual Lisp machine with an editor as a shell.
I think that it’s also true of Smalltalk.
For example, we used template wrappers around NSArray for static type checking and "smart pointers" to avoid manual release/retain calls all over the place, which was glorious.
Also bonus points for mentioning the work of Piumarta, whose paper on extensible object models is my all-time favourite and has occupied my mind for years.
> Can you go lower level than obj_msgSend?
In Oberon you have low-level message sending. See this article that builds in small steps through the various OOP strategies and shows message sending in the last example:
ChatGPT is giving me contrived examples or examples that could have been achieved with the knowledge of classes at compile time.
Send a message to an object that is actually proxied over the network to another server.
And after 30 years, the tooling still sucks, even though WinDev loves it so much.
Whether that's actually a good feature to have in your language is a different conversation entirely.
I don't remember what I did wrong but I somehow tripped over Objective-C's boolean which isn't a proper type but just a macro of an int value like it is now in C. I did probably something stupid like "if (b != TRUE) {}".
What made this so much more infuriating was that if I knew it was just a leaky abstraction over C I wouldn't have made that mistake. But I thought it was on the same level as languages from the Pascal family or Java or any other modern programming language.
That's not the case for the last couple of decades (I think since C99?). The underlying type of bool which is defined in stdbool.h is _Bool, which is a "proper" builtin boolean type. The type wrapping in a header is just there to not break existing code which had its own 'bool' typedef. AFAIK in C23, bool is a regular keyword now though.
You can still do "bool b = 10" or "int i = true". C being C ("everything is an int") this will be coerced to 1.
Post-rationalization can always blame the tools instead of one owning its own's mistakes. You can blame tools or documentation that omit crucial surprising information or explicitly lies to you. Everything else is assomption you'd better check, or just humbly accept that they will bite you, by definition, in the most unexpected ways.