[HN Gopher] C-Macs - a pure C macOS application
       ___________________________________________________________________
        
       C-Macs - a pure C macOS application
        
       Author : dgellow
       Score  : 142 points
       Date   : 2024-04-19 10:53 UTC (12 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | magicmicah85 wrote:
       | Good example of digging with a spoon as they stated was the
       | original goal. And it still compiles on an M1 macbook despite
       | being a decade old code base.
        
       | codazoda wrote:
       | No license typically means copyright with all rights reserved in
       | the U.S.
       | 
       | Perhaps you want to release this into the public domain (see
       | SQLite)?
        
         | actionfromafar wrote:
         | I'd say the license is:
         | 
         | " Use it at your own risk, and don't blame me if anything bad
         | happens. Oh, and if you extend it, make sure there isn't any
         | Objective-C in it!"
         | 
         | I'd classify it as Open Source.
        
           | nicky0 wrote:
           | Oh no that won't fly at all. People around here really like
           | "proper" licenses. And they'll tell you about it.
        
             | actionfromafar wrote:
             | I don't like the (perhaps actually a) license, because it
             | set's limits on what the user can do with the source code.
             | (Not allowing Objective C in it.)
        
               | fao_ wrote:
               | yeah i accidentally added objective c code and now im
               | kissing my ass bracing for the lawsuit!!!!!!!111
        
             | gleenn wrote:
             | I'm not a lawyer but one would definitely let you know that
             | at least in the US, software without a license is more
             | dangerous than software with even a very restrictive one.
             | Someone can come along and determine the license at any
             | time. So there is good reason to point it out unless you
             | crave legal jeopardy.
        
           | williamcotton wrote:
           | It's open source but it is still under copyright. There are
           | notices in the source file:
           | 
           | https://github.com/CodaFi/C-Macs/blob/master/CMacs/View.c#L5.
           | ..
           | 
           | I would definitely ask permission and encourage the author to
           | change the license before using this code.
           | 
           | Since API calls are purely functional and not covered by
           | copyright you can mimic the behavior here but you'll need to
           | rewrite everything from scratch, notably the most expressive
           | parts, which are:
           | 
           | https://github.com/CodaFi/C-Macs/blob/master/CMacs/CMacsType.
           | ..
           | 
           | https://github.com/CodaFi/C-Macs/blob/master/CMacs/CMacsType.
           | ..
           | 
           | The organization and structure of this code is arbitrary and
           | within the author's creative expression.
        
             | actionfromafar wrote:
             | In most jurisdictions _almost everything_ is under
             | copyright, until it expires. (Which is approximately right
             | before the heat death of the universe, after Disney get
             | their way. Or 70 years after the authors death, or
             | something like that.)
        
               | ranger_danger wrote:
               | https://arstechnica.com/tech-policy/2021/04/how-the-
               | supreme-...
        
               | ngcc_hk wrote:
               | Actually Micky is free.
        
             | numpad0 wrote:
             | Copyleft licenses depend on copyright. I think it was in an
             | FSF FAQ somewhere. GPL is as copyright maximalist as it
             | gets.
        
             | williamcotton wrote:
             | I always see the strangest fluctuations in upvotes and
             | downvotes whenever I state the laws and doctrines of
             | copyright.
             | 
             | FWIW, I do court ordered code inspections to assess alleged
             | copyright infringement for a living.
        
           | embirico wrote:
           | I do love the vibe of that license
        
             | actionfromafar wrote:
             | If it weren't for it claiming to not be a license in the
             | sentence before, it would be pretty good. Reminds me of the
             | WTFPL license. :)
             | 
             | https://directory.fsf.org/wiki/License:WTFPL
        
           | dec0dedab0de wrote:
           | It's definitely not Open Source with that Objective-C
           | restriction. Though it does fit the attitude of the project.
        
       | chunsj wrote:
       | It seems that the code is the result of the ObjC preprocessor.
       | :-)
        
         | CodeWriter23 wrote:
         | I know humor is not allowed on HN but lol
        
       | 9dev wrote:
       | 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.
        
         | jojobas wrote:
         | 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.
        
           | swatcoder wrote:
           | 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)
        
           | astrange wrote:
           | You can write one in X11 if you like, if you make people
           | install Xquartz.
        
             | ngcc_hk wrote:
             | 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 ...
        
           | steve1977 wrote:
           | Beneath Cocoa are Core Foundation and things like Core
           | Graphics for example, which both are C.
        
         | williamcotton wrote:
         | 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.
        
           | rankam wrote:
           | 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?
        
             | detourdog wrote:
             | That is what objC scripting brige is for.
             | 
             | https://developer.apple.com/documentation/scriptingbridge
        
             | jimbokun wrote:
             | 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.
        
             | CodeWriter23 wrote:
             | There's already PyCocoa and pretty sure *Cocoa exists for a
             | variety of languages.
        
             | flohofwoe wrote:
             | 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).
        
               | jackjeff wrote:
               | 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.
        
               | gwking wrote:
               | In fact, early objective-c was a preprocessor according
               | to Wikipedia!
        
           | ChrisMarshallNY wrote:
           | 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.
        
             | thenipper wrote:
             | 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...
        
             | jonhohle wrote:
             | It has, but there was also Carbon until around the Intel
             | transition.
        
               | LeoNatan25 wrote:
               | 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.
        
               | ChrisMarshallNY wrote:
               | I think it's cool that a lot of NextStep stuff is still
               | there (all those "NS _XXX_ " calls).
        
               | saagarjha wrote:
               | Wait until you see the NX* APIs ;)
        
               | ChrisMarshallNY wrote:
               | I have not encountered them. Are they public?
        
               | saagarjha wrote:
               | Some are, though heavily deprecated: https://developer.ap
               | ple.com/documentation/objectivec/nxhasht...
        
               | nxobject wrote:
               | Quick! The one comment where my username is relevant!
               | Must... reply... before.. opportunity... passes...
        
             | ryandrake wrote:
             | 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.
        
               | williamcotton wrote:
               | 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!
        
               | saagarjha wrote:
               | The runtime knows how to do that already. -[NSApplication
               | run] sets up the runloop to drain events among other
               | things.
        
               | astrange wrote:
               | Why would you want to manage your own runloop? It's both
               | not interesting and possible to get wrong.
        
               | adastra22 wrote:
               | Sometimes there are conflicting things you need to do in
               | the same main thread.
        
           | mycall wrote:
           | > 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.
        
         | swatcoder wrote:
         | > 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.
        
           | LeoNatan25 wrote:
           | 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.
        
           | johnnyjeans wrote:
           | 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.
        
             | saagarjha wrote:
             | App bundles have no fixed layout. How would rpaths work if
             | you didn't specify them yourself?
        
             | astrange wrote:
             | > 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.
        
               | nxobject wrote:
               | 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...)
        
             | deergomoo wrote:
             | > 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.
        
         | lsllc wrote:
         | 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.
        
       | rdrsss wrote:
       | Love this, if I never have to write a wrapper around objc again
       | I'd be in heaven.
        
         | LeoNatan25 wrote:
         | This uses the ObjC runtime to obtain the underlying ObjC method
         | implementation functions, to call directly, instead of relying
         | on the runtime to call them. If you find this more elegant than
         | a wrapper with some ObjC, good for you.
        
         | icedchai wrote:
         | I find Objective C more pleasant to use than C++. Maybe I'm
         | crazy.
        
       | JKCalhoun wrote:
       | I did a straight C++ app for MacOS but 1) I used SDL2 and 2) it
       | was a full-screen game so no Cocoa UI needed. It was kind of fun
       | though in a retro-computing way.
       | 
       | (I'm a big fan of SDL now.)
        
         | jonhohle wrote:
         | Don't people do that all the time with Qt?
        
         | speps wrote:
         | The linked project doesn't use any ObjC files at all. SDL2 has
         | a bunch of Cocoa files[1] so you did use Cocoa even if
         | unknowingly.
         | 
         | [1] https://github.com/libsdl-org/SDL/tree/main/src/video/cocoa
        
           | LeoNatan25 wrote:
           | The linked project also uses Cocoa, and guess what,
           | considering Cocoa itself is written in ObjC, the linked
           | project also uses OBjC "unknowingly".
           | 
           | Considering CodaFi works for Apple now, he knows. Spoiler: he
           | knew 11 years ago too.
        
             | anamexis wrote:
             | The OP says it is Cocoa-less in the readme, is that not
             | true?
        
               | electroly wrote:
               | It's not. Open up any of the .c files and you'll see lots
               | of references to Cocoa. One of the comments refers to
               | Cocoa by name! This is using objc_msgSend to call into
               | Cocoa. You'd have to squint your eyes pretty hard for the
               | claim in the readme to be true. What it doesn't have is
               | Objective-C code, which is different than not having
               | Cocoa.
        
               | cancerhacker wrote:
               | check out the clang objc rewriter - basically c++front
               | for objc.
               | https://www.jviotti.com/2023/12/01/understanding-
               | objective-c...
        
               | astrange wrote:
               | Doesn't work anymore, especially because it doesn't
               | support ARC.
        
           | JKCalhoun wrote:
           | Yeah, that's okay. It wasn't like a "purity thing" for me,
           | just nice to write portable code.
        
       | cnity wrote:
       | > A little bit of this also has to do to stick it to all those
       | Luddites on the internet who post "that's impossible" or "you're
       | doing it wrong" to Stack Overflow questions... Requesting
       | permissions in the JNI "oh you have to do that in Java" or other
       | dumb stuff like that. I am completely uninterested in your
       | opinions of what is or is not possible. This is computer science.
       | There aren't restrictions. I can do anything I want. It's just
       | bits. You don't own me.
       | 
       | From the wonderful CNLohr's rawdraw justification[0]. I always
       | enjoy these kinds of efforts because they embody the true hacker
       | spirit. This is Hacker News after all!
       | 
       | 0: https://github.com/cnlohr/rawdrawandroid?tab=readme-ov-
       | file#...
        
         | wil421 wrote:
         | I like this guys spirit. Once I had to pick up old code from a
         | guy with this spirit and it was f-ing horrible.
        
           | mtillman wrote:
           | I love this project (from 2014?) and perhaps my favorite part
           | other than the f-u of the whole thing is the commit message
           | "complete refactoring".
        
           | shrimp_emoji wrote:
           | Beats using Java
           | 
           | Think of it as exercise: it sucks up front but you won't end
           | up an obese diabetic on the WALL-E ship later.
        
       | jbverschoor wrote:
       | This would've been a lot easier to wrap my head around when I had
       | to work with Objective C for the first time
        
       | flohofwoe wrote:
       | Here's something similar by Garrett Bass:
       | 
       | https://github.com/garettbass/oc
       | 
       | ...I also experimented a bit with parsing macOS system headers
       | via clang-ast-dump and then code-generating C and Zig bindings
       | but that didn't get far:
       | 
       | https://github.com/floooh/objc-ast-experiments
       | 
       | ...with a bit of effort and maybe using libclang instead of
       | clang-ast-dump that's definitely feasible though.
       | 
       | I guess a similar approach is used by the official C++ bindings
       | for Metal:
       | 
       | https://developer.apple.com/metal/cpp/
       | 
       | ...also shameless plug: the sokol headers allow to write simple
       | macOS applications (just a Metal canvas in a window) in various
       | non-Apple languages (currently C, C++, Zig, Rust, Odin, Nim):
       | 
       | https://github.com/floooh/sokol
       | 
       | ...I'm cheating though and use ObjC under the hood to talk to
       | Cocoa and Metal ;)
        
       | dgellow wrote:
       | I found this repo while looking for an equivalent to Win32 hello
       | world[0] as a learning exercise during a long flight (with my
       | work MacBook instead of my personal Windows machines).
       | 
       | That's something I really like about Windows APIs -- I can pick a
       | new programming language I want to play with, as long as there is
       | a way to interface with C I can try to port the Win32 hello world
       | then play around.
       | 
       | 0: https://learn.microsoft.com/en-
       | us/windows/win32/learnwin32/y...
        
         | tredre3 wrote:
         | The WIN32 API is somewhat ugly. I hate how all types are
         | capitalized and their short abbreviations in arguments are
         | sometimes weird. I hate how they have their own version of lots
         | of standard C types that you have to be careful about (they
         | weren't standard at the time, to be fair).
         | 
         | But it's quite straightforward and easy to use. Any language
         | that has FFI can call into it and build GUI apps, I've made a
         | windowed Hello World in PHP with it.
         | 
         | And it has been that way for 30+ years at this point. It's
         | quite remarkable, really!
        
           | dgellow wrote:
           | Also, UTF-16 (or WTF-16 as defined by
           | https://simonsapin.github.io/wtf-8/#wtf-16)
        
           | QuercusMax wrote:
           | I remember ages ago when I was about 12, I got a copy of
           | Turbo C++ for Windows 3.1 for my birthday. (I had only
           | written in Basic before, and wanted to learn a "real"
           | programming language. My dad was a Fortran programming
           | physicist, and had heard that C++ was what everyone was using
           | then-a-days.) I mostly wrote simple console programs, and it
           | came with the Borland ObjectWindows library with a fun GUI
           | builder, but there was a section in the manual talking about
           | how to write directly using the Windows API.
           | 
           | I didn't really understand any of what I was reading, but I
           | typed in the whole basic sample complete with HWNDs and all
           | that nonsense. I can't remember if I could even get it to
           | compile, but the idea of an event-loop was beyond my
           | comprehension as a 12yo. I'm sure if I went back it would
           | make a lot more sense to me, but back in 1994 it seemed like
           | dark magic, especially compared to the much simpler and more
           | understandable OWL components.
        
       | cossinle wrote:
       | Crazy that this has to be a thing .. Why does Objective C even
       | exist anyways??
        
         | astrange wrote:
         | Because Brad Cox liked Smalltalk.
        
       | w10-1 wrote:
       | Draw a line through this 12+-year-old effort from Robert Widmann
       | and his 8-year-old exercise in type-lifting Swift [1] and ask
       | yourself: what is he doing now at Apple?
       | 
       | [1] https://github.com/typelift/Swiftz
        
         | saagarjha wrote:
         | You can peek at his GitHub
        
       | vineek wrote:
       | Very nice. In similar fashion, a few years back I set out to
       | create Wuhoo.
       | 
       | Wuhoo loosely stands for W indows U sing H eaders O nly. It is an
       | attempt to create a single-header library (in the spirit of STB)
       | for graphics related window management, compatible with both C
       | and C++.
       | 
       | It works on Windows, Linux and Mac.
       | 
       | https://github.com/ViNeek/wuhoo
        
       | ks2048 wrote:
       | This would seem more complete if it had a simple Makefile rather
       | than an xcodeproj.
        
       | cornstalks wrote:
       | If you want to optimize this (and you enjoy pain), you can
       | eliminate the dependency on objc/* headers and use compiler
       | attributes and link sections to compile your code to the
       | same(ish) assembly that Objective-C compiles to. I don't have a C
       | example on hand, but here's a Rust example that's pretty easy to
       | translate to C:
       | https://github.com/objrs/objrs/blob/master/HOW_IT_WORKS.md
        
       | MaxLeiter wrote:
       | For an iOS attempt, I've often gone back to this wonderful
       | StackOverflow post: https://stackoverflow.com/a/10289913
        
       | lapcat wrote:
       | This app uses objc_msgSend, which feels a lot like cheating, but
       | if you simply want to avoid using nibs (while still using
       | Objective-C or Swift), check out my NiblessMenu project and my
       | "Working without a nib" blog series.
       | 
       | https://github.com/lapcat/NiblessMenu
       | 
       | https://lapcatsoftware.com/articles/working-without-a-nib-pa...
        
         | krackers wrote:
         | You can probably do a "true" pure C application (as in no Cocoa
         | at all) by dropping down to the CoreGraphics layer, but a lot
         | of it is undocumented.
         | 
         | There's also Carbon (which I always assumed directly hit the
         | same underlying quartz apis), but that's long deprecated and
         | iirc never supported the UI portions in 64-bit
        
       | KerrAvon wrote:
       | Seeing some confusion. This is using what are effectively FFI
       | interfaces to the Objective-C runtime. There's really no good
       | reason to do this in production code that isn't a language
       | bridge. It's not as efficient at runtime as writing the
       | functionally equivalent Objective-C, because the ObjC compiler
       | statically allocates class/method data structures, and it's not
       | as safe, because you're bypassing ARC.
        
       | hgs3 wrote:
       | It would be nice to have something like this except for Metal.
       | I'm unsure why Apple made Metal an Objective-C API when C + Core
       | Foundation would suffice. One big advantage of a C API is it's
       | easy to interop with other programming languages.
        
         | AceJohnny2 wrote:
         | Apple is opinionated about which languages should be used on
         | their platforms, and they enforce it with these kinds of
         | decisions.
         | 
         | For example, there was a time where Steve Jobs threatened to
         | forbid iPhone apps not written in Obj-C, which would have
         | destroyed the cross-platform ecosystem, at Apple's expense.
         | Luckily, he was talked down from being that extreme.
        
       ___________________________________________________________________
       (page generated 2024-04-19 23:00 UTC)