Archive for the ‘Swift’ Category

Pronouncing “Tuple”

A tuple is a finite ordered list of elements. It is presented as a parentheses-braced, comma-delimited list. In Swift, you can use them as stand-alone heterogenous lists of values or pass them as arguments to functions and closures.

A tuple is pronounced “tupple” (TUH-ple), not “two-pull”. It’s a shortcut pulled from “double, triple, quintuple, sextuple, octuple”, etc. Yes, please note that “quadruple” doesn’t fit with the others and is not used as a basis for speaking the word. Rules about long and short “u”s that apply to other English words are also not relevant to this case.

In Swift, a tuple is analogous to an anonymous struct. Its members are indexed numerically (.0, .1.2, etc). You can also use labels to access members by name:

let point = (x: 5.0, y: 2.3)
print(point.1) // 2.3
print(point.y) // 2.3

Swift 3.0 and later no longer supports splatting, so you cannot decouple a tuple from a function call. You can read more about this in SE-0029, which disallowed the ability. Before the change, you could call a function either with its direct arguments or by passing a tuple:

func foo(a : Int, b : Int) {}
foo(a: 42, b : 17) // still allowed
let x = (a: 1, b: 2)
foo(x) // no longer allowed in Swift 3+

The continued work on SE-0110 is still resolving on how tuples and closures interact.

The word “arity” describes the number of members in a tuple. (It also describes the number of arguments or operands accepted by a function, method, or closure.) The examples above use an arity of 2. You can call this a “2-arity tuple” or the shortcut “2-ary tuple”. Some shorten that further to a “2-tuple”.  All are acceptable.

Some fun facts to finish with:

  • A figurative tuple with an arbitrary arity is an “n-arity” or “n-ary” or “n-tuple”.
  • A tuple with a variable number of arguments is variadic.

Working with optional errors in completion handlers

Foundation likes to pass optional errors (versus, say, a unified Result type) to completion handlers. A typical closure uses a (Value?, Error?) -> Void signature,where Value is some sort of data result that varies by operation.

A colleague was struggling to use conditional binding along with casting in his handler. Leaving aside for the moment any rational need to cast to NSError, this is an interesting demonstration of how you perform these two operations synchronously in code.

A cast from Error to NSError is guaranteed to succeed, so you can use the as operator. However, you must phrase the cast just right. Otherwise the Swift compiler emits warnings, as you see in the following screenshot. Here is an example of how you don’t get this job done properly:

As my friend complained in frustration: “But it tells me “did I mean as” and when I switch `as?` to `as` then it complains that error is Error? and isn’t convertible to NSError.

This attempt followed the normal pattern of conditional casting. Swift automatically lifts double optionals into a single optional result when used this way, but the cast from Error to NSError will always succeed, so you can’t use as? here.

To resolve, use a non-conditional cast to NSError? and then perform conditional binding to unwrap the value:

enum Bad: Error { case luck }

let error: Bad? = Bad.luck

if let error = (error as NSError?) {
    print("Worked")
}

The parens around the non-conditional cast make all the difference. Swift removes its warnings and makes everything work as expected.

More on SE-0110: Important fallout, please read (Updated)


Update: Statement from Austin

…I’d like to appreciate my heartfelt thanks to everyone who reached out to me one way or another. It’s clear to me that the Swift, Apple platform developers, and swift-evolution communities are amazing, and that the people in them are kind, wonderful, generous, passionate, and caring. The Core Team in particular has done an incredible job shepherding the community, befriending people on and off the lists, and leading an open-source project of great technical and social complexity.

After thinking about things, I plan to continue participating in swift-evolution and looking for new ways in which I can serve the Swift and Apple developer communities. I hope to listen more, speak less, be more sensitive to other peoples’ feelings, and offer fair, well-considered feedback.


Often the Swift core team will ask for community help to develop and sponsor a proposal. I’ve worked on several of these. These proposals are generally aimed towards simplifying the compiler, enhancing the language, or addressing technical issues that place stumbling blocks in the effective delivery of compilation.

The reconsideration of SE-0110 should not reflect in any negative way on Austin Zheng. He worked hard on a proposal whose intent was to serve the large Swift developer community. I congratulate Austin for shepherding through this proposal, which can be a long, frustrating process.

The usability regression was unexpected. I applaud the core team for its flexibility in responding to the community’s real concerns when its implementation showed issues.

Today, Austin tweeted:

If my posting of the SE-0110 notice last night contributed to a negative atmosphere, I apologize. I have written to Austin and I hope he will reconsider his decision and rejoin Swift Evolution.

On the SE-0110 Regression (full text)

Doug Gregor writes:

Hello Swift community,

Swift 3’s SE-0110 eliminated the equivalence between function types that accept a single type and function types that take multiple arguments. However, for various implementation reasons, the implementation of SE-0110 (as well as the elimination of tuple “splat” behavior in SE-0029) was not fully completed.

 

Swift 4 implemented more of SE-0110, which caused a fairly serious usability regression, particularly with closures. Here are a few simple examples involving closures that worked in Swift 3 but do not work in Swift 4:
// #1: Works in Swift 3, error in Swift 4
myDictionary.forEach {
  print(“\($0) -> \($1)”)
}
 
// #2: Works in Swift 3, error in Swift 4
myDictionary.forEach { key, value in
  print(“\(key) -> \(value)”)
}
 
// #3: Works in Swift 3, error in Swift 4
myDictionary.forEach { (key, value) in
  print(“\(key) -> \(value)”)
}
Similar issues occur with passing multi-argument functions where a tuple argument is expected:
// #4: Works in Swift 3, error in Swift 4
_ = zip(array1, array2).map(+)
In all of these cases, it is possible to write a closure that achieves the desired effect, but the result is more verbose and less intuitive:
// Works in both Swift 3 and Swift 4
myDictionary.forEach { element in
  let (key, value) = element
  print(“\(key) -> \(value)”)
}

 

The Swift core team feels that these usability regressions are unacceptable for Swift 4. There are a number of promising solutions that would provide a better model for closures and address the usability regression, but fully designing and implementing those are out of scope for Swift 4.  Therefore, we will “back out” the SE-0110 change regarding function arguments from Swift 4.

 

Specifically, when passing an argument value of function type (including closures) to a parameter of function type, a multi-parameter argument function can be passed to a parameter whose function type accepts a single tuple (whose tuple elements match the parameter types of the argument function). Practically speaking, all of the examples #1-#4 will be accepted in both Swift 3 and Swift 4.

 

We will revisit the design in this area post-Swift 4.

 

– Doug

 

The startling uniquing of Swift 4 dictionaries

As you’ve probably heard, Swift 4 now has multiline strings. Rejoice! And thank John Holdsworth. For now you can do stuff like this:

let xml = """
    <?xml version="1.0"?>
    <catalog>
    <book id="bk101" empty="">
        <author>\\(author)</author>
        <title>XML Developer's Guide</title>
        <genre>Computer</genre>
        <price>44.95</price>
        <publish_date>2000-10-01</publish_date>
        <description>An in-depth look at creating applications with XML.</description>
    </book>
    </catalog>
"""

It’s super handy, allowing you to incorporate newline and individual " characters without having to escape them. (You do have to escape the backslash, as in the preceding example).

One of the things you might want to do with a big hefty string is to count the number of words, and maybe find out which word occurs the most. So here’s another multi-line string, one pulled from a lorem ipsum generator:

let lipsum = """
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vitae hendrerit orci. Suspendisse porta ante sed commodo tincidunt.

    Etiam vitae nunc est. Vestibulum et molestie tortor. Ut nec cursus ipsum, id euismod diam. Sed quis imperdiet neque.

    Mauris sit amet sem mattis, egestas ligula ac, fringilla ligula. Nam nec eros posuere, rhoncus neque ut, varius massa.
    """

This particular example occupies 5 lines and includes a lot of text and punctuation. Because you can now treat Strings as collections, you can do stuff like this:

let w = "Hello".filter({ $0 != "l" }) // "Heo"

Similarly, you can use character set membership to select only letters and spaces:

let desiredCharacters = CharacterSet.letters
    .union(CharacterSet(charactersIn: " "))
let workString = lipsum.filter({ character in
    let uniScalars = character.unicodeScalars
    return desiredCharacters
        .contains(uniScalars[uniScalars.startIndex])
})

Unfortunately, Character and CharacterSet are still struggling a bit to get along with each other, which is why I’m doing that nonsense with the unicodeScalars.  Anyway, this gives you a single line string with just letters and spaces, so you can then break the string into words.

// Split along spaces
let words = workString.split(separator: " ")

Dictionary now has a feature that allows you to recognize you’re overwriting an existing key and apply a function to a key’s value each time the key is added. It’s called uniquing, and it lets you do neat things like count the number of times a token appears in a sequence:

// Add to dictionary, with "uniquing"
let baseCounts = zip(words.map(String.init), repeatElement(1, count: .max))
let wordCounts = Dictionary(baseCounts, uniquingKeysWith: +)

This code creates an infinite sequence of the number 1, and applies addition each time a duplicate key is found. You get exactly the same results by applying + 1 closure, although this is uglier and a little wasteful:

let wordCounts = Dictionary(baseCounts, 
    uniquingKeysWith: { (old, _) in old + 1 })

You can then find the word that appears the most

// Find the word that appears most often
var (maxword, maxcount) = ("UNDEFINED", Int.min)
for (word, count) in wordCounts {
    if count > maxcount { (maxword, maxcount) = (word, count) }
}
print("\(maxword) appears \(maxcount) times")
// et appears 8 times (at least it did 
// in my much longer text)

You can use uniqueKeysWithValues to fill up a dictionary by zipping two sequences:

let letterOrders = Dictionary(uniqueKeysWithValues: zip("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1...))
print(letterOrders)
// ["H": 8, "X": 24, "D": 4, "J": 10, "I": 9, "M": 13, "Z": 26,
//  "S": 19, "A": 1, "C": 3, "N": 14, "Y": 25, "R": 18, "G": 7, 
//  "E": 5, "V": 22, "U": 21, "L": 12, "B": 2, "K": 11, "F": 6, 
//  "O": 15, "W": 23, "T": 20, "P": 16, "Q": 17]

Another thing you might do with updated dictionaries is to build a set or array out of sequence values. This next example collects values for each key:

let invitedFriends: [(String, String)] = [
    ("Rizwan", "John"), ("Rizwan", "Abe"),
    ("Soroush", "Dave"), ("Joe", "Dave"), 
    ("Soroush", "Zev"), ("Soroush", "Erica")]
let invitationLists = Dictionary(
    invitedFriends.map({ ($0.0, [$0.1]) }),
    uniquingKeysWith: { (old: [String], new: [String]) in
        return old + new }
)
print(invitationLists)
// ["Rizwan": ["John", "Abe"], "Soroush": ["Dave", "Zev", "Erica"], "Joe": ["Dave"]]

You can store a tuple of the maximum and minimum values found for each unique key. The value structure has to be established in the initial streams, which can be ugly:

// Create 100 random numbers
let hundredRandom: [(Int, Int)] = (1...100).map({ _ in let value = Int(arc4random_uniform(10000)); return (value, value) })

// Create ten sequences of 1 through 10
let tens = sequence(state: 1, next: { (value: inout Int) -> Int in
    value += 1; return (value % 10) + 1
})

// Build the two together
let values = zip(tens, hundredRandom)
let extremes = Dictionary(values, uniquingKeysWith: { (old: (Int, Int), new: (Int, Int)) in
    return (min(old.0, new.0), max(old.1, new.1))
})
print(extremes)
// [10: (504, 8342), 2: (770, 8874), 4: (164, 7871), 9: (177, 8903), 
//  5: (1707, 9627), 6: (577, 8318), 7: (174, 8818), 3: (2837, 9198),
//  8: (3573, 9432), 1: (474, 8652)]

I probably could have made this a little more elegant but I was running out of time because I had to pick up my kids. If you have improvements for the last few examples, let me know. Sorry about the rush.

p.s. Thanks for the tip about using unicodeScalars on char.

Holy War: Mutable copies

Applying mutableCopy() to an NSObject returns Any, not the version of the type you’re attempting to make mutable, for example, NSMutableArray, NSMutableParagraphStyle, NSMutableAttributedString or whatever.

Nate asks:

Is is acceptable to use as! with mutableCopy() or is there a better way to do this?

// Approach 1: Forced unwrap
let mutableStyle1 = style.mutableCopy() as! NSMutableParagraphStyle

The forced as! cast used in this approach will always succeed (even if using as! makes you want to wash your hands afterwards). But there are other approaches to consider. What do you think of these alternative takes on the question? Here are some other solutions for you to weigh in on.

// Approach 2: Forced unwrap with explanation on failure

/// Very low precedence group
precedencegroup VeryLowPrecedence { lowerThan: FunctionArrowPrecedence }

infix operator !!: VeryLowPrecedence

/// Guaranteed safe unwrap or fatal error with custom error string
public func !! <Wrapped>(value: Wrapped?, complaint: String) -> Wrapped {
    guard let value = value
        else { fatalError(complaint) }
    return value
}

let mutableStyle2 = style.mutableCopy() as? NSMutableParagraphStyle !! "Guaranteed cast to mutable paragraph style failed"

// Approach 3: Guard with explanatory fatal error
guard let mutableStyle3 = style.mutableCopy() as? NSMutableParagraphStyle
    else { fatalError("Guaranteed cast to mutable paragraph style failed") }

// Approach 4: Create then set with current attributes
let mutableStyle4 = NSMutableParagraphStyle()
mutableStyle4.setParagraphStyle(style)

// Approach 5: Protocol to expose typed mutable version
public protocol AvailableMutatingVersion: NSObjectProtocol {
    associatedtype MutableForm
    func mutableCopy() -> Any
    var mutableVersion : MutableForm { get }
}

extension AvailableMutatingVersion {
    public var mutableVersion: MutableForm {
        guard let copy = self.mutableCopy() as? MutableForm
            else { fatalError("Guaranteed mutable copy could not be constructed") }
        return copy
    }
}

extension NSParagraphStyle: AvailableMutatingVersion {
    public typealias MutableForm = NSMutableParagraphStyle
}

let mutableStyle5 = style.mutableVersion

Which approach reigns supreme? Vote now or offer some alternatives…

The surprising awesomeness of Grouped Dictionaries

Yesterday, I was chatting about ways to partition a stream of values. I wanted to collect values into new streams: values that satisfied a predicate, and those that did not. A number of hugely complicated approaches were discussed until Nate Cook brought up a fantastic new Swift 4.0 API. The Dictionary type’s init(grouping:by:) call allows you to convert any sequence to a dictionary by grouping its elements.

Pass the initializer a sequence and a closure, and the initializer creates entries for each value returned by the closure. For a predicate, you end up with two groups: one populated for true predicate values, one for false:

let numbers = 1 ... 20
let predicate: (Int) -> Bool = {  $0 % 2 == 0 }
let grouping = Dictionary(grouping: numbers, by: predicate)
print(grouping)
// [false: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19], 
//  true: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]]

Once partitioned, you can pull values from each collection (true and false) and operate on the members of that particular group:

// Iterate through the even members of this sequence
for number in (grouping[true, default:[]]) { ... }

This example uses Swift’s new default value in its grouping look-up:

grouping[true, default:[]]

If you haven’t started using this new feature, you should really adopt it into your work flow. It’s wonderful. With this call, a dictionary returns the default value when a key is not found. This avoids forced unwraps (dictionary lookups normally return optionals) and acts as an alias for nil coalescing. In this example, the default call is an alias for (grouping[true] ?? []).

Dictionary grouping provides a solid solution for sequence partitioning by predicates. But you can also do a lot more with this API. Let me give you a bunch of examples that showcase the power of this one little call.

This example creates a dictionary of names grouped by first letter. Swift creates an entry for each unique capitalized letter it finds within the name collection:

let names = ["bob", "Amelia", "joe", "alice", "jane"].map({ $0.capitalized })
let nameDict = Dictionary(grouping: names.filter({ !$0.isEmpty })) {
    $0.prefix(1)
}
print(nameDict)
// ["J": ["Joe", "Jane"], "B": ["Bob"], "A": ["Amelia", "Alice"]]

You could easily expand this example to disregard diacritical marks by stripping them through a StringTransform. (This approach is left as an exercise for the reader. 😀 )

In more realistic text-based grouping, the information you want to group on is often a level or two down within a structure. Swift keypaths make it easy to access the information you need for grouping. This next example constructs a keypath to a contact’s last name, and uses that keypath to provide the partition keys for the dictionary.

/// A person
struct Person {
    let firstName: String
    let lastName: String
}

/// A contact entry
struct Contact: CustomStringConvertible {
    let name: Person
    let address: String
    var description: String { return "\(name.firstName) \(name.lastName) at \(address)" }
}

/// Construct some contacts
let lasts = ["smith", "jones", "simpson", "cheese", "putty"]
let contacts: [Contact] = zip(names, lasts)
    .map({ Person(firstName: $0.0.capitalized, lastName: $0.1.capitalized) })
    .map({ Contact(name: $0, address: "1 Main St" )})

// Establish keypath to the last name field
let lastNameKeypath = \Contact.name.lastName

// Construct the address book based on the first letter
// of the contact's last name, then print the
// address book
let addressBook = Dictionary(grouping: contacts) { 
    $0[keyPath: lastNameKeypath].prefix(1).uppercased() 
}
for (key, value) in addressBook { 
    print(key, value) 
}

// J [Amelia Jones at 1 Main St]
// C [Alice Cheese at 1 Main St]
// P [Jane Putty at 1 Main St]
// S [Bob Smith at 1 Main St, Joe Simpson at 1 Main St]

Grouped dictionaries aren’t limited to strings and numbers. They can be quite helpful when working with interface elements. For example, in a complex user-managed  presentation, you might group button views based on their control state:

// buttonArray is [NSButton]
let buttons = Dictionary(grouping: buttonArray, by: { $0.state })

Although all the examples so far have used sequence data to produce the keys used in grouping, those keys needn’t be pulled directly from the values they categorize. Enumerations make a great Swift choice for categorizing data. This example revisits the even/odd grouping shown in the first example of this write-up but replaces the true/false predicate values with a Parity enumeration.

enum Parity {
    case even, odd
    init(_ value: Int) {
        self = value % 2 == 0 ? .even : .odd
    }
}
let parity = Dictionary(grouping: 0 ..< 10 , by: Parity.init )

You can use this same approach with more extensive enumerations and more complicated data. That said, you can take exactly this example, and simplify it enormously by grouping numbers based on a simple function. For example, you can use the direct results of the modulo operator (which returns 1 and 0)  as the keys to your grouped dictionary:

let parity2 = Dictionary(grouping: 0 ..< 10) { $0 % 2 }

In the end, it’s up to you on how you want to split your sequence, and the keys you want to represent the subsequences derived from that split. Hopefully this post has given you a few ideas to inspire your own partitioning schemes.

If you like my write-ups, please consider buying a book. Thanks to everyone who contributed to the discussion about partitioning sequences, especially Nate Cook, Tim Vermeulen, Kabir Oberai, Daniel Jalkut, Tom Harrington, Soroush Khanlou, Paul Cantrell, and Zachary Drayer.

Working with text output streams

Here’s another great write-up from Tim V. 

By far the most common way to add a custom textual representation to a type is by implementing CustomStringConvertible. Consider this type:

struct Person {
    let name: String
    let age: Int
    let spouse: String?
    let children: [String]
}

A pretty standard way to conform to CustomStringConvertible would be this:

extension Person: CustomStringConvertible {
    var description: String {
        var description = ""
        
        description += "Name: \(name)\n"
        description += "Age: \(age)\n"
        
        if let spouse = spouse {
            description += "Spouse: \(spouse)\n"
        }
        
        if !children.isEmpty {
            description += "Children: \(children.joined(separator: ", "))\n"
        }
        
        return description
    }
}

This code doesn’t look too bad, but it’s a pain to write var description = "" and return description over and over, if this is a pattern you commonly use. It’s also quite easy to forget to add \n to each line.

The relatively unknown standard library protocol TextOutputStreamable solves both of these problems for you. Rather than adding a description computed property, all you have to do is write your properties to a TextOutputStream instance:

extension Person: TextOutputStreamable {
    func write<Target: TextOutputStream>(to target: inout Target) {
        print("Name:", name, to: &target)
        print("Age:", age, to: &target)
        
        if let spouse = spouse {
            print("Spouse:", spouse, to: &target)
        }
        
        if !children.isEmpty {
            print("Children:", children.joined(separator: ", "), to: &target)
        }
    }
}

That’s it! Whenever something that conforms to TextOutputStreamable but not to CustomStringConvertible is turned into a string, the write(to:) method we just implemented is used:

let person = Person(name: "Michael", age: 45, spouse: "Emma", children: ["Charlotte", "Jacob"])
print(person)

>Name: Michael
>Age: 45
>Spouse: Emma
>Children: Charlotte, Jacob

If you enjoyed this write-up, you might be interested in an old post I wrote about using streams to transform data.

Initializing Typed Arrays

Foundation’s URLQueryItem is just a stringly-typed key-value pair. You create one with a name and value:

public init(name: String, value: String?)

Since Swift supports literal initialization, you’d think you could use a dictionary to set up a [URLQueryItem] array, right? Well, yes and no.

You can’t just conform Array where Element == URLQueryItem to ExpressibleByDictionaryLiteral. Array extensions with constraints cannot have inheritance clauses. There are several ways around this limitation.

First (and best), you can just map an initializer across a dictionary literal:

let result = ["key1": "value1", "key2": "value2", "key3": "value3"]
    .map({ URLQueryItem(name: $0.key, value: $0.value) })

Second, you could make URLQueryItem itself dictionary initializable, but that starts to get ugly:

extension URLQueryItem: ExpressibleByDictionaryLiteral {
    public typealias Key = String
    public typealias Value = String
    public init(dictionaryLiteral elements: (String, String)...) {
        guard elements.count == 1
            else { fatalError("URLQueryItem requires single key-value pair") }
        self.init(name: elements.last!.0, value: elements.last!.1)
    }
}

let uq: URLQueryItem = ["key": "value"] // okay
let uqs: [URLQueryItem] = [["key1": "value1"], ["key2": "value2"], ["key3": "value3"]] // bleh

Third, you could use some kind of intermediate type to produce a URL query item array using Swift shortcuts. For example, you can set up a struct that builds the query item array and then pull from there:

struct URLQueryItems: ExpressibleByDictionaryLiteral {
    public typealias Key = String
    public typealias Value = String
    let items: [URLQueryItem]
    public init(dictionaryLiteral elements: (String, String)...) {
        items = elements.map({ URLQueryItem(name: $0.0, value: $0.1) })
    }
}

let uqis: URLQueryItems = ["key1": "value1", "key2": "value2", "key3": "value3"]
uqis.items

But again, it’s really not an improvement on using a mapped dictionary.

In the best of all worlds, which doesn’t exist, you’d be able to do something like this, but I don’t think there’s a way to accomplish this in modern Swift. Solution 2 is about as close as you get.

myRequest.queryItems = ["key1": "value1", "key2": "value2", "key3": "value3"]

Is there something I’m overlooking? If so, let me know. Drop a comment, mail, or tweet. Thanks.

Update:

and