Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Swift 3.1 Released (swift.org)
167 points by okket on March 27, 2017 | hide | past | favorite | 69 comments


A week or two ago I updated a fairly large project to 3.1. Not as painful as the 3.0 upgrade by any means, but there were still a fair few warnings about features that will be deprecated in future releases. Dropping support for the initialize() function was probably one of the most prominent.

To me that seems like a nice way of doing it - warning developers about approaching changes with a fairly strong warning message, and allowing time for those changes to take place.


Most of the new warnings in 3.1 were with things that never should have worked in the first place (some stuff with public declarations referencing private typealiases in their type signatures and things like that).

There were also some new warnings added for mixed type arithmetic which is a common source of surprising behavior.

The initialize thing is as far as I understand due to a limitation in the Objective C runtime and overriding initialize in Swift never fully worked in the first place.

If you feel the 3.0 to 3.1 migration was still too painful from a compatibility perspective, it is not too late to file bugs; Swift 4 will still remain compatible with Swift 3 source so we can make further adjustments to the type checker if needed.


Just installed, compiling a fairly large project gives me "Command failed due to signal: Illegal instruction: 4" without any further information. Smooth...


Congratulations, you managed to crash the compiler. Can you please file a bug?

https://swift.org/contributing/#reporting-bugs


Of course, just did. Very surprised that this happens for a 'source compatible' point release of Swift. Especially as this can be triggered with only five fairly simple lines of code. Not good.


Imho, Swift Compiler crashes are the single most worrying things for the swift language future, because it casts shadows over the unit tests, and thus make people doubt the reliability of the whole project.


Unit testing a compiler for a language like Swift is hard because there are so many features that interact in complex ways. There are unit tests but it's easy to miss things that look "obvious" in hindsight.

Until recently the focus was on finishing the design of the language itself and not fixing bugs or improving compile time. Now that the language is source stable the focus is shifting to the latter two tasks.

Also source stability means we can build up a larger body of code for testing (imagine having to constantly migrate unit tests that exercise corner cases and quirks... not fun).


I understand. I guess the problem comes from the fact that the language is still extremely young and moving fast, and yet advertized by Apple itself as something that should be used right now to develop apps for the billion dollars iOS market.


Well they are called bugs and they exist in every software. It's not like they did it on purpose.


Yea, but the Swift compiler is extremely buggy. Plus its gotten buggier with each release.


That sounds like you are making engineering decisions by superstition. Unless you have some source of data to back it up, please don't spread your subjective misinformation.


I'm curious! Mind sharing your five lines of code if they are simple and don't contain anything special?


https://gist.github.com/pixelspark/f4f34a257d84611e7204b646d...

Real-world use: https://github.com/pixelspark/warp/blob/dcf57462bd400df6d067...

(the typealias thing is a bit weird here, I agree - it also doesn't crash without it. Nevertheless this compiled fine on 3.0 and should show a nice error, not require me to leave out every other file from the build to find out where it goes wrong, then bisect that file to find out which line causes it)


Your snippet works in the latest master development snapshot too it seems.


Thank you!


Very anecdotal evidence: I work on a fairly large mixed Swift & Objc project and I was expecting a greater decrease in compile times.

At first it seemed 'snappier' but starting to notice not much of an improvement.

It definitely still feels like making small changes like changing a function name triggers a lot of extra work.

I should fire up some benchmarking of Swift 3.1 vs 3.0


There are two main sources of slow compile times in Swift -- the expression type checker has exponential in the presence of large numbers of overloads (which unfortunately includes arithmetic expressions and collection literals). The second is what I think you're hitting which is that incremental builds sometimes rebuild too many files because the dependency tracking is overly conservative.

There was some work on the expression type checker in 3.1 (string interpolation, casts and a limited "domain shrinking" pass to simplify some arithmetic expressions) but the main focus there was centered on the declaration checker, in particular up the generics implementation to fix lots of crashes and limitations.

Both the expression checker and incremental builds should receive more attention going forward though.

In the meantime the usual workarounds might help - splitting up your codebase into multiple Swift modules ("targets" in Xcode), and splitting up complex expressions and adding explicit type annotations.


Also have you tried enabling precompiled bridging headers? This was added in 3.1 with the goal of speeding up mixed Swift/ObjC builds (by none other than Graydon Hoare), but other than that I don't know much about it.


It looks like it was actually disabled before release

https://github.com/apple/swift/commit/5b9166ba8098a23e0601aa...


My understanding was that this was enabled by default


Upon further inspection they disabled pre compiled bridging by default before release

https://github.com/apple/swift/commit/5b9166ba8098a23e0601aa...

After turning it on compilation speed seemed to improve immensely


Interesting to hear that IBM helped improve the release on Linux, thanks. I may consider it for a project in the future.


Yes, IBM is putting some money into supporting Swift, just like they did with Java in the early days.

https://developer.ibm.com/swift/

https://developer.ibm.com/swift/kitura/

https://www.ibm.com/cloud-computing/bluemix/de/swift


Used objc a bit; never used swift. Question about this signature:

    func drop(while predicate: (Self.Iterator.Element) throws -> Bool) rethrows -> Self.SubSequence
I take it the "throws" on the type of predicate means it can 'throw/return' an error. Why would you do this? Why not just require your predicate function to be able to process any element?

Or I am confused?

It seems like the equivalent in Go, for example, would be something like this

   func drop(seq []T, while func(T) (bool, error)) ([]T, error)
which, again, seems like madness.

Or am I confused?


The key is the `rethrows` keyword, which allows the compiler to conditionally enforce error handling based on the signature of the given closure.

The equivalent Go code would then (presumably) be these two methods:

    func drop(seq []T, while func(T) (bool)) ([]T)
    func dropWithError(seq []T, while func(T) (bool, error)) ([]T, error)
If you pass in a closure that throws (i.e., can return an error) then the compiler will require try/catch error handling at the `drop()` method call site.

If you pass in a closure that does not throw then compiler will assume that `drop()` does not throw.


With 'drop' passing a throwing predicate feels a bit esoteric, but consider something like 'map'. Suppose you are mapping over an array of file names and loading each one, which can throw. You would expect the 'map' itself to throw if processing one of the elements throws.

You can write higher order functions that only take total functions as arguments and handle errors with an 'Either' type, which is more general but creates boilerplate.

Also 'rethrows' is a special keyword that means if you pass in a function that does not throw, the overall operation won't throw either. So mapping over an array of integers to increment each one won't require error handling, since the operation itself cannot fail.


"So mapping over an array of integers to increment each one won't require error handling, since the operation itself cannot fail."

Nitpick: in Swift, "since the operation itself cannot fail" isn't correct. The operation will fail on overflow, but it will terminate your application rather than throw.


Those are called "universal errors" and it's not very useful to reason about them. You could prove your program correct, use a total-function programming language, but it still could fail to complete - the power could go out halfway through execution.


Ah, OK, interesting. Thanks for the response.


> I take it the "throws" on the type of predicate means it can 'throw/return' an error. Why would you do this? Why not just require your predicate function to be able to process any element?

Because otherwise you can't use partial functions as predicates which is an unnecessary an oft annoying limitation, in my experience it's one of the biggest pains in the ass in Java and a major reason why its checked exceptions system was unusable: you couldn't create "transparent" functions (and interfaces) with respect to CE.

> It seems like the equivalent in Go, for example, would be something like this

`rethrows` is a transitive property, if the predicate is not a throwing function, the HoF isn't one either. So you'd need two functions in Go. And then `drop` works on a more abstract concept than concrete array slices ("Sequence" is what many other languages would call an iterable).


>Why not just require your predicate function to be able to process any element?

Because the predicate would then have to swallow any exceptions thrown downstream. What would it return in that case? True or false?


First, why not allow your predicate to throw? Maybe your program will be better structured that way.

Second, if you pass a predicate that is not declared `throws`, then the compiler treats `drop(while:)` as if it cannot throw either. This is what `rethrows` means: it makes `drop(while:)` covariant (in terms of throws-ness) with `predicate`.


I like Swift but I hate the Xcode and the Apple tools. Is so painful to code with it. Apple needs to change its entire development flow. Even working with the react-native I need to use Xcode. =l


Why do you feel it's painful? I've only written a tiny desktop menu bar app with it, but I liked the clean look of it and it didn't feel so cramped like Visual Studio.

Maybe I just don't have written with it enough.


I can honestly say that Xcode is the worst piece of software I have ever used.

It's incredibly slow, it has always been riddled with bugs, it has crashed on me more often than any other software, and it is lacking so much functionality that it doesn't deserve to be called an IDE at all.

For instance, it can't even rename a Swift function years after Swift's introduction.


You should give Android Studio a try, you will no longer complain about XCode being slow.


hahahaha I need to agree with you. Xcode is bad but Android Studio is worse than everything else.


What is this, the paralympics of software IDEs?


First place: Xcode

Second place: Driveway chalk with a water hose

Third place: Android Studio


I need to agree with you, Apple tools, in general, are very strange...


You forgot Lotus Notes.


If you work with a large-ish ObjC+Swift project, XCode is quite painful. I regularly lose syntax coloring. Compile errors get stuck and don't disappear when the code is fixed. Refactoring Swift code is non existent. Importing images in the project locks the entire UI thread. Storyboards that are more then a couple of screens take ages to open and edit.

SourceKit should help XCode to reason about Swift code but somehow XCode gets lost at least once or twice a day on my machine (MBP 15" i7, 16GB RAM).

Android development tools used to suck but since Android Studio 2.0 and the rise of Swift, it is now iOS dev tools that are lagging behind.


> I regularly lose syntax coloring.

Yep. Happens to me all the time too. Make some changes to code, then wait half a second of the syntax coloring to take effect.

How this is not instant boggles the mind. Maybe it's related to SourceKitService which randomly decides start taking up 100% CPU for no discernible reason.


SourceKit itself is fairly stable. However it embeds a copy of the Swift type checker. :-)


It's certainly stable, it just likes to take up 100% of the CPU.

It happens especially when writing new code or refactoring old code in a medium sized project and using function or variable names that don't yet exist but that I'm about to add in the next few minutes.

For example say I want take a chunk of code and move it to a new function fooBar. So I cut the old code and then replace it with a call to a not yet written fooBar function.

Then I go to write the definition of fooBar and paste previous code in there but before I can do that, SourceKitService has got itself into a CPU frenzy that won't calm down for 15-20 minutes (even after finishing writing the fooBar function) while it presumably tries to find where fooBar was defined.

It's gotten to the point where I have disabled 'live issues' (which seems to exacerbate the problem) and regularly have to kill the SourceKitService process so my fans will go back to normal.


Xcode is very slow. Every time that I open it, my computer switch on the cooler, the memory of my mac have a spike of consuming.

I don't like the IDE itself... for instance, if I need to rename something, Xcode uses an XML that when you have a team working on the same project, you will have huge problems with merge the commits.

Maybe the problem is me, but, I know XCode since 2012 and I never like it! =l


Have you tried the JetBrains AppCode IDE?


Never, is it a good choice?


Why do you feel the need to use Xcode (rather than just running the compiler and codesign tools using the build environment of your choice)?


Hum, to be honest, I don't like the Apple development flow. I don't like the Apple developer center, I don't like the Certificates, etc etc. In my case, I need to use XCode to find out the right places to link the react-native lib to my project...


Hopefully it has support for warnings when formatting strings with optional values:

http://stackoverflow.com/questions/42045139/i-want-a-compile...


Good news - it does. For me, it fixed a lot of bugs that I had no idea existed.

Seems like a pretty easy mistake to make, since third party libraries I use were littered with exactly the same mistake.


Yep it was a really nasty one. Because it used to work differently in Swift 2.x where it would not put Optional() around it in certain circumstances.


Interesting, I don't remember noticing it behaving that way. What were the circumstances, if you recall?


    var someInt: Int! // class parameter

    // later, in a method
    let url = "/api/bla/\(someInt)"
In Swift 2.x it would simply show the value of someInt. Now it will print Optional. The problem is described in the linked Stack Overflow question as well.

I never program like that but there's a ton of people out there that convince the compiler they're going to set that value in time even when it's not set when init is called. Just like some people (including Apple!) use this pattern for setting outlets:

    IBOutlet var someLabel: UILabel!


I think there were differences around calling .description versus .debugDescription when a type is converted to a String, which had some odd behavior with Optional. I think there was an evolution thread about this but you'll have to Google it yourself since I'm on my phone right now :-)


Does anyone know where the new Linux binaries are? The release announcement links to https://swift.org/download, but I can't actually find the 3.1 binaries anywhere.



There are neither source releases, nor tags in git repository yet (except the 'swift' repository).


You can download a 3.1 development snapshot. I'm not involved in preparing the official releases but I'm assuming the Linux 3.1 release will be very close to what is in swift-3.1-branch now.

And all the action these days is on the master branch so if you're on Linux and want to help us squash regressions you should periodically test your codebase with master snapshots.


At this stage, I'm more interested in properly packaging it (for a non-Ubuntu distribution), than compiler development itself. Not having at least tags for the release is very unusual, especially given the title of this article ;). As it is composed from multiple packages, there are too many moving parts than may or may not fit together.

It would be great, if there was a tag+source tarball for each release. I'm sure internally there must be something, your colleagues certainly must know, to which commit 'Apple Swift version 3.1 (swiftlang-802.0.48 clang-802.0.38)' maps to.


There is a tag for the release, called swift-3.1-RELEASE:

https://github.com/apple/swift/tree/swift-3.1-RELEASE

It's not showing up on GitHub's UI nor search for me at present, which may be why it seems like it's missing.

You can download a .tgz from GitHub but bear in mind that you have to do the same for each of the nested repositories as well. If you're building it for yourself, it's easier to download the swift-3.1-RELEASE content, and then run 'utils/update-checkout --clone --skip-history --tag swift-3.1-RELEASE' to procure the rest of the repositories.

There are a number of bugs to work on Swift packages for RHEL/CentOS:

https://bugs.swift.org/browse/SR-100

https://bugs.swift.org/browse/SR-108

https://bugs.swift.org/browse/SR-116

The issues are primarily around those operating systems having too old a version of Clang in their default repositories to be able to bootstrap the newer builds, and the fact that they don't have the blocks runtime available, both of which are used by the Swift runtime.


Thanks, there are tarballs for swift-3.1-RELEASE and swift-lldb-3.1-RELEASE now. For the rest (swift-llvm, swift-clang, swift-cmark, swift-corelibs-foundation, swift-corelibs-libdispatch, swift-corelibs-xctest, swift-llbuild, swift-package-manager, swift-xcode-playground-support, swift-compiler-rt) I will check for those invisible tags.


Does anyone have a good linux-based swift workflow? I'm starting to experiment with integrating the language in cross-platform projects and I'd love to be less reliant on Xcode.


I have a question. Why would you use Swift for linux development? Is there a binding to any major UI framework (QT...)?


For now it's mostly just experimentation/personal projects, but I'd like to be able to write web-servers in swift and to use it for image processing. Swift is interoperable with C, so any library with a C interface is freely available to a Swift application.


I am waiting for a swift->js compiler and a new explosion of hipster wave of how it is the greatest thing ever, even better than the last weeks hot tech.


there is already one. http://www.shiftjs.com/#/home


Would really be nice if it could offer generic linux binaries... this ubuntu only development approach is quite aggravating. I don't mind a big download, why not just bundle your LLVM changes and package it all in a single download?




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

Search: