So Swift has been out awhile, what do people think of it? What other language would you compare it to (e.g. C#, C, C++, etc)? What about the libraries are they well laid out?
My favorite thing about Swift is that is seems to get out of the way - and when it gets in the way it's usually with a nifty language feature (like the { $0 + $1 } closure syntax). I'm very excited for the future - between Go and Swift we now have two compiled fast languages that are almost as expressive as their slower dynamic/interpreted cousins.
As an aside, I like that Apple is betting the farm on ARC. I wish I could have been a fly on the wall when they were discussing ARC versus GC.
I really like the `deinit` construct that comes with ARC, which lets you know when an object is about to be deallocated. Makes it much easier to find memory leaks, imo.
Indeed. `deinit` has saved me from things that would have caused much greater problems later on. It's probably one of the more subtle features that one would miss the most when moving to a language that doesn't have it.
I love go but if one thing that it is not is - expressive, especially when compared to its dynamic cousins like Ruby/Python. That is a tradeoff I am willing to live with, but there is no need to get starry eyed over it.
GP was talking about Go. Not to beat a dead horse, but not having generics results in writing similar code over and over again, eg working with collections
I'm always a bit fascinated when what everyone knows is the next thing turns out not to be. RISC is a classic example. (ARM is light CISC compared to the sort of true minimal RISC I'm talking about.)
GC is borderline but it feels like it might be one of those. In retrospect one giveaway is how easy it is to avoid almost all memory problems in C++ with RAII and STL.
>I wish I could have been a fly on the wall when they were discussing ARC versus GC.
Apple shipped a tracing GC (RC is a form of GC) for a while, but couldn't get it to work reliably or with adequate performance. ARC was a bit of a "Hail Mary" and is problematic in its own right, but certainly better than the GC it replaced.
> ARC was a bit of a "Hail Mary" and is problematic in its own right
I'm just curious with your experience what you are pointing to as problematic. Other than potential extra release calls in tight loops, the main downside I saw was it made the use of C structs way less appealing---at the same time, I wouldn't want to with manually memory managed C structs in GCD blocks.
Last time I did any Objective-C you had to retain/release yourself so the auto stuff is interesting. As far as I can tell the benefit over Garbage Collection is that GC only works well when you have lots of excess spare memory, which is constrained on mobile devices.
There are hybrid systems that combine the prompt deallocation of pure reference counting with the superior throughput of tracing garbage collection.
Part of the reason I really dislike the "reference counting vs. garbage collection" debate, and keep emphasizing that reference counting is garbage collection, is that it sets up this false dichotomy. In reality, there are all sorts of automatic memory management schemes that combine aspects of reference counting with tracing in different ways, most of which were created in the 80s and 90s. Sadly, almost nobody in industry is aware of this enormous body of work, and the simplistic "RC vs. GC" model has stuck in everyone's heads. :(
Not just is reference counting a form of garbage collection (as pcwalton pointed out), it is also not the case that you had to retain/release stuff yourself, certainly not since Objective-C 2.0's properties.
Here is the code to define and use a property pre ARC with properties:
Spot the difference? Now it turns out that there are some differences, such as automatic generation of -dealloc methods and weak references and some cosmetic stuff. But overall, it's at best a subtle difference and for most code you won't be able to tell the difference.
Pre Objective-C 2.0, there were solutions such as AccessorMacros[1], which handled the same use-cases except without the dot syntax (which is somewhat questionable) and have the advantage of being user-defined and user-extensible, so for example if you want a lazy accessor, you don't have to wait for your liege lord, er language supplier to add them, or create a whole new language to do the trick. Instead, you just write 4-5 lines of code and: done!
This is one of the most uninformed posts I have read in a while. As someone who has been developing in Objective C for the last 6 years, and been through the transition of MRC to ARC, none of what is stated in this post is accurate.
Actually, all of it is accurate. Since you're spouting off your credentials as the only evidence for why what I wrote is wrong [not sure how that works], here are mine:
- programmed in Objective-C for ~30 years
- implemented my own pre-processor and runtime (pre NeXT)
- programmed in the NeXT ecosystem professionally since 1991
- additionally, worked in Objective-C outside the NeXT/Apple ecosystem for many years
- worked with Rhapsody and with OS X since the early betas
- worked at Apple for 2 years, in performance engineering (focus: Cocoa)
- one of my projects was evaluating the GC
With that out of the way (and just like your 6 years, it has no actual bearing on correctness): which specific parts do you believe are inaccurate? I'd be happy to discuss, show you why you're wrong, or correct my post if you turn out to be right on something that can be verified (your opinion as to how awesome ARC is doesn't count).
I think they had to go with ARC due to the requirement that swift interoperates with Objective-C. If that hadn't been a constraint, yeah it would be an interesting decision.
No - they already had GC working with Objective-C and could have chosen it for swift if they had thought it was the best technology.
Here's a quote from Chris Lattner:
"GC also has several huge disadvantages that are usually glossed over: while it is true that modern GC's can provide high performance, they can only do that when they are granted much more memory than the process is actually using. Generally, unless you give the GC 3-4x more memory than is needed, you’ll get thrashing and incredibly poor performance. Additionally, since the sweep pass touches almost all RAM in the process, they tend to be very power inefficient (leading to reduced battery life).
I’m personally not interested in requiring a model that requires us to throw away a ton of perfectly good RAM to get an “simpler" programming model - particularly on that adds so many tradeoffs."
Yes, they had GC working with Objective-C but there were so many problems with it that they dropped the GC in favor of ARC years ago. By the time Swift came along, GC with Objective-C was no longer an option.
Chris Lattner was already working on Swift when the decision to drop GC was made. Guess who made the decision? Chris Lattner. If anything, GC was dropped because of Swift, not the other way around.
Generally data lifetime in rust is fully deterministic and the borrow checker can statically determine when data should be deallocated. If for whatever reason you do need reference counted semantics there are options in the stdlib (alloc::rc).
And to elaborate on this, there's a namespace clash: Arc in Rust is _atomic_ reference counting, and Swift is _automatic_ reference counting, which, even more confusingly, is implemented using atomic reference counting in my understanding.
Automatic reference counting inserts all of the refcount bumps. In Rust, you have to write the up count yourself, but not the downcount.
But, reference counting isn't used very often, at least in my experience. It's very useful when you have non-scoped threads, though.
As far as I can tell, the impl of Arc and ARC are actually basically identical at the high level, with the only major diff being ARC only keeps 32-bit counts on 64-bit (so they only waste one pointer of space).
Everything else is just where retain/release (clone/drop) calls are made. Rust is insanely good at not frobbing counts because you can safely take internal pointers and move pointers into a function without touching the counts at all. Swift has lots of interesting optimizations to avoid touching the counts, but it's hard to compete with a system that has so much great static information related to liveness of pointers and values.
As a simple example, consider this code (which is conveniently valid Swift and Rust, modulo snake_vsCamel):
let x = make_refcounted_thing();
foo(x);
This code in isolation will always not frob counts for Rust. This code may not frob counts in Swift, depending on what follows `foo`. In particular if foo is in tail position (or at least tail-position-for-the-life-of-x), then we can avoid frobbing, because we know foo's final operations will be to release its function args. foo may in turn punt releasing its function args to anyone it passes them to as a tail call. Note that Swift and Rust both have the usual caveats that "less is a tail call than you think" thanks to side-effecting destructors.
The takeaway is that Rust's default semantics encourage releasing your memory earlier, which in turn means less traffic on the reference counts. Particularly interesting is that in Rust, you can run a function arg's destructor earlier than the end of the function by moving it in to a local variable. In Swift, I do not think this is possible (but I wouldn't be too surprised to be wrong -- Swift has tons of special attributes for these little things).
I have a production app in the AppStore in 100% swift 2.2. To me it's the most exciting new language out right now. It does not have too many brand new features that other languages don't have but it's implemented most of those modern features in a very solid robust easy to understand and use way. It's functional but not purely, it's object oriented but has great ways to avoid the worst of the designs most of us have been bitten by in the past. We are in a Java, PHP, Node.js, and Swift shop. Swift is BY far the least bug prone and most stable code. It's fast and easy to understand.
It's not perfect, Generics and Protocols are fuzzy at best and if you aren't careful with optionals you can actively harm the stability of your code base. It has a long way to go on the server side but I do believe that it will and should be a great server side language platform. That said in my opinion it's the best language I've worked with professionally.
For reference I've professional written a decent amount of code in:
Python
Java
C#
C++/C
Objective-C
Perl
PHP
Node.js/JavaScript
VB6/VB.net
Ruby
Groovy
Scala
How are generics 'fuzzy at best'? I can understand why you could think that associated types in protocols can be a pain in the ass, but there are reasons why its done this way.
Sorry was generalizing. I meant generics and protocols in combination. The ability to define a protocol based on a generic would be fantastic. It's something that is solved in Haskell fairly well.
Isn't that somewhat possible with extensions and constraints? At least that was the impression given by last year's WWDC talk [1], unless you're thinking of something else?
Scala tries a lot harder than Swift to unify object-oriented and functional programming principles.
For example, in Scala operators are (IIRC) implemented as methods on objects, there's a 'Nothing' bottom type that is used for covariant generic parameterization, and ADTs are implemented using inheritance in the form of case classes.
Swift has no top-level object type or bottom type, and a lot of its more functional style features (ADTs in the form of 'enums', value types that enforce immutability) are completely divorced from the object-oriented part of the language.
Very similar languages IMO. Scala is a little heavier on the functional and academic fronts. It's syntax is also much heavier on symbols. In general I think scala has a steeper learning curve. I like scala though. Similar ideas at their core, a mixed paradigm approach. Similar also in that both have a legacy language that they need to interop with. That legacy also bleeds through to both pretty heavily. I also much prefer a native ecosystem vs the jvm.
The one big area that separates the languages is tooling. I personally think Swift's tooling is much better. Faster compilation, faster runtime, faster startup, and better ide tooling.
I'm a big fan. I love the statically inferred type system, generics, & optionals. Also really like a lot of the functional programming concepts + value types but still enjoy being able to fall back on OOP. It feels like the best of both worlds. I can't wait till we have language native concurrency techniques, so I can start writing swift in backend code.
Me too, but I’d I realized that I’d rather the Swift team not half-ass such a big feature, especially when they’re working on ABI stability and translation of Foundation API’s.
Plus, I bet one of the things that’s holding proper concurrency back are Apple’s frameworks. I’d rather deal with callbacks for another year or two than use a rushed language feature.
Concurrency is done with libdispatch library, which is also open source. Right now, it's only compatible with OS X, but int their post, they said that "For Linux, Swift 3 will also be the first release to contain the Swift Core Libraries."
I'd put Go at the top of the languages to compare it to. Maybe Java as well. The ecosystem still needs some time, but Swift's potential on the server is excellent:
- It is incredibly fast compared to current interpreted languages (i. e. factor 30+ vs. Python, possibly faster than C)
- Linux & OS X, open source
- Typed, safe
People like node.js mostly b/c it allows some code to be written once and run on both the server as well as the client. Considering almost any Web API also has an IOS client, Swift has the same potential.
Lots of languages ARE faster than C, including older languages than C, like Fortran and Forth.
Being faster than C is not anything special in itself.
Most things being equal (typed, optimized, compiled, no runtime etc) C is mostly faster when it does something with a lower overhead than some other language (e.g. a specially written hashmap algorithm targeted to some program vs C++ std map type), not because of its primitives being faster.
Fortran especially. Forth seems to depend on processor characteristics. I seem to remember that Ada compilers routinely produce faster code than C compilers.
C has very loose semantics that make it difficult for a compiler to reason about code, as the saying goes, C is often little more than portable assembly. There's a reason that CLion was a big deal when JetBrains announced it, reasoning about C/C++ code is HARD.
If I wasn't more interested in Agent oriented languages, it might be interesting to see what could be done to design a new language built for performance. I would imagine you'd start with the Ada side of the house and work your way back to more pleasing syntax.
Ada and Rust are both significantly easier to perform aliasing analysis on, so frequently you can get much better code. Both languages have slight overhead for bounds checking and such, but you can turn it off (at least in Ada) if it's a problem (hint: it isn't).
Same reason Fortran is fast actually: it just disallows pointer aliasing entirely¹, meaning you get none of the flexibility of C pointers (heck, you don't even have pointers, basically), but if you're multiplying matrices it flies.
¹ I recall newer Fortrans have pointers, but as I'm not a Fortran programmer I don't actually know.
As someone mentioned below, C can almost be seen as a portable assembly. Given enough time and optimization it will always be as fast as the hardware allows. I guess my point was it is meaningless to say "faster than C" because it always depends on too many factors.
Do you have a link to some benchmarks at hand? Your "possibly faster than C" claim sounds too good to be true without a source, but I'd very much like to be proven wrong :)
I don't think these benchmarks are realistic. Yes, you can use UnsafePointers, but that's not the real world case. ARC, runtime generics and structs have a huge cost in real world programs.
Swift is unfortunatelly usually an order of magnitude slower then Java and C# in real world according to last benchmarks I've made. I'm hoping that will change because I really love Swift.
Obviously keep in mind the various caveats that come with benchmarks, but it seems that Swift is at least capable of achieving C-like performance[1] in some circumstances.
Note that I don't want to claim that Swift is faster than C in general/real life/anything but a few microbenchmarks. But the two just being within an order of magnitude makes a really strong case for Swift, I believe.
I made an app with Swift (my only iOS app). I like it. I like clean, easy-to-read languages where I can get stuff done quickly and reading code isn't a huge pain and using a new library isn't a huge pain. Swift seems to fit those preferences so far.
The debug messages were confusing. I never used Obj-C so I'm not sure if that's iOS or Swift that causes confusing error messages.
> The debug messages were confusing. I never used Obj-C so I'm not sure if that's iOS or Swift that causes confusing error messages.
While it has gotten a little better, it is Swift.
(EDIT:) But I've been loving Swift so far! I've found that there is some consistency to the weird errors, so eventually you can start to map them to past experiences.
I've been playing around with it a little and it's... fine? Very capable. Not run into any moments that have blown my mind, but neither have I found any that disgusted me.
In a weird way it actually reminds me most of TypeScript - JavaScript-y, but with types and stronger enforcement of rules.
For people coming from C/C++/ObjC, some things in Swift can take some time to get used to, e.g.
if case .Success(let person) = personResult {
...
}
My first thought when I saw this was, "only mother could love this syntax", but later you come to appreciate and enjoy the syntax.
I've used ObjC since NeXTSTEP 3.3, and I'm trying to work with Swift. At this point, I've classified it in the same vein as Transact-SQL, a language I need to learn and use, but one I will not love. I guess I love the selector syntax too much. Shame that F-Script never caught on.
I love guard statements, but Swift's `if case...` syntax is horrendous. I'm approaching a year of full-time Swift and I still struggle to get the syntax right on the first try.
For me the most exciting thing about Swift is the recent rumour that Google are looking at adopting it as a first class language for Android.
If that happened, you'd finally have an open, fast, expressive, modern language that you could use on the server and on the fronted for iOS and Android. Couple that with Typescript & Aurelia for the web frontend and I'd be in programming nirvana.
Having developed in Objective-C since iPhone was released, I am very appreciative of Swift. It really puts in a lot of effort to make it hard/impossible to write code that crashes. Swift is such a safe language to develop in, I was able to switch from ObjC to my first Swift project and release builds to my client for months without any reported crashes in my code.
The neat syntax is sometimes butchered by unnecessary casting orgies.
Swifts outstanding feature is its simple C interoperability.
The compilation times (Xcode) are lengthy compared to C or C++.
Semantically, it's probably closest to Rust (from my limited exposure). The syntax is slightly changed, but most things have a direct parallel between the two languages. Although Swift doesn't do ownership/borrow checking like Rust does and is a lot more relaxed in that department.
I tried it an pretty quickly went back to C#. The Apple-only nature was the major downside to me, so maybe these kinds of changes will help (assuming it sees wide adoption outside of Apple-land).
Check your local job boards, but if sell yourself as a Swift dev you're likely to be pigeon-holed into Apple-centric development for the foreseeable future.
With Apple sales and market share dropping like a rock in the last 12 months, that might not be the best position to put yourself in long term, career-wise.
>With Apple sales and market share dropping like a rock in the last 12 months, that might not be the best position to put yourself in long term, career-wise.
Like "a rock"? Where exactly did you see that?
Apple STILL sold 50M frigging iPhones in its "failed" quarter -- and had more profits and revenues that 3 next competitors combined.
And that with supply constraints for mobiles, Intel dragging its feet with laptop/desktop CPUs, and an atypical extraordinary last year-over-year quarter to compare to.
You may have missed the announcement where MS bought out Xamarin and is now giving it away for free. You owe it to yourself to at least give it a try while waiting for actual cross-platform Swift.
90+% of your mobile code can be shared between Android and iOS. Not sure if that's something currently possible with Swift or not, but it was worth keeping C# around for our needs.
We're more of a "mobile app is something we also offer" and web is our main presence though, so your mileage may vary (especially if you're mobile-only or mobile-centric).
If there was a common native language between Android/iOS, it would make things easier for sure. But using a third language to solve the existing problem is a rookie error.
> 90+% of your mobile code can be shared between Android and iOS
This stat depends on how complex your app is, but it usually only applies to gaming. Otherwise it's almost always false.
We've already been down this path with the webview craze a few years ago. It was a total nightmare. These newer cross platform frameworks may no longer use webviews, but under the hood things are just as gross.
What is true though is that these cross platform frameworks always oversell themselves (with the exception of Unity3D). You end up trading in one problem for another.
Among the many problems you will encounter:
1. You miss a lot of newer features in the native platforms. If you want to incorporate those features somehow, the code becomes a conditional mess.
2. Performance is very meh and your hands are mostly tied in optimization. In both Android and iOS, getting performance correct (for example in a table view) requires a lot of tweaking. All of the cross platform frameworks I've used, including React Native, work for basic cases but quickly start dropping frames after that.
3. The majority of a mobile app's code is front-end, and this is not the place where you want to share code. Users on each platform expect different types of interactions and behaviors, not to mention UI aesthetics.
4. These different platforms all have their own characteristics and ways of doing things. These differences are not easily abstracted out. At the point where you are coding around these differences, you might as well have two different code bases. For all the complaining about differences between WebKit/Chrome/IE etc, the behavior is remarkably similar -- mobile platforms are far more diverged.
5. Native third-party libraries are very difficult to use because there is never the same library on the other platform. If there is, say with Facebook, they are not in sync.
6. You end up writing a lot of bridge code between iOS/Android and the framework. It's never pretty and painful to debug.
7. Getting locked into a third-party's framework is a bad place to be later on. Once it's in there, it's never coming out.
I could go on...
If you absolutely need to go cross platform early on, the best thing you can do for yourself is to lock down a common API/data model as early as possible, and create an aesthetic and design that is simple to implement on both platforms.
I can see you have no idea what Xamarin is. With Xamarin, you still use UIKit and the native Android UI, the difference is that you program it in C# and thus the non-UI code can be shared seamlessly. Performance is not "very meh" as the UI is completely native and Xamarin compiles the C# to native code ahead-of-time. It has literally nothing to do with WebViews.
Nobody's saying that Xamarin uses web views, but clearly there's a comparison to be drawn with the craze a few years back for writing mobile apps using web views. This was advocated as being cross-platform, allowing developers to write the same code and run it on multiple platforms. The downsides are the same in some ways, as the parent enumerated.
Xamarin's use of native UI is important, but in my experience it's clearly not as seamless as you think; while you access the UI natively, there are intrinsic architectural differences that make it difficult to do so in a high-performance manner without a lot of fairly hacky code.
I haven't used Xamarin, but I've used a number of other frameworks (some webview based, many not). Some had benefits, but many had a lot of drawbacks.
I could write a long blog post about what a headache it is to support both platforms, but I don't think any of these frameworks solve the real pain points. It's generally a lot of small things which add up. It also takes a lot of team discipline.
Code sharing would be useful, but not massively since the majority of code is in the UI. When the UI is different, a lot of differences start to be needed in the non-UI code as well. Suddenly you are back at square one. Depends on the app though.
I didn't really want to get into the reasons why. I was just pointing out that investing in an Apple-only tech might be a bad idea because it sure looks to me (and the stock market) that Apple has peaked and is now on the decline.
However, since you said my statement was completely false without a source, I felt compelled to show my sources.
51 million iPhones sold compared to 61 million the same quarter last year a DROP of 10 million. iPad an Mac also down double digit percentages, but iPhone is the only thing that really drives Apple. Overall sales DROP from $58B to $50B Source: http://money.cnn.com/2016/04/26/technology/apple-earnings/in...
Sure Apple makes a ton of money and profit still, but you can't really argue that it's not dropping like a roick in the past 12 months. If you put $1,000 into Apple stock a year ago today, you'd have about $700 today. Source: https://finance.yahoo.com/echarts?s=AAPL+Interactive#{%22all...
Let me know where I went wrong, but I'm showing double digit sales drops, a large market share drop, and 30% stock value drops in the last 12 months. I'm not sure how my post is "completely false".
There have been 30% stock price drops multiple times during the 13 years of continuous growth. They are clearly not correlated with the actual growth prospects, and if the stock market actually thought that Apple was dropping like a rock as you claim, you would expect to see a far higher discounting.
You mention the Mac, which as declined in absolute terms but has continued to grow relative to the declining market.
The same is true of the iPad, and there is evidence that it's decline is actually halting - I.e. it is reaching a plateau that is lower than its peak. Whether it will return to growth or not is an open question, but it is clearly not dropping like a rock.
So - the stock market story doesn't support your conclusion, nor does the iPad or Mac.
That leaves the iPhone. It is possible that the iPhone has reached a peak in terms of revenue.
Is it possible that it has reached an all time high in terms of active user base? That seems extremely unlikely.
For one thing, the total number of iPhones sold per year is still astronomical, and the devices have a long useful life. Even without a change of strategy, there will still be a huge number of new iPhone customers over the coming years.
Secondly there are many possible strategic solutions to a reduction in sales. Apple is selling far more SE devices than they anticipated, suggesting that there is pent-up demand for cheaper iPhones. They can address this segment easily, which will continue to increase the user base of IOS, even if revenue growth stagnates as a result of lower ASPs. This is just one possible strategy adjustment that would address the concern.
As I said, there has been a decline, but nothing supports your conclusion that Apple is 'dropping like a rock'. As such this is a bad conclusion on which to make a choice about whether to learn Swift or not.
This "dropping like a rock" quarter was Apple's third most profitable Q2 of all time and they made more money than Alphabet, Microsoft, and Facebook combined. The Apple Watch so-called "flop" is estimated to have outsold Rolex by $1.5 billion in the past 12 months. Their services revenue grew by 20% year-on-year.
At some point you have to realise that there's nothing Apple can do that would count as a success in some people's eyes. They are the most successful total failure I've ever heard of.
Your message isn't really that convincing. Apple, while it may be "dropping", is far from doing so "like a rock" – the platform is clearly huge and will very obviously continue to be so for quite some time. Added to that, Swift is not an Apple-only technology.
Perhaps Swift likes Actionscript? That's where a lot of professional left Actionscript for Scala and some invested and adopted Swift. Who cares about sales drop when it's not your job, when the main goals to get Swift on cross-platforms and IoT. Contents drive sales, you seen Windows and BB, Jolla phones have failed.
It's safe to predict Swift will supported in Android and I still prefer iOS for entertainment whereas I have a bad experience on many Android phones for years including it took years for Samsung and LG to release new ROM.
As an aside, I like that Apple is betting the farm on ARC. I wish I could have been a fly on the wall when they were discussing ARC versus GC.