Archive for August, 2015

Naming Errors #swiftlang

In recent betas, Apple extended ErrorType for structs and classes, as well as enumerations. Even so, enumerations still win for quick-and-simple error reporting:

enum MyErrorEnumeration: ErrorType {case FirstError, SecondError, ...}

So what do you name your errors?

When dealing with trivial applications, feel free to use trivial names.

enum Error: ErrorType {case WrongFile, ItsMonday, IFeelCranky}

But when you expand errors to more significant use-cases, what’s a sound set of rules for naming? I don’t really have any good answers yet, but here are a few thoughts. Please pick these apart and suggest alternatives:

  • Use the word Error in enumeration names. Yes: FileProcessingError, No: FileProcessing
  • Describe the error circumstances in the enumeration case. Yes:FileNotFound, No:Missing.
  • Differentiate cases with associated values, case FileNotFound(fileName: String)
  • Don’t force enumerations when it’s easier to use classes or structs. If you need line tracking, source files, and free-form reason text, consider using a more appropriate type.

How to Print: the Beta 6 edition #swiftlang

Forget everything new about printing. RIP appendNewline. RIP last-position output stream. Print is new, redesigned, and totally facelifted in Beta 6.

Here’s what those public faces look like (and check out those hot non-terminal variadics):

public func print(items: Any..., separator: String = default, terminator: String = default) 

public func print<Target : OutputStreamType>(items: Any..., separator: String = default, terminator: String = default, inout toStream output: Target)

In its most basic form, you still print things:

print(something)

and Swift will use a variety of protocols (Streamable, CustomStringConvertible, CustomDebugStringConvertible, those do not appear to have changed) to write a textual representation to stdout.

In Swift 2.0 beta 6 and above, you can print several things at once:

print(thing, anotherThing, yetAnotherThing)

Two special parameters (separator and terminator) control what happens between items and at the end of lines. An output parameter toStream controls where text is sent.

So if you’re writing an IRC client, you might send both \r and \n.

print(myText, terminator:"\r\n", toStream:&myIRCStream)

Or you might create a comma delimited list of integers:

print(1, 5, 2, 3, 5, 6, separator:", ")

You skip newlines by overriding the default terminator:

print("on one line", terminator:""); print("on the same line")

As with earlier Swift 2.0’s, strings conform to OutputStreamType, so you can print to strings:

var string =""; print("hello", toStream:&string)

Probably the most useful thing about print is that its new variadic arguments are all Any, so you can create a heterogeneous list of strings and items of interest, e.g.

print("My number is ", myNumber, " And this one is ", otherNumber)

without having to use in-line escaping (although it remains there if you really want it). This way, if your function calls use quote marks you don’t have to go through the compute then print work-arounds you had to in earlier betas.

Here’s a quick overview of what this all looks like:

Screen Shot 2015-08-24 at 5.53.29 PM

Up the mix with Beta 6 #swiftlang

New in Beta 6

I talked about try? in a separate post because it really deserves a longer discussion than quick bullet points.

Completion. Context-sensitive Xcode completion for inferred dot syntax, e.g. MyEnum.Item vs .Item, when the type is clear to the compiler. neat.

Screen Shot 2015-08-24 at 5.41.17 PM

Static Computed Properties in Protocol Extensions. Yay. You can, I believe, also use required protocol members in computing those properties.

Screen Shot 2015-08-24 at 5.42.53 PM

Non-Terminal Variadics. They can appear anywhere in the parameter list, enabling you to most importantly combine variadics with trailing closures.

Screen Shot 2015-08-24 at 5.47.07 PM

Collection Clarity. Non-ObjC types cannot be stored within ObjC-marked properties, e.g. an Array of swift-specific enumerations. Collections containing types that are not Objective-C compatible are no longer considered Objective-C compatible types themselves. For example, previously Array<SwiftClassType> was permitted as the type of a property marked @objc. This is no longer the case. (19787270)

Block imports are now typealiases for Swift-style closures. I’ll just quote Apple: C typedefs of block types are now imported as typealiases for Swift closures. The primary result of this is that typedefs for blocks with a parameter of type BOOL are now imported as closures with a parameter of type Bool (rather than ObjCBool as in the previous beta). This matches the behavior of block parameters to imported Objective-C methods. (22013912)

Type Aliases now get an aka annotation in error messages. So you can see what they alias to for better clarity.

Screen Shot 2015-08-24 at 5.48.35 PM

Print and Debug Print on Steroids. They’re now variadic and you can add a String separator. (I wish they had called it separator and not string because better Update: they did.).  Quick separate post on this. It’s really cool stuff.

public func print(items: Any..., separator: String = default, terminator: String = default)
public func print<Target : OutputStreamType>(items: Any..., separator: String = default, terminator: String = default, inout toStream output: Target)

Screen Shot 2015-08-24 at 5.53.29 PM
RIP appendNewline.

RIP extend(). Long live appendContentsOf(). Same bat behavior, new bat name. Time to go back and fix all my code. *shakes fist*.

All collections are SliceableGinsu!

Most closure ops are rethrows-able. So you can now throw out of maps and filter, and you can try? and &&/||/?? together.

Screen Shot 2015-08-24 at 5.58.44 PM

Screen Shot 2015-08-24 at 5.58.52 PM

How to “try?” (Yoda alert) #swiftlang (hint: beta 6)

With Swift 2.0, you’ve probably been doing something like this to handle errors.

let foo = try somethingThatMaythrow

This calls a routine that potentially throws an error.

Somewhere in that calling chain, someone takes responsibility for catching errors, typically with do-catch. In this paradigm, the error is of interest primarily at the point of creation and the point of consumption. No other code needs deal with error conditions. Try is sufficient to pass the error handling along.

If you want to ignore the error chain, an exclamation point signals “success or die”. Any fail scenario creates a run-time crash.

let foo = try! somethingThatMayThrowIfItFailsCrashyCrashy

Now Beta 6 introduces try? (with a question mark). It returns an optional that wraps successful values and “catches” errors by returning nil.

guard let foo = try? somethingThatMayThrow else {
    handle error condition and leave scope}
if let foo = try? somethingThatMayThrow {}

In each of these example statements, the code conditionally binds a non-optional to foo, but you can assign foo directly and it’s assigned as an optional.

You can combine try? with ?? for fallback values but you must surround the try in parens at this point, as it took me several minutes to figure out:

Screen Shot 2015-08-24 at 6.06.51 PM

In both uses, be aware that your error is discarded. Instead of:

if (!(value = [instance request:blah withError:&error])) 
{
    ...print error and return/die...
}

or:

if let value = instance.request(blah, error:&error) {
   ...success..
} else {
   ...print error and return/die...
}

or:

do {
    let value = try instance.request(blah)
} catch {... print error and return/die ...}

You’re working in a system where error conditions are transformed automatically into nil values.

So, what this gets you:

  • Interoperability between Swift’s nullable optionals and its error system. For example, you can write throwing functions and consume them with if-let.
  • A focus on success/failure where the calling context solely assumes responsibility for reporting error conditions. “I tried to do X and it failed somewhere.” Traditionally errors describe what went wrong. Now you describe what you were trying to do.

What you lose:

  • Cocoa-style error handling. Any errors that are generated are eaten away and you won’t see them or know about them.
  • Error source information such as the file / routine that generated the issue. All you know is that the calling chain failed somewhere but not why or how.
  • Railway/Freight Train-style development, or as Jeremy Tregunna puts it, you lose “the either monad as inputs and outputs to code that can fail with left side being the error, right side being the value; binding these functions together with a binding operator that automatically propogates the first error through to the end of the chain”

When do you want to do this?

  • When you’re focused more on success/failure than why things failed.
  • When you’re working with well-tested API chains, so if you can’t construct a URL or save to file or whatever, you just want to note it and move on with your recovery code for a “did not succeed scenario”

This construct more or less steps back to using optional return values that signal success and failure, which we had moved beyond earlier this Summer. It’s time to rewrite a few manifestos.

In summary: ahoy ahoy, it’s a major paradigm shift. Developers take note.

CSS and Attributed Strings

Can you initialize an attributed string with CSS-populated HTML? This question popped up in #iphonedev. The answer is: kind of. HTML initialization is meant for lightweight use, not for full page layout. But yes, you can.

Screen Shot 2015-08-24 at 2.55.14 PM

This question in particular had to do with whether you could customize  list bullets:

Screen Shot 2015-08-24 at 3.05.37 PM

As far as I know, you cannot use externally sourced images but if you worked hard enough (and I’m not willing to do that), there are always attributed strings image attachments.

The upshot of all this is 1: I touched CSS. 2: I’m busy trying to figure out error naming. and 3: I figured that if it’s really important you’ll either use a web view or work out a post-hoc way to insert attachments that I’m not willing to spend any time on here but someone will point me to them if I throw out a post.

There you go.

source:

enum AttributedStringError : ErrorType {case Unconstructable}
func stringWithHTMLString(var string : String) throws -> NSAttributedString {
    string = string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    if !string.hasPrefix("<html>") {string = "<html>" + string}
    if !string.hasSuffix("</html>") {string = string + "</html>"}
    guard let htmlData = string.dataUsingEncoding(NSUTF8StringEncoding) else {
        throw AttributedStringError.Unconstructable}
    var attributes : NSDictionary = [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType]
    let options = [String : AnyObject]()
    let aptr = AutoreleasingUnsafeMutablePointer<NSDictionary?>(&attributes)
    return try NSAttributedString(data: htmlData, options: options, documentAttributes: aptr)
}

Swift protocol names: A vital lesson in -able vs -ible: #swiftlang

Warning. Blather follows.

Swift protocols describe the surface that connect a feature provider API with its consumer. Protocols establish a communication contract. They ensure a fit between each required member and the provider’s implementation. It’s like whether a virus can attach to a host cell’s receptors, or whatever the actual biological equivalent is.

You describe protocols using nouns (typically ending in Type, e.g. MirrorPathType, MutableCollectionType, ErrorType) and adjectives (typically ending in ble, like Streamable, Strideable, _ColorLiteralConvertible) that discuss what a conforming type is and what it does.

When naming a protocol, you’re of course not limited to Type and ble endings. Your protocol can be, for example, a DataProvider or a FloatConsumer. A protocol can describe a delegate relationship DownloadProcessingDelegate or a data source ListViewDataSource. You may implement an OutputDestination or an IntegerSink.

With ble endings, however, comes a world of pain because English basically sucks when it comes to whether to use able or ible. So I thought I’d share some basic rules I’ve scraped up from the net to help  name protocols:

  • Most of the time, you want able and not ible. The Spelling Blog suggests that there’s a 5:1 chance of able being right compared to ible.
  • If the main part of the protocol name is a complete English word, even if you’re going to drop an e or y at the end you probably use able. For example “Streamable“, “Strideable“, “_ObjectiveCBridgeable“, “Reflectable“. Access/accessible and collapse/collapsible are notable exceptions.
  • If the word before the ending is not strictly English, e.g. permissible’s permiss and audible’s aud, you’re probably going to use ible.
  • According to the Oxford Dictionaries site, if a word ends with a hard c or g, it’s able, for example UserNavigable.
  • If you can construct a word with the root word and ation, use able. If you can use ition, sioncian, or ion, use ible. For example, a vis root is like vision, so the protocol name would be MemberContentVisible. Convert goes to conversion, so I presume that’s why it’s convertible.
  • The Spelling blog says any Latin-sourced -are infinitive maps to able, while -ire and -ere are ible. The write-up adds that any new techno-word is able such as biodegradable, emailable, clickable, etc.

Now that I’ve wasted your time with all those points, I’d like to mention that all the words you want to use in a protocol are likely available in the OS X dictionary, so you can just look them up. A quick spell check1 will help you avoid unflattering code smell.

1 Now that I mentioned spell check, Skitt’s Law mandates that I majorly messed up somewhere in the post on spelling.

Update: k asks “Is there a reference for why protocols should be named like that? I forget if Apple recommended it or if that was community driven” Answer: personal mandate. Manifold2 destiny.

2 Please tell me that someone gets this joke

Laptops

As I’m handing over my 2010 MacBook Air to eldest child, it occurs to me that computing today is very different from 2010.

The MacBook did an okay job in its life. It hosted many OS’s, mostly betas, and was a go-to for kids homework, but it really stank at the one job that differentiated it from my iPad, which is to run Xcode and navigate docs.

Xcode doesn’t want to be on a teeny tiny screen with a crappy keyboard. It wants full glorious mechanical travel and many large monitors.

No matter how many times I promised myself that this time, I’d figure out how to do some light development on the damned thing, I ended up using it as a poorly designed iPad — email, browsing, books, media.

Its greatest utility was booting up a half dozen operating systems to test backward compatibility as it sat 2 feet away from my primary dev machine.

I don’t know what it is about laptops and me. For whatever reason, I can’t seem to get along with decaffeinated OS X. I can iPad, I can desktop, but I just can’t seem to laptop.

Perhaps I’m just deluding myself that there people out there who can actually get real work done on these things. What I can’t figure out is how.

What is the critical equipment line over which you can actually do development? Does it involve bringing along a 24″ monitor and a loud clicky keyboard to the coffee shop, or on a plane?

I’m back to lurking at the online store, trying to figure out if it’s even worth picking up a replacement at this point. What I really want is a portable ultra-light iMac/iPad hybrid, complete with handle on top and kickstand, and that’s just not going to ever happen.

So what do you suggest I look into? Will Retina make all the difference for my bad eyes? Or should I hold out for the mythical hockey-puck Mac or the iPadMac? What’s your advice? And how do you get that work done on yours?

Thanks.

Optional trailing closures #swiftlang

Question: Can I set an optional trailing closure in a function?

Answer: Easiest way is to use a non-optional default value.

func doSomethingWithCompletion(completion: () -> Void = {}) {
    // ... Do Something ...
    completion()
}

This popped up in a conversation yesterday and naturally the discussion then verged onto how efficient or inefficient this approach is over, say, passing an optional closure value, e.g. (() -> Void)?.

So after running a few tens of millions of iterations on several approaches, the results were pretty interesting:

func test1(c : () -> Void) {c()}
func test2(c: (() -> Void)?) {
    if let c = c {c()}
}
func test3(c: (() -> Void)?) {c?()}
func test4(c: () -> Void = {}) {c()}

In unoptimized runs, both test1 and test4 massively out-performed test2 and test3 by an order of magnitude on 10 million increments of a local variable.

test1
Elapsed time: 0.134177029132843
After tests: 10000000
test2
Elapsed time: 1.11247903108597
After tests: 20000000
test3
Elapsed time: 0.944562971591949
After tests: 30000000
test4
Elapsed time: 0.146546959877014
After tests: 40000000
Program ended with exit code: 0

 

Using whole module optimization, the latter three are more or less equal but the first, without default values or optionals, still runs much faster.

test1
Elapsed time: 0.00389701128005981
After tests: 10000000
test2
Elapsed time: 0.0398470163345337
After tests: 20000000
test3
Elapsed time: 0.0474460124969482
After tests: 30000000
test4
Elapsed time: 0.0474919676780701
After tests: 40000000
Program ended with exit code: 0

If you’re going to supply arguments, make sure you use an in-clause for the default no-op closure, e.g. {_ in} or {(_) in}, etc.