Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

As someone with no experience in native application development, could someone explain to me why this is significant? I have a rough idea, but I would like to understand it properly.


It's an exercise in recreating how an Objective-C app works in C from first-principles. For example, the creation of the AppDelegate (see CreateAppDelegate() in AppDelegate.c) is interesting because it shows how to create a class from NSObject and attach the applicationDidFinishLaunching: method along with it's implementation in C. I've used objc_msgSend() before from C (to access the pasteboard from a CLI app), but never implemented any ObjC classes using C!

It's similar how you might attempt to build a C++ class from only C components by creating a vtable.


MacOS apps are typically written in either Objective-C or Swift as these are the officially supported languages for the MacOS APIs.

The code in this template is interfacing with the Objective-C runtime but with pure C.


Does this mean that, theoretically, this could lead to the ability to build MacOS apps in higher languages that interoperate well with C such as Python? I know you can build MacOS apps with Python now, but does this potentially improve the experience?


You can already do this in the traditional way by building an ObjC shim which exposes a C API. The solution shown here just skips ObjC and talks directly to the ObjC runtime (which has a C API but is not as convenient to use as doing the same thing in ObjC or Swift).

In a highly simplified way you can think of Objective-C as preprocessor which replaces the ObjC syntax sugar with C function calls into the ObjC runtime (it's not how it works in reality, but how it could work).


That’s essentially what this project does. It creates the C code that the ObjC compiler would generate to “implement methods” or “send messages”.

It’s somewhat doable by hand because Objc is a thin lawyer.

Over 15 years ago I did stuff similar to this project to call some Objc code from a C++ app. Most of it was exposed to normal C APIs but one feature only available in AppKit. It was much simpler to do it this way than figure out how to make GCC or Objc like our C++ or any mess with bridging headers.

I think the move to Swift has made that harder in some ways.

But then again I don’t want to write C or C++ these days if I can avoid it.


In fact, early objective-c was a preprocessor according to Wikipedia!


That is what objC scripting brige is for.

https://developer.apple.com/documentation/scriptingbridge


I believe RubyMotion does basically this:

http://www.rubymotion.com

It was fun building an app in this a few years ago, but was difficult to keep up with updates to MacOS breaking my code.


There’s already PyCocoa and pretty sure *Cocoa exists for a variety of languages.


That has always been possible. Also, under the ObjC layer, is good ol' ANSI C (FreeBSD Unix).

There's a number of apps that run on modern Macs, that were written in C, but it is unusual to see ones that leverage the GUI.

That said, it's possible to walk from Boston to Portland (OR), but I'd rather take a plane.


I knew this was possible, but I had never actually seen it implemented before. And to think, the project is over 10 years old!

When I first started programming Cocoa, I was always kind of miffed that the happy-path was: "Use Objective-C and main() should just hand-off the reigns to NSApplicationMain()". Kind of like the happy-path on Windows is "WinMain plus a bunch of boilerplate crud".

It's always felt somehow vaguely "correct" to have main() be your actual application entry point and have it manage whatever main loop you need yourself. I see that this project doesn't actually quite get there either. It's the same kind of voodoo: boilerplate code, and then cmacs_void_msgSend(NSApp, sel_getUid("run")); hands over the reigns.


I agree. I recall the Windows API and the official Hello World. I'm sure they could have got to the same place in a slightly reorganised way that kept main() as the starting point and interfaced with the event loop and the entire windowing system via some API calls that hid the cruddiest parts of the boilerplate crud (apt phrasing, thank you) away in headers and libraries. Then progressively reveal the details when they're really necessary for more elaborate applications.


It has to hand over the reigns to the Objective-C runtime to allow for all the messages being passed between objects.

I’m not sure you want to spend your time rewriting what NSApp is doing!


The runtime knows how to do that already. -[NSApplication run] sets up the runloop to drain events among other things.


Why would you want to manage your own runloop? It's both not interesting and possible to get wrong.


Sometimes there are conflicting things you need to do in the same main thread.


You know i took the train to Boston to PDX, it was really relaxing. Not quite walking but definitely a lot different then a plane...


It has, but there was also Carbon until around the Intel transition.


Full Carbon was there until the 64bit transition officially, but much of it remained and still remains until now. For example, Apple only started using AppKit to draw menus in Sonoma; it was Carbon until now.


I think it’s cool that a lot of NextStep stuff is still there (all those “NSXXX” calls).


Wait until you see the NX* APIs ;)


Quick! The one comment where my username is relevant! Must... reply... before.. opportunity... passes...


I have not encountered them. Are they public?



> officially supported languages for the MacOS APIs

How often do you need to get support assistance from Apple? Just do what you want. If it means using Obj-C or Swift for ease, do that. If it means integrating another language, do that.


> why this is significant?

Ultimately, because new people keep being born and missed the years where this was pretty common and haven't yet bumped into the corners where it still is.

The repo and the SO discussion it was inspired by are themselves 11 years old and seem to be rooted in a new generation of iOS app developers starting to get more deeply curious about the system they're running on and how else it might be approached, which this person then ran with on MacOS.

Apple invites people to get started in making software for their platforms using (what's meant to be) more accessible tooling like Objective-C, Interface Builder, Swift, SwiftUI, etc but there's of course a whole BSD-rooted operating system sitting there once those those developers start digging. It's no secret, but it's a discovery that some people need to make on their own.


This isn’t an example of that. Have you looked at the code? This uses ObjC and Cocoa implementations in an unintuitive method. Nice exercise to learn about the ObjC runtime, but has zero practicality or use.


The funny thing is, Apple themselves seems to have forgotten about the whole BSD-rooted operating system. Anybody who ventures off the beaten path of developing software for a modern Mac will inevitably encounter a lot of cobwebs. One of my favorites: When Apple implemented app bundles, they never updated dyld's search paths to be aware of the app bundle directory structure, meaning you have to manually patch your rpaths. Not a huge deal, and one that's hidden from you if you only ever know xcode, but it's one of many very sloppy things I noticed coming from a strong Unix background to Mac. There's a lot of really weird incongruence where the deeper you go into the system, the more everything feels covered in dust and neglected. I was always sold on Macs having really great top-to-bottom integration and have all the polish and attention to detail you can expect out of a corporate Unix-like, but that's not what I found. It's more like a really shiny superstructure bolted on top of an ancient, rust-eaten BSD. Don't get me started on how a lot of the "newer" stuff at that low level tends to be some of the absolute worst takes on a concept. The "App Sandbox" might be the most disgusting, slap-dash design for process isolation I've ever seen bolted onto a kernel.

I get Apple's target market is quite literally the opposite kind of user that I am. That being said, I always find it curious that people still tout Mac as this kind of "Super Polished Desktop/Workstation Unix" and often cite the Unix certification. It feels like the more you try to use a Mac like you would any other Unix machine, the more you have to fight it. Often it doesn't feel any different to trying to wrangle Windows with WSL. I had less hiccups and trip-ups learning Plan 9 than I did coming to terms with macOS.


> When Apple implemented app bundles, they never updated dyld's search paths to be aware of the app bundle directory structure, meaning you have to manually patch your rpaths.

Typically things like this have binary compatibility reasons. (It wouldn't be because they forgot, actually I happen to know the same person has worked on dyld since the 90s.)

> but it's one of many very sloppy things I noticed coming from a strong Unix background to Mac

Funny thing to complain about. Sloppiness /is/ Unix design, that's intentional. It's called "worse is better".

On the other hand, nobody uses Plan9 because it's too well-designed to actually work.


Oh wow, employed since NeXT? (There needs to be an "Apple/NeXT long-hauler oral history" or something. Chris Espinosa, hired 1976, is still around...)


Avie Tevanian and Jon Rubenstein both have oral histories on the Computer History Museum website/YouTube.


> Sloppiness /is/ Unix design, that's intentional. It's called "worse is better".

That's missing the point. It's about simplicity through well designed abstraction. Unix was a runaway game engine that became Bell Lab's standard for talking to computers because it was vastly simpler than the poorly engineered MULTICS and friends. That's why it won.

> On the other hand, nobody uses Plan9

I use Plan 9 every day. I'm replying to you from inside abaco. I run a tablet with it, have a whole network of machines (most of them virtual). I'm in the middle of a project to create a light fixture I can talk to in 9p. It's not the first DIY IoT thing I've made to control over a Plan 9 terminal. My grid also runs my email, my file servers, an LLM chatbot (though this is actually served from a Linux machine via Inferno tsk tsk.) The only reason I use anything else is due to my job requiring me to ship a product in C++ and OpenGL. For something that doesn't "actually work", I find that it actually works excellently.


Hyperbole; "nobody" means an insignificant amount of people.


Go programmers use something Plan9-y, but I don't think much of Go's design either; it's a combination of Unix's underdesign with Plan9's inflexible and idiosyncratic taste.


Nah, this was already like this at NeXT.

The whole UNIX infrastructure was to get into the DoJ stuff that required POSIX compliance.

Just like with Microsoft, the approach was to allow UNIX software to come into NeXTSTEP, not to be created in NeXTSTEP and then leave it for other UNIX vendors.

All the relevant programs in NeXTSTEP used Objective-C, and even the drivers were written in Objective-C.

Apple was clever marketing OS X to the Desktop Linux crowd, that actually only cared about a POSIX experience and not so much about Linux itself.

Many of them helped Apple get out of red, into the company it is today.

This is how Microsoft finally understood how bad they did with POSIX on Windows NT linage, and out of Project Astoria ashes, WSL was born.

Had Microsoft actually kept POSIX subsystem up to date, and in parity with Win32 subsystem, and most likely Linux would never taken off, as everyone would have had their proper POSIX right there, without needing to look elsewhere.


> I always find it curious that people still tout Mac as this kind of "Super Polished Desktop/Workstation Unix" and often cite the Unix certification

I've always understood people to mean that it's a polished desktop operating system (though that's becoming increasingly questionable these days) that also happens to run the same CLI stuff they're used to using on Linux servers.

Pre-WSL just that was a pretty nice selling point by itself.


App bundles have no fixed layout. How would rpaths work if you didn’t specify them yourself?


They do if you want them to be signed.


I guess it's normally impossible to write a GUI application for mac os without objective-c libraries doing the talking to the OS, but what do I know.


It is not. This was just a new wave of people finally looking under the hood.

(Where they would have found many many dusty but detailed man pages and docs waiting for them)


Beneath Cocoa are Core Foundation and things like Core Graphics for example, which both are C.


You can write one in X11 if you like, if you make people install Xquartz.


Is there example how to do that on mac. Just happy to have an old emu ibm 5100 sun x program. Wonder I need to boot up a vm or can try squartz …


brew install --cask xquartz

Or install from the project homepage [1]. Then just launch the X11 app. Note that it does require the application to be built for Mac - it’s not an emulator, just an implementation of the X11 APIs.

[1] https://www.xquartz.org/




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

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

Search: