On Apple's Love Affair with Swift
stefan-lesser.com
stefan-lesser.com
”One of the best and most annoying things about Objective-C is that it has C in it. This has been hugely important for Objective-C in practice, because if you run into a performance problem with objc_msgSend, you can always rewrite that algorithm in C. That’s really, really, really important for Objective-C being successful in both in the days of NeXT on 16 MHz processors and also today for the low-level code that people are writing.”
This is indeed a great thing about Objective-C: it’s an improved C with a tight set of runtime features that help build interactive applications.
There’s a need for such a language, and I’m sad that so much of the rhetoric from Apple and the Swift community is working on the assumption that Obj-C should be completely replaced by Swift.
Swift is not a compact language like Objective-C. It’s more like C++ in how it tries to incorporate every programming paradigm that can possibly fit. The heavy focus on complex upfront typing is not necessarily the best choice for iterative app development.
Swift is useful in many places, but personally I found Objective-C’s “Smalltalk-flavored C” to hit a sweet spot for my GUI needs where integrating with C and C++ libraries is usually required all over the place.
> The fundamental problem was Objective-C was built on top of C. C inherently has pointers. It has uninitialized variables. It has array overflows. It has all these problems that even if you have full control of your compiler and tool stack, you just can’t fix. To fix dangling pointers, you would have to fix lifetime issues, and C doesn’t have a framework to reason about that, and retrofitting that into a compatible way into the system just wouldn’t really work.
If you took away C from Objective-C, you couldn’t use C arrays on the stack, for example. And if you couldn’t do that, there’s entire classes of applications where the performance just wouldn’t be acceptable. We went around, around, around. We said the only way that this can make sense in terms of the cost of the disruption to the community is if we make it a safe programming language: not “safe” as in “you can have no bugs,” but “safe” in terms of memory safety while also providing high performance and moving the programming model forward.
Microsoft, Apple, Google have the luxury to impose moving away from C on their platforms.
On other platforms you have developers that won't touch any kind of Safe C even at gun point.
I suspect that the move to swift would never have happened without LLVM. And I wouldn’t be surprised if llvm’s cross language compatibility was specifically attractive to Apple because it let them have their cake and eat it too - write a new language but keep legacy C code whenever that’s the best option.
I don't believe LLVM provides a stable cross language ABI, and AFAIK languages just use regular FFI (via the C ABI) to communicate with one another, regardless of them being implemented on LLVM or not.
Provided the compilers generate compatible versions of LLVM IR, then cross-language calls can be done at the IR level. See github.com/Keno/Cxx.jl
IIUC Swift already uses clang to load module maps in order to expose and call Objective-C, and they plan to do something similar with C++ (no link handy but I think there is an issue or enhancement proposal about it).
Is there really such a thing? I thought the ABI was dependent on the operating system and compiler.
I agree that C is unique in it's ability to generate programs that can be interfaced with from any language. This also seems to apply to older languages like Fortran and Pascal, for some reason. Higher level languages are an ABI nightmare; seriously doubt anyone will ever dynamically link against a C++ library at runtime and call a method on a C++ object from any language that isn't C++.
2. Prior to LLVM, there were much more complete attempts at this (that were even more successful, actually!)
A lot of C's endurance is related to programmer psychology, so it would be futile to design a better C.
C++, Rust, Go, Java will continue to drain the pool of C developers until it's only used for maintenance of existing projects.
This is why it's extremely irksome to see people recommend mixing C and e.g. Python for speed, or other such Frankenstein's monsters - it's just prolonging the agony of whoever will maintain that.
Rust, Go, and Java, with their memory management and cross-platform portability, and general non-determinism may eat away at the edge of C, but can never replace it.
I could see them fully replacing C if features like garbage collection and byte-code interpretation were handled at the chip-level, so languages would not have to necessarily deal with them. Could also see it happening if a chip's out-of-order execution was exposed at the language level. That would not necessarily make C worse, but Java may be more adept at handling it.
1. C is no closer than C++, or Rust (including unsafe) and they're all surprisingly pretty far from the hardware these days... this is visible the most in multi-threading, where high-level C statements are re-ordered by the compiler and even simple C statements like an integer assignment can be split into multiple instructions. Inlining and register allocation is also quite opaque and perhaps best left to the compiler, unless one uses non-standard code to force specific behaviour.
2. Well put: Go and Java were/are eating at the edge of C. Java took serious bites in the past, nowadays they're not really competing much. Today, what might have been a small Linux C program could be a Go program, especially if the performance constraints aren't too tight. Technically speaking, Rust can replace C almost everywhere, it's just that it's a significantly more complex language.
C++ introduces virtual functions, and when you make a function call, you're no longer going to a single place in memory, you go to where the class's virtual function table tells you to go, effectively jumping to a memory pointer. This is pretty helpful, but it's an incredibly different way to think about code. A function is no longer a set of instructions in memory, it's a logical representation of functionality.
And yes, I know in C, you can set a variable to a function location, and then jump there, but it's painful to do and you have to do it explicitly, so it doesn't really create an abstraction.
I am fully convinced that if Java and .NET had a proper AOT toolchain from day 1, meaning beyond dynamic linking (NGEN) or commercial offerings from 3rd party JDKs, C's influence on FOSS world would have been much less than it achieved to be.
And we would already have achieved an UNIX like stack closer to what Inferno/Limbo was all about.
Would you mind naming a few such classes?
Why would arena allocation, or evrn good generational GC fail to deliver the performance when quick allocation / deallocation of (large) arrays is required?
Java just made a couple of wrong decisions regarding AOT and value types that are now taking years to correct course, while avoid breaking backwards compatibility.
If something like Modula-3 had been granted Java's success story, we wouldn't be talking about how GC languages don't have good support for value types.
Also I think C# structs do not have mutable fields, but I could be wrong.
Edit: it looks like C# structs are mutable, my mistake.
Maybe take some time to check the other ones?
As for value types in Common Lisp, even if one bit is lost for tagging, it doesn't make arrays, structs and primitive values, less of value types.
Unfortunately, Swift doesn't fix that AFAIK.
I’ve debugged too much java code where the programmers thought that ”thread-safe” meant ”no need to think about threading issues”.
The Obj-C community (or what's left of it) is trying to make a martyr of an error-prone, cumbersome programming language.
And unlike JNI they aren't protected by a VM wall.
I find that this assertion holds about as much water for Swift as it does for Rust, Swift is not even remotely close to C++'s in terms of complexity, and that's with building in mechanisms for performant memory safety, a concept which C++ literally just shits on to this day and for the foreseeable future.
But once you learn to use the more advanced features, your code just gets easier to write and maintain. I enjoy that I can pickup new language features in Swift one at a time, figuring out where each adds its best value, and occasionally refactoring to take advantage as part of my ongoing efforts to minimize code debt.
It’s not even close. Swift is (still) minimalist by comparison to C++.
Still not seeing the problem.
Pointers aren’t magic and aren’t hard.
Pointers, in practice, are hard. Even C-family compilers cannot safely reason about them in many (most) cases.
“As an embedded engineer I can’t agree that C “has problems” because it treats you like a big boy with your big boy pants on. :)”
Edit: Nah, that’s OK. Just downvote and scamper on. Make HN more like Reddit, that’s what this place needs!
C is really good at exploiting those, while at the same time giving programmers a feeling of power.
Isn't that why everyone loves python, solving a complex problem in a handful of easily readable lines of code?
Also... I’m a little concerned that your post has “we’re all equal” social justice vibe to it... which is silly. C is more powerful than because “safety features” aren’t there.... deplorable... LOL.
You try going a day without using something programmed in C.
No social justice vibe was meant. I was trying to say that we're all bad at dealing with the kind of errors which appear in a typical C or (perhaps to a lesser extent) C++ program.
I know that some people are able to do this more successfully than others because of skill, etc, but it's not just about certain individuals. As a whole, the C community has a really poor track record at security and safety and that has a lot to do with the language itself.
Thankfully there was already C++ for those of us that wouldn't move into such a limited language versus what something like Turbo Pascal 6.0 for MS-DOS was already capable of, feature wise.
Man... to listen to hackernews tell it... no one should use C!
I wonder how many comments describing how bad C is are from people on Linux machines?
The problem with C, versus other systems programming languages it that it its pointers, implicit conversions of array into pointers, integer operations, string and array bounds don't have any kind of validation.
On other systems languages disabling such validations is explicit.
C is like JavaScript in the browser, we have to put up with it because UNIX clones won the market of commodity OSes.
C on its own without UNIX, would have failed in the market.
On the desktop world it was already being replaced by C++, Smalltalk, VB, Delphi and 4GL before FOSS based on UNIX and C started to be widespread.
Unfortunately it is impossible to convince people on pure UNIX based OSes to use something else.
Fortunately, Apple, Microsoft, Google, Sony, Nintendo are able to set which programming languages one is allowed to use on their platforms and C is on the way out on their SDKs.
I just cannot enjoy Swift at all. When I go back to Objective-C its just such a joy to write.
And I feel like I can write in Swift nearly as fast as Objective C. Objective C was always so baroque, when I define a method or variable and declare the exact same thing in a header file? Properties syntax?
I actually switched when Swift 1.0 came out (just after writing a twenty thousand line simulation engine in Objective C). It was so lightly baked I was starting to regret my decision for a couple months until version 1.2 released, only then could I ship my app commercially. Since then every release has only gotten better, and the rough edges are entirely gone. The only thing I miss from Objective C is compile time, and now just barely given how much faster the compiles have gotten.
Not all programming is the same. I've seen a lot more code churn in frontend projects than in the backend, where the actual logic and persistence happens. That makes the speed of (re)writing code relatively more important (at least for the iOS apps I've worked on, YMMV).
But even when I had to clean up legacy code, I spent most of my debugging time on on incorrect threading (typically using UIKit or Core Data from the wrong thread), AutoLayout errors, Apple framework bugs, storyboards/NIBs out of sync with code, performance degradations, or anything else where Swift doesn't help much.
In my experience, Objective-C programmers aren't allergic to safety or brevity. We love ARC! It's just that Swift has taken away too much productivity, mostly through terrible tooling and by dividing the community, for very little gain.
> Objective C was always so baroque, when I define a method or variable and declare the exact same thing in a header file
When I helped out on a Java project, I noticed that my coworkers religiously created interfaces for every single class they wrote. They couldn't really explain it beyond it being a "best practice", but I suspect they enjoyed being able to look at a short file that only contained the interface plus JavaDoc, instead of opening the full implementation every time. They basically re-invented header files :P
I don't think people would mind headers as much if Xcode was a better IDE, and we didn't have to copy declarations around manually.
Then they should have known better.
That makes sense for unit testing, in cases where mock classes would be required.
All Java IDEs have object browsers no need for header files.
Is this a joke? This sounds like "the language is wrong because it didn't completely ape C"
"Simple" things I want from generics:
1. Carry over generic information from header files to .m files, and not force us to drop all type information by having to use "id".
2. A compiler flag to enforce that the generic type must be specified at usage.
3. Where clauses in generics: Foo <T where T : NSCopying, MyProtocol>>
4. Generics on protocols, ideally with all the other features.
I know some of these are not trivial to implement, but they are mostly new syntax and hence don't have backward compatibility issues (except #2 which is why I asked for a compiler flag).
I ask, because the only way I could see it being better is if you're taking that array—that data structure—and passing it all over the program and using it everywhere. (Note to the literal-minded: this is hyperbole.) If that's what you're doing, that's not Object-Oriented Programming.
If you're instead doing real OOP, you're designing an object that will perform a clearly circumscribed bit of work for you by responding to a set of messages. The NSArray may live inside that object—in other words, the object is composed in part by using an NSArray—but that array is hidden from the rest of the program.
Generics are no big whoop-di-do in that case, because there is no client-programmer that has to worry about them; or, to put it another way, you—the original programmer—only have to worry about that NSArray with respect to the programming of that one object. In that case, the data type the array holds is not a big deal to keep track of.
So, again—seriously—what is so great about generics? The whole point of Objective-C, originally, was that it was late-binding—which, if you ask Alan Kay, was the point of OOP in the first place. If you're worrying about types all over the place, you're doing something wrong, no?
But that brings us to your first point: namely, what is the "right" way to approach OOP.
When I bring up Alan Kay, I'm bringing up a guy who was there at the start, and who set his stamp on OOP. Granted, "OOP" has been done in different ways. You'll note, however, my use of scare quotes. Allow me to explain.
When OOP had the misfortune to become a managerial buzz, somewhere back in the 1990's, and thus became a "must-have," what happened was a lot of procedural programmers simply took their procedural programming, wrapped in in C++, compiled it with a C++ compiler, nodded to the boss and assured him that they were doing OOP—and went along on their happy way.
Likewise, when college professors—set in their ways, as is their want—were told that they had to start teaching OOP, they largely did the same thing.
The result is that we have lots and lots of people out in the world "doing OOP"—who actually aren't. They're writing procedural programs, with the trappings of classes and sub-classing and what not. But all over in their programs, they are digging into the internals of their classes—and, sometimes, you see them digging in many layers deep.
And they're "doing OOP."
As I understand him, Kay is saying that you send a message to an object, on the understanding that the object will handle the message, the sender not having to worry about the ultimate who or how. If there's another kind of OOP other than that—or other than the travesty I described above—what is it?
But, that's another question, entirely. My original question was: why are generics such a big deal in OOP? I don't believe that's been answered.
I do have times when writing Swift where I miss some bit of Obj-C, but those are rare and are becoming fewer as the language develops.
Personally though, I’ve found that even when I’m keeping a close guard on things when writing Obj-C and am sure to avoid all the obvious pitfalls, bugs slip through in the most unexpected places, so I’m quite happy to have the Swift compiler double checking everything for me.
Unfortunately, as software continues disrupting various industries, it's less and leas certain that even buggy programs written by someone who thinks that safety is overrated will remain harmless.
A major feature of Swift is that it forces you to deal with error conditions and missing values. In practice you do the right thing once and early in your code, and you can write the majority of your code with guarantees that prevent major classes of bugs. Swift is not perfect, still changing, and many complain about being forced to write safe code, but it is absolutely the right move of Apple to make for their platform.
It depends on what you are building. For an app it is not a big deal to be slower. But you will not write a kernel in Swift as you will lose performance all over the place.
Python/Javascript/Lua are used as scripting languages to create video games. But the 3D engines are written in C or C++.
Each tool has its use.
That used to be the argument against C and C++ in the 80 and 90's regarding 16 bit home computers.
Any serious developer would know that Assembly was the only proper way to write software that required real performance.
Yet a couple of decades later.
> But the 3D engines are written in C or C++.
There is a world between every single string, array and numeric operation being a possible source of memory corruption and being forced to explicitly write unsafe code.
I have been using mostly safe languages since the 80's.
They only get in the way of cowboy programming, which is a very good thing for anyone that praises quality in software development.
C would no longer be around if companies got properly sued for each CVE exploit.
I have written systems in memory safe languages. The languages that provide memory safety also incur GC pauses, which means they’re unsuitable for applications where latency matters at all. (I’ve also noticed that programs written by professionals in memory safe languages tend to have many more serious high-level bugs than those written in C/C++, but I don’t have data to back that up.)
This is incorrect, you can have memory safety without a gc. An example is Ada, and more recently Rust.
Not really. RC algorithms can lead to stop the world in cascade deletion of highly nested data structures, and even cause stack overflow due to destructors being called.
Kinda sorta cheating. ;)
No. It's the inverse. People who are very good with C continue to have vulnerabilities in their code. Why? Because C.
https://www.cvedetails.com/vulnerability-list/opmemc-1/memor...
Apparently reviewing code before merging into mainline isn't of much help, but lets keep this myth of secure C code alive.
Σ (Logic errors in safe language) < Σ(Logic errors in C + Memory Corruption in C)
The default code you write in swift is safe. You spend less time worrying about its correctness, which means you can focus on solving higher level problem and less time debugging.
When people call swift pedantic, for example, and I take time to ask for the specifics, I mostly get "not familiar to me", or "I'm used to shooting myself in the foot and unwilling to consider alternatives". So my patience has run out.
extension Collection {
subscript (safe index: Index) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}
And now you have the choice: array[i] // traps for invalid indices
array[safe: i] // returns nil for invalid indicesBut what I want is a way to catch all errors that others may have introduced in code I have no control over. That includes arithmetic overflow as well.
What gracefully means depends entirely on the application. Often it means to log the error or display a meaningful error message if it's an interactive app, then maybe do other kinds of cleanup and shut the thread down.
It can also mean to retry later. Array out of bounds errors are quite often just a result of not properly handling an earlier temporary error.
Whether or not errors leave the rest of the application in an inconsistent state depends entirely on the design of the application.
I'm not saying that letting an app crash on buggy code is never the right thing to do. I just want the option to handle it differently where appropriate and possible (it's not always possible anyway).
https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9...
Speaking of reliable systems, introducing an actor model is a good opportunity and excuse to introduce a mechanism for handling and partially recovering from runtime failures (like failed force-unwrap operations, out-of-bounds array accesses, etc). We explore several options that are possible to implement and make a recommendation that we think will be a good for UI and server applications.
This looks like a more principled approach that we will eventually get in Swift.
One of my goals now is to outline safe ways of using C++ for various projects and I'm not too optimistic. In fact I'm unsure what we'll end up with.
Those of us that come from Wirth languages always put quality and delivering what the program is expected to do before going crazy with optimizations.
I always got the feel that many in the C communities write code as if they were micro-optimizing every single line, just because.
And those that care about type safe driven programming in C++ usually have background in safer languages.
Perhaps because it's not a huge problem in iOS apps, but for long running multi-threaded applications this is a problem.
1. Don’t check for it at runtime and the runtime writes to memory that it shouldn’t like C.
2. Throw an exception and prevent memory corruption.
3. Don’t ever work with indexes and just use iterators.
Is there a fourth way that it can be handled in other languages?
After working exclusively in it for a while now I can't help but cringe at the practices which I see encouraged in most other languages.
Also, if Swift is so much better and is supposed to be safer to use why are apps much slower and buggier than I ever remember? My iOS devices went from instant in iPhone 1.0 to pathetic and almost not useable at times on an iPhone 6 Plus, which would still be an awesome phone for my uses (using it as an iPod essentially and the occasional call) except it's slow and buggy. Even answering the phone is no longer instant. I could have sworn I remember when Jobs introduced the iPhone he was bragging how instant everything was. What would he say now and why are apps much less stable if Swift is supposedly that much of a benefit and greater than Objective-C
I think the idea is to make common things easy and uncommon things possible.
For speed of UI response, loading times, cursor and input latency we're at best no further forward. Quite often we're in an objectively worse situation. With a tiny few exceptions, no one cares about code or data sizes any more and that is reflected in what's delivered.
That's quite apart from the rise of web apps and the slowness that necessarily introduces.
Plus, low-level languages like C are sometimes the only way to go if you are writing for embedded systems with slow CPUs.
Mikroelektronika has Basic and Pascal compilers, in addition to C, for all those slow CPUs that are market relevant.
https://www.mikroe.com/compilers
And they aren't the only ones still alive.
Firefox is on a course to remove C++ from safety critical areas and replace those with Rust.
Edit: to be clear this is based on the blog posts I’ve read from Mozilla about the introduction of Rust in different areas of Firefox. I know nothing of firm plans.
> Moving forward, the goal of Oxidation is to make it easier and more pleasant to use Rust in Firefox, and correspondingly to increase the amount of Rust code in Firefox.
And then there is the Rust page on Mozilla’s site:
> Mozilla also utilizes Rust in many of its core initiatives including Servo and key parts of Firefox.
https://research.mozilla.org/rust/
Where “key parts” is a link to the project quantum announcement: https://medium.com/mozilla-tech/a-quantum-leap-for-the-web-a...
> Initially, Quantum will share a couple of components with Servo, but as the projects evolve we will experiment with adopting even more.
I think this is the root of my dislike of Swift. "Assembling" together the best ideas, which may only be 'best' within a specific context does not suggest the kind of design principles I am looking for in a language.
I was looking for a quote and it seems it was Antoine de Saint Exupéry who said something like "It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to remove."
So I contrast Lattner/Swift with Hickey/Clojure: a small set of coherent design choices that lead to a language that is simple but deep. It's by no means all things to all women and that's a good thing.
Surely every language designer including Hickey thinks they are assembling the best set of features for their goals.
I see Hickey as having a specific, focused, goal about enabling simplicity (given his specific meaning for that word) and yes I totally agree that every designer, including Hickey, does as you say.
What I was trying to get across was that I don’t see the guiding principle that guide the selection of those “best” features to include so much as “there’s this great stuff” that we must include.
Does that make more sense? Or should I put down my shovel?
† http://www.win.tue.nl/~evink/education/avp/pdf/feel-of-java....
> "We were after the C++ programmers. We managed to drag a lot of them about halfway to Lisp."
He appears to have specific aims and seems unafraid to make the necessary compromises to achieve them.
Non nullable default types, defer, patterns are great ideas.
Virtual by default, associated protocols instead of generic protocol, Exception handling designed based on how objc passes nserror, Generic instantiation is done at runtime, not by the compiler, so field access and even defining locals involves needless math,
All things with a lot better alternatives at the time swift was designed.
I didn’t see a reason to design a new language when Objective-C could be improved (for those that think it needs improved).
--------------
Swift ... really is designed and optimized for, as a programmer, you can spend the least amount of time to get to a working program as fast as possible.
Getting to a working program includes the time it takes to debug something, to iterate and develop and fight the type system, and all the other things you have to do. But that time you spend having to fight the type system or figure out optionals or things like that pays itself back because your program works more often. You’re actually not spending time chasing own dangling-pointer bugs
Swift really does not support quickly iterating on a design. It demands that you sit down with your plan fully-formed, ruler and protractor in hand. Due to its strictness, changes ripple very quickly across even a small codebase.
Realized you need another enum case? You can't compile again until you touch all your switches. Protocol would be more expressive with an associated type? Stop what you're doing and write some type eraser boilerplate. Function needs to signal an error condition? Try/do/catch anywhere you call it, right now, before you run again. Need to put another type into that array? Write a new protocol and add some conformances.
Changing a interface as you work in Swift immediately creates a sea of red marks, which hinders the ability to experiment.
You're right that this strictness helps write ~correct~ safe code, and I appreciate that. But it's a tradeoff; there's a real cost in developer productivity/creativity. And I believe that it does not help produce the best design. It takes too long to get to running, which makes it too costly to heavily revise based on what you learn as you build.
EDIT: Actually, I want to go even further, and strike out "correct" in the paragraph above. Swift helps at a certain level of correctness, which is really not much higher than the type system -- it would be better to call this "sound" code, rather than "correct".
The overall point that I'm trying to make is that at the level of application/business logic -- which is the whole point of the program, after all -- Swift does not help with correctness. In fact, it can be detrimental, because, unless/until you understand your use cases well enough to actually lift them into the type system, at that upper level it blocks exploration without adding rigor.
I find the opposite to be the case. You assume that compile errors are a net negative for speed of development and expressivity. Instead I find that the compiler reminds me upfront of all the places I would need to update anyway in due time. In a dynamic language those inconsistencies would be found hours/days later and usually after lengthy debugging. Instead I find myself making large sweeping changes in the design very frequently, because I trust the compiler to warn of any logical inconsistencies.
You have to admit at that this point it boils down to subjective preference. You sound averse to the swift style of doing the right thing up front, and using the compiler to help you stay consistent. I personally tired of the hidden and unacknowledged costs of unsafe language, and compilers that allow your design to degenerate into an unmaintainable ball of mud over time. I'm ok with swift being an acquired taste and a technical advantage of folks who get it.
With the exception of the associated types thing which is a language limitation that would be nice to see resolved eventually, the others can be resolved with a combination of automatic refactoring (add new enum cases, etc) and a compiler mode where type errors compile down to runtime traps without preventing you from running the program. (And faster compilation in general would help as well!) These are both non-trivial to design and implement well, but I think it’s a good future direction for statically typed languages that will give them many of the benefits of dynamic languages during the prototyping phase.
Absolutely, something like this would be perfect. I like being able to leverage the compiler in preventing runtime errors...just not necessarily all at once, right up front. Allowing some strictness to be dialed back in debug builds would be a very nice feature.
I realized recently that I actually do like static typing, as long as the cost is low. (I really like TypeScript)
Sorry, I don't want to reason about the "shape" of my application state vector before I've written it... but that's what Swift's static type checking forces me to do... Design my app and it's data model at the same time.
Call me a lazy software hippie I guess.
In C++ -Wswitch is a valuable tool to find the former, but there is no way to find the latter. This makes writing correct exception handling code much much harder, so having Swift's strict behaviour would be great from my perspective!
It sounds to me that you want to use a few days of exploratory coding to save a few hours of design work. If this type of exploration is needed, then it could be done in another language which supports it and then when the design is in decent shape it can be ported to Swift.
Swift is not detrimental to the correctness of the business logic. It offers you a bedrock at the type sustem level on which to build that.
Lattner used rhetorical slight of hand to assert, in effect, "you 'working quickly' developers need first to adopt my values; only then can you be admitted to the conversation." C.f. Yegge on liberal-vs-conservative developers. [1] Lattner (along with you) is adopting a position towards the conservative end of the spectrum, which is cool. What's not cool is gaslighting the existence of a liberal perspective.
[1] https://plus.google.com/u/0/110981030061712822816/posts/KaSK...
A program that executes and performs some I/O is a very very low bar to pass. The next step is not being ready for wide-scale production, in fact the IEEE Software Engineering Body of Knowledge aims to define the many steps required for that and it's a lot of them. Developing by the seat of ones pants is fine for personal projects, but not for publicly used software.
And why should what developers "want" be the main criteria that should be used to choose programming languages? It's certainly important that developers are able to extract some satisfaction from their work, but that doesn't mean we should sacrifice other important goals just for the personal comfort of developers.
Also, you really could have phrased this to be a little less inflammatory.
Here it seems like Apple's culture of secrecy just hurt them for no reason. No really, Apple, you can just tell people what your plan is.
https://www.reddit.com/r/swift/comments/8zb9y1/state_of_swif...
I'm playing with rust to solve my use case, but is certainly hard. Is very unlikely you can build a team of mixed developers and use it. Swift is more forgiving, yet you can get great results anyway.
They could have cleaned up all Objective-C and built a much nicer language, instead we get a improved Java / C++.
somePoint.moveBy(x: 2.0, y: 3.0)
as opposed to [somePoint moveByX: 2.0 y: 3.0];
most Objective-C code would get rid of the space too [somePoint moveByX:2.0 y:3.0];
Its just painful to type extra characters that don't do anything and don't help readability. Plus the weird splitting of the moveByX is still odd.I still am mystified why they didn't just start with:
somePoint.(moveByX: 2.0 y: 3.0)
to keep it inline with Objective-C and start working on giving the method names an overhaul that would benefit everyone including the Objective-C programmers.I’ve run into a lot of programmers that worked with ObjC as they would Java or C++, that is, using very small and fine grained objects to divide up the problem.
It’s the standard way in Java. It’s also the opposite of how ObjC is supposed to be, which is ”a few big classes” that uses message passing as glue.
How many former ObjC programmers actually heard of ”Software IC”?
Using ObjC like Java/C++, the language quickly becomes unwieldy and verbose. If you do that, then obviously Swift feels like a huge improvement.
On the other hand, if you essentially write C and let ObjC be your reusability layer, then Swift might feel like you’re back to working inefficiently in Java / C++ with objects all over the place.
The way that I write Objective-C is to use 'id' for everything and have as few classes as possible, mostly I just add methods to the existing classes mainly NSString, NSArray, and NSDictionary.
Objects are interchangeable as long as they can respond to certain messages. For example, any object can be an array as long as it responds to objectAtIndex: and count. There was a whole discussion above about how Objective-C doesn't have generics, but this completely misses the point because Objective-C doesn't even need generics. "Modern" languages are not necessarily an improvement, software generally does not get better over time, it reaches a peak then it declines.
Objective-C is one of the best languages I have ever used, but the vast majority do not understand it, even the ones who say that they used to write Objective-C for X amount of years but now love Swift. The truth is, they never understood the beauty of Objective-C.
I consider Swift to be a language for large teams of average programmers, reading Lattner's response to Swift's criticisms tells me that he is a compiler guy, but that expertise does not carry over at all to programming languages.
I don't really like the direction they were taking Objective-C anyway, so in the end it doesn't matter. I'm against things like dot notation for accessing properties and ARC, I don't use either when I program in Objective-C. Those recent changes end up making the compiler more strict and a pain to deal with.
Consider the types of some template generated pointers, or just something like std::unique_ptr<std::vector<std::shared_ptr<Foo>>> (which isn’t a very far-fetched example).
This is ”the generics problem”, where it actually starts having an obscuring effect.
ObjC is immune to the problem since it lacks any need to do do the specialization. Unlike Java where you needed a lot of manually inserted casts without generics, ObjC doesn’t need them at all.
Like you say, dot notation, ARC, stricter resolution of dynamic messages etc were weakening the strong points of the language and would push the programmer towards a Java-like object model - which is very far away from how the language ideally should be used.
What new does kotlin or swift offer which python or ruby can not? Why reinvent the damned wheel for syntax sake when they could have worked for their device centric compiler for creating binaries out of python or ruby?
Compared to Ruby and Python they doubtless seem a little verbose. Type system features like genetics, which help to make Kotlin and Swift “expressive” in their family of languages, seem pointless from the standpoint of Ruby and Python.
So there are two aspects to this:
* What makes Swift or Kotlin compelling relative to other languages in that family? * Why use that family instead of languages outside it like Ruby and Python?
People have been promoting dynamic languages as an alternative to static languages for many decades but it doesn’t seem like performance has ever truly caught up enough.
It is not true of LuaJIT, which is as dynamic as languages get. Error detection and correctness, sure; raw performance is not the issue you've made it out to be.
Ruby and Python were fair choices, together they must have 10-50x the mindshare Lua does.
Lua (like plain JavaScript) is a more spartan development experience than Ruby or Python. I'm not sure what it is; but languages with rich OO seem to be what get picked up by people who need to build "applications" (windows where people click around in them).
What does "higher-level application demands" mean?
Rust has dynamic polymorphism like Swift, but Swift you opt-out with final (correct me please if I’m wrong here), whereas in Rust you need to promote to a trait object.
This is a small difference, but means you’re starting with different principles available to you out of the box. Personally I prefer Rust’s opt-in to complexity model, but I can see why people see that as a hinderence, even if it’s technically just as possible to do in Rust.
Then there are Swift Playgrounds and REPL for quick prototyping and those still aren't a thing in Rust.
I think it’s time for Apple (and Google) to embrace JavaScript as the app development language.
I don’t think that’s a particularly great choice.
https://blog.meteor.com/an-interesting-kind-of-javascript-me...
Plex was ported to the 3rd Gen AppleTV as an unofficial app just by running a server on your computer and redirecting DNS to it.
https://www.raywenderlich.com/372-tvos-tutorial-using-tvml-t...