blog

Photo of Checkpoint Charlie, Friedrichstraße, Berlin, Deutschland by Etienne Girardet on Unsplash

Swift Journal: Day One

by

Learning a language is sometimes confusing

I decided to jump right into Swift without doing any research into the writing done over the past month so that my opinions were not colored. My background is in the C/C++ and, lately, Objective-C of which I’ve become quite fond. I approached Swift with the hope that it would provide the same kind of  power I’ve found Obj-C/Cocoa to have, but with some modern newness brought in from other successful languages. It is too early, and the tools are too fresh, for me to draw conclusions on how useful it will be for production code other than that it does look promising.

TL;DR after the jump wherein I detail experiences with the Xcode playground and a small Swift based iPhone app.

Smooth

  • It took only about a ten minute glance over the language docs to be able to port my C code to Swift
  • Explicit control of nil behavior such as when to require non-nil objects
  • Enums are first class types along with classes and structs
  • Property system like Objective-C’s with custom getters and setters
  • Aspect oriented features on the properties, didGet and didSet handlers
  • The beauty of every callable block being a closure: global functions, nested functions, class methods and traditional lambda style closures
  • Syntax shortcuts when they make sense like leaving off get for a readonly calculated property or return for one line closures

Friction

  • Tools: the playground, compiler, all are early versions and have problems; but we know that, and that’s why we will be shipping Obj-C apps for a while
  • The syntax is a step back from the terseness of Objective-C towards the explicitness of C++ (Python users are laughing right now; and yes Obj-C names are wordy, read that as “readable”, but the syntax mostly stays out of the way)
  • No headers; wade through the implementation to find the declarations you need (somehow Swift’s type declaration file avoids this)
  • I don’t think I like the declaration style var x: Int = 4 which reads like “assign something to SomeType” to me
  • It took some fumbling to figure out how to define outlets and actions in my first Cocoa Touch app (where are these language extensions documented?)

The most obvious place to start in Xcode was the REPL environment, the Playground. This is what gave the Swift unveiling demo the wow factor with its blimps traveling on sinusoidal waves, and changes taking effect immediately. Yes, you can debug some code here, but don’t expect to do more than light computation.

The Swift Playground template comes with some Hello World code which doesn’t give many clues about syntax. I found  Apple’s Swift language guide and skimmed over the basics. I decided to start by porting some C code I had for calculating Pi through various methods. It was easy to translate into Swift. let defines is a constant, var is a mutable variable. func introduces a function definition. Types come after names in declarations. Functions use a cool -> to denote the return type after the familiar parameter declarations.

The rest is mostly C like, and mostly behaves as expected. Chris Lattner, the language designer, put the safety on that gun pointing at your foot: switch case statements don’t fall through by default, and arithmetic operators fail on overflow by default. Not to mention the very sane nil behavior mentioned above.

// Gregory-Leibniz approximation of π
// See https://gist.github.com/jbagley/9558879 for C implementation
var factor = -1.0
var piAccumulation = 4.0
var denom = 3.0
// If using in a playground beware this many iterations, try 2500 instead.
for i in 1…500000
{
  piAccumulation += factor * (4.0 / denom)
  denom += 2.0;
  factor *= -1.0;
}
println(piAccumulation)

Once I had my code correct, the REPL did its thing and immediately ran without my prompting. I expected it to complete in a couple seconds at most. Unfortunately the playground couldn’t really handle the two billion iterations this code needs to get 10 correct digits of π. It could barely do 5,000 iterations, slowing down to a crawl after about 2,500. Anything more than that had my recent model Mac Mini with 16 GB RAM gasping for breath, and Xcode was unresponsive.

The reason I knew exactly when the playground was crippled was exactly the cause of the performance degradation. To the right of almost every statement is some trace output such as the number of times a statement was executed. You can even get a graph of a variable’s values over time. Everything is tracked and after all that information piles up, playtime grinds to a halt. Great for debugging, not great for a quick and dirty computation session.

I tried a different version using only constants and tail recursion. Fewer things to track should result in more performance. It could do 5,000 iterations before it hit its crawling point and took around 15 seconds to do 10,000 iterations.

// Recursive implementation
func LeibnizPiApproximationFunc(#afterIterations: Int) -> Double
{
   // See http://stackoverflow.com/questions/24270693/nested-recursive-function-in-swift
   var ApproxPi: (Double, Double, Double, Int) -> Double = { _ in return 0.0 }
   ApproxPi =
   {
      (denom : Double, factor : Double, piAccum: Double, iteration: Int) -> Double in
      if (iteration == 0)
      {
         return piAccum
      }
      return ApproxPi(denom + 2.0,
         factor * -1.0,
         piAccum + (factor * (4.0 / denom)),
         iteration - 1)
   }
   return ApproxPi(3.0, -1.0, 4.0, afterIterations)
}
let i = 6000
println(LeibnizPiApproximationFunc(afterIterations: i))

To confirm that performance is a Playground-only problem I created an iOS app to perform the approximation and allow editing of the number of iterations. Here 500,000 iterations was noticeable, but less than a second. More interesting was how familiar it felt to write up a view controller. I didn’t try 2 billion, but 2 million completed within a second or two on an iPad 4.

Reddit as usual has some interesting things going on to help you try it out yourself. I think I will go there now.

Cocoaphony also has interesting posts on Swift.

+ more

Accurate Timing

Accurate Timing

In many tasks we need to do something at given intervals of time. The most obvious ways may not give you the best results. Time? Meh. The most basic tasks that don't have what you might call CPU-scale time requirements can be handled with the usual language and...

read more