Do you need help on a specific subject? Use the contact form (Request a blog entry) on the right hand side.

2015-04-27

Book review: Functional Programming in Swift

The bloggers at objc.io have published the book "Functional Programming in Swift". Being a sucker to learn new concepts, I bought it last week for some inspirational reading.

So is it any good?

Hmm, though question...

I have absolutely learned something from it, mission accomplished.

Does it do a good job of explaining functional programming?

I really don't know. I am no software expert in the sense of language techniques. I am a software engineer that writes software for a living. Though I like thinking about (software) engineering as a discipline, I have no affiliation with any major institution or philosophy in that field. So I do not really know what functional programming is. Hence I cannot compare the book to anything I already know about the field.
What I gather from the book, its no real 'biggie'. Sure there are some neat things in looking at software development though the lens of functional programming, but it is not a paradigm mover. Like -for example- OO was to procedural development. Based on the book, functional programming is probably of great interest to language developers and scientists, but not so much to actual developers that make their living writing software.
That is not to say that it is something you can skip over. Imo that would be the wrong thing to do. Every software developer should know what functional programming is to have another tool in his box. It is very useful that way. And there are some special niches where it is really handy.

As to the book, it is clearly written by someone who knows a lot about the field. Unfortunately the pace is rather quick, and grokking the book on a first read is not something I can do. The last few chapters went largely over my head. So I will have to revisit that once the parts that did register have settled.

So what did I like about the book?

I really liked the part where optionals and enums are explained. It is probably too steep for beginners, but when you have a working knowledge of optionals and enums, this is really something you should read. It could easily lift you to the next level.

What surprised me

Pretty much the same as above: apparently optionals, enums, generics, generators and sequences are considered part of functional programming. I did not expect that. But it is a very useful and interesting part of the book.
Another thing is that much of the concepts in the book are imo relatively seldom used by novices and intermediate developers. As such, introducing functional programming will (IMO) produce code that will be hard to read by novices and intermediate developers. Usually code becomes better readable by advanced programming techniques, but I found that many of the more advanced examples are pretty difficult to "read". Yes, they can all be understood, but it is not an "easy read". I am thinking here of situations where a junior developer has to take over work from a well seasoned developer. I am rather sure that the junior will need some hand-holding at first if the senior used a lot of functional programming techniques.

Is it worth its money?

Hmm, another though question.

It basically boils down to how much you value your time. Reading the book saved me a few weeks -if not months- of scrounging the web. While $35-$40 is a lot of money for the content, it gives me some kind of "closure" (LOL!) on the topic of functional programming. That in itself makes it worth its money too me. If you are not after such immaterial things, the book is probably too expensive.

What would I like to see different?

Hmm, maybe a slower pace and easier (smaller) examples. And a lower price of course!

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

Functions returning a value or an error: use a tuple or an enum?

Many functions will either return a value or an error. Sometimes the error can simply be returned as a nil value. In that case the solution is simple: use an optional value as the return value.

But sometimes the function needs to return information about the error that occurred. Mostly to inform the user of some unexpected situation. In that case an optional value is of little use: the function needs to return either the successful value or the error information.

I am currently torn between two possible solutions for this: one is to return a tuple, like this:

func readFile(path: String) -> (result: String?, errorMessage: String?) {...}

the other is to introduce an enum to distinguish between the possible values like this:

enum ReadFileResult {
    case Success(String)
    case Error(String)
}

func readFile(path: String) -> ReadFileResult {...}

A full example using tuples:


func readFile(path: String) -> (result: String?, errorMessage: String?) {
    var error: NSError?
    if let result = String(contentsOfFile: path, encoding: NSUTF8StringEncoding, error: &error) {
        return (result, nil)
    } else {
        let errorMessage = error?.localizedDescription ?? "File read error without localized description"
        return (nil, errorMessage)
    }
}

let (fileContent, errorMessage) = readFile("/Users/Rien/MyFile.txt")

if let content = fileContent {
    // do stuff with file contents like:
    println(content)
} else if let message = errorMessage {
    // do stuff with error message like:
    println(message)
} else {
    fatalError("Impossible")
}

rather short and sweet imo.

A full example using an enum:


enum ReadFileResult {
    case Success(String)
    case Error(String)
}

func readFile(path: String) -> ReadFileResult {
    var error: NSError?
    if let result = String(contentsOfFile: path, encoding: NSUTF8StringEncoding, error: &error) {
        return ReadFileResult.Success(result)
    } else if let message = error?.localizedDescription {
        return ReadFileResult.Error(message)
    } else {
        return ReadFileResult.Error("File read error without localized description")
    }
}

let result = readFile("/Users/Rien/MyFile.txt")

switch result {
case let .Success(content):
    // do something with content like:
    println(content)
case let .Error(message):
    // do something with error message like:
    println(message)
}

this is perhaps a bit easier to read, but more verbose as we have to introduce a new type (enum). In my mind there is no clear winner. The first one is simpler to implement, but needs the fatalError handling, while the second one is more verbose but avoids the fatalError.

In an API, I would use the enum solution, but when implementing something in-situ I would probably go for the tuple.

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

2015-04-11

Swift Code Library: Detecting mouse clicks, single double or triple.

2015.05.07: Alert! it seems that it can and does happen that the clickcount for a draggingEnded event is sometimes 1. Hence the function that handles a single-click should also check if it is in fact a draggingEnded.

2015.04.13: Completely replaced the previous code with a new and better implementation.

When handling mouse-clicks in an application that must differentiate between single and double-clicks (and even triple-clicks) is a job that just begs for code reuse. As you may known, when the application receives a "triple-click-mouse-up" event, it has already received a single-click-mouse-up event and a double-click-mouse-up event. Any double-click-mouse-up or triple-click-mouse-up event may have to cancel the operation of the preceding event.

In this post I have included the source code for BRMouseUpView, a child class of NSView that replaces the mouseUp function with a "filteredMouseUp" function. The filteredMouseUp function will only be called for the last mouseUp event in a sequence. Be aware that this also means that any mouseclick action is called with a small delay. This delay depends on the "Double-Click speed" setting of the user in his "Mouse" Control Panel. This may result in an unacceptable user experience. If you use this code, please make sure that you application remains usable even when the user sets the double-click speed to its slowest value.

The code:

import Foundation
import Cocoa
import Dispatch


/// This class replaces the "mouseUp" function with a "filteredMouseUp" function. The filteredMouseUp function is only called for the last mouseUp even in a sequence of mouseUp events. A sequence of mouseUp events is defined by the "doubleClickInterval" (which is set by the user in the mouse control panel) and the maximum number of mouseUp clicks in a sequence as defined by the variable "maxClickCount".
///
/// Note: A mouseUp event for the end of a dragging sequence has a clickCount of 0, this mouseUp call is not filtered out!
///
/// Note2: By default the maxClickCount is set to 2, limiting the detection to drag-end-clicks, single-clicks and double-clicks. Set this variable to your desired maximum sequence length. Note that filteredMouseUp is never called for an event with a clickcount higher than this number.
//
// A suggested use of the filteredMouseUp is as follows:
//
// override func filteredMouseUp(theEvent: NSEvent) {
//     switch theEvent.clickCount {
//     case 0: draggingEnded(theEvent)
//     case 1: singleMouseClick(theEvent)
//     case 2: doubleMouseCLick(theEvent)
//     etc...
//     }
// }

class BRMouseUpView: NSView {
    
    
    // The double click time as defined by the user in the system preferences panel.
    
    final let systemDoubleClickDelay = NSEvent.doubleClickInterval()

    
    // The last mouse up event
    
    private final var lastMouseUpEvent: NSEvent!
    
    
    // Speed up the user experience by defining the maximum number of clicks in a sequence.
    // "filteredMouseUp" will not receive events with a higher clickCount than defined in this variable.
    
    final var maxClickCount = 2
    
    
    // This function will execute the last mouseUp in a sequence of mouseUp events
    
    private func delayedMouseUpAction(event: NSEvent) {
        

        // Check if a newer event is present in the lastMouseUpEvent. Done by comparing the clickcount.
        
        if event.clickCount >= lastMouseUpEvent.clickCount {
            
            
            // It is the same, no new mouseUp was received since this function was pushed on the queue
            
            filteredMouseUp(event)
        }
        
        // else: no else, if the old clickcount is lower than the lastMouseUpEvent clickcount, this call should be ignored.
    }
    
    
    // Handles the mouseUp event. Should not be overriden (there should be no need anymore to override this implementation).
    
    final override func mouseUp(theEvent: NSEvent) {
        
        dispatch_async(dispatch_get_main_queue(), {
            
            [unowned self] in
            
            
            // Special case: end of dragging, always call the filteredMouseUp for this case
            
            if theEvent.clickCount == 0 {
                self.filteredMouseUp(theEvent)
                return
            }
            

            // Store the latest event, this is used to discard older events
            
            self.lastMouseUpEvent = theEvent

            
            // Speed up the user experience for the max click count
            
            if theEvent.clickCount == self.maxClickCount {
                
                self.filteredMouseUp(theEvent)
                return
                
            } else if theEvent.clickCount < self.maxClickCount {
            
                // Dispatch this event, it will be canceled if another mouseUp event occurs within the doubleClickInterval.
                
                let executionTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1_000_000_000 * self.systemDoubleClickDelay))
                dispatch_after(executionTime, dispatch_get_main_queue(), {
                    [unowned self] in self.delayedMouseUpAction(theEvent)
                })
            }
        })
    }

    
    /// Handles a double mouse click on the mouse-up event. To be overriden by a child class

    func filteredMouseUp(theEvent: NSEvent) {
        // Remove or replace as necessary
        log.atLevelWarning(id: 0, source: "BRMouseHandlingView.handleMouseUpEvent", message: "Childview from BRMouseHandlingView should implement handleMouseUpEvent")
    }

}

PS: I use SwifterLog as the logging framework, if you use something else, please adjust the logging calls where needed.

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

2015-04-08

Swift Code Library: functions minmax and clippedMinMax

You are probably well aware of the functions:

func min<T : Comparable>(x: T, y: T) -> T
func max<T : Comparable>(x: T, y: T) -> T

When implementing functions that need a result in order we need to call both functions like:

let a = max(x, y)
let b = min(x, y)

Which is a bit laborious given that Swift has tuples that can be used to return values.

It would be nice to be able to write this as:

let (a, b) = minmax(x, y)

This is of course not all that difficult, I use the following implementation:

func minmax<T: Comparable>(first: T, second: T) -> (min: T, max: T) {
    let rmin = min(first, second)
    let rmax = max(first, second)
    return (rmin, rmax)
}

In addition, often I also have to safeguard the return values against minimum and maximum values. For that I use the following function:

func clippedMinMax<T: Comparable>(lowLimit: T, first: T, second: T, highLimit: T) -> (min: T, max: T) {
    let amin = max(lowLimit, min(highLimit, first))
    let amax = min(highLimit, max(lowLimit, second))
    return minmax(amin, amax)
}

This function can be called for example as follows:

let (a, b) = clippedMinMax(0, x, y, 100)

The function guarantees me that 'a' and 'b' will be in order, and that neither 'a' nor 'b' will be lower than 0 or higher than 100.

PS: I called the first function minmax rather than minMax because of similarity with the standard min and max functions. The clipped version deviates enough to fall back to my normal naming conventions.

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

2015-04-07

Swift extensions: NSEventModifierFlags functions isSet and isNotSet

This extension makes working with the NSEventModifierFlags a little easier by hiding the verbose testing code inside a test function.

extension NSEventModifierFlags {
    
    func isSet(bit: NSEventModifierFlags) -> Bool {
        return self & bit == bit
    }
    
    func isNotSet(bit: NSEventModifierFlags) -> Bool {
        return !isSet(bit)
    }

}

After this the code to test for a modifier becomes very readable:

if theEvent.modifierFlags.isSet(.ShiftKeyMask) { ... }


Happy coding

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

2015-04-06

Adding menu items and their actions

When developing OS-X applications its often necessary to create additional menu items and connect these to their handlers in our code.

I don't know about you, but I keep forgetting how to do this, hence this post as a reminder so that I don't have to search for it for the next project ;-)

The basic idea is to add the necessary functions to the FirstResponder and connect the menu items to the first responder.
The first responder can of course be found in your xib file, the MainMenu.xib.

In Xcode 6.3 the sequence of actions is the following:
  1. Open MainMenu.xib in Xcode.
  2. Select the First Responder.
  3. Select the "Attributes Inspector"
  4. An empty field "User Defined" is now visible. Click the "+" button to add new actions. These actions will be the name of your new functions. Suppose you want to add a menu item "Transpose Words" to the Edit Menu, and you have defined the function "transposeWords" in your NSView child. (This can be any class that can become the first responder, but we will use a child class of NSView here). The function must have the signature "name(sender: AnyObject?), after clicking the "+" sign, select the new name (called "action:") and rename it to "transposeWords:" (beware the colon sign!). Leave its parameter as "id".
  5. Add the menu & menu item as necessary. In the example add in the "Edit" menu an item named "Transpose Words". Open the Menu, open the Edit Item menu, open the Menu and now add a Menu Item through either drag & drop from the Utilities or by simply copy & paste of an existing item in the menu.
  6. Rename the new menu item "Transpose Words" and give it a Key Equivalent if necessary.
  7. Select the "Outlets" inspector.
  8. Remove any existing connections (possible if you used C&P)
  9. Drag a connection from the little circle behind "Sent actions->Selector" to the First Responder (in the navigator), a popup appears.
  10. Select from the pop-up the function you need to have triggered by the menu item. You should now see a new connection in the Outlet Inspector.
That is basically it. You will probably want to do some additional stuff like conditional highlighting or adding a selection mark in front of the menu item. To do this kind of stuff, look up the guide for Event handling in Cocoa. Look specifically for "validateMenuItem" and "menuNeedsUpdate".

2015.05.19: Don't be surprised when you close and reopen the project that in step 4 above the field is empty again. The functions you defined previously are still available.

Happy coding

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

2015-04-05

Swift extensions: String function fixIndex

In this post I will keep track of general purpose extensions for the Swift String type.

fixIndex

extension String {
    
    /// This function fixes the associated endIndex of the given index by returning a new index with the same value and a new associated endIndex.
    
    func fixIndex(index: String.Index) -> String.Index {
        let kludge = distance(startIndex, index)
        return advance(startIndex, kludge)
    }
}

Example usage:

var string = "12"
var index = string.startIndex.successor().successor()

string += "34"

// index = index.successor().successor() ==>> gives us an "EXC_BAD_INSTRUCTION"

index = string.fixIndex(index)

index = index.successor().successor() // OK

isLowercaseCharacterAtIndex

extension String {
    
    /// Returns true if the character at the given index is a lowercase character as defined in the lowercase character set. Works for UTF16 characters only.

    func isLowercaseCharacterAtIndex(index: String.Index) -> Bool {
        return NSCharacterSet.lowercaseLetterCharacterSet().characterIsMember(String(self[index]).utf16[String.UTF16Index(0)])
    }

}

Example usage:

let str = "1 gF🌵"

for i in str.startIndex ... str.endIndex.predecessor() {
    print("\(str.isLowercaseCharacterAtIndex(i)), ")

}

Prints:

false, false, true, false, false,

isUppercaseCharacterAtIndex

extension String {
    
    /// Returns true if the character at the given index is an uppercase character as defined in the uppercase character set. Works for UTF16 characters only.

    func isUppercaseCharacterAtIndex(index: String.Index) -> Bool {
        return NSCharacterSet.uppercaseLetterCharacterSet().characterIsMember(String(self[index]).utf16[String.UTF16Index(0)])
    }

}

Example usage:

let str = "1 Fg🌵"

for i in str.startIndex ... str.endIndex.predecessor() {
    print("\(str.isUppercaseCharacterAtIndex(i)), ")

}

Prints:

false, false, true, false, false,

replaceCharacterAtIndex

extension String {
    
    /// Replaces the character at the specified index with the given character. Returns true if the string was changed, false if not.
    
    mutating func replaceCharacterAtIndex(index: String.Index, with char: Character) -> Bool {
        if index == endIndex { return false }
        if self[index] == char { return false }
        let range = Range(start: index, end: index.successor())
        self.replaceRange(range, with: String(char))
        return true
    }

}

Example usage:

var str = "123456789"
str.replaceCharacterAtIndex(str.startIndex.successor(), with: "F")
print(str)

Prints:

"1F3456789"

changeCaseOfCharacterAtIndex

This extension needs the three preceding extensions.

extension String {
        
    /// Changes the case of the character at the specified index. Returns true if the string was changed, false if not.
    
    mutating func changeCaseOfCharacterAtIndex(index: String.Index) -> Bool {
        if isLowercaseCharacterAtIndex(index) {
            return self.replaceCharacterAtIndex(index, with: String(self[index]).uppercaseString[startIndex])
        } else if isUppercaseCharacterAtIndex(index) {
            return self.replaceCharacterAtIndex(index, with: String(self[index]).lowercaseString[startIndex])
        } else {
            return false
        }
    }
}

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

2015-04-03

Swift "Singleton" Design Pattern

The singleton, probably the most famous design pattern in existence.
For the simple cases, Swift makes this an extremely easy one:

// The simpelest singleton possible

var simpleSingleton = SimpleSingleton()

class SimpleSingleton {
    private init() {}
}

And that is all. Anywhere in your project you can now use the singleton "simpleSingleton", no need to instantiate it, or retrieve a pointer to it. It's simply there when you need it.

Being a very simple singleton there are some drawbacks: you might get a clash with other variables. I.e. the name of the singleton must be unique in your software. For general purpose singletons there is a real chance that you will already have other variables (either local or global in scope) that have the same name.

We can remove the chance for name collisions by making the singleton private and providing an accessor function for it:

// Still simple, but avoids name collisions

private var simpleSingleton = SimpleSingleton()

class SimpleSingleton {
    
    class func singleton() -> SimpleSingleton {
        return simpleSingleton
    }
    
    private init() {}

}

Whenever you need the singleton, you obtain it first through the class function. You can find this pattern throughout Cocoa in things like: NSFileManager.defaultManager() or NSBundle.mainBundle()

The main drawback of these simple patterns is that the singleton is created during application startup. This can be annoying if it takes a lot of time or if the singleton is not always needed in every application run. And it becomes downright impossible if the singleton cannot be created during startup because not all of the data necessary is available at that time.

The solution is to delay the creation of the singleton to the time where its really needed (or can be created). The result looks like this

// Delay the creation of the singleton until it's really needed.

private var delayedSingleton: DelayedSingleton?

class DelayedSingleton {
    
    class func singleton() -> DelayedSingleton? {
        
        if delayedSingleton != nil {
            
            return delayedSingleton!
        
        } else {
        
            if let delayedSingleton = DelayedSingleton() {
                
                return delayedSingleton
                
            } else {
                
                // Oeps, the singleton could not be created,
                // take corrective action or inform the user
                // (or leave it to the callee)
                
                return nil
            }
        }
    }
    
    private init?() {}
}

In the above example, notice that the "init" function now returns an optional. This is done to cover the case where the creation of the singleton depends on data that may not be available. If it is possible to ensure that the singleton will be created, then remove the optional aspect of the returned value of both the init and the singleton accessor.

We are not done yet. The above solution works perfectly in a single thread, but in a multithreaded environment we risk the creation of multiple instances of the singleton, exactly what we did not want! In the above case, do note that even if multiple instances were created, the software would only keep the one created last. This could make for some very hard to find bugs!

Using Grand Central Dispatch it is easy to avoid the creation of multiple instances, here is the code:

// Multithreading safe singleton with delayed creation.

private var threadSafeDelayedSingleton: ThreadSafeDelayedSingleton?

class ThreadSafeDelayedSingleton {
    
    
    class func singleton() -> ThreadSafeDelayedSingleton {
        
        // Avoid dispatching if the singleton is already created!
        
        if threadSafeDelayedSingleton != nil { return threadSafeDelayedSingleton! }
        
        
        // Create the singleton under explicit synchronisation
        
        let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
        
        dispatch_sync(queue, { self.createSingleton() } )
        
        return threadSafeDelayedSingleton!
    }
    
    
    private class func createSingleton() {
        
        // In the unlikely case that more than one creation request is scheduled,
        // only create the singleton the first time.
        
        if threadSafeDelayedSingleton == nil {
            threadSafeDelayedSingleton = ThreadSafeDelayedSingleton()
        }
    }
    
    private init() {}
}

Notice that I removed the optional from the init and the singleton accessor. In a multithreaded environment you better be sure that the creation of the singleton succeeds! If not, then a whole new can of worms opens which is beyond the scope of this article.

Btw: The very first example of a singleton creation is also multithreading safe ;-)

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.