Lars Lockefeer

Lars Lockefeer

To let their work speak for itself, Lars Lockefeer has not written a bio.

Location: Amsterdam RSS feed of posts by Lars Lockefeer 

Lars Lockefeer has published 19 posts:

→ Mechanics of good pairing

December 18th, 2015

A great post on how to set up pair programming environments effectively.

Map, filter and reduce in Swift

June 17th, 2015

Having worked with Swift full-time for over half a year, I feel that now is a good time to start sharing bits and pieces on how to write Swift code instead of Objective-C code that happens to be syntactically correct Swift. We'll start off easy today with an overview of map, filter and reduce, three nifty little methods that greatly reduce the amount of for-loops we write from day to day in Swift.

Having mentioned for-loops, you probably already guessed that map, filter and reduce can be used to perform operations on collections. Let's have a look at how these functions behave on a very simple collection: an array with elements of type T.

To start off our example, let's define an array of integers:

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

Map

map can be used to transform a collection. It takes a function t: T -> U and returns a collection containing the results of calling t on each element of the collection. We could use this method to multiply all elements in our array by 2:

let multipliedNumbers = numbers.map { elem in
  return elem * 2
}
// multipliedNumbers = [2, 4, 6, 8, 10]

Using Swift's syntactical sugar, we can make a few optimizations here. First of all, the parameter that is passed to the function t can be referred to with the shorthand syntax $0. Second, since t only consists of a single line, we can omit the return statement, yielding the following one-liner:

let multipliedNumbers2 = numbers.map { $0 * 2 }

The full signature of the map function is: map(t: T -> U) -> [U]. Note that the type of the resulting collection is not equal to the type of the collection it received as input. So rather than transforming integers into integers as we did in our example, we could transform them into any other type.

Filter

filter can be used to filter elements out of a collection depending on a condition. It takes a function i: T -> Bool and returns a collection containing those results in the original collection for which i returns true. Hence, the full signature of the filter function is: filter(i: T -> Bool) -> [T].

Now, let's use that to filter our collection by keeping only the even numbers:

let evenNumbers = numbers.filter { $0 % 2 == 0 }
// evenNumbers = [2, 4]

Reduce

With the reduce method, all values in a collection can be combined into a single value. The function takes two parameters: the initial value i: U and a function c: (U, T) -> U that takes the accumulated value and an element of the collection as a parameter. The full signature of the reduce method is: reduce(i: U, c: (U, T) -> U) -> U.

Let's use this method to calculate the sum of all elements in our array of numbers:

let sum = numbers.reduce(0) { $0 + $1 }
// sum = 15

It may not be immediately clear what is happening here, so let's look at the first two iterations. At the first pass, c is called with the initial value 0 and the first element of the array (1) as parameters. By definition, it calculates the sum of these 2: 0 + 1 = 1 which is then passed on to the next iteration. In this next iteration, c will again be executed, this time with the accumulated value (1) and the second element (2) as parameters, returning the sum: 1 + 1 = 2. This procedure continues until the last element of the array is reached, at which point the accumulated value will simply be returned.

Chaining the methods together

The full power of map, filter and reduce becomes especially apparent when these methods are chained together. Have a look at the following example:

let someNumbers = [1, 2, 3, 4, 5]
let result = someNumbers.filter {
  $0 % 2 == 0
}.map {
  $0 + 10
}.reduce(0) {
  $0 + $1
}

Here we remove the odd numbers from the array with filter. Then, we offset each of them by 10 and calculate the sum of all elements. Verify for yourself that, after executing these chain of methods, result should be set to 26.

That's it for today! Stay tuned for more Swifty bits and pieces.

Solving UI Lag in Yosemite

January 24th, 2015

After using Yosemite for a couple of hours on end, the system usually gets very slow. Especially User Interface transitions and animations (such as when opening Expose) become choppy and take longer to perform than they should. It seems that the Window Server is the cause for this problem, as it shows very high CPU activity whenever the problem occurs.

I used to resolve this issue with a reboot, but this is not really convenient. It turns out that simply killing the WindowServer process from the command line is sufficient:

sudo pkill -9 "WindowServer"

The system will bounce you back to the login screen and after logging in everything will be running smoothly again.

→ Synx

January 23rd, 2015

A command-line tool that reorganizes your Xcode project folder to match your Xcode groups.

→ Design Explosions

January 23rd, 2015

Jon Bell and William Van Hecke have started a blog in which they review UX designs in the wild with the purpose of learning from them. Their first episode takes apart Apple Maps and Google Maps on iOS, highlighting the differences and trying to understand the choices.

In their own words:

But this is a different kind of post. There’s no winner this time, just a bunch of design lessons inspired from studying two similar products. It’s fun to compare and contrast the approaches of two highly skilled teams working on a pretty unique design challenge.

...

Every decision has a tradeoff. Every thing you make easier can make another thing harder. There is no such thing as “the right design”. But we can learn a lot from seeing how experts in their field weighed the pros and cons of different approaches.

© 2019 Lars Lockefeer