tag:nomothetis.svbtle.com,2014:/feedAlexandros Salazar2015-06-12T22:50:03-07:00Alexandros Salazarhttps://nomothetis.svbtle.comSvbtle.comtag:nomothetis.svbtle.com,2014:Post/the-ghost-of-swift-bugs-future2015-06-12T22:50:03-07:002015-06-12T22:50:03-07:00The Ghost of Swift Bugs Future<p><strong>Update</strong>: <em>I wrote this with Xcode 7 β1, and playgrounds crashed a lot at the time. As a result, I gave up on testing all the cases, and a lot of errors creeped into the snippets. They are now corrected, thanks to (among others) <a href="https://twitter.com/CalQL8ed_K_OS">@CalQL8ed_K_OS</a> and <a href="https://twitter.com/IanKay">@IanKay</a>, who both corrected me and shamed me into fixing things. Thanks guys!</em></p>
<p>So Swift 2 is out, and they <a href="https://twitter.com/cocoaphony/status/608015927813238786">fixed enums with variable payloads</a>, so the party is <em>on</em>.</p>
<p>I haven’t had a chance to play with it too much, but watching the <a href="https://developer.apple.com/videos/wwdc/2015/?id=408">Protocol-Oriented Programming in Swift</a> session, a particular construct struck me as the most likely source of arcane, incomprehensible bugs in the future. I expect it to be the novice’s crucible, similar to the way deallocated delegates would lead to crashes in the days before the <code class="prettyprint">weak</code> attribute was introduced. I’m not yet sure what the searches will look like, but the fundamental question will be a variation of:</p>
<p><em>“Why does the method that I wrote overriding protocol extension X never get called?”</em></p>
<p>Stack Overflow will no doubt provide short answers. Here is my longer, more in-depth answer, hoping to explain the details to some lost soul.</p>
<p>• • • • •</p>
<p><em><a href="https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID521">Protocol extensions</a></em> are a new feature in Swift that allows default implementations of methods to be shared across types that conform to the protocol. The exact semantics place them in the vague mixin/typeclass area that other languages implement in different ways—I don’t claim to know enough about the semantics of the construct in <em>any</em> language to get more specific than that. It allows for shorter code and better modularity, and I think it is a fantastic feature. (And if you haven’t watched the session, go do that. Now. I’ll wait.)</p>
<p>However.</p>
<p>However, the dispatch rules can get confusing. To say the least.</p>
<p>Let’s begin with a quick intro; suppose we declare a protocol:</p>
<pre><code class="prettyprint lang-swift">protocol Formattable {
/// A string.
var content:String { get }
/// An formatting function.
func formattedContent() -> String
}
</code></pre>
<p>As stated, a protocol extension allows us to provide a default implementation for <code class="prettyprint">formattedContent()</code>:</p>
<pre><code class="prettyprint lang-swift">extension Formattable {
func formattedContent() -> String {
return self.content
}
}
</code></pre>
<p>But another thing we can do is add entirely new methods to our protocol:</p>
<pre><code class="prettyprint lang-swift">extension Formattable {
func debugFormattedContent() -> String {
return "Content: \(self.content)"
}
}
</code></pre>
<p>And now, any type that implements <code class="prettyprint">Formattable</code> has access to both methods. The Swift standard library uses this to have one centrally defined sorting algorithm, dependent on a type conforming to the <code class="prettyprint">Comparable</code> protocol. This is very different from how things were in Swift 1.x, where defining a <code class="prettyprint">sort([Self])</code> method on <code class="prettyprint">Comparable</code> would require every type to have its own distinct implementation—hence the existence of large numbers of top-leve functions like <code class="prettyprint">map</code>, <code class="prettyprint">reduce</code>, and, indeed, <code class="prettyprint">sort</code>.</p>
<p>Once you understand how protocol extensions work, their power is impressive, and their allure irresistible. But as with all siren songs, dangers lurk. Consider this implementation of <code class="prettyprint">Formattable</code>:</p>
<pre><code class="prettyprint lang-swift">struct Day : Formattable {
var content:String
func formattedContent() -> String {
return "Today is \(self.content)"
}
func debugFormattedContent() -> String {
return "Day: \(self.content)"
}
}
</code></pre>
<p>Seems simple enough; it overrides both methods. Now see if you can predict what happens with each of these calls:</p>
<pre><code class="prettyprint lang-swift">let a = Day(content:"Monday")
let b:Formattable = Day(content:"Monday")
a.formattedContent()
b.formattedContent()
a.debugFormattedContent()
b.debugFormattedContent()
</code></pre>
<p>Given it a go? Did you come up with:</p>
<pre><code class="prettyprint lang-swift">a.formattedContent() // "Today is Monday"
b.formattedContent() // "Today is Monday"
a.debugFormattedContent() // "Day: Monday"
b.debugFormattedContent() // "Content: Monday"
</code></pre>
<p>If yes, and you understand why, congratulations; you don’t need to read any further. If you expected <code class="prettyprint">b.debugFormattedContent()</code> to be the same as <code class="prettyprint">a.debugFormattedContent()</code>, read on.</p>
<p>• • • • •</p>
<p>In Objective-C and Swift 1.x a protocol, which could not be extended with methods, was an interface that defined behavior that a type <em>conformed</em> to. That is, the conforming type guaranteed that it implemented every function in the protocol. So in Swift 1.x, suppose we had:</p>
<pre><code class="prettyprint lang-swift">protocol A {
func m1() -> String
}
struct B : A {
func m1() -> String {
return "hello"
}
}
</code></pre>
<p>Then <code class="prettyprint">let a = B()</code> and <code class="prettyprint">let a:A = B()</code> were the same thing as far as calling <code class="prettyprint">m1</code> is concerned: they will both call the only implementation available, which is the one in <code class="prettyprint">B</code>. This is still true in Swift 2.</p>
<p>Protocol extensions, however, allow a form of polymorphism, which brings up the question of which method to dispatch. Suppose in Swift 2 we extend A:</p>
<pre><code class="prettyprint lang-swift">extension A {
func m1() -> String {
return "hello"
}
func m2() -> String {
return "planet"
}
}
</code></pre>
<p>And suppose we want <code class="prettyprint">B</code> to override both methods:</p>
<pre><code class="prettyprint lang-swift">struct B : A {
func m1() -> String{
return "greetings"
}
func m2() -> String {
return "earthling"
}
}
</code></pre>
<p>Now, for any instance of <code class="prettyprint">B : A</code>, there are <em>two</em> possible implementations of <code class="prettyprint">m1</code> and <code class="prettyprint">m2</code>: the one defined in <code class="prettyprint">B</code>, and the one defined in the <code class="prettyprint">A</code> extension. Which one should we choose?</p>
<p>Suppose we decide we should always choose the one in the type that implements <code class="prettyprint">A</code>, if it exists. And suppose we have another type <code class="prettyprint">C</code> defined as follows:</p>
<pre><code class="prettyprint lang-swift">struct C : A {
func m2() -> String {
return "darkness, my old friend"
}
}
</code></pre>
<p>Now suppose we have a heterogeneous array and call the methods:</p>
<pre><code class="prettyprint lang-swift">let a:[A] = [B(), C()]
let b = a.map {$0.m1()} // ["greetings", "hello"]
let c = a.map {$0.m2()} // ["earthling", "darkness, my old friend"]
</code></pre>
<p>This is what we would expect. So far so good. Suppose, however, that we call a function:</p>
<pre><code class="prettyprint lang-swift">func callM2(arr:[A]) -> [String]{
return arr.map { $0.m2() }
}
let a:[A] = [B(), C()]
let b = a.map {$0.m1()} // ["greetings", "hello"]
let c = callM2(a) // ["earthling", "darkness, my old friend"]
</code></pre>
<p>This time, the result, which is the same, might actually surprise the author of <code class="prettyprint">callM2</code> very much. After all <code class="prettyprint">m2</code> <em>is not defined</em> in the original protocol <code class="prettyprint">A</code>. So if they chose to call it, it must be because they expected the <em>specific implementation of the extension</em>.</p>
<p>By always calling the value in the type’s implementation, then, we forever hide the default implementation of the extension, even in cases where it would be expected. The solution Swift 2 adopted is to call the default implementation <em>when the protocol is explicitly specified</em>. So let’s look back at our example:</p>
<pre><code class="prettyprint lang-swift">let a = Day(content:"Monday")
let b:Formattable = Day(content:"Monday")
a.debugFormattedContent() // "Day: Monday"
b.debugFormattedContent() // "Content: Monday"
</code></pre>
<p>Since <code class="prettyprint">b</code> is explicitly specified as being a <code class="prettyprint">Formattable</code>, the method that gets called is the default implementation in the extension. Since <code class="prettyprint">a</code> is instead inferred to be a <code class="prettyprint">Day</code>, the method that gets called on it is the implementation in <code class="prettyprint">Day</code>.</p>
<p>In the case of the <code class="prettyprint">A</code> and <code class="prettyprint">B</code> protocols, this translates into Swift always calling the default implementation for the elements of the array:</p>
<pre><code class="prettyprint lang-swift">func callM2(arr:[A]) -> [String]{
return arr.map { $0.m2() }
}
let a:[A] = [B(), C()]
let b = a.map {$0.m1()} // ["greetings", "hello"]
let c = callM2(a) // ["planet", "planet"]
</code></pre>
<p>This brings up an interesting question. Is it possible to get the type’s implementation every time, instead of the extension’s? Or have we lost that ability forever? If you look back at the call to <code class="prettyprint">m1()</code>, you’ll see that it is always the type’s implementation that gets called. The difference is that <code class="prettyprint">m1</code> is declared in <code class="prettyprint">A</code>, whereas <code class="prettyprint">m2</code> is declared in the extension. So if we wanted <code class="prettyprint">m2</code> to be called on the actual type of the array’s elements, we would declare it in <code class="prettyprint">A</code>.</p>
<p>• • • • •</p>
<p>The rules for dispatch for protocol extensions, then, are:</p>
<ul>
<li>IF the inferred type of a variable is the <em>protocol</em>:
<ul>
<li>AND the method is defined in the original protocol
<ul>
<li>THEN the runtime type’s implementation is called, irrespective of whether there is a default implementation in the extension.</li>
</ul>
</li>
<li>AND the method is <em>not</em> defined in the original protocol,
<ul>
<li>THEN the default implementation is called.</li>
</ul>
</li>
</ul>
</li>
<li>ELSE IF the inferred type of the variable is the <em>type</em>
<ul>
<li>THEN the type’s implementation is called.</li>
</ul>
</li>
</ul>
<p>Note the use of “runtime type” in the first THEN clause. This refers to the type of the variable when the program is actually running, as opposed to the type the compiler infers. This is relevant if we write a function <code class="prettyprint">callM1()</code> as follows:</p>
<pre><code class="prettyprint lang-swift">func callM1(arr:[A]) -> [String] {
return arr.map($0.m1)
}
</code></pre>
<p>Here, the compiler doesn’t know the type of the elements of <code class="prettyprint">arr</code>; it only knows that they all have an <code class="prettyprint">m1</code> method. At runtime, however, each element will have a specific type, perhaps <code class="prettyprint">B</code>, or perhaps <code class="prettyprint">C</code>. That’s when the method that gets called will be determined. This is referred to as <em><a href="https://en.wikipedia.org/wiki/Dynamic_dispatch">dynamic dispatch</a></em>.</p>
<p>By contrast, in the <code class="prettyprint">callM2</code> implementation, per the rules we just established, the compiler will know exactly what method to call: the one in the extension to <code class="prettyprint">A</code>. This is referred to as <em>static dispatch</em> and, incidentally, allows for certain optimizations (general rule: if you know something at compile time, odds are you can optimize something with that knowledge).</p>
<p>• • • • •</p>
<p>So, that’s it. As I said, I expect this to be a very common error among beginners; in fact, I expect to run into this issue multiple times myself. It’s just too easy to forget when things are dispatched dynamically and when they’re dispatched statically.</p>
<p>Incidentally, if anyone knows of other reasons to dispatch statically on extensions, please let me know; I’ll amend the post to reflect them.</p>
tag:nomothetis.svbtle.com,2014:Post/reactivecocoa-ii-reacting-to-signals2015-05-22T14:45:11-07:002015-05-22T14:45:11-07:00ReactiveCocoa II: Reacting to Events<p>In my <a href="http://nomothetis.svbtle.com/an-introduction-to-reactivecocoa">previous post</a>, I introduced <a href="https://github.com/ReactiveCocoa/ReactiveCocoa">ReactiveCocoa</a> and went over the basic steps of creating a <code class="prettyprint">SignalProducer</code>. I showed how you can process the events via the pipe forward operator <code class="prettyprint">|></code>, and teased a little at the end about the various functional compositions you can work with. What I did not go into was how to react to those events. Given that this is functional <em>reactive</em> programming that we’re talking about, perhaps a follow-up on that is not the worst idea.</p>
<p>Even if it’s three weeks overdue.</p>
<p>• • • • •</p>
<p>As I discussed, events come in four varieties: <code class="prettyprint">.Next(T)</code>, <code class="prettyprint">.Error(E)</code>, <code class="prettyprint">.Completed</code>, and <code class="prettyprint">.Interrupted</code>. Working with a <code class="prettyprint">Signal</code> (which remember, has neither beginning nor end), we listen for those events by <em>observing</em> them:</p>
<pre><code class="prettyprint lang-swift">someSignal.observe(next: {
data in
displayData(data)
})
</code></pre>
<p><code class="prettyprint">Signal</code>s typically don’t have errors and don’t terminate, so that’s all we need to do for most signals.</p>
<p><code class="prettyprint">SignalProducer</code>s, on the other hand, can run the full gamut. And since they are started on demand, their API is a little different:</p>
<pre><code class="prettyprint lang-swift">someSignalProducer.start(next: {
data in
displayData(data)
}, error: {
error in
displayError(error)
}, interrupted: {
handleInterruption()
})
</code></pre>
<p>The <code class="prettyprint">start</code> and <code class="prettyprint">observe</code> methods have very similar calling conventions, and all take the parameters <code class="prettyprint">next:</code>, <code class="prettyprint">error:</code>, <code class="prettyprint">interrupted:</code>, and <code class="prettyprint">completed:</code>, which have default values that do nothing. That’s why in the last snippet, I was able to do nothing on completion: if I don’t need to inform the user that a request finished, there’s no need to include a parameter for it.</p>
<p>• • • • •</p>
<p>Okay, so now we know how to create signals and signal producers, and how to listen to them. Are we done?</p>
<p>Theoretically, yes. But in our work with RAC, there have been many patterns that have come up over and over again that are supported, but that are not always obvious to implement. To help maybe pave the way for others, I’m going to go over a few common examples.</p>
<p>Let’s get back to Comic Cathy. The data stored in her local store is missing the cover images, which she wants to load from the server. If you remember, her producer function was:</p>
<pre><code class="prettyprint lang-swift">func comicCollectionProducer()
-> SignalProducer<[Comic], RetrievalError> {
let localFetchProducer = SignalProducer(result:localComics())
|> mapError(retrievalErrorFromStoreError)
let networkFetchProducer = SignalProducer.try(networkComics)
|> mapError(retrievalErrorFromNetworkError)
return localFetchProducer |> concat(networkFetchProducer)
}
</code></pre>
<p>What she wants to do is this: take every group of comics returned by the producer, and for each comic, request the cover image. At this point, we need to start making things a little more realistic. In order to do this, what Cathy has written is a <code class="prettyprint">SignalProducer</code> that will fetch the image and send events with the data (or any errors). She has a function that will return it:</p>
<pre><code class="prettyprint lang-swift">func producerToFetchImageForComic(comic:Comic)
-> SignalProducer<UIImage, NSError>
</code></pre>
<p>The first problem is that this function takes a single <code class="prettyprint">Comic</code>, but we will be getting an array of <code class="prettyprint">Comics</code>. What we want, then, is to use this function to create a new function:</p>
<pre><code class="prettyprint lang-swift">func producerToFetchImagesForComics(comics:[Comic])
-> SignalProducer<[UIImage], NSError>
</code></pre>
<p>We can’t use a plain old for-loop, because <code class="prettyprint">SignalProducer</code>s are asynchronous by nature. Instead, we have to break down the task into steps:</p>
<ol>
<li>Create a stream of individual comics from the array.</li>
<li>Replace each comic in the stream with the corresponding image.</li>
<li>When the stream completes, recombine the entire stream into one array of images.</li>
</ol>
<p>ReactiveCocoa has functions that let us do each of these things. First off, much like it has a convenience initializer for a <code class="prettyprint">Result</code>, it also has a convenience initializer for an array of values:</p>
<pre><code class="prettyprint lang-swift">let individualComicProducer =
SignalProducer<Comic, NSError>(values:comics)
</code></pre>
<p>When started, this producer will emit the values one by one and then complete. So that’s step one. Step three is also easy. RAC has a function called <code class="prettyprint">collect</code> that waits for a signal to complete, and then forwards all the values in an array. In effect, it’s the reverse of the convenience initializer and would look like this:</p>
<pre><code class="prettyprint lang-swift">let comics:SignalProducer<Comic, NSError>
= individualComicProducer |> collect
</code></pre>
<p>As before, the pipe forward operator is a shorthand for <code class="prettyprint">collect(individualComitProducer)</code>, and returns a <code class="prettyprint">SignalProducer</code>. This is important: there is no way to get the values put into a producer out of it without using the <code class="prettyprint">start</code> function; in effect, the producer adds a context that can’t be discarded. But that’s okay, because our <code class="prettyprint">producerToFetchImagesForComics</code> function returns a producer.</p>
<p>This leaves step two in our list. That’s the trickiest one. What we want to do is:</p>
<ol>
<li>Take every comic handed to us.</li>
<li>Call the <code class="prettyprint">producerToFetchImageForComic</code> function.</li>
<li>Return the image we receive as a result of the producer.</li>
</ol>
<p>In type terms we have a producer of type <code class="prettyprint">SignalProducer<Comic, NSError></code>. And we have a function that turns <code class="prettyprint">Comic</code> values into <code class="prettyprint">SignalProducer<UIImage, NSError></code> values. What we want is a <code class="prettyprint">SignalProducer<UIImage, NSError></code>.</p>
<p>Hmm. We’ve seen this pattern before. It’s like what we want to do with <code class="prettyprint">Result</code> sometimes:</p>
<pre><code class="prettyprint lang-swift">result:Result<T, E>
COMBINED_WITH
f:T -> Result<U, E>
SHOULD_RETURN
newResult:Result<U, E>
</code></pre>
<p>That’s our old friend flatMap!</p>
<pre><code class="prettyprint lang-swift">newResult = result.flatMap { value in f(value) }
</code></pre>
<p>So does RAC have <code class="prettyprint">flatMap</code> for signals? Of course it does! RAC loves <code class="prettyprint">flatMap</code>! It loves <code class="prettyprint">flatMap</code> so much, it has <em>three</em> versions of it, depending on what behavior you want out of your signal. I can’t go into too much detail about what each does,<sup><a name="fn1s" href="#fn1">1</a></sup> so I’ll stick with the one that will preserve the order of the comics: <code class="prettyprint">flatMap(.Concat)</code>. It works like this:</p>
<pre><code class="prettyprint lang-swift">let signalOfImages = individualComicProducer
|> flatMap(.Concat, producerToFetchImageForComic)
</code></pre>
<p>And therefore, the complete function looks like this:</p>
<pre><code class="prettyprint lang-swift">func producerToFetchImagesForComics(comics:[Comic])
-> SignalProducer<[UIImage], NSError> {
return SignalProducer(values:comics)
|> flatMap(.Concat, producerToFetchImageForComic)
|> collect
}
</code></pre>
<p>Again, step back for a second and realize that it took me multiple paragraphs to explain three lines of code — which exactly match the three conceptual steps we wanted to execute. So while there was a lot of explanation for the details, the mapping from concept to code is almost one-to-one. Once you become fluent with the various functions in the API, you might not even think of things in ambiguous English steps — the transformations might naturally map into <code class="prettyprint">collect</code>s and <code class="prettyprint">takeWhile</code>s and <code class="prettyprint">signalOn</code>s and <code class="prettyprint">flatMap</code>s until running across a problem that doesn’t match those fundamentals becomes rare, and a warning sign that the problem statement is unclear.</p>
<p>• • • • •</p>
<p>Now Cathy has her function to get the images. How will she integrate it in her app? Ideally, she wants a producer that will return both the images and the comics, together. This is a trickier thing to get right, because it involves creating a producer that calls producers, which always feels dirty to me. Here’s how Cathy goes about it:</p>
<pre><code class="prettyprint lang-swift">func comicsCollectionDisplayProducer()
-> SignalProducer<([Comic], [UIImage]), NSError> {
return SignalProducer { sink, disposable in
let disp = comicCollectionProducer()
|> start(next: {
comics in
let disp2 = producerToFetchImagesForComics(comics)
|> start(next: {
images in
sendNext(sink, (comics, images))
}
disposable.add(disp2)
}
disposable.add(disp)
}
}
</code></pre>
<p>We’re now seeing the use of that <code class="prettyprint">disposable</code> parameter. It exists to ensure that if the enclosing <code class="prettyprint">SignalProducer</code> errors out or is terminated, no events from the inner producers are propagated along the computational chain. In other words, it’s a way way of doing manual computation management. I don’t love it, but I haven’t found a better way to do it, so I accept it. The rule is: whenever you <code class="prettyprint">observe</code> or <code class="prettyprint">start</code> something, you should have worked out how to manage the <code class="prettyprint">Disposable</code> that is returned. It’s similar to retain/release management. In this case, the initializer provides a <code class="prettyprint">CompositeDisposable</code> to which Cathy can add any disposables she creates. The initializer is responsible for managing the disposable it provides.</p>
<p>Cathy’s implementation works great. It does exactly what it needs to do. And yet it still looks ugly. There’s a lot of deep nesting going on, a lot of closures getting called back and forth, and it generally feels clunky.</p>
<p>There are ways around this. For one, none of the solutions so far change the fundamental nature of what the code is doing: the new functions are composed from previously written functions. Because RAC makes composition natural, that’s a tendency that can go too far; sometimes the solution is a different approach to the problem. For instance, instead of <code class="prettyprint">producerToFetchImageForComic</code>, we could have a similar function that returned a tuple:</p>
<pre><code class="prettyprint lang-swift">func producerToFetchInfoForComic(comic:Comic)
-> SignalProducer<(Comic, UIImage), NSError>
</code></pre>
<p>The tuple pairs the comic with its corresponding images — a very useful pairing. That change would propagate up the chain, and lead us to a top-level function whose signature would be:</p>
<pre><code class="prettyprint lang-swift">func comicsCollectionDisplayProducer()
-> SignalProducer<[(Comic, UIImage)], NSError>
</code></pre>
<p>See if you can work out how. This pairs each comic with its corresponding image explicitly and is decidedly cleaner.<sup><a name="fn2s" href="#fn2">2</a></sup></p>
<p>This is only one approach to resolving the nesting issue, and what I want to emphasize is that the old <a href="http://www.quora.com/What-are-some-unofficial-mottos-of-programming-languages">Haskell joke</a> applies equally well to RAC: “An hour of meditation, followed by the emission of a single ‘fold’ expression.” Just because what you’ve come up with works doesn’t mean that it’s the best or cleanest way to do it. Trust your instinct if something feels ugly. There may be better ways of doing it.</p>
<p><strong>Update:</strong> <a href="https://twitter.com/jspahrsummers">Justin Spahr-Summers</a> was nice enough to provide a much better implementation of <code class="prettyprint">comicsCollectionDisplayProducer()</code>:</p>
<pre><code class="prettyprint lang-swift">func comicsCollectionDisplayProducer()
-> SignalProducer<([Comic], [UIImage]), NSError> {
return comicCollectionProducer()
|> flatMap(.Concat) { comics in
producerToFetchImagesForComics(comics)
|> map { images in (comics, images)
}
}
</code></pre>
<p>He’s using the form of <code class="prettyprint">flatMap</code> that takes an explicit closure, which I hadn’t thought about. I like it much better because is avoids the use of disposables entirely. Since this pattern comes up over and over again, I recommend learning it; I’m probably going to go back and look through some of our code and see if we can use it to clean things up.</p>
<p>• • • • •</p>
<p>With these two posts, you should have the basics to start writing code that leverages RAC. We have found it great to work with, despite some annoying warts, like a nagging feeling that disposables should not exist. While there is a steep learning curve, the <a href="https://github.com/ReactiveCocoa/ReactiveCocoa/issues">issues page</a> on the ReactiveCocoa project is full of active, helpful, and knowledgeable users who try their best to help newcomers. As the popularity of the framework grows (and I expect it to keep growing), so will the quality and promptness of the help available.</p>
<p>So give RAC a try. If you’re already familiar with functional programming, it will be like seeing an old friend. If you’re not, it will teach you new ways of thinking about your software. And in both cases, it will lead to very expressive code that is far more testable than the code that typically finds its way in iOS apps.</p>
<p><br><br>
<br><br>
<br><br>
<small><br>
<sup><a name="fn1"></a>1</sup> I literally can’t. I am at this point not even positive that all three version of <code class="prettyprint">flatMap</code> obey the three monad laws, but I believe they do. The most interesting thing is that there is yet another method, <code class="prettyprint">mapError</code> that is technically a <code class="prettyprint">flatMap</code>, but on the error part of the <code class="prettyprint">Signal</code>. All in all, <code class="prettyprint">SignalProducers</code> and <code class="prettyprint">Signals</code> are much more complex than regular monads, and I’m not going to pretend I can tell you much more about their theoretical underpinnings, though I suspect that would be a fantastic topic for a post or even paper.<a href="#fn1s">↩︎</a><br>
</small><br>
<br><br>
<br><br>
<small><br>
<sup><a name="fn2"></a>2</sup> We could get the same result by operating on the arrays we get from <code class="prettyprint">comicsCollectionDisplayProducer</code>, but that would assume that they are of the same size and in the same order. Written properly, that would include all sorts of error checking that this approach sidesteps.<a href="#fn2s">↩︎</a><br>
</small></p>
tag:nomothetis.svbtle.com,2014:Post/an-introduction-to-reactivecocoa2015-04-28T21:08:05-07:002015-04-28T21:08:05-07:00An Introduction to ReactiveCocoa<p>A lot of the <a href="http://nomothetis.svbtle.com/error-handling-in-swift">posts</a> I’ve <a href="http://nomothetis.svbtle.com/error-handling-in-swift-part-ii">written</a> <a href="http://nomothetis.svbtle.com/understanding-optional-chaining">so</a> <a href="http://nomothetis.svbtle.com/implicitly-unwrapped-optionals-in-depth">far</a> are by and large foundational work. They are, so to speak, table stakes for functional programming. But once at the table, it’s hard to know exactly where to go. There are many great articles on using these principles to, e.g., <a href="http://chris.eidhof.nl/posts/json-parsing-in-swift.html">parse JSON</a>, but at the end of the day, that’s one problem, there are <a href="https://github.com/thoughtbot/Argo">solid solutions</a> out there, and it doesn’t need to be solved again. Parsing JSON is hardly a reason to adopt functional programming wholesale. Functional programming should help you write better code.</p>
<p>Over the past couple of months, our team at work has been developing an application in pure Swift using the pre-release versions of <a href="http://reactivecocoa.io">ReactiveCocoa</a>, and it has been a complete joy. We have been able to test far more of our code than ever before in unit tests, we have been able to break it into tiny functions that are easy to review on their own, and we have been having a ton of fun. Since RAC, as it is often called, uses and expands on a lot of the topics I’ve written about in the past, I thought it would be good to share.</p>
<p>Let’s get the introductions out of the way. ReactiveCocoa is a functional reactive programming (FRP) framework developed by GitHub, primarily <a href="https://twitter.com/jspahrsummers">Justin Spahr-Summers</a> and <a href="https://twitter.com/joshaber">Josh Abernathy</a>. FRP, for its part, is a specific way of writing and architecting software that creates a malleable abstraction for timelines; RAC implements one version of it for iOS and OS X.</p>
<p>The good folks at GitHub are about to release version 3.0, which is the one we have been using and I will focus on. While version 3.0 is (mostly) backward compatible with version 2.0, we have actually not used 2.0 at all; the basic Swift API has served us well so far, and understanding it will give you the tools to explore the more elaborate features at your leisure. So with that said, let’s get started. I assume you have no idea what FRP is about and will try to build things up from scratch.</p>
<p>As a result, this will be long.</p>
<p>• • • • •</p>
<p>At the base of FRP is the notion of <em>events</em>. Events are simply <em>things that happen</em> — which is obviously a concept that every type of programming supports. However, in ReactiveCocoa, events are first-class citizens; in fact, they have their own type. Here is a summary:<sup><a name="fn1s" href="#fn1">1</a></sup> <sup><a name="fn2s" href="#fn2">2</a></sup></p>
<pre><code class="prettyprint lang-swift">enum Event<T, E: ErrorType> {
case Next(T)
case Error(E)
case Completed
case Interrupted
}
</code></pre>
<p>The <code class="prettyprint">.Error</code> case is the simplest: it represents an error event. The <code class="prettyprint">.Next</code>, <code class="prettyprint">.Completed</code> and <code class="prettyprint">.Interrupted</code> cases are a little different: they imply an ordering. What does a <code class="prettyprint">.Next</code> event follow? What is <code class="prettyprint">.Completed</code>? What got <code class="prettyprint">.Interrupted</code>? Say hello to the next fundamental type: the signal.</p>
<pre><code class="prettyprint lang-swift">struct Signal<T, E:ErrorType> { /*…*/ }
</code></pre>
<p>A <code class="prettyprint">Signal<T, E></code> is a sequence of <code class="prettyprint">Event<T,E></code>s in time, with precise semantics: every event must be of type <code class="prettyprint">.Next</code>, except the last one. The last one can either be an <code class="prettyprint">.Error</code>, a <code class="prettyprint">.Completed</code>, or an <code class="prettyprint">.Interrupted</code>. But the key factor is that these events carry <em>information</em>. That’s the generic types <code class="prettyprint">T</code> and <code class="prettyprint">E</code>, denoting arbitrary and error-specific information in both in <code class="prettyprint">Signal</code> and <code class="prettyprint">Event</code>.</p>
<p>The information <code class="prettyprint">T</code> can be anything: the components of a data stream, the contents of a text field over time, or even a <code class="prettyprint">Void</code> type that signifies something happened, but doesn’t have any actual data (think of a signal that represents button presses; we need to know they happened, but there is no data associated with the button press event).</p>
<p>Here is a valid sequence of events for a signal, one that enumerates the first three letters of the alphabet:</p>
<pre><code class="prettyprint">.Next("a") -- .Next("b") -- .Next("c") -- .Completed
</code></pre>
<p>Here’s another, that enumerates the result of dividing 3 by 3, 2, 1, and 0:</p>
<pre><code class="prettyprint">.Next(1) -- .Next(1.5) -- .Next(3) -- .Error("Division by zero")
</code></pre>
<p>The remaining case, <code class="prettyprint">.Interrupted</code>, can come up when a signal is forcibly stopped, but it has been relatively rare for us, and the framework often handles that case transparently.</p>
<p>• • • • •</p>
<p>Let’s be honest, the examples above for a signal were pretty artificial. That’s because in real life, signals actually come in two flavors, typically referred to as “hot” signals and “cold” signals, and I wanted to avoid mixing them up.</p>
<p><code class="prettyprint">Signal</code> represents hot signals: signals that have no beginning and typically no end, but are simply a set of events in the world that can be observed. UI interactions, for instance, fall nicely within this. Button presses are a signal: they don’t really have a beginning, they just happen. But so do events like push notifications. <code class="prettyprint">Signal</code> can represent any stream of such events, possibly combined.</p>
<p>For instance, suppose we want to update the screen on button press <em>and</em> push notification. We can represent both these events with a single <code class="prettyprint">Signal<Void, NoError></code>, where <code class="prettyprint">NoError</code> is a built-in type that, you guessed it, means the signal can’t error out. This makes sense, since there is no notion of a button press being an error from the application’s standpoint, nor of a push notification being one. The timeline for a signal like that is dead simple:</p>
<pre><code class="prettyprint">… -- .Next(Void) -- .Next(Void) -- .Next(Void) -- …
</code></pre>
<p>In our experience, most of our <code class="prettyprint">Signal</code> instances have had <code class="prettyprint">NoError</code> as their error type. When something doesn’t have a well-defined beginning or end, it becomes more convenient to model it as never failing.</p>
<p>Cold signals, by contrast, are signals that encapsulate a behavior that can be started and that often finishes. A network call is an excellent example: it is started on demand, and it can succeed, returning the data, or it can fail, returning an error code. The type we use for cold signals is <code class="prettyprint">SignalProducer</code>:</p>
<pre><code class="prettyprint lang-swift">struct SignalProducer<T, E:ErrorType> { /*…*/ }
</code></pre>
<p>Like <code class="prettyprint">Signal</code>, a <code class="prettyprint">SignalProducer</code> emits <code class="prettyprint">Event</code>s. The big difference comes in the way the timelines will typically look. For instance, let’s think again about our network call. Its type would likely be <code class="prettyprint">SignalProducer<NSData, NetworkError></code>, where we assume we have a <code class="prettyprint">NetworkError</code> type that conforms to <code class="prettyprint">ErrorType</code>. We have several possible timelines for this signal. One is the successful network call:</p>
<pre><code class="prettyprint lang-swift">| -- .Next(data) -- .Completed
</code></pre>
<p>Here, I have used <code class="prettyprint">|</code> as an indication that the producer was explicitly started. Another timeline is the bad call:</p>
<pre><code class="prettyprint lang-swift">| -- .Error(.NotFound)
</code></pre>
<p>Finally, another one is the cancelled call:</p>
<pre><code class="prettyprint lang-swift">| -- .Interrupted
</code></pre>
<p>But what makes this representation really powerful is that there is no need to assume all the data returns at once. If we have a long-lived data task, say an <code class="prettyprint">NSURLSessionDownloadTask</code> that calls a delegate many times during its execution, it can still be represented by the same type. Here are the equivalent timelines in that case:</p>
<pre><code class="prettyprint lang-swift">| -- .Next(data1) -- .Next(data2) -- .Completed
| -- .Next(data1) -- .Error(.ConnectionLost)
| -- .Next(data1) -- .Interrupted
</code></pre>
<p>Thus, a <code class="prettyprint">SignalProducer<NSData, NetworkError></code> is a generalized representation of a network call that can be adapted to any specific case.</p>
<p>• • • • •</p>
<p>Okay, all of this may make sense, but it still doesn’t explain <em>why</em> anyone would go through the effort of representing things as <code class="prettyprint">Signal</code>s or <code class="prettyprint">SignalProducer</code>s. Nor do we yet know how to create them, or use them. So let’s look at the first part, creating a <code class="prettyprint">SignalProducer</code>.</p>
<p>Comic Cathy is writing an app that keeps track of her comic book collection. The collection is on a server, but she doesn’t want to download the entire thing every time she launches her app, so she has a local store. When the app launches, she wants to populate a table view with her collection. However, she doesn’t want to wait until the app is done syncing; she wants to display what’s in the store first, and then load any updates.</p>
<p>Fresh from learning about <code class="prettyprint">SignalProducer</code>s, Cathy thinks about her data. She sees that what she wants will come in two steps: first an array of existing comics, and then an array with any new comics. Getting the first array could fail if the local store produces an error, and getting the second array could fail if the network call produces an error. Either way, that would be a retrieval error. Oh, and if the store fails, she doesn’t want to make the network call and show the user confusing or incomplete info. Perfect! Cathy can define a function that returns the appropriate producer:</p>
<pre><code class="prettyprint lang-swift">func comicCollectionProducer()
-> SignalProducer<[Comic], RetrievalError>
</code></pre>
<p>What should the implementation be? Let’s make a few simplifying assumptions. Let’s assume that both retrieving the comic info from the local store and retrieving it from the network are synchronous calls. Let’s say the functions are:<sup><a name="fn3s" href="#fn3">3</a></sup></p>
<pre><code class="prettyprint lang-swift">func localComics() -> Result<[Comic], LocalStoreError>
func networkComics() -> Result<[Comic], NetworkError>
</code></pre>
<p>If we look at the API for <code class="prettyprint">SignalProducer</code>, we see that the main initializer has a strange type:</p>
<pre><code class="prettyprint lang-swift">public init(_ startHandler:
(Signal<T, E>.Observer, CompositeDisposable) -> ())
</code></pre>
<p>Ouch. What does that mean? Let’s break it down. First of all, <code class="prettyprint">init</code> takes a closure. This is called the <code class="prettyprint">startHandler</code> because it gets called when the <code class="prettyprint">start</code> method is called on the producer. Now let’s look at the parameters. The first parameter to the handler is a <code class="prettyprint">Signal<T, E>.Observer</code>; this is, in common parlance, a <em>sink</em>: it’s where we send the events that the producer generates. The second parameter is a <em>disposable</em>. This is a memory management mechanism that is specific to ReactiveCocoa; for now, we can ignore it.</p>
<p>Armed with this knowledge, Cathy writes the following implementation for her function:</p>
<pre><code class="prettyprint lang-swift">func comicCollectionProducer()
-> SignalProducer<[Comic], RetrievalError> {
return SignalProducer { sink, disposable in
switch localComics() {
case .Success(let comics):
sendNext(sink, comics)
case .Failure(let error)
sendError(sink, retrievalErrorForStoreError(error))
return // errors terminate the signal
}
switch networkComics() {
case .Success(let comics):
sendNext(sink, comics)
sendCompleted(sink)
case .Failure(let error)
sendError(sink, retrievalErrorForNetworkError(error))
}
}
}
</code></pre>
<p>She first fetches the comics from the local store and sends them along by calling <code class="prettyprint">sendNext</code>. This creates a <code class="prettyprint">.Next</code> event of the appropriate type and emits it on the sink. If that fails, she sends an error to the sink, first turning it into a <code class="prettyprint">RetrievalError</code>.</p>
<p>If the local fetch completes successfully, she carries out the network call and repeats the process. The only difference is that, since there is no more work to be done after sending the network data, she calls <code class="prettyprint">sendComplete</code>, thus terminating the signal.</p>
<p>To her delight, everything works.</p>
<p>• • • • •</p>
<p>Still, this doesn’t seem like it’s a brilliant argument for using ReactiveCocoa, does it? Or for thinking all those posts about error handling and <code class="prettyprint">flatMap</code> were particularly useful. That’s because Cathy’s implementation doesn’t make use of the standard library of functions that ships with RAC and, indeed, with any FRP framework.</p>
<p>You see, signals are fundamentally collections. And just like one can define <code class="prettyprint">map</code>, <code class="prettyprint">reduce</code>, <code class="prettyprint">flatMap</code>, and other functions on arrays, one can define similar functions on signals and signal producers. So the power of this representation is in the way it allows us to manipulate signals as collections. For instance, what if I told you that the initializer above could be rewritten as:</p>
<pre><code class="prettyprint lang-swift">func comicCollectionProducer()
-> SignalProducer<[Comic], RetrievalError> {
let localFetchProducer = SignalProducer(result:localComics())
|> mapError(retrievalErrorFromStoreError)
let networkFetchProducer = SignalProducer.try(networkComics)
|> mapError(retrievalErrorFromNetworkError)
return localFetchProducer |> concat(networkFetchProducer)
}
</code></pre>
<p>Now it’s looking more interesting, isn’t it? But of course, a lot more dense. So let’s take a look line by line at what is happening. I am going to focus on the <em>meaning</em> of the lines, and less on the mechanics of how every detail is achieved, because part of the power of FRP is that it gives you a vocabulary that abstracts those mechanics away.</p>
<p>At a high level, we are creating two producers and concatenating them. The <code class="prettyprint">|></code> operator is an extremely versatile and powerful operator whose mechanics we are going to ignore for now. When you read it, just read “take the thing on the left, and do the thing on the right to it once the signal is started”.</p>
<p>That last bit is crucial, by the way. The <code class="prettyprint">|></code> operator creates a <em>specification</em>. It doesn’t do anything during the call to <code class="prettyprint">comicCollectionProducer</code>; instead, it defers all actions to the moment when the <code class="prettyprint">SignalProducer</code> returned by the function is started.</p>
<p>Reading the return line in that light, we see it says “take the producer on the left and concatenate to it the producer on the right”. In this context, “concatenate” means “wait until the first one is done, and then start the second one”. Simple. Crucially, the second one is started <em>only</em> if the first one completes; if it is interrupted or errors out, the second one is never started. This is exactly the behavior Cathy wants.</p>
<p>Now let’s take a look at how we create the two producers. The first producer, <code class="prettyprint">localFetchProducer</code>, is created in two steps. First, we create a new <code class="prettyprint">SignalProducer</code> from the result of the <code class="prettyprint">localComics()</code> call. This equivalent to writing the following:</p>
<pre><code class="prettyprint lang-swift">SignalProducer { sink, disposable in
switch localComics() {
case .Success(let comics):
sendNext(sink, comics)
sendCompleted(sink)
case .Failure(let error)
sendError(sink, error)
}
}
</code></pre>
<p>It’s such a common thing to want to write that the framework provides this convenience initializer. Now if you look at the code carefully, you’ll see that the type of this producer is <code class="prettyprint">SignalProducer<[Comic], LocalStoreError></code>. However, the signature of the <code class="prettyprint">comicCollectionProducer</code> function calls for the error to be a <code class="prettyprint">RetrievalError</code>. That’s where the second part of the creation comes in.</p>
<p>Per our previous semantics, the second part of the initialization of <code class="prettyprint">localFetchProducer</code> says “take the signal producer and map its errors to new errors using the <code class="prettyprint">retrievalErrorFromStoreError</code> function”. Again, it looks like this:</p>
<pre><code class="prettyprint lang-swift"> |> mapError(retrievalErrorFromStoreError)
</code></pre>
<p>In other words, if the first signal results in an array of comics, this line has no effect. If, however, it results in an error, it takes that error and uses the <code class="prettyprint">retrievalErrorFromStoreError</code> to turn it into a <code class="prettyprint">RetrievalError</code>. Since this is a specification rather than a direct action, what the <code class="prettyprint">|></code> operator returns is actually another signal producer, with type <code class="prettyprint">SignalProducer<[Comic], RetrievalError></code>. Victory! That’s what we wanted.</p>
<p>The second producer is slightly different. We want to make the network call, but it’s very important that it happen <em>after</em> the local store fetch, because we don’t want to block or delay that fetch (remember that <code class="prettyprint">networkComics</code> is synchronous).</p>
<p>If we were to use the same initializer as before, <code class="prettyprint">networkComics</code> would get called at initialization, i.e. during the <code class="prettyprint">comicCollectionProducer</code> call. That’s fine for the local store call, but definitely not for the network call, which should not be made if, say, the local store call ends in error.</p>
<p>Fortunately, that too is a very common scenario, and <code class="prettyprint">SignalProducer</code> has the <code class="prettyprint">try</code> static function that instead of taking a <code class="prettyprint">Result</code> takes a closure that returns a <code class="prettyprint">Result</code>. This function gets called only when the <code class="prettyprint">start</code> method is called on the producer. Effectively, it can take a function, like <code class="prettyprint">networkComics</code>, and wait until it is started to execute it.</p>
<p>Once again, the signal producer returned by <code class="prettyprint">SignalProducer.try(networkComics)</code> has the wrong type: <code class="prettyprint">SignalProducer<[Comic], NetworkError></code>. Like before, we deal with that through <code class="prettyprint">mapError</code>, which is the second line of this call.</p>
<p>• • • • •</p>
<p>If you’re still with me, you waded through twelve paragraphs to explain five lines of code. First of all, congratulations. Second, isn’t that cool? The semantics of that code are precise <em>and</em> concise — and more abstract than anything I’ve ever been able to write with any framework. At the end of the day, this is what that code is saying:</p>
<ul>
<li>Try to fetch things locally, and turn any errors into something we can understand.</li>
<li>If that succeeds, do a network fetch, and again turn any errors into things we can understand.</li>
</ul>
<p>The fact that we can express it almost as concisely as we can say it at that high level is incredible. And in addition to being concise and high-level, each part of this process is testable in isolation:</p>
<ul>
<li>The network and local fetches can be tested by themselves.</li>
<li>The error transformations can be tested by themselves.</li>
</ul>
<p>Finally, if we make <code class="prettyprint">networkComics</code> and <code class="prettyprint">localComics</code> parameters to <code class="prettyprint">comicCollectionProducer</code>, <em>the entire chain can be unit tested</em>. In a completely controlled manner. That’s truly golden.</p>
<p>• • • • •</p>
<p>Oh, man. It’s the end of the day, and Cathy just decided she really would rather wait for everything to sync. And she really wants to show her work to her friend in like an hour. How can she rewrite the whole thing to return everything at once quickly and without error?</p>
<p>Turns out, she doesn’t have to. All she needs to do is change the return line in <code class="prettyprint">comicCollectionProducer</code> from this:</p>
<pre><code class="prettyprint lang-swift">return localFetchProducer |> concat(networkFetchProducer)
</code></pre>
<p>to this:</p>
<pre><code class="prettyprint lang-swift">return localFetchProducer |> concat(networkFetchProducer)
|> reduce([]) { $0 + $1 }
</code></pre>
<p>It’s that simple. I promise.</p>
<p>• • • • •</p>
<p>Alright, I’ve shown you a reasonably thorough example of how to create a <code class="prettyprint">SignalProducer</code>, including creating simple ones from primitives and combining them into the producer we want using the <code class="prettyprint">|></code> operator and various higher order functions. That’s half of using FRP. The other half is how to use the events the producer emits. This post has grown enormous already, so I’m going to leave that aspect for <a href="http://nomothetis.svbtle.com/reactivecocoa-ii-reacting-to-signals">my next post</a>. Stay tuned.</p>
<p><br><br>
<br><br>
<br><br>
<small><br>
<sup><a name="fn1"></a>1</sup> Swift 1.2 <em>still</em> doesn’t support declarations like that one; the cases have to instead take <code class="prettyprint">Box<T></code> and <code class="prettyprint">Box<E></code> types. I have removed that for simplicity and because I’m hopeful that one day, that blight on my soul will be lifted and this post will be both easy to follow and valid Swift.<a href="#fn1s">↩︎</a><br>
</small></p>
<p><small><br>
<sup><a name="fn2"></a>2</sup> SWIFT 2 MAKES THIS CORRECT CODE!! Ahem. Carry on.<a href="#fn2s">↩︎</a><br>
</small></p>
<p><small><br>
<sup><a name="fn3"></a>3</sup> I’ve <a href="http://nomothetis.svbtle.com/error-handling-in-swift">written before</a> about the <code class="prettyprint">Result</code> enum, and <a href="http://twitter.com/cocoaphony">Robert Napier</a> wrote a nice implementation that has been <a href="https://github.com/antitypical/Result">merged</a> into the microframeworks maintained by <a href="https://twitter.com/rob_rix">Rob Rix</a>.<a href="#fn3s">↩︎</a><br>
<small></small></small></p>
tag:nomothetis.svbtle.com,2014:Post/you-are-more-than-a-coder2015-02-25T09:35:32-08:002015-02-25T09:35:32-08:00You Are More Than a Coder<p><br><br>
<em>The answer — by demonstration — would take care of that, too.</em><br><br>
— Isaac Asimov, <a href="http://www.multivax.com/last_question.html"><em>The Last Question</em></a></p>
<p><br></p>
<p>From time to time, I stumble across something beautiful and true. It happened recently, and this is me trying to share it. It has a formal name, the <a href="http://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence">Curry-Howard correspondence</a>, but it’s one of those rare bits of knowledge that, once known, feel so inevitable, they almost don’t <em>need</em> a name. It may not impress you as deeply as it did me; you may not see the point; you may not care. But it is the most profound and elegant thing I know about programming.</p>
<p>• • • • •</p>
<p>Programming is an act of creation. Constrained by business needs, by hardware limitations, by our own reach which may exceed our grasp, we are still, in the end, creators. But — we are not artists. There is elegance in what we do; it is not the goal. There can be beauty in the product; it is subordinate to function. There can even be transcendence; it is not a given. We have obligations: stability, reliability, functionality, effectiveness, productivity, testability, maintainability; we have jobs, and if art results, fantastic; if it doesn’t, that’s fine.</p>
<p>Neither are we engineers or scientists. We don’t design physical objects; we don’t care about gravity, electricity, or magnetism; evolutions is irrelevant to us; neuroscience is a mystery. We create in an abstract world that interacts, in points, with the concrete, but that is separate from it. We manipulate <em>ideas</em>; we transform <em>data</em>; we process <em>knowledge</em>; we present <em>concepts</em>. Under it all, no matter how we dress things up, what we do is invent new ways to move around zeros and ones. There’s a name for our kind: we are mathematicians.</p>
<p>Some of us may not think so. Some of us hated mathematics in school, some ran from calculus, some balked at statistics. Some of us came to programming through an altogether different route, via the liberal or fine arts. Some of us may even be <em>bad</em> mathematicians. But mathematicians we all are. That is what the Curry-Howard correspondence tells us.</p>
<p>• • • • •</p>
<p>If you’re like me, your first instinct when you look at a function is to wonder what it <em>does</em>. Take the following Ruby method:</p>
<pre><code class="prettyprint lang-ruby">def add_numbers(arr)
arr.reduce { |memo, num|
memo + num
}
end
</code></pre>
<p>What it does is clear: it adds (<a href="http://nomothetis.svbtle.com/types-as-units">or concatenates…</a>) the values in an array. But let’s look at it a different way; let’s look at only the declaration: <code class="prettyprint">def add_numbers(arr)</code>. Even by itself, it carries information: it says there is a method that takes an object as a parameter and returns another object.<sup><a name="fn1s"></a><a href="#fn1">1</a></sup></p>
<p>Let’s look at a similar method in Swift:</p>
<pre><code class="prettyprint lang-swift">func addNumbers(arr:[Int]) -> Int {
return reduce(arr, 0) { memo, num in
return memo + num
}
}
</code></pre>
<p>What does the declaration tell us this time? It tells us hat there is a function that takes an <code class="prettyprint">Array</code> of <code class="prettyprint">Int</code>s and returns an <code class="prettyprint">Int</code>. Obviously this declaration conveys more information than the Ruby one; that’s an important point and I’ll get back to it later. For now, let’s just recognize that in both languages, declarations contain information.</p>
<p>I’m still phrasing the information in terms of what the function or method <em>does</em>. It’s equally appropriate to phrase it as a statement about the world:</p>
<ol>
<li>The Ruby method declaration states that <em>there exists a way to transform</em> an object into a (possibly different) object.</li>
<li>The Swift function declaration states that <em>there exists a way to transform</em> an <code class="prettyprint">Array</code> of <code class="prettyprint">Int</code>s into a single <code class="prettyprint">Int</code>. </li>
</ol>
<p>Once you start making statements about the world, though, you have to back them up. Doing so in this case is easy: write at an implementation. How do you show that there is a way to transform an object into another object? Write code that does it! How do you show there is a way to transform an array of integers into a single integer? Write code that does it! And how do you know your implementation is valid? <em>You type-check it.</em></p>
<p>And this is the important caveat. A proof of a declaration is <em>valid</em> if it type-checks. But that doesn’t mandate a particular implementation. Here is a Ruby method that type-checks,<sup><a name="fn2s"></a><a href="#fn2">2</a></sup> i.e. that matches its declaration:</p>
<pre><code class="prettyprint lang-ruby">def add_numbers(arr)
return nil
end
</code></pre>
<p>This implementation doesn’t do what the function name says, but that doesn’t prevent it from type-cheking. Likewise, this Swift implementation function fulfills <em>its</em> declaration, despite not adding the numbers either:</p>
<pre><code class="prettyprint lang-swift">func addNumbers(arr:[Int]) -> Int {
return 0
}
</code></pre>
<p>From this, we can get to the essence of the Curry-Howard correspondence, which is that type systems define a <em>logic</em>: a set of statements that can be made and proven <em>using only types</em>. Function declarations are the statements; implementations are the proof. Since the name of a function isn’t part of its type, it places no constraints on the proof; that’s why we can have a Swift function <em>named</em> <code class="prettyprint">addNumbers</code> that does no such thing. What we can’t do is declare our <code class="prettyprint">addNumbers</code> function as above, but have it return a <code class="prettyprint">String</code>. Its type doesn’t allow it.</p>
<p>Put all this another way, every time we write a function declaration, we state a theorem, and every time we write an implementation that type-checks, we prove it. As I said, we are all mathematicians.</p>
<p>• • • • •</p>
<p>If type systems define the statements that can be made and proven, that would imply that different type systems let you prove different things. And indeed, that is the case. Some type systems are powerful and others are not, in a very precise sense. Ruby’s type system is not very powerful, because not many statements can be made with it. In fact, only one statement can be made. Here it is:</p>
<p><em>Every group of objects can be transformed into an object.</em></p>
<p>To be a little more charitable, there is in fact an infinity of statements that can be made, but they all follow the same pattern:</p>
<ul>
<li>There is a way to create an object.</li>
<li>There is a way to transform an object into an object.</li>
<li>There is a way to transform two objects into an object.</li>
<li>There is a way to transform three objects into an object.</li>
<li>Etc.</li>
</ul>
<p>This is a fundamental limitation of the language — but notice that it doesn’t make the language any less useful for software development. It’s simply that its type system isn’t very expressive.</p>
<p>Swift, by contrast, is much more expressive. Here are a few statements that can be made with Swift function declarations:</p>
<ul>
<li>There is a way to transform a string into an integer.</li>
<li>There is a way to transform a URL into an HTTP response code.</li>
<li>There is a way to transform a touch and a map view into geographical coordinates.</li>
<li>There is a way to transform an array of integers into an image.</li>
</ul>
<p>As before, we need to remember that statements being more specific is not the same as their admitting only one implementation (in other words, a unique proof). However, an expressive type system serves to narrow down the possible implementations to only those that satisfy the statements’ type, and an automated type checker serves to verify that the type declarations are respected — that is, proven.</p>
<p>And this is where we come full circle to how this knowledge is changing the way I program. Because while the Curry-Howard correspondence shows that there is a direct mapping between doing something and proving that it can be done, there is a world of difference in how I approach a task and how I approach a proof.</p>
<p>In the past, my mental process when I wrote a function has been:</p>
<ol>
<li>What does my function need to do?</li>
<li>What parameters does it need to do it?</li>
<li>Implement it.</li>
</ol>
<p>I am now shifting to a different way of thinking:</p>
<ol>
<li>What truth do I know about the world?</li>
<li>Prove it.</li>
</ol>
<p>The first two questions are condensed into one, because the parameters are the first part of any theorem: given X, Y is true. By tying them at the hip, I find that I often have to think about whether the statement makes sense before starting to write code, particularly if I try to write in a <a href="http://en.wikipedia.org/wiki/Referential_transparency_(computer_science)">referentially transparent</a> style.</p>
<p>The action item, though, is where the main difference lies. An implementation has to work; a proof must be ironclad. While the type checker will verify that my implementation proves the function declaration, I am invariably trying to prove a much more specific statement than can be expressed in a declaration. For instance, I would not be trying to prove <em>just</em> that a touch and a map can be transformed into a coordinate; I would be trying to prove that they can be transformed into <em>the coordinate of the point on the map where the touch occurred</em>. This is not expressible in the function declaration, but it is still a provable fact about the world. I find that thinking about my functions as proofs makes me write better code, code that is more cognizant of edge cases and error conditions.</p>
<p>This approach is completely language-agnostic and type-system agnostic. Yes, stronger type systems allow the function declaration to be more specific. Since all strong type systems typically include a type checker in the compiler toolchain, a side-benefit is that they also verify the declaration’s proof is valid.<sup><a name="fn3s"></a><a href="#fn3">3</a></sup> But once again, valid is not necessarily useful. I’m trying to encourage a different way of thinking about what it means to program, not pushing a particular language or type system.</p>
<p>• • • • •</p>
<p>I’ve tried to keep this post light on the theory of the Curry-Howard correspondence, because what was revelatory to me wasn’t the mathematics of it, but rather the idea that I could approach programming as an exercise in proving theorems. For actual details, I highly recommend Alyssa Carter’s <a href="https://codewords.hackerschool.com/issues/one/type-systems-and-logic">fantastic introduction</a> to the formalism of type systems and the logics they correspond to; it’s an incredible read and I learned a lot from it — with a grin on my face the whole time. This stuff is just <em>cool</em>.</p>
<p>If you’re not so inclined, though, I still hope you have gotten something out of this rumination. If nothing else this: that you, the programmer, are a mathematician. Every time you’ve written a function declaration, you have had something to prove. And proven it you have, over and over again.</p>
<p><br><br>
<br><br>
<br><br>
<small><br>
<sup><a name="fn1">1</a></sup> In Ruby, every scope has a return value, and it is the last value computed in the scope. Therefore, every function has a return value, whether <code class="prettyprint">return</code> is explicitly called or not. In addition, everything in Ruby is an object (including entities other languages might treat as primitives, like <code class="prettyprint">nil</code>).<a href="#fn1s">↩︎</a><br>
</small></p>
<p><small><br>
<sup><a name="fn2">2</a></sup> Ruby does have types; they’re just so simple that a Ruby method is consistent with its declaration by virtue of being syntactically correct.<a href="#fn2s">↩︎</a><br>
</small></p>
<p><small><br>
<sup><a name="fn3">3</a></sup> And as <a href="http://www.idris-lang.org">increasingly powerful type systems</a> start appearing, more and more of the proof will be verifiable.<a href="#fn3s">↩︎</a><br>
</small></p>
tag:nomothetis.svbtle.com,2014:Post/types-as-units2015-02-18T20:20:31-08:002015-02-18T20:20:31-08:00Types as Units<p>A few years ago, Steve Yegge wrote a <a href="https://plus.google.com/110981030061712822816/posts/KaSKeg4vQtz">great piece</a> arguing that software developers can be divided into conservatives and liberals, and moreover that, like in politics, there are some issues where the dividing lines are very clear. The first issue on his list was type systems. Given how different Swift’s type system is from Objective-C’s, I’m going to take a more general look at types as a concept. You’ll find that, like many people who were enthusiastic about Swift from the get-go, I am a software conservative on this issue.</p>
<p>The prototypical example of a liberal language is Ruby. Ruby has no compile-time type checking. As long as your syntax <em>looks</em> like it belongs to a Ruby program, the interpreter will happily load it and try to do something with it — but it will crash your app if you messed up and tried to add a <code class="prettyprint">Restaurant</code> and a <code class="prettyprint">PoisonDart</code> (you have an interesting problem space).</p>
<p>The paragon of conservative languages is Haskell. Its compiler will exhaustively check every implication of your declared types and only produce an executable if they are consistent. Your application will rarely crash once it’s running, but the compiler will not let you get away with trying to <code class="prettyprint">juggle</code> an <code class="prettyprint">Airplane</code>.</p>
<p>On the spectrum, Swift falls much closer to Haskell than to Ruby. Objective-C as used by most people I know and open-source projects I’ve seen is still closer to Haskell than to Ruby, but only by a little; it can <em>potentially</em> be very close to Ruby, as it uses dynamic dispatch under the hood and practically everything can be cast to <code class="prettyprint">id</code>.</p>
<p>But really … what are these “types” that so divide us?</p>
<p>• • • • •</p>
<p>Before I ever wrote a line of code, I studied engineering. Early physics classes emphasized the importance of <em>units</em>: a ball doesn’t have a speed of 5, it has a speed of 5 <em>meters per second</em>. Non-controversial, but there’s a subtlety here. Suppose I want to find another speed. Nothing in arithmetic prevents me from multiplying 5 meters per second by 10 apples per pear. I’ll get fifty…meter-apples per second-pear? That makes zero sense. But <em>why</em>?</p>
<p>To say that 5 is the <em>speed</em> of a ball implies that 5 has <em>units</em> of distance per unit of time, and vice versa. The reason the result was nonsense is clearly that meter-apples per second-pear is <em>by definition</em> not a unit of speed — any such unit must be some distance over some time interval.</p>
<p>Put that way, units seem tautological, except for this: <em>arithmetic doesn’t understand units</em>. Units constrain arithmetic, defining how quantities with units combine to create quantities with other units — and letting you know that certain arithmetical operations give nonsense results for your problem and certain operations aren’t allowed at all.</p>
<p>For instance, you can always multiply quantities with disparate units — but you might get results that are in meter-apples per second-pear, which might not be what you were looking for. On the other hand, you <em>can’t</em> add quantities with disparate units: 5 meters per second can’t be added 20 inches per year; you have to convert one to unit to the other. Units annotate our quantities and imbue them with additional information that, when enforced, keeps results <em>consistent</em>.</p>
<p>• • • • •</p>
<p>Several of my classes featured equations galloping across the whiteboard like Cossack armies in the Russian winter, and my professors often brought up <a href="http://en.wikipedia.org/wiki/Dimensional_analysis">dimensional analysis</a> as a useful tool for double-checking our work. After a derivation that would often take a page or two, they recommended looking at the resulting units of all the quantities before plugging the final numbers in, to make sure that we were getting the right units out.</p>
<p>None of us ever did that.</p>
<p>It’s not that we didn’t care. We were learning to design airplanes; an error would result fiery death; of course we cared. (Okay, we didn’t care <em>that</em> much; we were students.) The problem was that it was an extra set of computations that was time-consuming and that was about as good as looking at our results and making sure they passed the smell test, i.e. that they were in the right ballpark. It wouldn’t save us on a test if we really screwed up, but we trusted our symbolic manipulation skills enough to say that if 1. we got a result and 2. the result was in the right ballpark, the result was probably right.</p>
<p>If we’d had a way to put the final algebraic result in a computer and have it spit out the units, though, a lot more of us would have done it. After all, manually computing the units is tedious (and error-prone), but using an automated tool to sanity-check our work would have been just common sense.</p>
<p>Here’s where I’m going with this: <em>types</em> in software development are directly equivalent to <em>units</em> in engineering and science. They aren’t <em>necessary</em> to do your work, they don’t prevent you from screwing up, and they don’t prevent you from being inconsistent — but they help you understand what the entities you’re dealing with are.</p>
<p><em>Automated type checking</em>, on the other hand, is a tool that helps you <em>be consistent</em>. And the more powerful your type system, the surer you can be of your code’s internal consistency.</p>
<p>• • • • •</p>
<p>The value of consistency to a software project is hard to quantify. Consistency doesn’t equal quality, and it doesn’t even equal sanity. But I am a conservative when it comes to type systems because it does equal <em>focus</em>.</p>
<p>Back in school, when I made a mistake that resulted in a quantity with nonsense units, I felt like an idiot. Seriously, at what point did I think I’d multiply speed by distance and get a pressure? The mistake was completely preventable and I had nevertheless burned time thinking about my problem with an inconsistent mental model of the world. For however many computations until I caught a given unit error, my mental model of the universe had that error as a valid thing to do.</p>
<p>And sometimes the model would stay wrong for a good long while! A page or two of calculations! If someone had told me, from the get-go, that what I was trying to do was nonsense, all that work would have been saved, and I would have spent more time building an appropriate model and <em>solving the actual problem</em>. That someone, when I program, is the compiler.</p>
<p>In a language like Ruby, a type error will go undetected until runtime. Consider this simple method to add the numbers in an array:</p>
<pre><code class="prettyprint lang-ruby">def add_numbers(arr)
arr.reduce { |memo, obj|
memo + obj
}
end
</code></pre>
<p>It does its job magnificently — as long as we’re passing in an array with numbers. If we pass in an array with strings, though, it concatenates them. Most of the time, this is fine. But what if I am manipulating an array of numbers represented as strings, say <code class="prettyprint">["1", "2", "3"]</code>. Mentally, I could very well be thinking of that array as numbers, and when I pass it to the array, I would get back <code class="prettyprint">"123"</code> instead of <code class="prettyprint">6</code>. At some point, this inconsistency will bite me — but not until I’ve expended significant effort writing code that assumes there is no inconsistency.</p>
<p>In Swift, by contrast, the method is explicit:</p>
<pre><code class="prettyprint lang-swift">func addNumbers(nums:[Int]) -> Int {
return reduce(nums, 0) { memo, num in
return memo + num
}
}
</code></pre>
<p>I could never call <code class="prettyprint">addNumbers</code> with <code class="prettyprint">["1", "2", "3"]</code>, because that array’s type would be inferred as <code class="prettyprint">[String]</code>, and the compiler would immediately let me know that I am trying to do something inconsistent. That wouldn’t by itself solve the problem (do I need to make the method more generic, or do I need to convert the strings into integers?), but at least it would prevent me from writing code as if there were no problem.</p>
<p>• • • • •</p>
<p>I emphasize that this is personal preference. I can’t claim that I will write code faster, or that my code will be better, due to the type system. I merely say that the compiler will catch a certain class of mistake early in the development process, and force me to keep an internally-consistent model of the world — to <em>focus</em> on my model. I value that, but others might prefer the freewheeling development afforded to them by Ruby. That’s fine.</p>
<p>What I do want to emphasize, though, is how much like units types are. You can do science and engineering correctly without doing dimensional analysis. But if you get into an inconsistent state with your units, they will <a href="http://en.wikipedia.org/wiki/Gimli_Glider">bite you</a> — perhaps <a href="http://en.wikipedia.org/wiki/Mars_Climate_Orbiter#Cause_of_failure">catastrophically</a>. The only way to avoid such issues is to do (correct) dimensional analysis before using the results of any calculations.</p>
<p>Software has it a little easier. During development, it’s okay to get in an inconsistent state: the app will crash in the test server, or the compiler will whine, and the bug will be fixed before being rolled out to the real world. Even in production, most applications aren’t so critical that an occasional crash will have dire consequences.</p>
<p>Some are, though. And those applications — avionics, guidance, air traffic control — are often written in type safe languages like <a href="http://en.wikipedia.org/wiki/Ada_(programming_language)#History">Ada</a>. Even when written in more traditional languages, their code style guidelines are <a href="http://spinroot.com/gerard/pdf/P10.pdf">very stringent</a>, in hopes that the compiler and analyzer will catch more bugs. Isn’t that interesting?</p>
<p>It makes sense, if you think about it. Mission critical software has a very high cost of failure, and is often difficult to test until it is actually controlling a plane, or guiding a missile, or directing air traffic — and those are terrible, horrible, no good, very bad times to discover an internal consistency error. Even in a testing context, crashing a test plane is a multi-million dollar error, and I’m sure air traffic control validation tests are not cheap.</p>
<p>What type systems give us, then, is a particular class of verifiable facts about our code base. In some contexts, knowing those facts is not particularly useful; in others, it is absolutely critical. But no matter what the actual needs of the software system itself, one can have a preference for up-front verifiability or a preference for implicit trust in the developer’s abilities. I tend to prefer verifiability, stodgy conservative that I am.</p>
<p>• • • • •</p>
<p>“Verifiability” … that’s very very close to “provability”, isn’t it …? Does that mean that type systems let us prove certain things?</p>
<p>Yes, as a matter of fact.</p>
<p>And this newfound knowledge is slowly changing how I approach programming. I’ll go into that soon.</p>
tag:nomothetis.svbtle.com,2014:Post/magical-future-swift-is-almost-here2015-02-15T09:01:00-08:002015-02-15T09:01:00-08:00Magical Future Swift Is (Almost) Here<p>I’ve been holed up dealing with Metal for a bit (which I was completely unfamiliar with, and therefore unable to blog about), but Swift 1.2 came out last week, rousing me out of my graphics-induced coma. And boy was I in for a surprise. Remember my posts on <a href="http://nomothetis.svbtle.com/the-culmination-part-ii">monads</a>, and all my talk of Magical Future Swift? It’s here!</p>
<p>Well…almost.</p>
<p>• • • • •</p>
<p>A brief recap for those who don’t remember: I motivated my discussion of Magical Future Swift by talking about the nested optionals problem, wherein Birthday Beth wants to have a super fun birthday party, but only if all of her friends show up:</p>
<pre><code class="prettyprint">func partyGameForFriend1(friend1:Friend?,
friend2:Friend?,
friend3:Friend?) -> Game {
if let f1 = friend1 {
if let f2 = friend2 {
if let f3 = friend3 {
return Game.Superfun(f1, f2, f3)
}
}
}
return Game.Regular
}
</code></pre>
<p>Recognizing how awkward this was (as has everyone who has used Swift 1.1 and below), I made the suggestion that Magical Future Swift would allow something different: <em>for-comprehensions</em>:</p>
<pre><code class="prettyprint">// Magical Future Swift
func partyGameForFriend(friend1:Friend?,
friend2:Friend?,
friend3:Friend?) -> Game {
let optionalGame = for {
f1 <- friend1
f2 <- friend2
f3 <- friend3
} yield {
Game.Superfun(f1, f2, f3)
}
return optionalGame ?? Game.Regular
}
</code></pre>
<p>Basically, the <code class="prettyprint"><-</code> operator unwraps the optionals, and calls the yield block with the unwrapped result, but <em>only if all the optionals are unwrapped</em>. If you’ve looked at Swift 1.2, this should be awfully familiar. It’s the new, supercharged <code class="prettyprint">if-let</code>:</p>
<pre><code class="prettyprint">// Swift 1.2
func partyGameForFriend(friend1:Friend?,
friend2:Friend?,
friend3:Friend?) -> Game {
if let f1 = friend1,
let f2 = friend2,
let f3 = friend3 {
return Game.Superfun(f1, f2, f3)
}
return Game.Regular
}
</code></pre>
<p>I didn’t discuss the possibility at the time (and to be truthful, was only vaguely aware of it), but Swift 1.2 adds some extra sweetness to the deal in the form of guard clauses. Suppose the super fun party only works if Beth’s first two friends are still on good terms. With the new <code class="prettyprint">if-let</code> syntax, we can do that without an extra <code class="prettyprint">if</code> block:</p>
<pre><code class="prettyprint">// Swift 1.2
func partyGameForFriend(friend1:Friend?,
friend2:Friend?,
friend3:Friend?) -> Game {
if let f1 = friend1,
let f2 = friend2,
let f3 = friend3
where f1.isGoodFriendsWith(f2) {
return Game.Superfun(f1, f2, f3)
}
return Game.Regular
}
</code></pre>
<p>This will <em>only</em> call the super fun game branch if all the values exist <em>and</em> <code class="prettyprint">f1</code> is still good friends with <code class="prettyprint">f2</code>. Pretty powerful stuff. To make things even better, we can use an optional unwrapped in an early <code class="prettyprint">let</code> declaration in a later let declaration. Suppose, for instance, that inviting <code class="prettyprint">friend3</code> always results in her best friend showing up (if she has one). We could write:</p>
<pre><code class="prettyprint">// Swift 1.2
func partyGameForFriend(friend1:Friend?,
friend2:Friend?,
friend3:Friend?) -> Game {
if let f1 = friend1,
let f2 = friend2,
let f3 = friend3,
let f4 = f3.bestFriend() // Friend.bestFriend() -> Friend?
where f1.isGoodFriendsWith(f2) {
return Game.Superfun(f1, f2, f3)
}
return Game.Regular
}
</code></pre>
<p>This works as long as the right side of the binding (i.e. <code class="prettyprint">f3.bestFriend()</code>) returns an optional—which makes sense; if it didn’t, we could simply work it in the body of the <code class="prettyprint">if-let</code> block.</p>
<p>The only real difference between Magical Future Swift’s for-comprehensions and the <code class="prettyprint">if-let</code> version is that <code class="prettyprint">if-let</code> does not return a value; instead it behaves as a traditional control flow statement. But this is, in fact, a little limiting.</p>
<p>• • • • •</p>
<p>If you remember, for-comprehensions weren’t limited to optionals. They could handle any monadic type: optionals, lists, futures, errors, etc. Swift 1.2’s <code class="prettyprint">if-let</code> syntax doesn’t let us do that—and the fact that <code class="prettyprint">if-let</code> statements don’t return a value actually makes it somewhat difficult to adapt them.</p>
<p>Let’s be specific. What would it look like if we used <code class="prettyprint">if-let</code> in the context of lists? Let’s review the example where Scheduling Sam tries to create match-ups between players from different cities for a chess tournament, presented as a for-comprehension:</p>
<pre><code class="prettyprint lang-swift">func matchupsForCities(cities:[City]) -> [Matchup] {
return for {
city <- cities
p1 <- teamAForCity(city)
p2 <- teamBForCity(city)
} yield {
Matchup(city:city, player1:p1, player2:p2)
}
}
</code></pre>
<p>With the appropriate semantics, the <code class="prettyprint">if-let</code> idiom can be adapted:</p>
<pre><code class="prettyprint lang-swift">func matchupsForCities(cities:[City]) -> [Matchup] {
var matchups = [Matchup]()
if let city = cities
let p1 = teamAForCity(city)
let p2 = teamBForCity(city) {
matchups.append(Matchup(city:city,
player1:p1,
player2:p2))
}
return matchups
}
</code></pre>
<p>This follows the same rules as the optional binding: the right side of the <code class="prettyprint">let</code> bindings must be lists, and the left side will be whatever the elements of the list are: City or Player, in our case. But there’s that nasty <code class="prettyprint">var</code> that we have to declare at the beginning, because <code class="prettyprint">if-let</code> doesn’t return values. And if it <em>did</em> return values, we’d have to introduce a new keyword, like <code class="prettyprint">yield</code>, to differentiate what is supposed to be returned as a value from the <code class="prettyprint">if-let</code> statement from an early return call that exits the function.</p>
<p>To add a further blemish, <code class="prettyprint">if-let</code> isn’t very intuitive in this context. While we could get used to reading it, in the case of lists, as “do this if there are still city-and-two-player-combinations that haven’t been processed”, it’s not the first interpretation; <code class="prettyprint">for-let</code> would probably work better.</p>
<p>So while I really like the <code class="prettyprint">if-let</code> idiom for optionals, it’s not easily extensible. What happens when we deal with futures and promises? At that point, should we stick with <code class="prettyprint">if-let</code>, try <code class="prettyprint">for-let</code>, or have a more dedicated <code class="prettyprint">when-let</code> or <code class="prettyprint">after-let</code>? What about other monadic types? Does Swift have to provide specific syntax for every monad we could possibly want to use? The advantage of for-comprehensions is that they’re <em>just</em> generic enough that they can acceptably work in any context. The <code class="prettyprint">if-let</code> idiom is less intuitive to expand.</p>
<p>Of course, some of this is habit, and, much like before, I have no particular intuition as to where the language is headed. In fact, I’d say that my focus on for-comprehensions made me miss the obvious <code class="prettyprint">if-let</code> extensions that made optional handling better, despite them having been discussed on the developer forums a few times. </p>
<p>• • • • •</p>
<p>At the end of the day, I have to try to remember Chris Lattner’s admonition that Swift is intended above all to be a practical language. The new <code class="prettyprint">if-let</code> syntax solves an acute existing problem; full for-comprehensions would be nice to have <em>in my view</em>, but people aren’t exactly clamoring for them (I checked by searching the dev forums; nowhere to be found).</p>
<p>So Magical Future Swift is almost here. But it might stay almost here for quite a while. As for myself, I look forward to Swift Next. Extrapolating the release schedule so far, it would be shipping sometime in June.</p>
<p>Say, does Apple have some sort of event in June where it might showcase it?</p>
tag:nomothetis.svbtle.com,2014:Post/swift-for-scripting2014-10-09T08:55:27-07:002014-10-09T08:55:27-07:00Swift for Scripting<p>So Swift 1.0 has come and gone, and Swift 1.1 is just around the corner. As we’re getting closer to a more stable shape for the language, I’m interested in its potential as a scripting language for OS X. In case you missed it, Swift <a href="http://practicalswift.com/2014/06/07/swift-scripts-how-to-write-small-command-line-scripts-in-swift/">can be used</a> as a scripting language by invoking it via the good old-fashioned shebang syntax:</p>
<pre><code class="prettyprint lang-swift">#!/usr/bin/env xcrun swift
import Foundation
… // do the things
</code></pre>
<p>However, being able to invoke it and being able to do something useful with it are two very different issues. Swift is not yet ready for <em>useful</em> scripting — but I think it has the potential.</p>
<p>• • • • •</p>
<p>Brevity is the soul of scripting. There are a few things any scripting language needs to get right, to support out-of-the-box in a solid and reasonably intuitive sense. They are:</p>
<ul>
<li>File I/O (including file system traversal, permissions, and of course reading and writing)</li>
<li>String manipulation (including sensible methods for trimming strings, as well as strong regular expression support)</li>
<li>Option parsing — because any non-trivial script will take options</li>
</ul>
<p>At this point, Swift is good at none of these. String manipulation is reasonably close, minus the complicated regex syntax, but file I/O is shackled to the <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html">NSFileManager API</a>, which is powerful but insanely verbose, and <a href="https://github.com/mysteriouspants/ArgumentParser">Objective-C option parsing</a> libraries are also not notable for pithiness.</p>
<p>So a good place to start to make Swift usable is to write a good library to support strings (ExSwift is already reasonable), a good library to do file I/O (preferably with strong defaults for line-by-line parsing of a file), and a good library for option parsing. With that, the foundation is laid.</p>
<p>• • • • • </p>
<p>That’s the <em>language</em> foundation. If Swift is to take off as a scripting language, it also needs infrastructure: a good framework management system. Apple does provide strong support for frameworks, with <code class="prettyprint">/Library/Frameworks</code> being reserved for third-party frameworks that the compiler automatically picks up. It also provides <a href="https://developer.apple.com/library/mac/documentation/macosx/Conceptual/BPFrameworks/Concepts/VersionInformation.html#//apple_ref/doc/uid/20002255-BCIECADD">versioning guidelines</a> that are very close to semantic versioning, minus the obligation that the main version identifier be a number.</p>
<p>However, this is short of what’s needed. What we really need is <a href="http://brew.sh">Homebrew</a> for OS X modules. I would expect that CocoaPods is a better starting point than Homebrew for actual implementation purposes, of course, since it already addresses a similar problem for applications, but the general idea is there.</p>
<p>Irrespective of how it works, though, it brings up the problem of proper versioning. The most consistent and well-defined versioning scheme I’ve come across is <a href="http://semver.org">Semantic Versioning</a>, which is also the system used by CocoaPods. If the tools quickly emerge to support this standard, a lot of heartache, confusion, and dependency hell is going to be easily avoidable going forward.</p>
<p>Good versioning tools should support two main things:</p>
<ul>
<li>Consistent bumping of versions.</li>
<li>Automated API diffing that determines whether a bump between two points in code should be a major, minor, or patch bump.</li>
</ul>
<p>This would allow automated versioning, helping to reduce human error, and allowing versions to live up to their contract more consistently.</p>
<p>• • • • •</p>
<p>With this in mind, over the past few weeks, I’ve worked on two libraries that help a little bit with Swift’s command-line scripting.</p>
<p>The first and most complete is <a href="https://github.com/nomothetis/SemverKit">SemverKit</a>. It’s a library for parsing version strings according to the semantic versioning spec, with additional support for bumping versions in a consistent manner. Applications include:</p>
<ul>
<li>Dependency resolution</li>
<li>Automated versioning (coupled with some API diff tools)</li>
<li>Stabilization of CocoaPod libraries (this can be useful if you use internal libraries with alpha/beta versions)</li>
</ul>
<p>SemverKit is ready for general usage; it implements version equality and comparison in a spec-compliant manner and supports metadata as well.</p>
<p>The second, which is less feature-complete, is <a href="https://github.com/nomothetis/OptionKit">OptionKit</a>, a library for parsing command-line options. It supports the most common scenarios (flags, named commands, required parameters), but does not have any advanced features (sub-parsers, for instance). Still, I believe it can be taken out for a spin, and will serve basic needs. As more advanced uses are needed, it can expand.</p>
<p>Incidentally, both of these depend on custom implementations of the <code class="prettyprint">Result</code> object, which has been implemented many times, most notably by <a href="https://twitter.com/cocoaphony">Rob Napier</a>’s <a href="https://github.com/LlamaKit/LlamaKit">LlamaKit</a>. LlamaKit is a great example of what should be one of the foundational libraries of all Swift — including command-line Swift. It could then live in <code class="prettyprint">/Library/Frameworks</code> and would be easily imported into a project.</p>
<p>• • • • •</p>
<p>So there we have it. I believe Swift is an excellent candidate for scripting on OS X, being that it’s naturally pithier than Objective-C, and has strong type inferencing that reduces typing overhead. In addition, it’s more productive to be able to script and write application code in the same language.</p>
<p>However, we are not there yet. There is still a lot of work to do to set up the plumbing. I hope OptionKit and SemverKit help a little along the way. How about it? Want to join the fun?</p>
tag:nomothetis.svbtle.com,2014:Post/gotcha-frameworks-testing-swift2014-09-11T03:25:26-07:002014-09-11T03:25:26-07:00A Gotcha When Testing Swift Frameworks with Xcode 6<p>After spending most of the summer delving into what Swift can and can’t do as a functional programming language, I’ve turned my attention to writing real library code in Swift. I do have a day job, after all, and while thinking about <a href="http://nomothetis.svbtle.com/the-culmination-part-ii">Magical Future Swift</a> is a fun exercise, I still need to learn how to do the basic everyday things. Which is where I was tripped up by the default framework test settings.</p>
<p>The issue occurred when I created a new Cocoa framework project, in Swift. By default these come with tests, so you’d be forgiven for thinking that the tests just run when you type <code class="prettyprint">Cmd-U</code>, as they would for an app. You would be wrong, however. Most of the “Product” menu is disabled and gives that heart-sinking “you can’t do what you think you can do” sound when you try the shortcuts.</p>
<p>What happens is that by default, the test bundle is not added to the test configuration of the framework’s build scheme. Here’s how you reenable it. Say you named your framework “test” (I’m creative like that). Select it and then select “Edit Scheme…”:</p>
<p><a href="https://svbtleusercontent.com/o0ngm3vgb7zwpa.png"><img src="https://svbtleusercontent.com/o0ngm3vgb7zwpa_small.png" alt="edit-scheme.png"></a></p>
<p><br><br>
Then go to “Test” and hit the + in the lower left-hand corner of the detail view:</p>
<p><a href="https://svbtleusercontent.com/airmxh0pdilyw.png"><img src="https://svbtleusercontent.com/airmxh0pdilyw_small.png" alt="add-tests.png"></a></p>
<p><br><br>
Select your test bundle (my clever naming pays off dividends…):</p>
<p><a href="https://svbtleusercontent.com/rfbxthkcg3ofng.png"><img src="https://svbtleusercontent.com/rfbxthkcg3ofng_small.png" alt="select-bundle.png"></a></p>
<p><br><br>
Make any modifications you want — in this case, let’s add a location for the tests to run against, and click “Close”:</p>
<p><a href="https://svbtleusercontent.com/rb2yfhd9wnssa.png"><img src="https://svbtleusercontent.com/rb2yfhd9wnssa_small.png" alt="finish.png"></a></p>
<p><br><br>
Now all your testing shortcuts should be enabled and working (your running shortcuts still won’t be, since a framework can’t be run on its own).</p>
<p>Happy testing!</p>
tag:nomothetis.svbtle.com,2014:Post/third-monad-law-derivation2014-08-30T16:35:36-07:002014-08-30T16:35:36-07:00Addendum: Deriving the Third Monad Law From Nested Comprehensions<p>The third monad law declares that the following identity must hold for a monad <code class="prettyprint">M</code>, where <code class="prettyprint">a:M<A></code>, <code class="prettyprint">f: A -> M<B></code>, and <code class="prettyprint">g: B -> M<C></code>:</p>
<pre><code class="prettyprint lang-swift">(a >>=- f) >>=- g == a >>=- { b in f(x) >>=- g }
</code></pre>
<p>To motivate this, we first want to show that the snippet below is a form of the left-hand-side of the identity:</p>
<pre><code class="prettyprint lang-swift">// Form 1
let val = for {
b <- for {
ignore <- doSomething()
b1 <- doSomething()
} yield {
b1
}
c <- process(b) // process(val:Int?) -> Int?
} yield {
c
}
</code></pre>
<p>Then we want to show that Form 2 below is a form of the right-hand-side:</p>
<pre><code class="prettyprint lang-swift">// Form 2
let val = for {
ignore <- doSomething()
b <- doSomething()
c <- process(b) // process(val:Int?) -> Int?
} yield {
c
}
</code></pre>
<p>Intuitively, these two snippets should do the same thing, which is the impetus for enshrining the behavior in a law.</p>
<p>• • • • •</p>
<p>Remembering that the right-hand side of a <code class="prettyprint"><-</code> assignment is monadic, we can write Form 1 as:</p>
<pre><code class="prettyprint lang-swift">// Form 1
let optB = doSomething() >>=- { ignore in
doSomething() >>=- { b in
lift(b)
}
let val = optB >>=- { b in
process(b) >>= { c in {
lift( c)
}
}
</code></pre>
<p>Clearly, we can rewrite the snippet like this:</p>
<pre><code class="prettyprint lang-swift">// Form 1
let val = doSomething() >>=- { ignore in
doSomething() >>=- lift
} >>=- { b in
process(b) >>=- lift
}
</code></pre>
<p>Notice, incidentally, that nested for-comprehensions are the equivalent of chained <code class="prettyprint">>>=-</code> calls. Using the second monad law (see, it’s useful), we can simplify it as:</p>
<pre><code class="prettyprint lang-swift">// Form 1
let val = doSomething() >>=- { ignore in
doSomething()
} >>=- { b in
process(b)
}
</code></pre>
<p>Now let’s simplify by introducing the definition of<br>
<code class="prettyprint">doSomethingWhileIgnoring</code>:</p>
<pre><code class="prettyprint lang-swift">func doSomethingWhileIgnoring(ignored:Int) -> Int? {
return doSomething()
}
</code></pre>
<p>This takes us to the final form, with added parentheses to emphasize that <code class="prettyprint">>>=-</code> is a left-associative operator.</p>
<pre><code class="prettyprint lang-swift">// Form 1
let val = (doSomething() >>=- doSomethingWhileIgnoring) >>=- process
</code></pre>
<p><br><br>
• • • • •</p>
<p>For the second snippet, we’re going to work backwards. This means I’m going to start with what I already know I’m trying to get to, and I’m going to show you that it’s equivalent to Form 2. This is just as valid as going from Form 2 to the final result, but it’s easier to follow. What I want to show is that this snippet is the same as Form 2:</p>
<pre><code class="prettyprint lang-swift">// Form 2 candidate
let val = doSomething() >>=- { ignore in
doSomethingWhileIgnoring(ignore) >>=- process
}
</code></pre>
<p>So let’s get to substituting:</p>
<pre><code class="prettyprint lang-swift">// Form 2 candidate
let val = doSomething() >>=- { ignore in
{ _ in doSomething() }(ignore) >>=- { b in
process(b)
}
}
</code></pre>
<p>And now, using the second law, but in reverse, we have:</p>
<pre><code class="prettyprint lang-swift">// Form 2 candidate
let val = doSomething() >>=- { ignore in
{ _ in doSomething() }(ignore) >>=- { b in
process(b) >>=- { c in
lift(c)
}
}
}
</code></pre>
<p>Finally, it’s pretty clear that the second line is an unnecessary wrapper, and that we can write it as:</p>
<pre><code class="prettyprint lang-swift">// Form 2 candidate
let val =
doSomething() >>=- { ignore in
doSomething() >>=- { b in
process(b) >>=- { c in
lift(c)
}
}
}
</code></pre>
<p>But this is precisely the <code class="prettyprint">>>=-</code> version of Form 2.</p>
<p>• • • • •</p>
<p>Again, remember that this appendix is not <em>proving</em> the law, but instead showing how it naturally comes out of expecting intuitive semantics from for-comprehensions. In the context of monads, “law” doesn’t mean something observed to be true, but rather a prescribed rule that a type must follow in order to be called a monad.</p>
tag:nomothetis.svbtle.com,2014:Post/the-culmination-final-part2014-08-30T16:25:50-07:002014-08-30T16:25:50-07:00The Culmination: Final Part<p>In my <a href="http://nomothetis.svbtle.com/the-culmination-part-ii">last post</a>, I finally came out and admitted that all my posts about errors and optionals have been about monads. And to justify this gross act of deception, I posited for-comprehensions, a nifty new syntax in Magical Future Swift that improves how we can work with optionals and arrays—a syntax that only works with monads.</p>
<p>So monads are entities that work with for-comprehensions. But for-comprehensions must work in a sane manner, that is, intuitively. I’ve already gone over two behaviors that are required; they are called the first two monad laws. There is one missing. You’ll be stunned to know it is the third law.</p>
<p>• • • • •</p>
<p>The first law addressed using a for-comprehension with a lifted value. The second law addressed the behavior of comprehensions when nothing was done to the assigned values. One last thing we want to be able to do with comprehensions is nest them.</p>
<p>To see why, suppose we have a function that has side effects with type signature <code class="prettyprint">doSomething() -> Int?</code>. We call this function to do things for us, and we potentially get a number back. Here’s something we might want to do with this function:</p>
<pre><code class="prettyprint lang-swift">func doSomethingTwice() -> Int? {
return for {
ignore <- doSomething()
b <- doSomething()
} yield {
b
}
}
</code></pre>
<p>In effect, we call the function twice, but we only care about the result the second time. There is no need to do this with a comprehension, of course, but if comprehensions are available, it must work, and the whole point is to discover what monad laws make comprehensions intuitive. Now, let’s use this function:</p>
<pre><code class="prettyprint lang-swift">let a = for {
b <- doSomethingTwice()
c <- process(b) // process(val:Int?) -> Int?
} yield {
c
}
</code></pre>
<p>We can substitute the definition of <code class="prettyprint">doSomethingTwice</code>:</p>
<pre><code class="prettyprint lang-swift">// Form 1
let val = for {
b <- for {
ignore <- doSomething()
b1 <- doSomething()
} yield {
b1
}
c <- process(b) // process(val:Int?) -> Int?
} yield {
c
}
</code></pre>
<p>I call it “Form 1” because we know that the return value of the first call gets discarded (though still made), which means we should be able to write that snippet like this:</p>
<pre><code class="prettyprint lang-swift">// Form 2
let val = for {
ignore <- doSomething()
b <- doSomething()
c <- process(b) // process(val:Int?) -> Int?
} yield {
c
}
</code></pre>
<p>Let me be clear. When I said “which means” above, I meant that it made intuitive sense. There is nothing that guarantees that this is the case. It’s our job to guarantee it—and that is the role of the third monad law.</p>
<p>The the third law follows from turning these two different forms into their <code class="prettyprint">>>=-</code> versions. Doing so is nothing overly complicated, but it is a bit lengthy, so I’ve put the details in an <a href="http://nomothetis.svbtle.com/third-monad-law-derivation">addendum</a>. The end result is that Form 1 can be rewritten as:</p>
<pre><code class="prettyprint lang-swift">let val = (doSomething() >>=- doSomethingWhileIgnoring) >>=- process
</code></pre>
<p>Here, <code class="prettyprint">doSomethingWhileIgnoring(Int) -> Int?</code> is a wrapper around <code class="prettyprint">doSomething</code> that matches the required type for the right-hand-side of <code class="prettyprint">>>=-</code>. The parentheses are there to emphasize that <code class="prettyprint">>>=-</code> is defined as a left-associative operator.</p>
<p>As for Form 2, it can be rewritten as:</p>
<pre><code class="prettyprint lang-swift">let val = doSomething() >>=- { ignore in
doSomethingWhileIgnoring(ignore) >>= process
}
</code></pre>
<p>So these two forms have to be equivalent for our for-comprehensions to work. What we are dealing with here is a monadic value <code class="prettyprint">a:M<A></code> (the output of <code class="prettyprint">doSomething()</code>), and two functions: <code class="prettyprint">f:A -> M<B></code> (<code class="prettyprint">doSomethingWhileIgnoring</code>) and <code class="prettyprint">g:B -> M<C></code> (<code class="prettyprint">process</code>). Our law then becomes that these two forms must be the same for all monads:</p>
<pre><code class="prettyprint lang-swift">// Form 1 // Form 2
(a >>=- f) >>=- g == a >>=- { b in f(b) >>= g }
</code></pre>
<p>That’s the third monadic law, for your sugary syntactic pleasure.</p>
<p>• • • • •</p>
<p>Whew! That was a lot of ground to cover, so let me give you a brief recap. A very common problem when dealing with optionals is dealing with multiple ones. We quickly end up with a bunch of nested <code class="prettyprint">if-let</code> statements that look very bad—especially since most of the time, the recovery from any one of them failing is the same.</p>
<p>Other languages with optionals deal with this problem by introducing syntactic sugar; Scala calls it for-comprehensions, while Haskell calls it do-notation. They are similar, though not identical, and I endowed Magical Future Swift with the Scala version.</p>
<p>While investigating for-comprehensions I showed that they work for a specific class of types, which have one type parameter, and which follow three laws. These types are called <em>monads</em>, and they follow the following rules:</p>
<ul>
<li>There exists a function, by convention called <code class="prettyprint">lift: A -> M<A></code>, which takes a non-monadic value <code class="prettyprint">a:A</code> and wraps it in a monadic value <code class="prettyprint">M<A></code>.</li>
<li>There exists a function, by convention called <code class="prettyprint">>>=-</code>, whith signature <code class="prettyprint">(val:A, f:A -> M<B>) -> M<B></code>.</li>
<li>First monad law: for any unwrapped value <code class="prettyprint">a:A</code> and function <code class="prettyprint">f:A -> M<B></code>, <code class="prettyprint">lift(a) >>=- f == f(a)</code>.</li>
<li>Second monad law: for any monadic value <code class="prettyprint">m:M<A></code>, <code class="prettyprint">m >>=- return == m</code>.</li>
<li>Third monad law: for any monadic value <code class="prettyprint">m:M<A></code>, and functions <code class="prettyprint">f:A -> M<B></code>, <code class="prettyprint">g:B -> M<C></code>, <code class="prettyprint">(m >>=- f) >>=- g == m >>=- { x in f(x) >>=- g }</code>.</li>
</ul>
<p>The three laws allow for-comprehensions to work the way we would intuitively expect them to:</p>
<ul>
<li>The first law allows us to apply for-comprehensions to unwrapped values by lifting them into the relevant monad.</li>
<li>The second law allows us to have an identity operator in for-comprehensions, for the times when we don’t actually want to modify the unwrapped values.</li>
<li>The third law allows us to nest for-comprehensions.</li>
</ul>
<p>The wonderful thing about for-comprehensions is that they don’t only apply to optionals—they are a general way of dealing with monads. They can apply to arrays, results, futures—any type that follows the rules above.</p>
<p>These rules might seem much ado about nothing, but if you look at a for-comprehension, it tends to look like a regular imperative program—but with some logic abstracted away. Beth’s birthday problem looked like regular assignments—except we didn’t have to worry about the nil case; everything was taken care of. Sam’s scheduling problem looked like it was doing regular assignments as well—abstracting away the fact that the code was iterating through multiple lists at the same time.</p>
<p>This means that each monad, in a way, defines its own imperative semantics when used in a for-comprehension—but in a way that still provides type safety and referential transparency. For-comprehensions therefore provide the best of both the imperative and the functional world.</p>
<p>• • • • •</p>
<p>Alright, I’m almost done. There’s one thing I still need to justify. I claimed, rather brashly, that monads had to do with the future of Swift. Of course, since I don’t work at Apple I can’t know for certain. But every language that has introduced optionals has had to introduce the associated syntactic sugar—dealing with them is too painful otherwise.</p>
<p>So because Scala, Haskell, and F-Sharp all sooner or later felt the need to introduce for-comprehensions, I feel fairly confident in predicting that they will make their way into Swift. What this would mean for the rank-and-file developer is some new syntax; this doesn’t require a deep understanding of monads—the whole point of for-comprehensions is that they work intuitively. I happen to believe, however, that taking the time to truly understand the semantics of your language can only help.</p>
<p>And if we can be a step ahead of the game by looking toward the future, so much the better.</p>
<p>• • • • •</p>
<p>Thanks for sticking with me through this series. There were seven total posts—beginning with <a href="http://nomothetis.svbtle.com/error-handling-in-swift">error</a> <a href="http://nomothetis.svbtle.com/error-handling-in-swift-part-ii">handling</a>, continuing with <a href="http://nomothetis.svbtle.com/understanding-optional-chaining">understanding</a> <a href="http://nomothetis.svbtle.com/implicitly-unwrapped-optionals-in-depth">optionals</a>, and ending with the <a href="http://nomothetis.svbtle.com/the-culmination-i">three</a> <a href="http://nomothetis.svbtle.com/the-culmination-part-ii">culmination</a> posts. I hope I managed to convey why the monadic pattern is important, and to explain where the three laws come from.</p>
<p>“Important”, though, is not the same as “required knowledge”. The details of RAM fetching are important, but most developers can ignore them, and so it is with monads. At the end of the day, it is never the point of a construct to make life more difficult. As a dev, you’ll only have to worry about monads when trying to implement a type that can be used in a for-comprehension. For the rest, life will go on as usual.</p>
<p>But a little safer, and a little more functional. And isn’t that a good thing?</p>