Tuesday, June 3, 2014

The Swift (short) history

The language announced at WWDC yesterday came as a big surprise to almost everyone. At Chris Lattner's Homepage you can find a short summary on the history of the Swift programming language. He started work on the language in July 2010, and it became a major focus for the Apple Developer Tools group 3 years later. Other people started to contribute to the project in late 2011. He mentions Objective-C, Rust, Haskell, Ruby, Python, C#, CLU as inspirations for the language itself, and Bret Victor's ideas and Light Table as inspiration for Xcode Playgrounds (Playgrounds allow you to edit the code listings and see the result immediately). He says that Playgrounds and REPL (Read-Eval-Print-Loop) were a personal passion of him. REPL is an interactive version of Swift built into the debugging console of Xcode. You can use Swift syntax to directly evaluate and interact with your running app in the Xcode console.

A new language: Swift from Apple

I've just developed my first application in Swift, the new language announced by Apple yesterday. I downloaded the Swift book on my iPad during the Keynote, and started programming immediately. When I got hold of Xcode beta 6 I got it running in seconds.

My first impression: Swift is a modern language. It is closely related to popular scripting languages, like Python and Ruby, but is is a compiled language. It is also a type safe language, but when the type is obvious, the programmer doesn't have to bother with it (the compiler infer its type). The Swift syntax is easy to read and not strange and new. Important features that often make the syntax of a language complex and unreadable is actually quite clear in Swift (including generics, protocols and extensions). This is a class Amplifier implementing a protocol VolumeControl:

protocol VolumeControl {
    var level: Int { get }
    mutating func increase() -> Int
    mutating func decrease() -> Int
    mutating func mute()
}

class Amplifier: VolumeControl {

    var level: Int {
    didSet {
        if level < 0 { level = 0 }
    }
    }
    var step: Int
    var source: String

    init(level: Int = 0, step: Int = 1, source: String = "dvd") {
        self.level = level
        self.step = step
        self.source = source
    }

    func increase() -> Int {
        self.level += step
        return self.level
    }

    func decrease() -> Int {
        self.level -= step
        return self.level
    }

    func mute() {
        self.level = 0
    }

    func selectSource(source: String) {
        self.source = source
    }

}

The protocol specifies one attribute with a getter and three methods. The class implements this protocol by providing access to the attribute and implementations of the methods. The didSet on the property is used to ensure that its value is never negative. The default values in the init method arguments means that these arguments are optional. We can create instances of Amplifier like this:

var a1 = Amplifier()
var a2 = Amplifier(level: 3)
var a3 = Amplifier(level: 1, step: 2)
var a4 = Amplifier(level: 10, step: 5, source: "phono")

But more interestingly, we can access the implementation through a protocol (and only have access to what the protocol provides, not everything from the class instance):

var v: VolumeControl = a1
var level = v.increase()
if level > 100 {
    v.mute()
    level = v.level
}

A good place to start is A Swift Tour. More on Swift later.

Sunday, April 20, 2014

How to use Interface Builder to create OS X Cocoa applications with Python

When programming Python I prefer to use native GUI on OS X. Very Simple OS X Cocoa Application using Python and Interface Builder is a good place to start. The example works with Python 3 on OS X 10.9.2 when PyObjC is installed following the instructions in one of my earlier posts: Python 3 and PyObjC.

Perl modules on Mac

I needed a few Perl modules that weren't installed on the standard Perl installation on my Mac (OS X 10.9.2). In How to install Perl modules on Mac OS X in 4 easy steps I found all the details needed. I didn't need to do step 1 (and 1.5) since this is the first thing I do on every new Mac instance. To summarize what I did in 3 steps to install the two modules I needed:

  1. sudo perl -MCPAN -e 'install Bundle::CPAN'
  2. sudo perl -MCPAN -e 'install Text::Iconv'
  3. sudo perl -MCPAN -e 'install HTML::TokeParser::Simple'

Wednesday, January 8, 2014

A suggestion for backup on Mac

A lot of options for backup on your Mac exists. I use Time MachineBackblaze, Crash PlanTransporterCarbon Copy Cloner, and other tools for different types of backup on different Macs. The challenging backup for me are my pictures. I want at least one backup not in my house. The size of this backup is large, and since I am using Aperture, the meta-data of the file-system has to be preserved. Large amount of data and continuous minor updates of the data also suggest that the backup solution should support incremental backups. My first thought was to use two Transporters, one at home and one at my office. This will give me the option to have two (or more) working copies of the Aperture data and everything will just work. However, this doesn't work because the Transporter doesn't support HFS+ (with meta-data), and Aperture uses the features of the file system extensively.

Newer versions of rsync does support HFS+ meta-data. I am currently using version 3.0.9 (3.1.0 has an annoying bug on OS X). OS X 10.9.1 comes with rsync version 2.6.9, and this is to old for our purpose. I installed version 3.0.9 using Homebrew.

The magic option of rsync that we need is -X, preserve extended attributes. We will also use the -a option to transfer the files in archive mode (ensures that symbolic links, devices, attributes, permissions, ownerships, etc. are preserved in the transfer). You might also add the -H option to preserve hard links and -v for verbose mode. If you are brave you might even add the --delete option. This will remove files at the backup folder that is no longer at the source folder. If you don't use this option you might end up with more files in the backup folder. See the manual pages of rsync for more details.

To back up a folder (the source folder with my Aperture library) I will use the following rsync command:

rsync -avXH --delete source-folder backup-folder

In my case the source and backup folders are located on different computers at home and work. I prefer that the file transfer over the network is using ssh. To do this I add the option --rsh=ssh. So from my home computer I will use the following command to backup my Aperture library to the backup folder of my work computer:

rsync -avXH --delete --rsh=ssh Pictures my.work.com:backup

I had to install rsync version 3.0.9 on both computers and I had to configure the remote computer to use that version of rsync and not the pre-installed version. You can do this command to check what version of rsync that will be executed on the remote computer my.work.com:

ssh my.work.com "rsync --version"