Just a note as to the distinction in dispatch mechanisms here: ObjC, Ruby, and other Smalltalk-like languages use “message passing”, which encapsulates a call symbolically as a “message” (name + args) then does a “dispatch” operation that looks up the code through the inheritance chain and runs it. If you override the dispatch mechanism you can do things like delegation or forwarding with great flexibility.
NewtonScript does the symbol lookup first (same as for any member lookup) and retrieves a function/closure object, then executes that function with an implicit “this” argument. Closer to the way JavaScript, Python, Go, or C++ do it.
Something like: implementing your own small if/else DSL [1]! I'm not saying that this is a good idea. I am saying that this is possible with overriding the method dispatch :')
In Pharo (a Smalltalk descendant) one needs to override the doesNotUnderstand method.
The thing is: the whole DSL that I made (with if/else/elif) is its own method call. It's exactly one method call. So if you write "code" like that, then you'll always have a variable length type of method call that Pharo won't understand. By overwriting it and checking for the right symbols (If, Else and Elif) one can group them together and mimic if-statement type of behavior.
Method swizzling is actually something different: replacing a concrete method definition.
There really isn't any good way of messing with the underlying message dispatch mechanism, objc_msgSend() unless you do DYLD interposing or some such hackery.
However, objc_msgSend() has enough hooks to allow you to do custom dispatching, but only after the normal lookup has failed.
Initially there was -forward:: which essentially gave you a pointer to a stack frame. Later, -forwardInvocation: gave you an NSInvocation, which was the message wrapped in an object. Nice, but slow. Since a lot of time the idea was just to forward the exact same message to another object, we later got a new intercession point that allowed you to return that other object.
But again, all these only got activated once ordinary lookup failed, hence NSProxy and friends (objects with very few methods implemented).
Oh, and there was the nil class hook: objc_msgSend() short-circuits when the receiver is nil, but for a while you could theoretically set a class to which the messages to nil would be dispatched. I tried it out a couple of times and it worked, but it was never really used, mostly undocumented and has since been removed, AFAICT.
Right, method swizzling is actually "monkey patching" in ruby parlance. You arent replacing the _dispatch mechanism_, you are relying on the fact that its a dynamic lookup to replace that entry in the lookup table at runtime. Which then the dispatch mechanism happily plays along with.
The original Doom was developed on NeXT, so a lot of the tooling (like DoomEd) was written in ObjC. If I recall correctly they abused this whole thing by making proxy objects that would happily call methods across the network, so they had level cooperative editing back in the early 90s (minus all the concurrent edit stuff we take for granted today, of course).
I was trying to google for some sort of reference to what I meant, but couldn't find one (found this thread instead...) but NSProxy seems to have been around long enough that it might well be the core of the implementation for what I was talking about.
Yes and no. Concurrency was still a problem that got short shrift. But the "overload doesNotUnderstand:, serialize the message and dispatch it over the network" was a fun way to do rpc-ishness in Smalltalk and ObjC before people got hung up on writing IDLs. (Looking at you, CORBA)
I'm reminded of Larry Wall's quote: "languages differ not in what they make possible, but in what they make easy."
With the latter approach, you can save the bound method as a value. Depending on the way this is implemented, it can carry some additional overhead—because you create an object to represent the closure. The Objective-C dispatch, objc_msgSend, is very fast and allocates no memory. This is an implementation detail, however.
I’d say that there’s a big difference between Python/Go and JS/C++.
In Python, obj.method returns a bound method call—basically, a function that saves obj and passes it in as the first argument, and obj.method() has exactly the same semantics as x=obj.method;x(). In JS, obj.method returns an unbound method, and the equivalent to obj.method() is x=obj.method;x.call(obj).
Objective-C has some nice semantics and a little bit of typing to help you out here.
objc_msgSend does allocate memory - for the IMP caches, and the class initialization costs (and calling +initialize) the first time you message a class.
Tangentially... The OpenStep spec was a collaboration between NeXT and Sun. Essentially, it was the NextStep API but cleaned up and made more OS-independent. Aside from running on NeXT (Mach), it ran on top of Solaris and Windows NT.
This was back in the day when Apple's preferred adjective was "beleaguered" and every 6 months there was a rumor that Sun would buy up Apple (while we're at it, Apple sold Mac Execution Environment that was a MacOS emulator for Solaris), so in a slightly different universe, Sun bought Apple and OS X happened 5 years ahead of schedule.
Sun and Apple were drawn together as my-enemy-is-your-enemy due to Microsoft. There the cultural overlap stopped. It is not surprising to hear about some inside lower-upper-management plot among stock owners, to M&A their was to personal Lambo riches. Neither user community wanted this, and the World was a very different place at that time.
Some sources actually say the NS prefix in Cocoa/OpenStep classes stands for NeXT/Sun.
(others say it’s simply NeXTSTEP, however considering that those classes had a NX prefix initially, the NeXT/Sun bit might actually be closer to truth)
Aha. I think that explains why NS<foo> methods started creeping into NeXTStep 3. That's about the same time frame as the yellow box, NeWS and sparc becoming a first class supported platform for gnu/objc.
"James Gosling, being much older than I was, he had lots of experience with SmallTalk and Simula68, which we also borrowed from liberally."
The "objective" part of Obj-C is itself obviously a calque of Smalltalk, so we can pretty much reduce it to these two. And then if you look at them and compare either to Java, it's obvious that it is much more of a Simula descendant. As is C++, by the way, so while Java may not descend from C++ other than syntactically, they're still siblings.
When Objective-C was two guys in a garage the company I was working at was pitched by them to use it for writing software that would run on a minicomputer. This was way before Next.
My initial impression was "Huh, so I could take the syntax definition for SmallTalk and add it to the syntax definition for C and there would be almost no collisions. Cool!" At the time I was playing with parsers in connection with automating law form filling, e.g. Westlaw form books.
I agree with another poster's impression that it's more Simula-like. As an undergrad I played with M4 macros to make C more object-ish.
To me Java is a fantastic high-level language. I think a lot of people in the web world would be pleasantly surprised to re-discover it.
Python/Ruby only became popular because of Oracle licensing fees (now a non-issue thanks to alternative JVM implementations), and stayed popular because of science (you really can't beat the simplicity of Python for the sciences, people don't really want to have to fight with syntax in the science fields).
I think the only areas where Java isn't good are when you need deterministic latency (such as in a 3d renderer), or when you need a simplistic syntax that non-programmers can use.
finally my life makes sense! I was a java programmer asked to build an iphone app in 2008 and I learned Objective-C by hacking my way through it. Anyone remember three20? https://stackoverflow.com/questions/tagged/three20
Oh man three20. I was freshly hired at my first dev job at a startup as a self-taught rails dev. I like to learn and was open to doing more, so they had me start to take over some of the ios dev, which heavily leveraged three20.
Unless you have the same experience, you can't imagine how difficult it is to get your head around native ios development with this kitchen-sink, highly-opinionated library layered on top. I had no frame of reference for understanding ios, or three20, or even development in general really (I had done some webapps and api servers...). That was the most difficult phase of "this seems like it should be incredibly simple but I'm now a week into trying to figure it out". So frustrating.
I made it out the other end, ultimately by just throwing my hands up and asking for help, then really digging into native ios first so I had a solid frame of reference of what the system was intended/designed to do, and what three20 was doing for/against you.
I had a similar experience with Ruby/Rails actually (not understanding what rails did vs just ruby), and now I recognize I'm falling into that trap immediately when getting into new ecosystems. Now I try to make sure to start from the basics, and layer the complexity on only after I have a frame of reference for understanding the platform.
oh three20 was an objective-c iphone library named 320 because that was the size of the screen. Created by facebook but everyone started using it until iphones started to come in other sizes!
I recall people dropping three20 long before screen sizes were an issue. I can't speak to all the issues with its design; I think I got to the part where it tried to model navigation similar to Ruby on Rails' routes and gave it a big "Nope."
my first professional programming with java was right near the beginning, in about 1997 or so. Funny at that job I had to deal with both Smalltalk and Obj-C fans who thought everything about Java was awful, preferring their two respectively favorite languages instead.
Why not just use C# instead? It was purposefully designed to address and correct the many mistakes of Java, and much more importantly, it's not owned by Oracle.
It sure doesn't _feel_ like Java is owned by anyone. I pick an open-source JDK to use, install it with my package manager, and I'm off to the races. C# is dripping with Microsoft. Installation takes me to a Microsoft support page, then I'm installing PPAs and copy-pasting lines of Bash. Gross.
> Installation takes me to a Microsoft support page, then I'm installing PPAs and copy-pasting lines of Bash
Which Microsoft support page are you looking at? The one I copied the below commands from[1] literally just lists these commands. On occasion, an additional repository and Microsoft keys need to be added, but everything else just works™.
All work on their respective distros/OSes. Once installed:
dotnet new console
to create a new console app. Fire up any editor (doesn't need to be Visual Studio Enterprise 2022) and start coding.
The only place where installing the .NET SDK is complicated is macOS, but that goes for anything there, honestly. Even getting non-Apple Clang + LLVM on macOS is a pain.
> then I'm installing PPAs and copy-pasting lines of Bash. Gross.
That's not exactly Microsoft's unique flavour, lots of open-source projects don't end up in the centrally maintained and approved repositories of your distro of choice and are instead distributed in all kinds of god-forsaken ways. Have you ever tried to install Conda on Linux? Just go and look at its installer, now that is gross.
And then there's packages that are in distro repos, but are so difficult to build correctly that the developers' advice is to not use the distro package, but instead download a tarball and compile it yourself (despite the user being no less prone to build pitfalls than distro maintainers are). This is how the spaced repetition flash card app Anki is, and it means that getting it up and running on a proprietary OS, which properly built binaries are readily available for, is easier and more consistent.
Probably my mostly-Javaless background showing but I've found Kotlin nicer to write than C#. It might actually be .NET that I don't enjoy though, because when you're not particularly familiar with either the line where one begins and the other ends is blurry.
> and much more importantly, it's not owned by Oracle
How's any better that it's owned by Microsoft? Furthermore, all of Java is open source. Cannot say the same about dot net, where parts still remain closed source.
It was owned by MS, but the entire .NET ecosystem has since been open-sourced and released with a permissive MIT licence. It is managed by the .NET Foundation[1].
The MIT license is worth nothing because it does not contain a patent release. Microsoft's sword of damocles has always been in patents they held with regard to C# and .NET. Have they released this IP as well?
I have been a MSFT customer and an ORCL customer. While both do things to you that cannot be described in polite company, MSFT at least buys you dinner first.
NewtonScript does the symbol lookup first (same as for any member lookup) and retrieves a function/closure object, then executes that function with an implicit “this” argument. Closer to the way JavaScript, Python, Go, or C++ do it.