Swift Builders

Similar to languages such as Groovy, Swift has special syntax support for lists (Array) and maps (Dictionary) which results in a compact representation of what’s being defined, inline with the code that is using it. e.g.

println([1,2,3,4,5].count) //Output: 5

or

var x = 0
[1,2,3,4,5].each { x += $0 }

where:

extension Array {
  func each (block: (T) -> ()) {
    for item in self { block(item) }
  }

Tree Based Syntax

In this article, we extend the concept of syntactic support to defining (somewhat) arbitrary nested tree structures.

Let’s say we want to programmatically generate HTML, an imperative solution for which likely requires lengthy code with templates engines / variable substitution, interspaced with loops and branching, and associated glue code.

Syntactic builders can offer an elegant alternative:

html {
  head {
    title( "Page Title" ) {}
  }

  body(["class":"bodyClass"]) {
    for i in 0..3 {
      div(["id":"div_(i)"]) {
        p("Click ") {
          a(["href":"http://www.example.com/link(i).html"], 
             "link (i+1)") {}
        }
      }
    }
  }
}

The above example is valid Swift code and generates the following HTML code:

  <html>
    <head>
      <title>Page Title
      </title>
    </head>
    <body "class"="bodyClass">
      <div "id"="div_0">
        <p>Click 
          <a "href"="http://www.example.com/link0.html">link 1
          </a>
        </p>
      </div>
      <div "id"="div_1">
        <p>Click 
          <a "href"="http://www.example.com/link1.html">link 2
          </a>
        </p>
      </div>
      <div "id"="div_2">
        <p>Click 
          <a "href"="http://www.example.com/link2.html">link 3
          </a>
        </p>
      </div>
    </body>
  </html>

Builder Methods

The builder operates by invoking several custom methods on a underlying Builder class where method names parallel html tag names. e.g. the div tag:

func div(block: ()->()) { div(nil, nil, block) }
func div(attr: Builder.Attributes?, block: ()->()) { div(attr, nil, block) }
func div(value: AnyObject?, block: ()->()) { div(nil, value, block) }
func div(attr: Builder.Attributes?, value: AnyObject?, block: ()->()) { Builder.node("div", attr: attr, value: value, block) }

All builder methods follow the same syntax and accept

  • an optional map of attribute name/value pairs
  • an optional tag value and
  • a closure for configuring the tag.

Internally, the Builder creates a tree of Node objects which parallels the Swift tree.

class Node {
    var name : String
    var parent: Node? { didSet { level = parent!.level + 1} }
    var children = Node[]()
    var attr = Attributes()
    var block: Block?
    var level = 0
    var value : AnyObject?

    init( name: String) {
      self.name = name
    }

    func visit(before: Visitor?, after: Visitor?) {
      if let v = before { v(self) }
      for c in children { c.visit( before, after ) }
      if let v = after { v(self) }
    }
  }

Traversing with Visitors

A visitor method on the Builder allows for customized traversal of the object tree:

func visit(before: Builder.Visitor?, after: Builder.Visitor?  = nil) {
  Builder.visit(before, after)
}

visit accepts two closures which are applied before and after visiting a node’s children, respectively. Here is a simplified visitor for generating HTML markup:

visit( {
  let node = $0
  let r = repeat(" ", node.level*2)
  var tag = "(r)<(node.name)"
  for a in node.attr { tag += " "(a.0)"="(a.1)"" }
  tag += ">"
  if let v:AnyObject = node.value { tag += "(v)" }
  println(tag)
  },
  {
    let node = $0
    let r = repeat(" ", node.level*2)
    var tag = "(r)</(node.name)>"
    println(tag)
  } )

Notes

  1. Swift closures aren’t dynamic in that variables and methods in a closure are bound at compile time. This is in contrast with dynamic closures in Groovy for example, where methods calls within closures are’t checked at compile time and an exception can be thrown at runtime. Further, references to instance members are required to be explicit with a self. prefix, which only adds to verbosity.

  2. In this example, tree node methods such as div are kept in the global namespace to avoid self. prefix clutter.

Source

The full source listing can be found here.

Key Value Observation in Swift

With XCode Beta 5, this article is outdated. See updated article .

Documentation for KVO in Swift is listed as information forthcoming.

We favor KVO as a means for MVVM / reactive binding so we poked under the hood to see what it takes to support KVO with the current release of Swift.

Let’s start with defining a Publisher object with a property someProperty which we will observe from a Subscriber object.

import Foundation

class Publisher : NSObject {
  var someProperty = 100

  override var description: String { return "Publisher:{someProperty: (someProperty)}" }
}

As an aside, since we’re inheriting from NSObject overriding the description property gives us pretty printing abilities with println.

var pub = Publisher()
println("(pub)")

We’ll use an instance of the Subscriber class to listen for changes on Publisher.someProperty.

class Subscriber : NSObject  {
  override func observeValueForKeyPath(keyPath: String!, ofObject object: AnyObject!, change: NSDictionary!, context: CMutableVoidPointer) {
    println("observeValueForKey: (object)")
  }
}

var sub = Subscriber()

pub.addObserver(sub, forKeyPath: "someProperty", options: nil, context: nil)

Ordinarily the call addObserver should succeed and our subscriber should start receiving messages from the publisher. Instead, the REPL spits out the following error:

objc[17599]: no class for metaclass 0x10286f410
Playground execution failed: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
* thread #1: tid = 0xa8623, 0x00007fff8569375b libobjc.A.dylib`_objc_trap(), queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
  * frame #0: 0x00007fff8569375b libobjc.A.dylib`_objc_trap()
    frame #1: 0x00007fff8569389b libobjc.A.dylib`_objc_fatal + 195
    frame #2: 0x00007fff8568c6a1 libobjc.A.dylib`_class_getNonMetaClass + 454
    frame #3: 0x00007fff8568d1f8 libobjc.A.dylib`_class_resolveMethod + 99
    frame #4: 0x00007fff856982c8 libobjc.A.dylib`lookUpImpOrForward + 286
    frame #5: 0x00007fff8568acb8 libobjc.A.dylib`class_getInstanceMethod + 52
    frame #6: 0x00007fff866bc277 Foundation`+[NSObject(NSKeyValueObservingCustomization) keyPathsForValuesAffectingValueForKey:] + 213
    frame #7: 0x00007fff866bbf21 Foundation`-[NSKeyValueUnnestedProperty _givenPropertiesBeingInitialized:getAffectingProperties:] + 141
    frame #8: 0x00007fff866bbc26 Foundation`-[NSKeyValueUnnestedProperty _initWithContainerClass:key:propertiesBeingInitialized:] + 145
    frame #9: 0x00007fff866bb7d9 Foundation`NSKeyValuePropertyForIsaAndKeyPathInner + 281
    frame #10: 0x00007fff866bb47b Foundation`NSKeyValuePropertyForIsaAndKeyPath + 169
    frame #11: 0x00007fff866e16d7 Foundation`-[NSObject(NSKeyValueObserverRegistration) addObserver:forKeyPath:options:context:] + 80

Apparently, even through our Publisher object inherits from NSObject, two class methods required for KVO are missing, namely keyPathsForValuesAffectingValueForKey and automaticallyNotifiesObserversForKey.

Let’s add these methods to Publisher with a default implementation:

extension Publisher {
  override class func keyPathsForValuesAffectingValueForKey(key: String!) -> NSSet! {
    return nil
  }

  override class func automaticallyNotifiesObserversForKey(key: String!) -> Bool {
    return true
  }
}

Now our subscriber receives change notifications from the publisher:

println("Changing value to 101")
pub.someProperty = 101

//Output
Changing value to 101
observeValueForKey: Publisher:{someProperty: 101}

Syntactic Sugar

With a little bit of syntactic sugar, we can clean up the subscription code to look like this:

pub.addSubscriber("someProperty") { println("callback: ($0), ($1)") }
println("Changing value to 102")
pub.someProperty = 102

//Output
Changing value to 102
callback: someProperty, Publisher:{someProperty: 102}

And the code:

typealias ObserverCallback = (String, AnyObject) -> ()

class SimpleSubscriber: NSObject {
  var callback: ObserverCallback

  init( cb: ObserverCallback ){
    self.callback = cb
  }

  override func observeValueForKeyPath(path: String!, ofObject object: AnyObject!, change: NSDictionary!, context: CMutableVoidPointer) {
    callback(path!, object!)
  }
}

extension Publisher {
  func addSubscriber(path: String, sub: NSObject) {
    self.addObserver(sub, forKeyPath: path, options: nil, context: nil)
  }

  func addSubscriber(path: String, sub: ObserverCallback ) {
    var wrapped = SimpleSubscriber(sub)
    self.addObserver(wrapped, forKeyPath: path, options: nil, context: nil)
  }
}

Regular Expressions in Switch Statements

Expression Patterns in Swift appear in switch statement case labels. The expression represented by the expression pattern is compared with the value of the switch statement input using the Swift standard library ~= operator. The matches succeeds if the ~= operator returns true. By default, the ~= operator compares two values of the same type using the == operator. It can also match an integer value with a range of integers in an Range object. The ~= operator can be extended to provide custom expression matching behavior.

In this post, we will extend the ~= operator to match the String type with regular expressions (specifically NSRegularExpression). Combined with bit of syntactic sugar, we will be able to write compact pattern expressions like this:

switch("apple"){
  case "appl": println("string")        
  case ~/"a..le": println("regex")  // Match!
  default: println("none")
}

//Output: regex

In this example, the switch statement matches the second case which is a regular expression a..pl.

Extending the ~= Operator

We can extend the ~= Operator to match NSRegularExpression:

func ~=(pattern: NSRegularExpression, str: NSString) -> Bool {
  return pattern.numberOfMatchesInString(str, options: nil, range: NSRange(location: 0,  length: str.length)) > 0
}

The pattern matching ~= operator is not commutative. A reverse matcher must be defined for cases where the input to the switch statement is a regular expression and is being compared to string via a case statement.

We can now introduce a regular expression in a switch statement to and check for matches:

switch("apple"){
  case "appl": println("string")
  case NSRegularExpression(pattern: "a..le", options: nil, error: nil): println("regex")
  default: println("none")
}

//Output: regex

Regex Creating Operator

Borrowing from Groovy et al., we can define a regex creating operator which accepts a string and returns a NSRegularExpression object (using default options, for now).

operator prefix ~/ {}

@prefix func ~/(pattern: String) -> NSRegularExpression {
  return NSRegularExpression(pattern: pattern, options: nil, error: nil)
}

This lets us create regex objects with the compact notation from the first example.

~/"\\wpple" ~= "apple is a fruit"     //Boolean: true

Note that the regex group \w is escaped in the string literal.

In Swift, custom prefix and postfix operators cannot specify precedence, requiring the use of parenthesis: (~/”a..pl”).numberOfMatchesInString(…)

List Traversal with Discriminated Unions in Swift

… by decoupling how a function recurses over data from what the function actually does, we reduce cognitive overhead and can focus entirely on the core behavior of our recursive functions. No matter the structures in question—lists, directory hierarchies, control flow graphs, database records—recursion schemes bring us an orderly and predictable way to traverse them.
Link

Swift supports Discriminated Unions as first class citizens within the language. This creates interesting possibilities especially with respect to pattern matching. Here is an example of recursive traversal of a native Array with a discriminated union:

let list = [1,2,3,4,5]

func sum( l : Array<Int> ) -> Int {
  switch( l as Structure ) {
  case let .Cons(head, tail) : return head + sum(tail)
  case .Empty: return 0
  }
}

println(sum(list))  //Output: 15

Here the enum Structure is representation of contents of the list as a head::tail structure.

enum Structure<T>{
  case Cons( T, Array<T> )
  case Empty
}

The enumeration has two cases:

  • Empty: represents a list with no elements.
  • Cons: represents a list as two parts: a head element for the first element in the list and a tail list comprising the remaining list elements.

Finally, an Array extension provides type conversion between a list and its corresponding Structure representation:

extension Array {
  func __conversion() -> Structure<T> {
    switch(count) {
    case 0: return Structure.Empty
    case 1: return Structure.Cons(head, [])
    default: return Structure.Cons(head, tail)
    }
  }

  //Returns the tail of this list using copy semantics
  var tail : Array<T> {
  var t = Array<T>()
    for x in self[1..count] { t.append(x) }
    return t
  }

  //Returns the head element of the list (count must be >=1)  
  var head : T { return self[0] }
}

Opt-in Type Conversion Method in Swift

Swift supports opt-in to convert an object to a type via the instance method __conversion(). This method can used through the as operator and is overloadable to support conversion to multiple types:

class X {
  func __conversion() -> String { return "as a string!" }
  func __conversion() -> Double { return 101.2 }
}

println( X() as String )  //Output: as a string!

var d : Double = X()      
println( d )              //Output: 101.2

Discriminated Unions in Swift

In Swift, enumerations have built in support for Discriminated Unions through what they call Associated Values.

From MSDN:

Discriminated unions provide support for values that can be one of a number of named cases, possibly each with different values and types. Discriminated unions are useful for heterogeneous data; data that can have special cases, including valid and error cases; data that varies in type from one instance to another; and as an alternative for small object hierarchies. In addition, recursive discriminated unions are used to represent tree data structures.

A discriminated union is a simpler alternative to a small object hierarchy. For example, the following discriminated union could be used instead of a Shape base class that has derived types for circle, square, and so on.

import Darwin

enum Shape {
  case Rectangle(Double, Double)
  case Circle(Double)
  case Square(Double)
  case EquilateralTriangle(Double)


  var area : Double {
    switch(self)
    {
    case .Rectangle(let w, let h): return w * h
    case .Circle(let r):  return M_PI * r * r
    case .Square(let x):  return x * x
    case .EquilateralTriangle(let s): return sqrt(3.0) / 4.0 * s * s
    }
  }
}

The area of a rectangle is:

let s1 = Shape.Rectangle(10, 20)
println(s1.area) //Output: 200.0

Coming Soon: Recursion

Recursive Discriminated Unions (where an associated value is the enum itself) can be used for tree structures. It’s unclear if Swift supports such recursion because the REPL crashes with a segmentation fault. We’ll post an update when more information is available.

Recursion looks like this:

enum Tree {
  case Tip
  case Node(Int, Tree, Tree)

  var sumTree: Int {
    switch self {
      case .Tip: return 0
      case let .Node(value, left, right): return value + left.sumTree + right.sumTree
    }
  }
}

let tree = Tree.Node(0, Tree.Node(1, Tree.Tip, Tree.Tip), Tree.Node(3, Tree.Tip, Tree.Tip)), Tree.Node(4, Tree.Tip, Tree.Tip))
println(tree.sumTree) //Output: 10

The example above creates this tree:

Function Composition & Pipelining Operators in Swift

In functional programming, the composition of two functions function1 and function2 is another function that represents the application of function1 followed the application of function2. Pipelining enables function calls to be chained together as successive operations. The difference is that composition returns a function for future application whereas pipelining applies the function chain immediately. Here, we’re borrowing F# operator definitions for both composition and pipelining.

Composition

First, an example. Lets define three functions, plusOne, timesTwo and minusThree to do exactly what their names suggest. We then compose them in that order to create a composed function c1 and finally apply c1 on Int(10).

func plusOne (x:Int) -> Int { return x + 1 }
func timesTwo (x:Int) -> Int { return x * 2 }
func minusThree (x:Int) -> Int { return x - 3 }

var c1 : (Int) -> (Int) = plusOne >> timesTwo >> minusThree
println( c1(10) )  //Output: 19

In this example, we’ve using the &gt;&gt; operator (F#) to imply left to right composition. Composition in reverse (right to left) looks like this:

var c2 : (Int) -> (Int) = plusOne << timesTwo << minusThree
println( c2(10) ) //Output: 15

Composition Operators

The (overloaded) operator are defined like this:

operator infix >> { associativity left }
operator infix << { associativity right }

@infix func >> <T1, T2, T3> (left: (T1)->T2, right: (T2)->T3) -> (T1)->T3 {
  return { (t1: T1) -> T3 in return right(left(t1)) }
}

@infix func << <T1, T2, T3> (left: (T3)->T1, right: (T2)->T3) -> (T2)->T1 {
  return { (t2: T2) -> T1 in return left(right(t2)) }
}

We need to specify associativity to ensure sequence of application for our operators.

Pipelining

Here is an example of function pipelining.

println( 10 |> plusOne |> timesTwo |> minusThree )   //Output: 19
println( plusOne <| timesTwo <| minusThree <| 10 )   //Output: 15

Pipelining Operators

Again borrowing from F#, we define pipelining like this:

operator infix |> { associativity left }
operator infix <| { associativity right }

@infix func |><T,U> (left: T, right: (T)->U ) -> U {
  return right(left)
}

@infix func <| <T, U> (left: (T)->U, right: T ) -> U {
  return left(right)
}

Tuples

Lets throw in a couple of additional operators to be used with tuples:

operator infix ||> { associativity left }
operator infix |||> { associativity left }
operator infix <|| { associativity right }
operator infix <||| { associativity right }

@infix func ||><T1, T2, U> (left: (T1,T2), right: (T1, T2)->U ) -> U {
  return right(left)
}

@infix func |||><T1, T2, T3, U> (left: (T1,T2,T3), right: (T1, T2, T3)->U ) -> U {
  return right(left)
}

@infix func <|| <T1, T2, U> (left: (T1,T2) -> U, right: (T1,T2) ) -> U {
  return left(right)
}

@infix func <||| <T1, T2, T3, U> (left: (T1,T2,T3) -> U, right: (T1, T2, T3) ) -> U {
  return left(right)
}

And finally an example of tuples in pipelining:

func append(a: String, b: String) -> String { return "(a).(b)"}

println( ("x","y") ||> append )  //Output: x.y

In the next example, we inject a point (10, 10) in the pipeline which computes the length (assuming a (0,0) origin), multiplies the scalar by two and adds 1. Note that efficiency isn’t the overarching consideration of these example.

func length(x: Double, y: Double) -> Double { return sqrt(x * x + y * y) }

(10, 10) ||> length |> timesTwo |> plusOne |> println   //Output: 29.2842712474619
println <| plusOne <| timesTwo <| length <|| (10, 10)    //Output: 29.2842712474619

In the example above, println is included as part of the pipeline (see comment below).