Archive for June, 2016

Dear Erica: What’s the biggest and best Swift 3 change?

Dear Erica: “What do you think is going to be the biggest/best Swift 3 change for people who haven’t been following the process? I’m feeling a little underwhelmed, to be honest.  Compared to the Swift 1 -> 2 changes (aka protocol extensions) it feels like there are big changes, but not ones that change how you approach designing a program…

I’m not entirely sure that “no new paradigm shifts” are a bad thing. As a language, Swift pretty much knows what it is. It hasn’t quite reached fully cooked (incomplete generics in Swift 3 are a really good indicator that the language still needs more time in the oven) but it’s settled on what kind of language it is. There’s a clear Swift philosophy that’s driving the effort.

Swiftory

Swiftory goes something like this:

Swift 1 set the baseline: type safe, fast, modern. It showed what Swift could be. We got optionals, smart value types, and a lot of great features that started the hard sell. It’s where a lot of Objective C programmers sat up and said “Oh, look at that. There’s something there worth investigating.”

Swift 2 revolutionized itself with protocol oriented programming and lots of cool new feature like reengineered error handling. It showed what Swift should be. Suddenly, Swift wasn’t just making sense, it was creating new paradigms for the Apple community and, after open sourcing, making inroads towards new platforms.

Swift 3 is the”clean house”, “break everything” release. Think of this as necessary language trauma to ensure the language fundamentals are sound and consistent going forward release. It might not be the funnest release (when put on the spot, the best I could come up with for pure “joy” features was Lily Ballard’s sequence/take/drop functions) but it’s one that’s creating a massively cleaner language.

Swift 4 should hopefully be full of additive glory. We should see completed generics, concurrency, and more: features that are fun, provocative, and powerful. Swift 4 gets to be inspired by other languages and will incorporate several years of public use and feedback. Swift 4 should be the release that “doesn’t break nearly as much stuff”, which if you think about it, isn’t exactly how public relations should try to sell it. (It’s also probably where the Swift Package Manager should hit its “Swift 2” glory phase.)

Denial, Anger, Bargaining, and Acceptance

There’s plenty in Swift 2 -> 3 that’s going to freak people out. We’re seeing the death of beloved vestigial constructs. Swift’s renaming everything in what are frankly weird ways (“sorting”, “unioning”, etc — and no, I cannot guarantee that the API directives weren’t settled on without the use of hallucinogenics when you compare these to “sortInPlace” and “unionInPlace”). There’s prefix stripping on familiar names and defaulting arguments changing the way signatures look, and so forth.

A lot of this feels like a language enema. It’s not really a transition you seek out for fun but it can get your development moving properly again afterwards. (“Swift 3: The healthy fiber update!”)

Sure, it’s hard to get super excited about language changes like “move inout keyword to decorate type instead of label” but these are necessary housekeeping if the language is going to keep its promise of excellence and deliver on the next phase of its roadmap.

If there’s anything missing in my summary about the roadmap to Swift 3, it’s this: Swift is a really great language to work in. And Swift 3 is a better language to work in than Swift 2 was.

I may laugh at some naming choices and worry about unfamiliar Cocoa calls but all in all, Swift is the language I’d like to be writing code in for the next few years. And I think after Swift 3 drops, a large part of the Apple community (and beyond!) will agree.

You’ll find a list of adopted and implemented Swift 3 proposals in the main Github repo README. They may look a little boring but they’re going to shake things up. In a high-fiber vitamin laden smoothie kind of way.

Swift Doc Markup generator

Screen Shot 2016-06-08 at 1.11.33 PM

Ankit Agarwal’s new SwiftMarkupGen is an open source package that offers a quick way to generate a Swift 3 markup template from the command line. Meant strictly for use with the Swift 3.0 toolchain, just download, make, and install in  your favorite bin folder.

Unlike VVDocumenter, another great tool, SwiftMarkupGen isn’t  pushy in Xcode. As a standalone command-line utility, it doesn’t catch you by surprise in Xcode when you’re intending to edit comment markup by hand, which is why I eventually disabled VVDocumenter and haven’t updated it.

SwiftMarkupGen is brand new, and I’m sure it can easily be adapted to produce, for example, //* */ delineated markup as well as the more Apple-y /// variation with a simple command line option and a pull request.

Both are great tools and well worth checking out.

Swift: The joy of sequences

I am really happy with how SE-0094 turned out. I helped with the paperwork but it was all Lily Ballard‘s brain child, putting together the two new sequence functions. If you haven’t been playing with these yet, they’re available in the latest developer snapshots (both the main trunk and the public branch) and they’re delightful.

There are two variations:

public func sequence<T>(first: T, next: (T) -> T?) -> 
    UnfoldSequence<T, (T?, Bool)>

public func sequence<T, State>(state: State, next: (inout State) -> T?) -> 
    UnfoldSequence<T, State>

The first one just takes a value, and then keeps applying a function to it, the second allows you to store associated state, meaning you can build functions like this:

extension Sequence {
    // Not to spec: missing throwing, noescape
    public func prefix(
        while predicate: (Self.Iterator.Element) -> Bool) -> 
            UnfoldSequence<Self.Iterator.Element, Self.Iterator> {
        return sequence(state: makeIterator(), next: {
            (myState: inout Iterator) -> Iterator.Element? in
            guard let next = myState.next() else { return nil }
            return predicate(next) ? next : nil
        })
    }
}

The preceding example showcases a very rough preview of the prefix(while:) function that will appear when SE-0045 gets implemented. In this version, I used  sequence to generate a series of elements while a predicate returns true. And yes, a few items are still less than ideal: you have to use a full type signature when using inout parameters in a closure, so things get a little wordy.

If you were using the old AnySequence/AnyGenerator (or Sequence/AnyIterator) approach, you’d create the iterator separately. Something along these lines:

public func prefix(while predicate: (Self.Iterator.Element) -> Bool) -> AnySequence<Self.Iterator.Element> {
    var iterator = self.makeIterator()
    return AnySequence {
        return AnyIterator {
            guard let next = iterator.next() else { return nil }
            return predicate(next) ? next : nil
        }
    }
}

Incorporating the state into the sequence generator simplifies nearly any stream of data that’s more complex than a mathematical progression:

sequence(first: 1, next: { $0 + 2 })

You can imagine any kind of function being used here, whether additive, multiplicative, etc. Pairing prefix with sequence lets a few tiny fireworks get started:

Count to 10:

for i in sequence(first: 1, next: { $0 + 1 })
    .prefix(while: { return $0 <= 10 }) {
    print(i)
}

Powers of 3 to 59049:

for i in sequence(state: 0, next: { 
    (idx: inout Int) -> Int in
    defer { idx += 1 }; return Int(pow(3.0, Double(idx)))})
    .prefix(while: {return $0 <= 59049})
{
    print(i)
}

Speaking of wordiness, Swift still doesn’t support x^n exponentiation, and when chaining in this way, you can’t use trailing closure syntax due to compiler confusion.

Any further exercise in state-based sequences is left as an exercise for the reader because I’m busy making lunch for the family.

Update: Back from lunch, here you go.

typealias PointType = (x: Int, y: Int)
func cartesianSequence(xCount: Int, yCount: Int) -> UnfoldSequence<PointType, Int> {
    assert(xCount > 0  && yCount > 0, 
    "Must supply positive values to Cartesian sequence")
    return sequence(state: 0, next: {
        (index: inout Int) -> PointType? in
        guard index < xCount * yCount else { return nil }
        defer { index += 1 }
        return (x: index % xCount, y: index / xCount)
    })
}

for point in cartesianSequence(xCount: 5, yCount: 3) {
    print("(x: \(point.x), y: \(point.y))")
}

Would you buy this book? Swift from 2 to 3

twothreescaled

If you thought Swift 2.2 was a big change, just wait until Swift 3 hits Xcode. I’m considering writing a quick reference to help you migrate your code, going beyond the automated tools, so you can start using Swift 3’s kickass new features.

Here are few samples pages from my proof of concept. The screenshots come from the already fleshed out 2 to 2.2 section rather than from the later 2.2 to 3 section, which I’m working on now. The format should remain the same more or less: what is the language change, why was it added, how do you use this and/or refactor, what are some examples of use, and where can you learn more about the change:

(Sorry about the voting on the sample pages. Apparently I can turn on gallery voting for everything or nothing but can’t mix and match what’s votable and not votable.)

Does this look like something you’d pay for?

And would it be okay to release it incomplete, updating it regularly over the year until Swift 3 hits this winter?

Thanks in advance for your feedback and comments.

Nostalgia Tuesday: By request, my 2012 Siri Post

Well, if anything does happen on Monday, we can play “How badly did she get it wrong“, right? And to add some icing, here’s a what-if post about Siri controlling your Apple TV and a proof-of-concept Siri-style dictation used in-app.

(There’s a comment on the video that I particularly love: “Scammer watch the mouse across the screen at the end.” I hate to destroy the tinfoil but I was feeding the Apple TV output through EyeTV and recording the output on my Mac. Bless that person’s conspiratorial heart.)

How 3rd Party apps might integrate with Siri

Third-party integration into Siri remains at the top of many of our TUAW wish lists. Imagine being able to say “Play something from Queen on Spotify” or even “I want to hear a local police scanner.” And Siri replying, “OK, you have two apps that have local police scanners. Do you want ScannerPro or Wunder Radio?”

So why doesn’t Siri do that?

Well, first of all, there are no third party APIs. Second, it’s a challenging problem to implement. And third, it could open Siri to a lot of potential exploitation (think of an app that opens every time you say “Wake me up tomorrow at 7:00 AM” instead of deferring to the built-in timer).

That’s why we sat down and brainstormed how Apple might accomplish all of this safely using technologies already in-use. What follows is our thought experiment of how Apple could add these APIs into the iOS ecosystem and really allow Siri to explode with possibility.

Ace Object Schema. For anyone who thinks I just sneezed while typing that, please let me explain. Ace objects are the assistant command requests used by the underlying iOS frameworks to represent user utterances and their semantic meanings. They offer a context for describing what users have said and what the OS needs to do in response.

The APIs for these are private, but they seem to consist of property dictionaries, similar to property lists used throughout all of Apple’s OS X and iOS systems. It wouldn’t be hard to declare support for Ace Object commands in an application Info.plist property lists, just as developers now specify what kinds of file types they open and what kind of URL addresses they respond to.

Practicality. If you think of Siri support as a kind of extended URL scheme with a larger vocabulary and some grammatical elements, developers could tie into standard command structures (with full strings files localizations of course, for international deployment).

Leaving the request style of these commands to Apple would limit the kinds of requests initially rolled out to devs but it would maintain the highly flexible way Siri users can communicate with the technology.

There’s no reason for devs to have to think of a hundred ways to say “Please play” and “I want to hear”. Let Apple handle that — just as it handled the initial multitasking rollout with a limited task set — and let devs tie onto it, with the understanding that these items will grow over time and that devs could eventually supply specific localized phonemes that are critical to their tasks.

Handling. Each kind of command would be delineated by reverse domain notation, e.g. com.spotify.client.play-request. When matched to a user utterance, iOS could then launch the app and include the Ace dictionary as a standard payload. Developers are already well-acquainted in responding to external launches through local and remote notifications, through URL requests, through “Open file in” events, and more. Building onto these lets Siri activations use the same APIs and approaches that devs already handle.

Security. I’d imagine that Apple should treat Siri enhancement requests from apps the same way it currently works with in-app purchases. Developers would submit individual requests for each identified command (again, e.g. com.spotify.client.play-request) along with a description of the feature, the Siri specifications — XML or plist, and so forth. The commands could then be tested directly by review team members or be automated for compliance checks.

In-App Use. What all of this adds up to is an iterative way to grow third party involvement into the standard Siri voice assistant using current technologies. But that’s not the end of the story. The suggestions you just read through leave a big hole in the Siri/Dictation story: in-app use of the technology.

For that, hopefully Apple will allow more flexible tie-ins to dictation features outside of the standard keyboard, with app-specific parsing of any results. Imagine a button with the Siri microphone that developers could add directly, no keyboard involved.

I presented a simple dictation-only demonstration of those possibilities late last year. To do so, I had to hack my way into the commands that started and stopped dictation. It would be incredibly easy for Apple to expand that kind of interaction option so that spoken in-app commands were not limited to text-field and text-view entry, but could be used in place of touch driven interaction as well.

 

Annual Repost: “All I want from WWDC is…nothing”

wwdc-2016-635x384   

From February 2014: original post

February may seem early to you to be strategizing about Apple WWDC announcements. For tech writers, it’s crunch time. To plan books, posts, and other coverage, you try to anticipate how big a change is coming up and what areas will be affected.

For example, Victor was asking me the other day what I’d like to see in the next installments of iOS and OS X. My answer is the same as it’s been for years: “Bug fixes and security enhancements.” I’m a bit over the yearly update cycle.

I think iOS 7 needed more time to simmer before its debut and I’d rather see more mature products instead of constantly living in an alpha test. I’d love for Apple to spend time fine-tuning its codebase rather than pushing new features. It’s awesome to innovate but I’m not sure that innovation really needs to come in 12-month waves.

If I had to dream about this summer’s announcements, I think I’d want to see an Apple/Tesla iCar that doesn’t catch on fire when you plug in its magsafe connector, a super fitbit-like iWatch, or even “Apple and Samsung finally settle all legal disputes.” We’re probably going to get iOS 8 and OS X Malibu Barbie.

There’s plenty of room for growth and new features, of course. Each year’s API change list includes logical progressions to existing classes as well as keynote-worthy game-changers. I’d just like to see those emerge as slower dot releases than full OS revolutions.

It may already be happening. We’re now about six months or so in from the 7.0 release. Apple is still evolving 7.1, now in its 5th beta. That’s a trend I want to encourage — slow, deliberate, and careful where the end-user benefits from the extra time.

All told, I have no idea what Apple is going to announce this summer but it would be great if the company took a bit of space to breathe.

Sneaky Swift Tricks: The fake Boolean

Moshe Berman writes, “If I’ve got a bunch of chained guard let statements, how can I diagnose which condition failed, short of breaking apart my guard let into multiple statements? Given this example:

guard let keypath = dictionary["field"] as? String,
    let rule = dictionary["rule"] as? String,
    let comparator = FormFieldDisplayRuleComparator(rawValue: rule),
    let value = dictionary["value"]
    else
    {
        return nil
    }

How can I tell which of the 4 let statements was the one that failed and invoked the else block?

Or to summarize in Zork terms:

Given how less than perfect the Swift debugger is, it can often help to turn to everyone’s good old friend, the print statement. There is never a bug so profound that a surfeit of prints cannot detect it1.

My suggestion was to suborn the where clause and use it to provide feedback by calling a function that returns true but has a side effect of printing the file and line information:

func diagnose(file: String = #file, line: Int = #line) -> Bool {
    print("Testing \(file):\(line)")
    return true
}

The advantage of this approach is that it lets you know when the last guard fires, provides minimal intrusion onto existing code, and can be easily removed after debugging. Use it like this:

guard let value = optional where diagnose()

When a binding fails, the diagnosis will not print.

Screen Shot 2016-06-06 at 1.25.55 PM

While discussing this on slack, some interesting alternatives came up in conversation. Lily Ballard suggested extending Optional:

extension Optional {
    @inline(__always) func expect(@autoclosure msg: () -> String) -> T {
        guard let value = self else { fatalError(msg()) }
        return value
    }
}

He adds, “if you tweak it to return `T?` instead of aborting then you can just add `.expect("foo")` to any optional”

Davide De Franceschi had another take:

func diagnoseOptional<T>(optional: T?, message: String = "Found nil in \(#file) at line \(#line)") -> T? {
  guard let unwrapped = optional else {
    print(message)
    return nil
  }
  return unwrapped
}

He says, “Wouldn’t something like this be cleaner, although maybe a tad too specific?”

Joe Groff rocks it out by suggesting dump: the standard library dump function returns its parameter after printing an object’s contents using its mirror to standard output:

Another clever solution from Jérôme Alves:

If you’d like to see other feedback, Moshe also posted his question to Stack Overflow.

1 Took me forever to find where I had first written this, but I eventually spotlighted it (spotlit it?) up: “There is no problem so big so strong so bad that it cannot be solved with a surfeit of print statements”

Sing out your Mac

Use tcsh (just enter /bin/tcsh) and then:

  • repeat 22 echo "da" | say -v good
  • repeat 26 echo "da" | say -v cello
  • repeat 22 echo "da" | say -v "bad news"

and of course

  • say -v cello droid

Was reminded of this today by:

Swift from Two to Three: Currying Favor

First entry into the “Swift 2 to 3” challenge comes from Cristian Filipov, who brings me a routine to extract words from phone numbers.

There are several points of interest in this port, which I’ll get to in just a second, but since his code didn’t arrive with the vital isWord(string:) function, I had to build one myself.

Building isWord

It’s in Cocoa because I find that writing OS X Command Line apps are the most congenial way to build small Swift 3 apps. At this point, playgrounds (as you see, his code was originally intended for playground use with the in-line markup) do not support Swift 3. That should change within the next two weeks but I didn’t want to wait for WWDC to start showing tricks of the transition trade.

So here’s the function in question:

import Cocoa
func isWord(string: String) -> Bool {
    // If it's a number, nope
    if let _ = Int(string) { return false }

    // Use NSSpellChecker to find misspelling
    // if it fails, the string is proper
    let range = NSSpellChecker.shared()
        .checkSpelling(of: string, startingAt: 0)
    return range.location == NSNotFound
}

Currying

Christian’s code heavily depends on currying, which is one of the easiest points of transition in Swift 2 to Swift 3 code. Here’s an example:

func transform<T: Hashable, V>(dict: [T:V])(element: T) -> V? {
    return dict[element]
}

Establishing the dictionary is curried from looking up an element in the dictionary. How to fix?

  1. Place an arrow between each curried element
  2. Use “return { argument in...}” closures for each curry

Here’s the fixed example

func transform<T: Hashable, V>(dict: [T:V]) -> (element: T) -> V? {
    return {
        element in
        return dict[element]
    }
}

Mandated Function Parens

This is one of the Swift 3 changes I was really excited to see adopted. Prior to Swift 3, you could specify types of T -> U. Now it’s uniformly (T) -> U. So this example:

func not<T>(pred: T -> Bool)(e: T) -> Bool {
    return !pred(e)
}

becomes the following (with some bonus curry update):

func not<T>(pred: (T) -> Bool) -> (e: T) -> Bool {
    return {
        e in
        return !pred(e)
    }
}

Taking Charge of Parameter Labels

With Swift 3’s new mandated first parameter labels, it’s time to toss away duplicated names and add in first parameter labels that normally defaulted away. Starting here:

func phoneWords(minLength minLength: Int)(number: String) -> [String] {
    if number.characters
        .filter(("2"..."9").contains)
        .count >= minLength {
        return phoneWords(number)
    } else {
        return [number]
    }
}

Ending up here:

func phoneWords(minLength: Int) -> (number: String) -> [String] {
 return {
     number in
     if number.characters
          .filter(("2"..."9").contains)
          .count >= minLength {
            return phoneWords(number: number)
        } else {
            return [number]
        }
    }
}

Other tweaks

I had to fix the isSeparator closure (needed a closure and a first parameter), and add in one or two more parentheses around parameter types but other than the mystifying spellchecker that insists that “eloydqs” is a word just like “flowers”, everything seems to work beautifully

Screen Shot 2016-06-03 at 2.55.34 PM

You can find the diffed/forked gist here.

Got a short standalone Swift 2.2 code sample that needs updating to new syntax and concepts? Send it along and I may do a post on it. Please no requirements outside the sample, and keep the code short. Code that introduces new kinds of issues (for example, currying is pretty much already covered now) will be preferred.