Hacker News new | past | comments | ask | show | jobs | submit login

The Objective-C old guard has had a very hard time dealing with Swift. For a couple years now, every 3 months they have another blog post hand-wringing about what they used to do in Objective-C, how they can't in Swift, with the implicit warning this is worrisome and _needs_ to be reimplemented in Swift, or Swift isn't a serious contender long-term.

Most of the of the community seems to have moved on, with the understanding that of course you can't reimplement performSelector/KVO/(insert dynamic, non-type safe feature that usually just bites you in the ass in the long run) from scratch, but we still have Objective-C that already implemented those features, and we will have it for years, if not decades, to come. Maybe Apple doesn't have to open source UIKit to prove their commitment to Swift (a short, albeit slightly unfair, summary of a blog post last week from another member of the old guard)

There seems to be a general lack of imagination, and lack of understanding that Apple would never rewrite UIKit or other large, existing frameworks in Swift. But, once Swift is more stable in a year or two, maybe you start thinking about new frameworks being written in Swift, with Objective-C compatibility, instead of vice versa.

Maybe you can't write Rails in Swift, but by god, why would you ever write Rails again? There's been two heavily up voted stories here in the past two weeks describing how awful it is to have a career dependent on a framework so dependent on dynamic untyped code. That matches exactly with my experience being pressed into service writing Rails code for a couple months - the development experience felt like the Stone Age compared to Swift, even if I could write a method ~20% faster.




> That matches exactly with my experience being pressed into service writing Rails code for a couple months - the development experience felt like the Stone Age compared to Swift, even if I could write a method ~20% faster

Me, too. At work, I am on two different projects at the moment: an SDK and application written in Swift, and a run-of-the-mill Rails app.

Going back to the Rails app is frankly gut-wrenchingly bad. Every aspect of coding and debugging — and especially refactoring — is so much worse when doing it in ruby.

The strength of Swift type system makes the tools so much better, and at least for me, it's easier to code in it and reason about it effectively (even if yes, you do type more letters).

But, I want to point out: the same is not true of Objective-C. Even though it has a lot of dynamism under the covers, coding in Obj-C in Xcode is much closer to coding in Swift than Ruby. It's only in 'special cases' that you would really use an untyped object reference. So the compiler is able to catch a huge number of errors at compile time, the editor knows what type your variable is so autocomplete is intelligent, etc.

I do like Swift better, but coding in Obj-C is much closer to Swift than Ruby in terms of the tooling experience, and in terms of how much dynamic untyped code there actually is in a program. Modern Obj-C is "mostly typed", and swizzling and weird object casting are seldomly done (usually only in a tricky situation, which is when you appreciate the ability).


Absolutely agree. I have only one or twice used method swizzling, but when I have used it it has absolutely saved my bacon in the face of nasty platform bugs. Fighting fire with fire, so to speak.


So, I'm deeply involved in Swift, in the sense that: I write the odd compiler feature.

From my vantage point it seems to be the opposite of your analysis. While it is true that ObjC's dynamism has all kinds of problems we want to avoid, we're also running into lots of cases where the obvious solution is dynamism, and the other solutions aren't obvious.

One concrete example I can offer you is NSCoding, which is being reimplemented right now in corelibs-Foundation. That API pretty much needs a way to look up classes at runtime, (there's really no other sane way to provide the feature). You could argue that we don't need NSCoding (in fact that was argued), but ultimately, we decided we needed NSCoding more than not. So Swift 3 adds a `_typeByName` API which does dynamic lookups of classes by string. It landed, it exists, the ship has sailed.

Another concrete example that may be interesting is XCTest. The way XCTest works is your unit tests are written as functions on a class, and we "discover" the tests by enumerating the functions at runtime. But oops, Swift has no way to enumerate functions at runtime, so we can't find any of your tests. The solution to this problem is actually pretty interesting: the latest proposal is to do sourcecode analysis from the compiler to enumerate your test functions, dump that somewhere, and then generate a second program that uses the dump to call the enumerated functions.

Now that is very interesting, and certainly less dynamic than ObjC (e.g. no method_exchangeImplementations and other nonsense), and I would argue quite a lot saner for the scope of the XCTest problem. But it follows easily that as soon as we do that we could emit a program that uses that same function enumeration to emit a giant switch statement that does dispatch-by-string. Of course it would be opt-in, so only callers that wanted it would use it, but there's nobody to stop you.

All of that to say, I think what is actually happening inside Swift is we're coming up with more structured kinds of dynamism, rather than a knee-jerk reaction against the ObjC philosophy. ObjC's model certainly has its issues, and we have gotten surprisingly far without really much dynamism at all. On the other hand, Swift constantly hits cases that are "solved" by ObjC's dynamism, those are definitely real (doesn't get more real than the core libraries), and dismissing them out of hand would be stupid. Meanwhile it takes time to come up with solid "structured" approaches to all the various cases people use dynamism in the wild, so it will be a long process of enabling more and more kinds of dynamism over time.

As for the ObjC runtime, we will not actually have it for years. Maybe on Apple platforms. But the decision has been made not to ship it for Linux, and Linux is of course the next big frontier for Swift. All code that wants to run on Linux (or run on both platforms) better not use the ObjC runtime for anything ever. So this places increasing pressure on designers to figure out what our answer to all the dynamic usecases will be, because there is no seatbelt to save you on one of our platforms.

Basically, I would very much not be dismissing these critiques out of hand. They are not (other than a few) arguing for a return to ObjC. But they are raising issues not seriously solved by Swift at present, and we need to be uncovering those and putting in the design effort to generate solutions for them.


There's definitely some nuance to this situation – I didn't mean to imply dynamic features aren't needed, or have no place. While writing my comment, there was a nagging voice in my head saying "What about Swift Foundation?"

What I meant to communicate was that there's a histrionical air to most of the commentary that is unfounded. We don't need to be able to reimplement Rails, or KVO, or Core Data – we need to come up with new ways to solve those problems with an approach like you're seeing working in practice, a more structured dynamism. And for what it's worth, all of those problems deserve another try at an answer. They're some of the most tricky parts of the platform.


Other than "we want to rewrite Foundation/XCTest in Swift", why do we need XCTest or NSCoding implemented in Swift? Neither is particularly Swifty - many things in Foundation that ought to be structs are classes, for example, and there's the nonsensical duplication of String/NSString/NSMutableString and the other containers.

If you want a Swifty testing framework, just pass a bunch of test functions to a function, or define a test case protocol. Similarly, a coding-style protocol can be represented as an encoded associatedtype and encode/decode functions. Plus, you can throw in the decode instead of having to return nil with no explanation.


> why do we need XCTest or NSCoding implemented in Swift?

Linux compatibility. As long as Foundation is written in Obj-C it can't be ported.


I get that it's necessary for running them on Linux, I just question the need to do that in the first place, instead of creating new, Swiftier APIs. NSURLSession's delegates have optional requirements, for example, which aren't supported in pure Swift code.


Regarding XCTest, could you extend Mirror to provide methods as well as fields? That seems to me like it would be a more natural solution.


For what it's worth, that's my preferred solution in the long-term too.

Speaking narrowly about the XCTest case:

* It doesn't actually require runtime dynamism (since you have a finite number of tests that can be statically enumerated). Following the principle of least power, don't do it if you don't have to.

* A runtime-dynamism-based solution would require `dynamic` sprinkled on function definitions which would be a departure from source compatibility with Darwin XCTest which relies on the superclass and @objc inference on methods.

* Mirror offers reads but not writes, and there is some sense that offering the ability to mutate through Mirror is uncharted design territory.

Then there is debate about whether other "dynamic" cases can also be solved with static analysis. I am in the "probably not all of them" camp, but that still leaves some of them, and it would be good to study that boundary condition in more detail.

With sufficiently robust static analysis you "can" implement your mirror trick for example (by code-generating a bigass extension to Mirror that just returns statically-analyzed data). Somebody will do that, and so I think upstream will be following how well it works out for them and letting the larger community build the case for or against the feature.


It's a really interesting point that you don't need runtime dynamism for this so maybe that shouldn't be the go-to solution. It's easy to just decide to do it that way because that's how it works currently.


Honestly, determining that all methods that start with "test" are your unit tests is pretty bad. We do this because this was the most obvious solution in obj-c. A much better Swift solution is to instead use an attribute, such as `@test`, to mark test functions. This requires compiler support for now, but the long-term goal could then be to come up with a generic way of declaring and handling attributes.


I do hope Apple unveils a unified protocol-oriented framework for both MacOS and iOS. One that, when necessary, keeps Swift in mind before Objective-C.


Definitely - it would be awesome, but way ahead of schedule, if they're thinking about a true UXKit landing with ABI stability and "finished" generics in Swift 4.


Well, considering that Swift was in development for 4? years or so before they announced it, it would make sense if they've already been working on a new API platform for a while. Something that pleasantly unites iOS+MacOS+Swift on the developer side, while letting those operating systems retain their differences and strengths on the user side.


Many geeks seem to forget that development time equals developer time, expressed in money per hour.

Because it just feels good, is never a business value to spend money on.

Yet, every company gets criticized for not doing "it feels good" development to replace a framework that is stable and doing its work.

I don't do Apple platforms professionally, but on my side of the fence, other companies get that same time of bashing.

Yet given the amount of Swift vs Objective-C content at WWDC 2015, and now the upcoming WWDC 2016, Apple is more than fully committed to Swift.




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

Search: