Archive for March, 2016

SE-0054: Implicitly Unwrapped Optionals probably go away

This morning SE-0054, which abolishes the ImplicitlyUnwrappedOptional type (to be clear, the functionality will now be limited to declarations) was tentatively accepted by the Swift Core Team.

There is generally positive feedback on the proposal, as it keeps the good behaviors of the existing T! type syntax (including support for importing un-nullability-audited APIs, support for 2-phase initialization patterns, etc) while dramatically reducing the confusion and surprise that they introduce as they trickle through type inference.  The core team sees significant value in having a simple and predictable model that can be explained concisely.

At the same time, the team recognized that adopting this proposal without giving it a good proper run, on real life projects, might not be the best idea in the world. It accepted it “pending implementation experience,” or with an option to back out if things go belly up in real life.

That said, this is the sort of proposal that can have a profound impact on the actual experience using unaudited APIs.  The core team believes that the experience will be good, but we would like to get some experience moving a couple of existing projects (both low-level code that interacts with C, and an “App” project working with high level frameworks) to see what the impact is in practice.  If something unexpected comes up, we will revisit this, and potentially reject it later. Chris Willmore is working on an implementation of this now, so we should know in the next week or two.

While several proposals have been accepted for Swift with requested revisions, this is the first one to include an official escape clause.

Swift Style: Are you a 4-denter?

Two space indentation seems to be the new craze. “Four space indentation? Are you mad, that’s nearly as bad as tabbing with eight?” is the meme of the moment. (Or, as established in Zoolander, “Two spaces? It’s so hot right now.”)

While two space indentation offers more horizontal space to work, four spaces continues to create an elegant sense of white-space and scope-based horizontal stepping that provides light and easy reading.

(I ignore the three space addicts in this discussion, while acknowledging they do exist. As Mike Ash puts it, “I think three spaces should be, ‘Do not approach. Retreat to a safe distance and call the police as soon as you’re clear.‘” Chris Lattner counters, “I think you under appreciate 3 space indent.  It looks the best, and conclusively settles the tabs vs spaces debate.” coughtrollcough1)

Like my previous colon discussion, Apple answers seem to vary by group. Apple docs, including the Swift Programming Language, consistently use four spaces, enabling clean examples that breathe:

Screen Shot 2016-03-31 at 9.00.40 AM

and the Standard Library group uses 2, following LLVM Coding Standards, which I find a bit claustrophobic. (Thanks, Greg!)

Screen Shot 2016-03-31 at 9.01.39 AM

So I went off to google. First up, I found a 1983 ACM paper by Richard Miara, Ben Schneiderman, and some others called “Program Indentation and Comprehensibility“, which sought to test whether 2-4 spaces were more ideal than 0 or 6 spaces. Unsurprisingly, this premise was born out by their research.

They found that indentation level had a statistically significant effect on comprehension, and optimal indentation fell somewhere between 2 and 4 spaces. As the spacing increased beyond that (6 spaces or more), comprehension decreased.

It’s worth noting that all testing was done: (1) in the 1980’s (2) on 80-column-limit systems, and (3) with choices limited to 0, 2, 4, and 6 spaces. “The level of indentation we tested (0-6 spaces) gave strong results favoring 2 or 4 spaces.” The paper recommends that more indentation levels (0-8 spaces, or nine total levels) be studied in further depth. I’m sure someone got around to it before Starbucks and the MacBook Pro were invented.

In contrast, there’s the Jay Bonci codex (Perlmonks, 2002, “The One True Style of indentation“), a sociological introspection of indentation. Here’s a subset of the Bonci codification that maps spacing choices to internal coding intent.

  • One space – Screw readability. I’m pissed they even make me separate my operators. Perl should be more like Latin.
  • Two spaces – I have my head on straight AND I respect screen real estate.
  • Three spaces – I have a little flair, or a nervous twitch. Or the second disguised as the first. Or you listen to waltz while you code.
  • Four spaces – I read a few standards docs and now I think I’m all spiffy. Vannila (sic) Ice, I know you’re in there.
  • Six spaces – I have agression (sic) issues, and my outlet is machine gunning the space bar
  • Eight spaces – You end every line with a meniachal (sic) “DIE! HAHAHAHAH! DIE! YOUR FRIENDS CANNOT SAVE YOU NOW.”
  • Tabs – I’m a lazy person. I know all of the vi commands by heart. Or you drank the 80’s soda.

In the real world, indentation seems to have settled on two, four, and sadly three space standards. So what’s your indentation style? And why?

1  My personal use of 3-space indentations have almost entirely been predicated on accidental deletion of a member of a 4-space unit, but they have happened.

Like my posts? Consider buying a book or two. Thanks!

Swift Style: Inferring Floating Point

The following code is thoroughly legal in Swift:

Screen Shot 2016-03-30 at 11.13.47 AM

You can also initialize a Double with an Int because Double is an IntegerLiteralConvertible.

let myDouble: Double = 1

This kind of thing gets on my style nerves. If you were theoretically writing an opinionated guide to Swift Style, what kind of advice would you give here? What practice offers the greatest advantage when reading coding intent?

My first go at it is this: In any situation where you have the ability to accurately express the intended type of a constant value, prefer the typed variant over one that can be inferred or cast.

Swift Documentation Markup update

HeaderDocCoverscaled

I just uploaded version 1.2 to both iTunes and Leanpub. They should go live fairly soon.

This release takes advantage of my dumpster diving through Swift’s sources, updating details of Xcode’s CommonMark support and expanding information about the supported markup tags in Xcode 7.3.

I expanded the playground section to describe the new 7.3 markup tags and added coverage about embedding videos using playground markup.

Thanks again to everyone who continues to support my independent book projects. I am also hard at work on the Swift 2.2 content update for the cookbook and my indie Swift Style project.

Boolean multiplicity and Swift

Late last week, I was helping a fairly new Swift developer with his code that initially looked like this:

func generateContact(withAddress: Bool, withEmail: Bool, withPhone: Bool) -> Customer // not my code

It occurred to me that multiple Boolean flags would be much better represented as ad-hoc option sets. So I set out to discover how often this pattern showed up in code. I asked for examples on the Swift Evolution list, headed over to both Github and to searchcode.com, trying to track down examples and determine whether this was a relatively common pattern in Swift.

I pulled down all the Apple code, cloned a lot of the top Swift Github repos, and performed searches (the best I could, all things considered) through gists to test whether multiple Bool arguments was a common use that could be improved.

What I found was this:

  • In both Apple and “Top Swift” repos, I found few circumstances where multiple boolean flags were used at all.
  • Two flags was the most common multiplicity. Three flags were rare. I don’t remember finding any with four or more.
  • Multiple booleans were primarily used initializers, with a few instances from graphics code for things like stroke and fill.
Examples:
convenience init?(before: Bool, during: Bool) {
convenience init?(before: Bool, during: Bool, after: Bool) {
func nested_if_merge_noret(x: Int, y: Bool, z: Bool) {
func render(fill: Bool, stroke: Bool) {
public init(hasStroke: Bool, hasFill: Bool, evenOdd: Bool = false) {
public init(x0: CGFloat, y0: CGFloat, rx: CGFloat, ry: CGFloat, angle: CGFloat, largeArcFlag: Bool, sweepFlag: Bool, x: CGFloat, y: CGFloat) {
I’m probably not going to press forward with the language enhancement I had in mind because I don’t see a compelling reality-based need for it after performing this check, but it would have been nice to be able to declare:
convenience init?(flags: @options(before, during, after)) {
and call it with
let foo = T.init(flags: [.before, .after])

Swift Colon Care: High Fiber usage

Since I started programming in Swift, I moved to the “Ash Rule” of left-hugging colons in all uses except ternary, up to and including dictionary references,  protocols, etc. Here’s what that looks like in use:

let x: [String: String] = ["key": "value"]
let y = foo(param1: value1, param2: value2)
func bar<T: Hashable>(a: T) -> Void {}

It felt weird for a while but I’ve now grown used to it. This approach is consistent, prioritizes the role of the left item, and is (in my opinion) quite readable. Compare and contrast with my prior style, which I call the “Full Space Monty” approach:

let x : [String : String] = ["key" : "value"]
let y = foo(param1 : value1, param2 : value2)
func bar<T : Hashable>(a : T) -> Void {}

The Ash Rule puts me in step with about half of Apple source code and out of step with the rest. Colon magnetism tends to vary by both group and individual producer. I mention this because Dave Abrahams clarified StdLib style on the Swift Evolution list today:

  • Full monty spaces for declarations and extensions
  • Left magnetism for providing values

Here’s an example I grabbed from Evolution that showcases some fascinating code styling choices. Focusing only on colons however, here’s what there is:

public func contains(value: Bound) -> Bool 
public var description: String 

protocol _ClosedRange : _RangeProtocol {}
public struct ClosedRangeIndex<
  Bound : Comparable where Bound : _Strideable
> : Comparable {

I’m going to assume the bolded use in the following snippet is an oversight:

extension _ClosedRange {
 @inline(__always)
 public init<
   Other: _ClosedRange where Other.Bound == Bound
 >(_ other: Other) {
     self.init(
     _uncheckedBounds: (lower: other.lowerBound, upper: other.upperBound)
     )
   }
...
}

While this next one is intentional since the ClosedRangeIndex is typing the lhs and rhs arguments:

public func == <B>(lhs: ClosedRangeIndex<B>, rhs: ClosedRangeIndex<B>) -> Bool {

This style isn’t universal. Apple Developer Publications uses Mike Ash colons.

When it comes to colon style, I don’t think there are right or wrong answers but I do think that whatever style you do choose naturally breaks down into the following categories:

  • label declarations func f(x: T)
  • collection lookups [key: value] (Empty case is universally [:] not [: ].)
  • cases case A, B:
  • inheritance class x: Y
  • conformance <T: A>, <T: protocol<A, B>> {}
  • attribute  @attribute(key: value), e.g. @available(*, unavailable, renamed: “MyRenamed”)
  • ternary A ? B : C

I think there’s a general unity of opinion when it comes to case and ternary. No space for cases; always spaces for ternary. There’s little controversy or variation as far as I can tell.

Screen Shot 2016-03-25 at 1.45.32 PM

The newly attribute style is up for grabs but I think it will follow label declarations in using left-magnetic colons.

Screen Shot 2016-03-25 at 1.46.24 PM

The Swift Programming Language uses left-magnetic colons for dictionaries:

Screen Shot 2016-03-25 at 1.41.33 PM

although the grammar does not: (Jordan Rose: ” Not sure I’d count the grammar as any particular evidence. Traditionally, grammars put spaces around everything.”)

Screen Shot 2016-03-25 at 1.42.27 PM

Its property, constant, and variable declarations are pretty much uniformly left-magnetic:

Screen Shot 2016-03-25 at 1.43.06 PM

I didn’t find any inheritance that wasn’t left-magnetic:

Screen Shot 2016-03-25 at 1.44.06 PM

So what’s your house style and how did you come to it?

Playground Secrets 3rd Edition

CoverPlayground3scaled

I just pushed the 3rd edition to the store. If you’ve already purchased a copy, the update should appear tomorrow or over the weekend. Check for available downloads. As always, if you find any mistakes or if I overlooked any content with the new updates, please do let me know!

New purchasers, the 3rd edition will be available on iTunes and LeanPub as soon as it is approved and processed.

From the release notes:

Massive revision for Xcode 7.3, Swift 2.2 changes. Highlights include new examples for Swift 2.2, new doc rendering styles (much prettier, but also much larger so the screenshots suffer from being able to present less material at once). Removed (most) coverage of the now deprecated value capture feature, added strike-through for one section just in case a replacement shows up, added notes in the section about arranging assistants. Added coverage of new build configuration tests, enhanced the playground rich text markup section, added info about literals and embedded videos. Chapter 7 lost content because of the introduction of live interaction. Sadly, live input also disabled things like drag-and-drop windows and pop-ups, so a lot of the cute utilities that playgrounds could do in Xcode 7.2 no longer work. Sandboxing means that many really useful OS X utilities (although not all) are now history.

Exhaustive, safe, non-optional Dictionary lookups

Another little tweak in response to a Swift Evolution thread:

public extension Dictionary {
    public subscript(key: Key, default fallback: Value) -> Value {
        return self[key] ?? fallback
    }
}

Always returns an unwrapped value. You supply a fallback.

values[self, default: "?"]

If you omit the external default keyword, it looks like this instead:

values[self, "?"]

Immutable setters

Idea brought up on Swift Evolution by Zsolt Szatmari:

The only thing I am really missing right now from Swift is described as following. This works in some other languages, e.g.  F#, Kotlin, and Haskell.

let john = {firstName="John"; lastName="Doe"}
let alice = {john with FirstName="Alice"}
Current way to do this in Swift is:
let john = (firstName:"John", lastName:"Doe")
var alice = john
alice.firstName = "Alice"
This might seem to be a nuance, but it’s more cumbersome (especially if one wants to do this frequently), and we are left with a var at the end.  Also, this idea rhymes with the current direction of removing var arguments from functions.

Unless I am overlooking something major here (wouldn’t be the first time), there’s actually a pretty easy way to do this in existing Swift:

struct Person {
    var firstName, lastName: String
}

let john = Person(firstName: "John", lastName: "Doe")

func modify(item: T, update: (inout T) -> Void) -> T {
    var this = item
    update(&this)
    return this
}

let carol: Person = modify(john) { $0.firstName = "Carol" }

print(carol) // Person(firstName: "Carol", lastName: "Doe")

The `modify()` function makes a new copy, applies any changes, and returns the new instance. Swift’s type inference system ensures that the  associated closure can access instance members.

Swift Evolution News

Like my posts? Consider buying a book or two. Thanks!

Accepted Proposals

SE-0044: Import as member provides 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. Discussion

SE-0043: Declare variables in ‘case’ labels with multiple patterns removes errors when a pattern declares the multiple variables with the same name and types. This change reduces repetitive code, and therefore reduces mistakes. It’s consistent with multi-pattern matching when variables aren’t defined.

SE-0042: Flattening the function type of unapplied method references makes unapplied method references more useful and consistent with idiomatic Swift and workable for mutating methods, by changing them to produce a function with a flat function type.

SE-0047: Defaulting non-Void functions so they warn on unused results flips Swift’s default behavior. Unused results are more likely to indicate programmer error than confusion between mutating and non-mutating function pairs. This proposal makes “warn on unused result” the default behavior for Swift methods and functions. Developers must override this default to enable the compiler to ignore unconsumed values. (Preliminary revision per Core Team feedback adds default migration behavior section for the Clang importer.)

In Review

SE-0053: Remove explicit use of let from Function Parameters In review to 3/27

SE-0055: Make unsafe pointer nullability explicit using Optional makes UnsafePointer<Int> represent a non-nullable pointer, and UnsafePointer<Int>? a nullable pointer. This also allows us to preserve information about pointer nullability available in header files for imported C and Objective-C APIs. In review to 3/27

SE-0048: Generic Type Aliases aims to add generic typealiases to Swift In review to 3/29

Scheduled Reviews

Design Discussion

Core Team Feedback on Pull Requests

Make pointer nullability explicit using Optional

Biggest open issue is what to do with UnsafeBufferPointer which has a base address and a count of the number of elements at that address. The most common use is to do fast things with an array. The problem is when you have an empty array.

We have a statically initialized empty array, so this doesn’t apply to array. But slices and Cocoa arrays can do it.

Half of the use cases are subscripting off of the buffer, so they don’t actually use the base address. They can’t actually subscript an empty array, but it’s not a syntax error — the loop is run zero times, so it doesn’t matter. The other half pass the pointers down to a C API that takes an address and count.

Someone might expect that the base address doesn’t change when something is initialized.

We can’t easily use the zero pointer because SIL already uses it for nil. But there are issues with using the same representation as C to avoid bridging costs.

We’re mapping two things in C onto one thing in Swift. In C, the buffer pointer would be __nullable long * and the length is ulong.

Given everything else in the system, it’s more like pointer. We didn’t call it a buffer because that tends to imply ownership.

Sketching out the state space:

Pointer Length Static type
null 0 UBP?
valid >= 0 UBP
valid < 0 X
vull != 0 ???

This issue would go away if we got rid of the base address on UnsafeBufferPointer, but that would get rid of a number of valid C operations like calling memcopy.

It seems like withUnsafeBufferPointer should never produce nil. With that in mind, why should UnsafeBufferPointer need to?

We do need a properly-aligned “valid” invalid pointer. LLVM makes assumptions about things being aligned.

Dominant feedback on the list has been for people want something that round trips cleanly. Making the base address non-optional adds overhead and removes the ability to round trip.

It’s unfortunate that we don’t have a way to represent in the type system a buffer pointer that isn’t nullable, from within withUnsafeBufferPointer which wouldn’t even call its closure if the buffer has a null base address.

Allow Swift types to provide custom Objective-C representations

The associated type could be AnyObject rather than NSObject. The use case for a non-subclass of NSObject is very narrow, but it’s not a needed restriction.

The unconditionalyBridgeFromObjectiveC function can probably go away. Calling initializers from the downcasting infrastructure is horrible. If we need a function, they

This doesn’t break the ability of the optimizer to reason about what a dynamic cast can do. We require that the bridgeable conformance must be in the same module as where the type is defined, and we have a white list of things that don’t follow that. Ok… but do we want people to expand casting this way? If we say no, we should take it away from array and string and dictionary too.

You shouldn’t need implicit conversions — the use case is very narrow, and we would rather have things use explicit conversions. The APIs come in with the right type; the implementation of the bridged type has to do conversion, but its clients don’t have to see that. From the Swift point of view, there won’t be any APIs that take the reference type.

Implicit conversions. In this proposals, you don’t get implicit conversions. Have a separate discussion about whether we can get rid of the four types that have implicit conversion. We see the existing ones as deeply problematic.

Dynamic casts. For example, AnyObject to a bridged value type. The whole reason for the dynamic cast infrastructure is to make the reference types irrelevant. Should this be using cast syntax or should we have a different type of function? It’s hard to describe what as does. It’s magic because you are casting AnyObject to a struct — calling it AnyObject doesn’t make a lot of sense.

If we have reference counted existentials, we could merge Any and AnyObject.

Resilience concern: you can not add this protocol after the type has been published.

SE-0054: Abolish ImplicitlyUnwrappedOptional type

IUO as a type is bad; it should become conceptually a decl attribute instead. If we import things that can be nil, their formal type is Optional but we can add an attribute that says when you form a rvalue to that thing, you get implicit unwrapping. The typechecker inserts a diamond that lets you convert it to T? or T. Meaning T! never enters the type system — although it does still appear in user-facing decl descriptions.

For example:

let y = P       // y is of type T?
let y: T! = P   // y is of type T!
let x = [P]     // x is of type [T?]

One issue is that we don’t have a good way to mark a function that takes a block pointer, when that block has not been audited.

void foo(C *(*fp)(C* x)) {}
func foo (fp: ((C?) -> C?)!) {}
func foo (@IUO fp: (C?) -> C?) {}

That is a regression from our current behavior. It would have to be a type attribute because they can chain. This will show up in places where you return (and then call) a block.

For example, you can no longer express the type let y: (T?, U!).

We don’t need to have a diamond for currying, only for rvalue access and application.

x.foo()         // T!
Type.foo(x)()   // T? return type

A source breaking change here is that if extract something into an intermediate variable could change type in a very important way. That’s already somewhat true because of overload resolution, but this makes it much more visible.

Does this gloss over the audit problem? We’ve gotten most of the really important stuff audited, but there are lots of unaudited things such as most of the SDK on Linux. This means we don’t propagate the IUO stuff up, meaning we end up with more explicit forces in code when you are using unaudited API.

Deferred initialization is still a good argument for why we need the feature. This approach locks down propagation and makes IUO more predictable: if the expression can typecheck as optional it will, otherwise it will force.

Awaiting Scheduling