Ordovician Swift: Evolutionary Advances

Accepted

SE-0088: Modernize libdispatch for Swift 3 naming conventions is accepted with revisions. “libdispatch on Darwin already presents Objective-C compatible types to allow its objects to participate in automatic reference counting. We propose extending this support to present a design that feels “object-oriented” and inline with Swift 3’s API guidelines, all without adding runtime overhead.”

Under the current 2.2 system, dispatch looks like this:

let queue = dispatch_queue_create("com.test.myqueue", nil)
dispatch_async(queue) { 
   print("Hello World") // etc
}

The new system modernizes the calls to look “Swifty”, eliminate snake case, and provide a user experience that better mirrors the readability and flow of modern Swift.

let queue = DispatchQueue(label: "com.test.myqueue")
queue.asynchronously {
    print("Hello World") // etc
}

Team feedback:

The community and core team are both very positive about this massive improvement to the libdispatch APIs.  Much of the discussion has centered around specific details in the proposal – for example the “.asynchronously” method on DispatchQueue.  This great discussion leads to several requested revisions in the proposal:

  • Rename the DispatchQueue.[a]synchronously methods to “.async” and “.sync”, to follow the term of art.
  • Rename DispatchIO setHighWater, setLowWater –> setLimit(highWater:), setLimit(lowWater:)
  • Rename setTargetQueue(queue:) and DispatchSource.setTimer
  • Rename Semaphore, Group and WorkItem: .wait(timeout:) –> wait() and wait(withTimeout:)
  • Expand source handler methods to take the same arguments as async()
  • Expand DispatchQueue.after to take the same arguments as async() in addition to the when: argument

SE-0081: Move where clause to end of declaration is accepted. Team feedback:

The feedback on this proposal was strongly positive from the community and core team.  Some concerns were raised (e.g. about possible interaction with the future “generalized existentials” feature) but further examination turned up that they were at issue regardless of whether this feature is accepted.

The core team agrees that this syntactic structure allows a more natural and beautiful way to structure complex generic constraints, and that “where” clauses should be considered secondary to the primary signature of the declaration (e.g. func, class, etc) in question.

SE-0075: Adding a Build Configuration Import Test is accepted.  Team feedback:

The community and core team are both very positive about adding this functionality.  It is precedented by the __has_include feature in Clang, and may have applicability allowing “conditionally available” features for SwiftPM modules in the future.  The core team spent a significant amount of time discussing the proper naming for this, and came to agree that “canImport” (as proposed) is the best name for this conditional.

Rejected

SE-0041: Updating Protocol Naming Conventions for Conversions is rejected. Team feedback:

The feedback on the proposal was generally positive about the idea of renaming these protocols, but the specific names in the proposal are not well received, and there is no apparent confluence in the community on better names.  The core team prefers discussion to continue — if/when there is a strong proposal for a better naming approach, we can reconsider renaming these.

Active Reviews

Upcoming Reviews

Awaiting Scheduling

If you enjoy these Swift Evolution updates and want to say thank you, consider picking up a book or two. Swift Documentation Markup teaches you how to use Swift’s documentation system to better annotate your code. Playground Secrets and Power Tips unlocks the power of Xcode’s Swift playgrounds. And if you’re looking to pick up solid, day-to-day Swift skills, look no further than the Swift Developer’s Cookbook. (It’s not exactly a cookbook but the name was chosen long before WWDC 2015, so we kind of got stuck with the title.)

Swift: Things I really wanted that won’t make it

Here’s a short list of things that aren’t (or probably aren’t) going to be in Swift 3, that I was hoping to see.

Like my posts? Consider buying a book or two or three. Thanks!

Fixed Ranges, Striding, and Range Operators. This splintered down into a series of I believe four separate proposals of which only the first one (improving floating point math) has gotten into review. A lot more work to be done here. Plus extending striding to collections.

Disambiguating SPM Naming Conflicts. My idea would be to come up with a way to allow multiple packages to share the same simple names (like “JSON Parser”) and differentiate them based on their source repo. Swift names should be simple and concise. Namespacing modules (“MySwiftStringUtilityCollection”) is very unSwift so overlap is not just likely, it’s already happening.

The language would adjust to add import as as well, so same-named modules (or modules with difficult names, or submodules) could be pulled in with simpler access from code.

Most of this depends on the overworked and overwhelmed build team, plus it would then require a Swift Evolution proposal for the “import as” component. There are already bug reports of package conflicts in the wild and this would introduce a simple way to add resolution.

Introducing Build Configuration tests for Simulator/Device targets. I gave up on even trying to do #if debug (if one is going to do the configuration tests, there doesn’t seem to be a large enough middle group that wants a preconfigured simple test) but I think #if target(device) (vs simulator/emulator) is doable and useful. Backburnered, along with any platform tests (Windows, Linux, Unix, Apple) until there’s time.

Method Cascades. Dart-like for the win. Postponed until after 3.x at a minimum. It’s language additive, which makes it less critical for 3.

Interpolated String Formatting. Brent Royal Gordon started this off and then it went into limbo. I think it’s important to be able to not just add \(aFloat) into strings but be able to do some kind of inline safe formatting about the number of decimal places, leading zeros, etc.

Core Error. Not hugely popular but not entirely dead, I thought it would be nice to have a built-in basic “default error” to throw that included source site (where the error was thrown) and an optional customizable string and/or dictionary. This wouldn’t replace any other errors but it would provide a convenient error for anyone building scripts and playgrounds (or, let’s be honest, simple apps) where you didn’t want to build something more carefully and extensive with individual error condition cases.

Macros. Didn’t happen. Won’t happen for a while.

Decimal Numbers. Ditto.

Duplicating and modifying immutable structs. Brought up “with” on list, showed an implementation, it got discussed, went nowhere.

Final by default for Swift-sourced classes (would not apply to anything from ObjC), where you enable subclassing rather than disable it. Seemed to split down between Swifties (for it), ObjCHeads (against it).

A Result Type for use in completion blocks, rather than the data, status, error signature we currently have. Big war over Result (specific use case, measurable benefit) and Either (just a thing that could be built and used for this). I prefer Result.

Intrinsic Member Collection for Enumerations. There’s a pull request but that’s about it.

Expanding Cocoa Touch Defaults. The idea was to take a cue from the better-imports from ObjC (SE-0005) and extend the pruning and defaults to other common classes. This isn’t a Swift Evolution process but I have no contact point with whom to take it up with for Foundation and UIKit. (initial unreviewed list), and I’m not yet satisfied with which defaults I actually want to push on.

There’s actually two more items on my list that just might squeak through:

Adding the Unfold Sequence. Kevin’s sequence -> UnfoldSequence  was part of SE-0045 and the only part of the proposal not to be accepted. After a spate of bikeshedding, I think the name sequence() was not hated, but it’s unclear whether this needs a new proposal (it’s getting kind of late to the party) or can be shoehorned in. SE-0094: Add sequence(initial:next:) and sequence(state:next:) to the stdlib in review to 5/23

Evan Maloney’s end to the Strong Weak DanceI was writing this up, and I checked the pull request and behold, it is now in the proposal queue as SE-0079. Still not sure this will go through but it would make coding a lot better.

Okay, that’s my (partial) list. What’s yours?

If I had my druthers: Swift 2.2, Swift 3.0, ABIs, etc

If I could wave a magic wand, I’d push Swift 3.0 out by a year or even better three years and fix Swift 2 as the standard App Store language (and for Linux, and upcoming Windows) exactly as is, barring a few tweaks and fixes over this time.

[tl;dr summary: Make big breaking changes later and once rather than sooner and multiple times. If a delay allows a single stable language transition, it is to be preferred. Aim for post-3.0 language updates to be additive not transformative.]

Swift 2.2 is a great language. It’s amazing to work in. It offers utility and concepts that Objective-C cannot provide. It pushes iOS and OS X development forward in an important and exciting way, affecting development not just on Apple platforms but wherever Swift touches. From first class structure and enumeration types to protocol oriented programming, Swift 2.2 delivers the goodies.

If you need just one compelling single example, take CGRect: Swift 2.2 lets you expand this essential structure with methods and properties that let you center on a zero origin, or scale and transform, or add math to combine instances. It’s so practically useful that going back to ObjC to work in geometry metaphysically hurts.

Swift 2.2 gets it right in so many ways, that it seems ridiculous to throw it away at the end of the year. A language this good should have a lifetime longer than 8 or 10 months. I’d be really happy if at the WWDC keynote, Tim Cook said, “We got it so right, we’re going to stick with Swift 2, let you build your code for long term use, and make sure the transition to Swift 3 will be perfect.”

The move to Swift 3.0 isn’t just going to be disruptive. It’s going to be traumatic. With its expansive renamification and redesigned core types and APIs, Swift 3 is going to be a tidal wave of retraining and refactoring. And with a list of objectives that didn’t quite make the cut, and a laundry list of of items that should have, Swift 3 just doesn’t have enough time or scope to be perfected.

So why not just push it back?  Let us devs use Swift 2.2, which is terrific, for a few more years and get Swift 3 right the first time?

It’s not as if Swift Evolution needs to be fast paced and hectic. The bikeshedding, the simple natural discussion overhead, the need to foster a courteous open source community means the natural speed of development has taken a huge hit.

These arbitrary “update every year” advances that Apple has bought into are more than a little ridiculous when it comes to firmware and OS updates; for languages it pushes beyond the practical.

Orson Welles promised that Paul Masson would sell no wine before its time. Apple should take a lesson from Welles and ship no language before the follow-up version has properly evolved.

I want to see Apple slow down, take some deep breaths, and seriously consider letting Swift 2.2 come into its own rather than cutting it down after a few months of use.

As it is, I am constantly having to answer “Is it time yet to switch to Swift?” As this breakneck development continues, I’ve been hesitant to recommend jumping aboard the Swift train for simple practical reasons.

I’d be far more confident with my advice if I could see a 2-3 year window with stable code that could benefit from Swift’s modern language features, and a payoff of investment in training and refactoring that won’t have to be re-addressed with each new beta and each new release.

To paraphrase a line from Aesop, slow and steady really does win the language race.

Like my posts? Consider buying a book or two or three. Thanks!

Playing with the future

A few test runs for fun.

Proposal SE-0071. “Allow (most) keywords in member references” is implemented. This allows the use of members after a dot without backticks, e.g. “foo.default”.

Verdict: Not quite ready for prime time. Chris Lattner tweets: “Fwiw, that is the intended design of SE-0071.  It only changes “after the dot”.  You need to use back ticks after [v]ar”

Screen Shot 2016-05-18 at 9.23.41 AM

Screen Shot 2016-05-18 at 9.58.10 AM

Proposal SE-0046. Function parameters now have consistent labelling across all function parameters.

Verdict: Working.

Screen Shot 2016-05-18 at 9.27.00 AM

Proposal SE-0037. “Comments are now treated as whitespace when determining whether an operator is prefix, postfix, or binary. Comments can no longer appear between a unary operator and its argument.”

Verdict: Working.

Screen Shot 2016-05-18 at 9.35.53 AM

Proposal SE-0031: inout now decorates types, not labels

Verdict: Working

Screen Shot 2016-05-18 at 9.39.41 AM

New Active Swift Reviews

SE-0087: Rename lazy to @lazy in review to 5/23. “Swift’s rule for attribues/keywords is that keywords usually modify type of variable; attributes do not. lazy clearly does not modify type of its variable, it only delays side effects of its initializer. Type of resource in the example above is still NSData. Many other similar declaration modifiers are already attributes including @available@objc@nonobjc@NSCopying@NSManaged@IBOutlet, etc.”

SE-0077: Improved operator declarations in review to 5/23. SE-0077 introduces general precedence that isn’t numerically based. “In the beginning, operators had nice precedence values: 90, 100, 110, 120, 130, 140, 150, 160. As time went, new and new operators were introduced. Precedence could not be simply changed, as this would be a breaking change. Ranges got precedence 135, as got precedence 132. ?? had precedence greater than <, but less than as, so it had to be given precedence 131. Now it is not possible to insert any custom operator between < and ??. It is an inevitable consequence of current design: it will be impossible to insert an operator between two existing ones at some point.”

SE-0091: Improving operator requirements in protocols in review to 5/23. “When a type conforms to a protocol that declares an operator as a requirement, that operator must be implemented as a global function defined outside of the conforming type. This can lead both to user confusion and to poor type checker performance since the global namespace is overcrowded with a large number of operator overloads. This proposal mitigates both of those issues by proposing that operators in protocols be declared statically (to change and clarify where the conforming type implements it) and use generic global trampoline operators (to reduce the global overload set that the type checker must search).”

SE-0090: Remove .self and freely allow type references in expressions in review to 5/23. “Swift’s grammar currently requires that type references only appear as part of a constructor call T(x) or member access T.x. To get the metatype object for T, one must refer to the special member T.self. I propose allowing type references to appear freely in expressions and removing the .self member from the language.”

SE-0089: Renaming String.init<T>(_: T) in review to 5/23. “Swift’s String type ships with a large number of initializers that take one unlabeled argument. One of these initializers, defined as init<T>(_: T), is used to create a string containing the textual representation of an object. It is very easy to write code which accidentally invokes this initializer by accident, when one of the other synonymous initializers was desired. Such code will compile without warnings and can be very difficult to detect.”

SE-0050: Decoupling Floating Point Strides from Generic Implementations in review to 5/23. “Swift strides create progressions along “notionally continuous one-dimensional values” using a series of offset values. This proposal supplements Swift’s generic stride implementation with separate algorithms for floating point strides that avoid error accumulation.” Another step in fixing Swift Floating points.

Accepted

SE-0092: Typealiases in protocols and protocol extensions is accepted. “In Swift versions prior to 2.2, the typealias keyword was used outside of protocols to declare type aliases and in protocols to declare associated types. Since SE-0011 and Swift 2.2, associated type now use the associatedtypekeyword and typealias is available for implementing true associated type aliases.”

Chris Lattner notes:

The new proposal for SE-0092 “Typealiases in protocols and protocol extensions” is proactively approved for Swift. The core team consider this as an obvious follow-on to SE-0011, and thus doesn’t itself demand a proposal. However, including a proposal in the swift-evolution archive does have a benefit to keep track of the new capability it enables.

The core team accepted this without a formal review period (because it its obviousness) as an attempt to optimize process. If there are any serious concerns, please raise them and we are happy to reconsider and start a normal review cycle.

SE-0085: Package Manager Command Names is accepted, with original naming. “This is a proposal for changing the command names used for invoking the Swift package manager. Instead of hanging all functionality off of swift build and swift test, we will introduce a new swift package command with multiple subcommands. swift build and swift test will remain as top-level commands due to their frequency of use.”

Daniel Dunbar writes:

The Swift package manager core team met last week to discuss this proposal, and we ultimately *accepted* it relatively unchanged. I have amended the proposal to include more information on the alternatives discussed:
https://github.com/apple/swift-evolution/blob/master/proposals/0085-package-manager-command-name.md

We discussed at length the `spm` and `swiftpm` alternatives raised on this thread. In the end, we chose not to go that direction with the proposal for the reasons I included. We do recognized the desire for a shorter command, and view having an alias as something that can be added later if it proves to be the right thing to do.

More about the Swift ABI postponement; The laws of ABI changes

Via Greg Parker:

We apologize for the inconvenience. The OS X and iOS architecture transitions demonstrate the two fundamental laws of ABI changes:

  1. Opportunities to break ABI compatibility are rare.
  2. Any opportunity to break ABI compatibility will suffer from severe schedule pressure.

The Objective-C ABIs have many problems that would have been improved with more time.

  • We tried to get a “modern” ABI into i386, but the schedule was too tight and we lost time with some initial design ideas that didn’t pan out. x86_64 was also a tight schedule, but much of the work was already in place from the i386 attempt so we were able to get it done.
  • Fixing BOOL was repeatedly not quite high enough priority.
  • The 64-bit metadata structures have at least one field that is 64-bit by accident (protocol_list_t.count). There was miscommunication between the compiler and the runtime when the design was specified, and then it was never high enough priority to coordinate a fix later.
  • armv7 uses setjmp-longjmp exceptions instead of “zero-cost” exceptions because that’s what GCC’s arm compiler used then and we didn’t have time to change it.
  • The very first iPhone did not use a “modern” ABI. We knew we could break ABI compatibility at any time before 3rd party apps were supported, so we punted ABI modernization until after 1.0.
  • Non-fragile ivars on iPhone had a fragility bug in the compiler. (You don’t see non-fragile ivars doing their thing until the *second* release, except for deliberate testing. We didn’t test enough.) Luckily the bad case was narrow and the miscompiled code was detectable by inspecting binaries in the App Store, so we were able to ask all of the affected apps to recompile with a fixed compiler before the next iPhoneOS version shipped.

If we tried to rush Swift ABI stability out the door for Swift 3 we would certainly end up with deliberate or accidental flaws like the above. Being able to take the time to get it right is a rare luxury.

Winding down Swift 3.0; ABI stability deferred

Chris Lattner writes:

Hi Everyone,

As we get deeper into the Swift 3 release cycle, we’re beginning to have a more precise understanding about what the release will shape up to be. Ted posted details of the Swift 3 release process last week and I just updated the main swift-evolution README.md file with some updated details about the goals of Swift 3.

This release is shaping up to be a really phenomenal release that will redefine the feel of Swift and make a major leap towards maturing the Swift language and development experience. We have had a focus on getting to source stability, with the forward-looking goal of making Swift 4 as source compatible with Swift 3 as we can reasonably accomplish. It tackled API naming head on (which is one of the hardest problems in computer science [1]), made major improvements to the consistency and feel of the language, and has several nice across the board additions.

That said, it is also clear at this point that some of the loftier goals that we started out with aren’t going to fit into the release – including some of the most important generics features needed in order to lock down the ABI of the standard library. As such, the generics and ABI stability goals will roll into a future release of Swift, where I expect them to be the highest priority features to get done.

I expect discussion and planning for Swift 3.x and Swift 4 to start sometime around August of this year. Until then, it is very important that we as a community stay focused on the goals of Swift 3: I’d really prefer us all to resist the urge to discuss major blue sky features for future releases. We would also like to put a significant amount of effort into bug fixing and quality refinements as well, which means that the core team will be proactively deferring evolution proposals to later releases that don’t align with the Swift 3 goals, especially those that are strictly additive.

Thank you for all of the amazing community that has developed on this list, it is great to work with you all! Let us know if you have any questions,

-Chris

[1] It is well known that the two hard problems in Computer Science are naming, cache invalidation, and off-by-one errors.

Like my coverage of Swift news? Consider buying a book or two to help support the blog. Thanks!

Dear Xcode Santa: What I want for Playground Dubmas

Dear Santa Ken,

I’ve been very good excellently behaved somewhat good okay this year.  Here’s what I’m looking for under my playground tree. I kept the list shorter than my original because I figure I don’t want to overwhelm you with too big a list.

  • Can I please be able to sort my playground pages by creation date as well as name? While we’re at it, can I please add word tags and color tagging and be able to search and sort my pages that way too? My primary playground use these days is prototyping and exploration, so keeping things organized is primo key!
  • Please can I annotate playgrounds with stickies that I can hide and show? These can be tied to “TODO”, “MARK”, and “FIXME”, etc if they have to be, but having any sort of meta annotation for back and forth revisions would be really great.
  • May I have build phases please so I can add linters? I want my distribution playgrounds are clean and well formed and right now running them on the contents individually from the command line kind of sucks. It would be great if the warnings and errors were issued in-line so I could fix as I go.
  • I’d love to be able to embed off-site Youtube videos, not just video resources. It would save a lot of space for distribution. Also, some people have asked me about a way to defer downloads so distributions are way smaller, with a lazy “fetch from repo or other URL” scheme that doesn’t perform the download until the playground actually needs it.
  • I know a lot of people who are writing examples and tutorials in playgrounds. (A lot of them are really cool.)  They could totally use spellcheck and grammar check. It really needn’t be more complicated than what TextEdit offers (at least to start with) but even that would be a great step forward.
  • Please can I have a some kind of way to build quiz and freeform text-entry pages? Some built-in playground native way to do multiple choice and essays, with a submission button and an email destination would rock. It doesn’t have to be super secure (although that would be nice in “distribution mode”) but it would really enhance creating workbooks for friends.
  • Please let us lock our playgrounds for distribution, with a reset-button that reverts to that pristine state. This way, people can experiment and play, but you can also reset and start again fresh. Again for the tutorial crowd mostly, but doing API docs would benefit as well.
  • I would love to have some embeddable timeline controls, whether for simulating input for in-line algorithms or for sending notifications to the playground page’s live view. A button here, a slider there, pretty soon you can build some really great triggers for your live view client or embedded value pane. Sure, live views can also offer its own interactive elements but sometimes it’s all about the client code.
  • Speaking of live views, any way we can get it out of the assistant editor. I have no personal animus about the assistant — its terrific for doing code editing in multiple files — but for live views it’s kind of stinky. The geometry is never right, it always takes up space it shouldn’t. I’d must rather have a floating live view if you wouldn’t terribly mind thankyouverymuch.
  • Oh how I would love some sort of CSS system that lets me skin my playgrounds. And please support Command-+ and Command– as well for those of us with iffy vision. If we’re building beautiful Swift documents, whether for reference, for teaching, or even as log books, it would be killer to have them look tight and clean.
  • And because playgrounds are superb for prototyping, not just teaching and documentation, can I please have a way to run tests? So I can build algorithms, throw together tests, and let them run against my code without having to have that directly on the playground timeline page.

Hugs, milk, and cookies,

— Erica

p.s. I really really love that you can do history charts for non-numeric values in value panes but you might want to tweak the spacing. It kind of looks awful when your 160-by-120 point view takes up half a screen.Screen Shot 2016-05-13 at 3.40.47 PM