Swift is full of syntactic sugar. One particular taste of sweet is the callAsFunction feature. If a type has a method of that name, you can call an instance or value of that type like a function. That’s used in SwiftUI to pass actions around in the environment, for example. Quick demo: See how the call looks like there’s a function updateWidgets(newerThan:) but actually it’s calling the value itself?
Working on a greenfield project is nice, but it also brings up all the uncertainties of the start: which components, modules, objects, interfaces do you need? With Swift, you even have to decide if you want to design the system in an object-oriented or a functional way. As far as the core functionality is concerned, you do have this choice. (When it comes to UIKit/AppKit, you don’t.)
In “Creating a Cheap Protocol-Oriented Copy of SequenceType (with a Twist!)” I created my own indexedEnumerate() to return a special kind of enumeration: instead of a tuple of (Int, Element), I wanted to have a tuple of (Index, Element), where Index was a UInt starting at 1. A custom CollectionType can have a different type of index than Int, so I was quite disappointed that the default enumerate() simply returns a sequence with a counter for the elements at first.
During the last weeks, I tried to use map() even when the conversion wasn’t straightforward to learn how it affects reading code. I found that some applications of map() were dumb while I liked how others turned out to read. The functional programming paradigm is about writing code in a declarative way, which has its benefits.
I’m back from my vacation and very deep into programmin already. Before I left, my subconscious mind brought up the notion of a Lens (functional programming) while I was modelling tabular data in Swift and I think this is a very cool approach to keep value types clean and easy to test. I use lenses in my current project to provide a specialized interface to operate with the table. The lenses provide access to column and row iterators, independent of the table’s underlying data structure. This way the table doesn’t have to worry about all this stuff.
The other day, I wrote a post about bind() and the >>= operator and how it can help chain function calls together. The example was a bit too contrived and making it fit the requirements left us with really bad code. I came up with an even better implementation: use plain Swift objects and express your intent carefully.
East-Oriented programming can, for example, be implemented through delegates or callback blocks. “East” is all about Tell, Don’t Ask: don’t query for values; instead, pass a handler around so the flow of information doesn’t return to your current scope.
I discovered a Swift library called Static the other day. It helps set up and fill UITableViews with static content – that is, it doesn’t permit deletion or rearrangement of new rows into the table. I think the following example to configure sections with rows reads really nice:
I’ve written about using the Result enum to return values or errors already. Result guards against errors in the process. There’s also a way to guard against latency, often called “Futures”. There exist well-crafted solutions in Swift already.
After the latest change in my diet, I eat a lot more often throughout the day and try to spend the time watching educational talks to make use of my time. Functional programming seems to not only be all the hype – its concepts seem to reach mainstream thinking, too. Here’s a collection of talks you might find worth your while.
Functional Swift – conference recordings with tons of great stuff
Erica Sadun brought up a topic which is bugging me for some time already. It’s how Swift encourages you to handle optionals. It’s related to handling exceptions, which I covered earlier. Either you use if-let to unwrap them implicitly and do all the stuff inside the nested code block, or you end up with code which is a lot wordier than I’d like it to be.
In Swift, there’s no exception handling or throwing. If you can’t use exceptions for control flow like you would in Java, what else are you going to do if you (a) write library code which executes a failing subroutine, and (b) you find unwrapping optionals too cumbersome? I played with the thought of keeping Swift code clean, avoiding the use of optionals, while maintaining their intent to communicate failing operations.
Chris Eidhof provided an excellent example for creating a mini Swift networking library. It executes simple requests and can be extended to work with JSON (or XML, if you must) without any change. The accompanying talk is worth watching, too. You should check it out to see well-factored Swift code in action. It’s a great example.