Archive for May, 2016

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

Review: BetterTouchTool

I am a shortcut-addict. Right now my drugs of choice are the superb Keyboard Maestro and Apple’s built-in Spotlight. Now that I bought my new (well, new-ish refurbished) Macbook Pro, I’ve been frustrated by my trackpad and the limited vocabulary of available useful gestures and the overwhelming vocabulary of gestures I don’t think I’ll ever actually use.

While Safari’s pinch-to-overview tabs is nifty, it’s slow and annoying. I just want to flip between tabs and I don’t want to have to reposition my hands from their “scroll au natural” baseline.

Enter BetterTouchTool ($7, with adjustable pricing). It’s basically Keyboard Maestro for trackpads and within minutes, I was set up with my new touch-then-tap to flip tabs. It was exactly what I needed and my money was soon winging its way through Paypal.

Like Keyboard Maestro, you can set the scope of the gesture to be universal or a single app. It offers a wide range of gesture customization, and you can set it up to activate menu items, take screenshots, mimic the built-in gestures with different touch styles, and more.

If you want to give it a full test ride, the developer offers a 45 day try-before-you buy. For me, it solved a problem that needed solving, it worked, and I was sold.

First parameters, Swift signatures, and conditional builds

One of the many challenges in moving code from Swift 2.2 to Swift 3 is dealing with changed method signatures. For example, say you have the following function in Swift 2.2:

func frobnicate(runcible: String) { 
    print("Frobnicate: \(runcible)") 
}

You call this with frobnicate(string) in 2.2 and frobnicate(runcible: string) in 3. The new first label rule introduced in SE-0046 means that  you have to differentiate calls based on how they consume this already existing function:

// Consuming
func frotz() {
    #if swift(>=3.0)
        // Swift 3.x code
        frobnicate(runcible:"frotz 3.x " + string)
    #else
        // Swift 2.2 code
        frobnicate("frotz 2.2 " + string)
    #endif
}

Remember that Swift’s compile-time build directives must surround entire statements and expressions. You cannot “cheat” to surround only the runcible: label. (And even if you could, it would look horrible.) The expression limitation means you’ll need to take care when introducing multi-version code.

The previous example worked by differentiating code at the call site. An alternative approach involves leaving the consumer untouched and supplying consistent API signatures based on the Swift distribution used to compile the code. That approach looks like this:

// Supplying consistent API signatures
#if swift(>=3.0)
    func fripple(_ fweep: String) {
        // Full 3.x codebase
        print("3.x fripple", fweep)
    }
#else
    func fripple(fweep: String) {
        // Full 2.2 codebase
        print("2.2 fripple", fweep)
    }
#endif

In this example, both fripple implementations can be called without first labels.

The big problem here is that you must duplicate the full codebase for both implementations, even if they are essentially or entirely the same. If you fix a bug in one implementation, you must mirror that fix in the other implementation.

Fortunately there is a way around this. It works by unifying shared code in a separate closure. By moving the code out from the functions or methods, you can treat the signatures and the implementations as separate configurations and avoid code duplication.

// Alternatively pull the code out to a closure
let sharedIzyuk: (String) -> String = {
    krebf in
    // Place full codebase here, assuming it
    // runs under both 2.2 and 3
    return "sharedIzyuk \(krebf)"
}

#if swift(>=3.0)
    func izyuk(_ krebf: String) -> String {
        return "3.x " + sharedIzyuk(krebf)
    }
#else
    func izyuk(krebf: String) -> String {
        return "2.2 " + sharedIzyuk(krebf)
    }
#endif

However ugly, this approach enables you to isolate the shared functionality from the different signatures. You’ll only need to maintain one closure — even if that closure itself contains conditional compilation for 2.2 and 3 code.

The only other practical solutions are to commit to a full Swift 3 migration, to maintain separate 2.2 and 3 repositories, or to create parallel full implementations using #if swift() build configurations with duplicated code.

Swift 3.0 PR 1 has been cut

Nichole Jacque writes on the swift-dev email list:

Hello everyone. We have cut the swift-3.0-preview-1-branch. Any changes to that branch need to go through pull requests, and be approved by the release manager.

For more details on the Swift 3.0 Release Process, please check out the blog post: https://swift.org/blog/swift-3-0-release-process/

Marc points out in the comments that “The first developer preview branch swift-3.0-preview-1-branch will be created from master on May 12. It will be released 4-6 weeks later.”

What does Debug mean to you?

Assuming my current proposal about using “can import” for build configuration tests is accepted, I’d like to tackle the outstanding question of #if debug next. This is slightly problematic because as I learned, “debug” can mean many things to different people.

For example, David Owens II writes,

I have a set of test automation that I want to ensure works. However, running this automation with a blocking assert is not what I want. Instead, I’ve created a mechanism for asserts, configurable at runtime, for the way in which those asserts are handled. During automation, I want those asserts to simply log, but code execution is not halted. During my normal dev cycle though, I want those asserts to be raised immediately so the developer sees the error and can chose to investigate or ignore the assert.

I suspect that despite this, that there is a value to supporting a general #if debug configuration test that doesn’t require you to explicitly set command line flags with -D <#flag#> and then test for the named flag. I’m hoping that a general utility that’s true for unoptimized builds where asserts can fire is useful enough for a sufficiently large group When I first brought up this topic, I put it this way:

Figuring out what debug *means* is an important first step. To “my people”, it’s the Xcode Build Configuration > Debug scheme setting. For language purposes, the only definition I can come up with at the moment is that debug is what happens when asserts can fire and are not disabled by compile-time optimizations.

Is that a sufficiently convenient definition for a wide enough variety of use cases that it’s worth proposing and putting the effort in to make sure this is included into the language? I need a community consensus before I commit the evolution list to another protracted discussion let alone a formal review. Your feedback will certainly help.

Worth it?

Swift Taxonomy: Acceptances and Rejections

SE-0060: Enforcing order of defaulted parameters IS ACCEPTED. I voted no. Team writes,

The feedback on the proposal was generally positive (several people remarked that they didn’t know this was allowed).  Some people pointed out that removal of this capability penalizes API design in cases where there is no inherent order to parameters, but this is also true of non-defaulted parameters.  The core team prefers to encourage consistency at call sites.

SE-0073: Marking closures as executing exactly once IS REJECTED “This proposal introduces an optional once argument to the @noescape attribute. The @noescape(once) attribute enforces that the closure does not escape, and that it is run exactly once on any code path returning from the function. For clients, it allows the compiler to relax initialization requirements and close the gap between closure and “inline code” a little bit.” Team writes,

The feedback on the proposal was generally positive both from the community and core team.  That said, it is being rejected for Swift 3 two reasons:

1) The surface level syntax of @noescape needs to be reconsidered.  At the minimum, we need to rename @noescape to @nonescaping for consistency with our previously agreed attribute naming scheme.  However, it is also work discussing whether @nonescaping should be the default: if so, the attribute should actually become @escaping, and the functionality proposed in SE-0073 would be named @once.

2) Separate from the surface level issues, the implementation underlying this work has some significant challenges that are doable but would require major engineering work.  Specifically, the definite initialization pass needs to “codegen” booleans in some cases for conditional initialization/overwrite cases, and these state values would have to be added to closure capture lists.  This would require enough engineering work that it seems unlikely that it would happen in the Swift 3 timeframe, and beyond that this could theoretically be subsumed into a more general system that allowed control-flow-like functions to have closures that break/continue/throw/return out of their enclosing function, or a general macro system.

Overall, everyone desires the ability to produce more control-flow like functions, but Swift 3 isn’t in a place where it can make sense to tackle this work.

SE-0074: Implementation of Binary Search functions IS REJECTED. “Swift does not offer any way to efficiently search sorted collections. This proposal seeks to add a few different functions that implement the binary search algorithm.” Team writes,

The feedback on the proposal was generally positive about the concept of adding binary search functionality, but  negative about the proposal as written, with feedback that it was adding too much complexity to the API.

SE-0076: Add overrides taking an UnsafePointer source to non-destructive copying methods on UnsafeMutablePointer IS ACCEPTED WITH REVISION “UnsafeMutablePointer includes several methods to non-destructively copy elements from memory pointed to by another UnsafeMutablePointer instance. I propose adding overloads of these methods to UnsafeMutablePointer that allow an UnsafePointer source.” Team writes,

The feedback on the proposal from the community and the core team universally agreed that there is a problem that needs to be solved here.  However, instead of adding overloads of the methods as proposed, it would be better to change the existing methods to take UnsafePointer<> instead of UnsafeMutablePointer<>.  Given the existing promotion rules that exist in the compiler, it will achieve the same effect.  As part of this, other similar functions in the standard library should be audited and fixed as well.

SE-0080: Failable Numeric Conversion Initializers IS ACCEPTED WITH REVISIONS. “Swift numeric types all currently have a family of conversion initializers. In many use cases they leave a lot to be desired. Initializing an integer type with a floating point value will truncate any fractional portion of the number. Initializing with an out-of-range value traps. This proposal is to add a new family of conversion initializers to all numeric types that either complete successfully without loss of information or throw an error.” Team writes,

The feedback on the proposal from the community and the core team was universally positive, and the new initializers on the primitive integer and floating point types have been approved.  However, swift-evolution isn’t the right mechanism to propose extensions to Foundation types, so the extensions that adds conversions from NSNumber and to Foundation types should be subset out of the proposal.

SE-0078: Implement a rotate algorithm, equivalent to std::rotate() in C++ AWAITS DECISION. “There are three different versions of the rotate algorithm, optimized for collections with forward, bidirectional, and random access indices. The complexity of the implementation of these algorithms makes the generic rotate algorithm a perfect candidate for the standard library.”

In Review

Awaiting Scheduling

Guarding against an empty sequence

On Swift-Users yesterday, someone asked how to guard against an empty sequence. The context of the question was how to test a sequence against a predicate and the problem was that an empty sequence returned true for satisfying the predicate.

Now, leaving aside the entire question of the base behavior (which I believe is correct since no element in an empty sequence fails to satisfy the predicate), I thought Jeremy Pereira came up with an especially cute solution:

func all(@noescape where predicate: Generator.Element throws -> Bool) rethrows -> Bool {
	var count = 0
       for element in self {
	    guard try predicate(element) else { return false }
	    count += 1
       }
       return count > 0
}

One of the big questions though that grew out of the discussion was “how do you non-destructively test a sequence for being empty?”  My answer to this was to use a buffer with look-ahead. Here’s my first shot at this, completely a rough draft and open for any improvement suggestions you might offer.

public struct BufferedSequence<Base : SequenceType>:GeneratorType, SequenceType {
    
    internal var _base: Base
    internal var _generator: Base.Generator
    public var bufferedElement: Base.Generator.Element?
    
    public init(_ base: Base) {
        _base = base
        _generator = base.generate()
        bufferedElement = _generator.next()
    }

    public mutating func next() -> Base.Generator.Element? {
        defer {
            if bufferedElement != nil {
                bufferedElement = _generator.next()
            }
        }
        return bufferedElement
    }
    
    public func isEmpty() -> Bool {
        return bufferedElement == nil
    }
}

Interestingly enough, the most difficult thing in throwing this little thing together was not trying to think about look-ahead but to translate  Swift 3 idioms back to Swift 2.2 so I could mess with this in a playground.

How is the transition going for you? Are you all 3’ed up yet? Or are you still holding firm in 2.2 land and writing production code?