Archive for March, 2016

Dear Erica: A few q’s on generic types

Yesterday, was hanging out in #swift-lang, and Josh A asked how to create a generic type where 1. the same type was used for multiple members, and 2. that type was limited to UIView subclasses.

Answer:

struct MyStruct<T: UIView> {
  var view: T
  var handler: (T) -> Void
}

(I should point out that this was Josh’s architecture before I suggested he just capture the view into a handler closure. But I’m going to keep using this example because it’s a good demonstration of constraining types.)

More after the fold…

Read On…

What’s up in Swift Language Evolution

A lot of proposals have been evaluated over the last couple of weeks since the “Big 3” acceptance. Here’s a quick wrap-up of what’s been accepted and deferred, and what’s currently under review.

Newly accepted proposals:

SE-0046 Establish consistent label behavior across all parameters including first labels normalizes the first parameter declaration in methods and functions. First parameter declarations will now match the existing behavior of the second and later parameters. All parameters, regardless of position, will behave uniformly. This will create a simple, consistent approach to parameter declaration throughout the Swift programming language and bring method and function declarations in-sync with initializers, which already use this standard.

Because of this proposal, the need to “double up” first parameter names to expose them as external labels is gone. To hide the parameter label, use the same “_ ” (underscore followed by space) approach as you do with second and later parameters.

SE-0037 Clarify interaction between comments & operators fixes inconsistencies in how comments are treated when determining whether an operator is prefix, postfix, or infix. They are sometimes treated as whitespace, sometimes as non-whitespace, and this differs depending on whether they are to the left or right of an operator, and the contents of the comment itself. This proposal introduced a uniform set of rules for how these cases should be parsed.

SE-0040 Replacing Equal Signs with Colons For Attribute Arguments. (Thanks Daniel Duan for implementation) Attribute arguments are unlike other Swift language arguments. At the call site, they use = instead of colons to distinguish argument names from passed values. This proposal brings attributes into compliance with Swift standard practices by replacing the use of “=” with “:” in this one-off case.

SE-0039 Modernizing Playground Literals Playground literals tokenize colors, files, and images. They provide drag-and-drop convenience and in-context visualizations that offer easy reference and manipulation when designing playground content. These literals are built using a simple square bracket syntax that, in the current form, conflicts with collection literalsThis proposal redesigns playground literals to follow the precedent of #available and #selector.

SE-0033 Import Objective-C Constants as Swift Types Given a list of constants in an Objective-C file, add an attribute that will enable Swift to import them as either an Enum or a Struct, using RawRepresentable to convert to their original type. Instead of passing strings around for APIs, the proposal introduces type-safe objects to take advantage of Swift’s code completion. This proposal should make Swift (and Objective-C!) code more readable and more approachable to beginners.

Deferred

SE-0026 Abstract Classes and Methods is deferred until after Swift 3. Completing generics takes priority for now

Active Review

SE-0044 Import as Member review runs until 3/22. This proposal seeks to provide a mechanism for C API authors to specify the capability of importing functions and variables as members on imported Swift types. It also seeks to provide an automatic inference option for APIs that follow a consistent, disciplined naming convention.

Michael Ilseman writes,

There’s two things present in this proposal, manual annotation and automatic inference. Projects such as sqlite3 can use manual annotation, so that they can control their APIs and have a chance to import e.g. sqlite3_stmt_readonly as a member on a type (perhaps also named/defined otherwise, e.g. through existing attributes or other proposed elsewhere).

Automatic inference, at least in the near term, will not be turned on by default for all C APIs, but will start out as opt-in. In the near term, heuristics and techniques are tuned for CF-style naming conventions…Future work could expand the inference system to have many more (configurable) heuristics, but that’s out of scope for this proposal. But, unless the project opts-in, the inference system will not try to infer how to import as a member.

Upcoming Reviews

 

Afternoon Whoa: Swift’s guard case =

Bryan Luby asks: “What is your take on using the Swift 2 “guard case” syntax vs using the “~=” expression pattern?” And I was all, aren’t guard cases really for pattern matching associated values like this?

enum Test {case a(Int), b(String)}

let x = Test.a(2)
let y = Test.b("Hello")

guard case Test.a(let value) = x else {
    fatalError("shouldn't fire")
}

guard case Test.b(let value) = x else {
    fatalError("will fire")
}

But no, Bryan was talking about guard case indices = index else { return nil }, which works like this:

let foo = "abcdef".characters
let bar = "abcdefghij".characters
guard case foo.indices = foo.startIndex else {fatalError("won't fail")}
guard case foo.indices = bar.endIndex.predecessor() else {fatalError("fails")}

It’s a really weird way of testing the rhs value against the pattern on the lhs. Compare and contrast with

guard indices ~= index else { return nil }

After thinking about this for a bit:

  1. That is quite cool
  2. I don’t think I like it at all.

The readability is awful. And, I don’t think a large part of the Swift community is aware of or uses this pattern. Going by the principle of “code is more often read than written” (not to mention the “principle of least astonishment”), I’d stick with the pattern matching operator over guard case.

Agree? Disagree? Comment, tweet, or email. And thank you Bryan because I love discovering stuff like this.

Zachary Waldowski tweets: “if/guard/for/while case is the built-in way, whereas ~= is essentially an implementation detail. :/”. Maybe so but I don’t think that make the code any prettier or easier to read. He replies: “Honestly, I couldn’t tell you; I think “if case” reads better, but my coworkers say I’m nuts.”

Swift: My `attempt` code vs try? and try!

In Swift, the try? keyword converts a call that may throw an error into an optional value. It returns a successful value (.some(T)) or nil (.none). Using try? enables you to incorporate throwing code into guard statements, allowing you to break the error handler chain and leave scope, and into conditional binding for success-specific clauses.

The merits and costs of try? are numerous. It allows you to create more predictable code, especially in completion blocks and playgrounds, but discards errors which are almost always of value to the developer.

A while ago, I created a version of try? that prints. It offered a balance between the desire to retain error information and the need to use optional-based control statements.

Over time, I’ve been tweaking away at this, evolving and refining the idea to get to a point where I could reproduce the overall behavior of both try? and its fatal-error sibling try! while retaining error-handling features. I call this multi-purposed alternative attempt.

My attempt function passively picks up context where a throwing statement executes and provides a default printing error-handler. If you set crashOnError to true, the attempt acts like try! and aborts execution, but only after printing the error that caused this and the source location where the problem originated.

The newest component of attempt is a custom error handler, the one that defaults to printing.  It’s a little overkill, but I like the idea that I can customize the behavior as needed. If you just want to add clean-up and then print, you can call the default handler from the custom one.

An attempt call looks like this in standalone use, with a trailing closure:

attempt {
   let mgr = NSFileManager.defaultManager()
   try mgr.createDirectoryAtPath(
       "/Users/notarealuser",
       withIntermediateDirectories: true,
       attributes: nil)
}

But requires a more traditional argument approach when combined with guard calls that cannot distinguish the trailing closure from their required else clause.

guard let fileContents = attempt(closure: {
    _ -> [NSURL] in
    let url = NSURL(fileURLWithPath: "/Users/notarealuser")
    let mgr = NSFileManager.defaultManager()
    return try mgr.contentsOfDirectoryAtURL(
            url, includingPropertiesForKeys: nil, 
            options: [])
}) else { fatalError("failed") }

The code for attempt follows below or you can visit the wider-scoped CoreError.swift implementation on Github, which adds (updated) contextualization utilities as well. The screaming snake case constants will change soon as the modernized debug identifiers are adopted into Swift.

As always, if you find any issues or have any suggestions, please let me know.

The current art of Build Configuration Tests

Swift now supports the following configuration tests:

  • The literals `true` and `false`
  • The `os()` function that tests for `OSX, iOS, watchOS, tvOS, Linux, Windows, and FreeBSD`
  • The `arch()` function that tests for `x86_64, arm, arm64, i386, powerpc64, and powerpc64le`
  • The `swift()` function that tests for specific Swift language releases, e.g. `swift(>=2.2)`

Update additions thanks to Dmitri Gribenko, who knows the source code.

Safely invoking removeAtIndex

Michelle Elliot saw my post on safe indexing and asks: Is there a similar easy syntax for safely invoking removeAtIndex(index: Int) -> Element?

Here’s what I came up with. You need to call it with safe and it returns an optional. Improvements, issues, and suggestions are as always welcome.

public extension RangeReplaceableCollectionType where Index: Comparable {
    public subscript (safe index: Index) -> Generator.Element? {
        get {
            guard indices ~= index else { return nil }
            return self[index]
        }
        set {
            guard indices ~= index else { return }
            if let newValue = newValue {
                self.removeAtIndex(index)
                self.insert(newValue, atIndex: index)
            }
        }
    }
    
    public mutating func removeAtIndex(safe index: Self.Index) -> Self.Generator.Element? {
        guard indices ~= index else { return nil}
        return self.removeAtIndex(index)
    }
}

The push-pin principle

I’ve written before on my desire to reconstitute a weak reference in completion handlers, something along the lines of :

guard bind self else { return }

John Estropia writes,

About the weak-strong dance, it’s currently perfectly fine to do

guard let `self` = self else {return}; self.doSomething

We actually made this a rule in our team.

I feel all kinds of odd about this approach, which rests on the notion of ensuring a strong reference to self that persists through the handler’s scope. Once you pass through the guard, the self reference will be valid for that lifetime. What do you think of this work-around, which of course would be improved merely by renaming `self`?

guard let strongSelfReference = self else {return}
self.doSomething

(Mike Ash offered another solution that works in existing Swift that I encourage you to peek at. His approach registers items and invokes callbacks.)

Looking forward in terms of Swift Evolution, I’ve recommended enhancements along the lines of:

// self-shadow a weak item
guard bind self else {return}
self.doSomething

//and an equivalent for a symbol that doesn't shadow itself
guard bind symbol = someInstance.blah.weakReference else {return}
symbol.doSomething

But don’t hold your breath waiting for bind to appear in Swift. I find `bind` clearer than overloading a constant or variable declaration. It’s garnered no supporters and I’ve reluctantly been letting it go. (Although not so quickly that I didn’t first include it in this post as a last farewell.)

Others suggested integrating a guard into the initial weak capture. Unfortunately [guard self] doesn’t express how scope should exit. Should it return? Throw? Print an error? A separate guard statement is more verbose but it places explicit control in the hands of the developer on exit strategies.

Alternatively, you could introduce a weakstrong capture specifier that’s limited to -> Void closures (thanks Davide De Franceschi and Mike Ash)

[weakstrong self] in

Evan Maloney’s Allow using optional binding to upgrade `self` from a weak to strong reference proposal recommends allowing shadowing self without backticks.

[weak self] result in
guard let self = self else { return }

How would you redesign things? What do you think of the pushpin? Does Swift need to change? If so, how?