Functional Reactive Awesomeness With Swift

Functional or reactive programming? Why not both? Ash Furrow begins this talk with a brief history of functional reactive programming and ReactiveCocoa, before explaining the motivations behind its use. Along the way, he walks us through three excellent demos that showcase functional reactive programming in Swift, before discussing advanced concepts like MVVM in iOS.


A Brief Overview of Programming (0:00)

Today, we’re not going to talk about math, monads, burritos, or anything. We’re going to have fun — and what better way to have fun than talk about history. In the evolution of programming in our industry, we started out writing assembly and moved to C. Eventually we weren’t even programming real machines anymore.

As it evolved, programming has become more abstract. As time goes on, abstraction goes up. This has made a lot of people very angry. At every step of the way, we saw resistance to progress — that’s totally natural and understandable. Humans don’t like change. We’re afraid of things that aren’t familiar to us. It makes us uncomforatable. Those are all reasonable, totally relatable feelings.

But the thing is that progress happens anyway. Most of us don’t write our applications only using C; we use Objective-C, and now Swift. Based on where we were and where we are now, we can get a pretty good idea of where we’re going. So what’s next? Well, today I’m going to talk to you about Functional Reactive Programming.

FRP: Functional Reactive Programming (2:13)

First of all, you need to know that Functional Reactive Programming is the future, and the future is now. Functional Reactive Programming is good for any code base, and we are here to help. The first question you might be having is, what is Functional Reactive Programming, or FRP? Well, I already answered this question: it’s the future. You may be looking for a more serious answer. That’s totally understandable.

Functional Reactive Programming is a recipe that takes three simple ingredients. Really, they’re individually very simple ideas. We’re going to talk about each one individually. Functional Reactive Programming is a combination of streams, transformations and bindings.

Streams (2:57)

Let’s start with streams. Streams send stuff. They’re a very familiar data structure. They can send anything, just like an array can hold anything. They’re very familiar, and very close to arrays in that they hold stuff. The difference between arrays and streams is that an array can be accessed at anytime. You can always look into an array and get whatever it has, at any given time. With streams, they send stuff at a specific time. If you’re not listening for that stuff, then you miss it. You can’t just reach into a stream and grab data. If you miss it, it’s gone forever.

I know this sounds like a pretty big limitation, but you’ll see in a few minutes that it’s actually really cool. I like to think of streams as a pipe. It goes, pew pew pew. Stuff goes through it, and if you don’t catch it on the other end, it’s gone forever.

Transformations (4:51)

The next thing you have to know is transformations. Transformations turn one thing into another. Your’re probably already familiar with this kind of idea using map and filter, which are things that Kyle talked about. Basically, if you have an array of one type of thing, you can map it into an array of a new type of thing. If you have a Person object and an array of Persons, then you can turn that into an array of their first names, their date of births, their employer’s names, or any type of data you want. You can also filter that array. You can take an array of Persons, and turn it into an array of everyone older than the age of twenty-one.

You take something and turn it into something else. The same things apply with streams. If you have stream of people, you can turn that into a stream of their names, their employers, or a stream of all the people who are over the age of 21. When you take a stream, and transform it, you get a new stream. You don’t modify the original, but you actually create a whole new one. New streams are produced, not modified.

The really cool thing with transformations is that you can chain them. So, you can take an array of people and turn it into an array of employers, and then turn that into an array of employer addresses. Same thing with streams — you can turn a steam of persons into a stream of employers, and then turn that into a stream of employer addresses.

Bindings (5:22)

The question is, why chaining useful? What’s the point? The point is bindings, which are the third ingredients to Functional Reactive Programming. They are the secrect sauce that makes it all work. Without bindings, Functional Reactive Programming would be useless. To recap, you make a stream, transform that stuff into other stuff, and then you bind that stuff to things.

Examples (5:42)

Let’s look at some examples. Consider you have a simple user interface, with a text field at the top and a submit button. You’re looking for the user’s email address. Now, you don’t want them to hit the submit button if email address isn’t there, or if what is there isn’t an email address. What you do is take the text stream from the text box, and anytime the user changes the text in the box, that stream sends the new text. It just sends text, text, and more text.

Get more development news like this

You have to have a stream of strings, and what you can do is turn that into a stream of something else. In this case, we can map that with this isEmail concept. You can say, “Map this stream of strings into a stream of bools”, and those bools represent whether or not the text was an email address. Finally, you can bind that to the enabled property on the button. All of a sudden, you have your entire form validation logic written for you in one or two lines of code.

That’s pretty cool, but it’s not the only thing that streams can do. You have a stream that represents an API request. When the response gets back to you, the stream will send that data. You can map that data from the API into models, and then you can bind those models to a data source, like an array, back in your table view. Now all of a sudden, you have something like a Twitter bot that fetches Tweets from the Internet and displays them to the user. Whenever there are new Tweets, the stream sends the new Tweets. Those get put in the array and displayed to the user automatically.

The really amazing thing is that all this is declarative. As we saw with Kyle’s talk, declarative things are awesome, and Functional Reactive Programming is declarative. So, Functional Reactive Programming is awesome. All the concepts can be really combined together, chained, and used in an infinite number of ways.

When I began programming I was excited, and I think that most people were excited. We get into programming because we love it. We enjoy it, and we’re exhilarated by it. When I first really understood the possibilities that programming opened up to me and to humanity, I felt like I was standing on this shore of this infinite expanse of awesome things that I could do - things that I didn’t even know I could do yet. I feel like with Functional Reactive Programming, I have that same feeling of exhilaration again, and that’s why I’m so excited to talk about it today.

The Benefits (8:20)

We’ve covered the basics of Functional Reactive Programming. Now I want to talk about some of the benefits. Just because something is cool, doesn’t mean it’s useful. What kind of benefits does Functional Reactive Programming provide? Well, there are a lot, and I want to start with some of the intangible ones.

The first one is a community. There are a lot of Functional Reactive Programming frameworks out there, including Rx.rb for Ruby and extensions for .NET. For pretty much any type of programming language environment out there, there’s someone doing reactive for it. It’s a very unique community I think, because in general it’s very forward thinking and very open to new ideas. In iOS, FRP started with ReactiveCocoa a number of years ago, and that was great because ReactiveCocoa used what was unique in iOS, the Objective-C Runtime, to make things very cool and very easy to do.

Now we have Swift, which has an amazing new type checker. But we can do even new, more amazing, way cooler things with that than we could do in Objective-C - whole new possibilities. We see new frameworks popping up, like RxSwift and ReactKit, all kinds of different frameworks that you could call competitors, but aren’t really competing. They all take a different approach on something, and borrow ideas from one another in order to create something new and cool that they’ll care about. They’re not competitors; they’re colleagues. That’s why today, I’m really trying to focus on the ideas behind functional programming, Functional Reactive Programming, and not on the implementation details.

Demo 1: Email Validation (10:05)

I’ve spoken before about ReactiveCocoa, and that’s Objective-C. I’m sort of past the implementation details phase of talking about Functional Reactive Programming. I really love the ideas. In order to show you some of those ideas, I want to do a demo and show you some of the cool, practical, tangible benefits. In my Xcode project, I have a fairly simple user interface. We have the navigation controller, which has a number of static table view cells. These cells contain email validation, networking, and signup, and do each of these things. For now, they pushed their own view controllers.

Let’s take a look at the first example, email validation. This is the example that I used earlier. If I look at the interface in Interface Builder, it’s fairly straight forward, just auto layout. You see the buttons in Interface Builder, and here in the simulator it’s disabled. If I type an email address in, at a certain point it becomes enabled because the thing I’ve entered is an email address. We’re going to take a look and see the code behind this. In order to do that, I’m going to do what you should all do when you’re opening your controller code and open the Assistant Editor.

We have EmailValidationDemoViewController. We’ve got a couple IBOutlets, which has this weird DisposeBag thing. I’ll talk about that in a little bit. We also have a viewDidLoad, and not much else in here. I’m going to turn this into the form validating powerhouse that you saw in the simulator earlier. First thing we have to do is get the stream of strings, the text stream. We can do that with the emailTextField.rx_text property. This is going to send a stream of strings any time the user changes what they’ve entered in.

That’s not very interesting by itself, so I’m going to map it. I’m going to turn it into isEmail, and all of a sudden I’ve taken my stream of strings and turned it into a stream of booleans. These booleans represent whether or not that string was an email address. So we’ve got the first step, stream, second step, transformations, and the third step is bindings. All I’m going to say do is bind to submitButton.rx_subscribeEnabledTo. Whenever the stream of booleans sends a new value, it’s going to change the enabled state of the button. Finally all you need to do is take care of a little notation detail, which you don’t have to pay attention to, but just says that when the ViewController goes away, the binding should be at the allocated spot. That’s it - four lines of code to get form validation working.

class EmailValidationDemoViewController: UIViewController {
    @IBOutlet weak var emailTextField: UITextField!
    @IBOutlet weak var submitButton: UIButton!

    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        emailTextField.rx_text
            >- map (isEmail)
            >- submitButton.rx_subscribeEnabledTo
            >- disposeBag.addDisposable
    }
}

Demo 2: Networking (13:04)

Pretty cool, but that’s not the only thing we can do. The other example we saw was networking. We can go into the network and fetching stuff, so in this case, we’ll be fetching friends. You can see the activity indicator spinning - the network request goes, and I get an array of my friends that I show on in a table view. Let’s take a look at how we can build that. I’m going to select my NetworkDemoViewController, and you can see there is nothing magic going on. We have an array of friends that we’re going to use, and we’ve got a DisposeBag here as well. numberOfRowsInSection is just the number of friends we have, and cellForRowAtIndexPath sets the text field’s text to the friend at that index path row.

extension NetworkDemoViewController: UITableViewDataSource {

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return count(friends)
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell

        cell.textLabel?.text = friends[indexPath.row]

        return cell
    }

}

So what do we do? Well, first I’m going to call this function fetchFriends, which will return a stream of friend objects. Now all I have to do is subscribe my friends to that stream, so whenever the fetch friends stream sends new friends, they get sent to my friends array. What’s even cooler is that as a side effect of that, it’s actually going to take care of reloading my table view for me. All I have left to do is call disposeBag.addDisposable, and that’s it. Three lines of code in order to grab stuff from a network and put it in a table view.

class NetworkDemoViewController: UITableViewController {

    var friends: [String] = []
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        fetchFriends()
            >- subscribeFriendsTo
            >- disposeBag.addDisposable
    }
}

Demo 3: Signup Logic (14:36)

Finally, there’s one other cell in my root view controller: signup logic. This is the most complicated and the most fun, so I’ve left it for last. This is a signup form for this new micro-social network blogging service called AltTweet. It takes the email address just like the other one did, but when I enter in a valid email address, the button still isn’t enabled. That’s because it also needs a password. Passwords are valid for AltTweet if they’re over six characters, so I type in a really secure password, and then the button becomes enabled. I’m going to include a 1Password extension in a point release in a few weeks. If I go back to the email field and I take out the @ sign, it’s no longer a valid email address and the button becomes disabled. I put in a new @ sign, and it’s enabled again.

How are we going to build this? The UI is fairly straight forward, with two text fields and a button. The view controller has IBOutlets, and just like before, a DisposeBag and an overridden viewDidLoad. First I’m going to create a couple intermediate variables to make things a bit more readable. I set isEmailValid equal to the property emailAddressTextField.rx_text. That’s a stream of text strings, and I’m going to map that into whether or not that’s the email address. Now I’ve produced the stream of bools.

class SignupDemoViewController: UIViewController {
    @IBOutlet weak var emailAddressTextField: UITextField!
    @IBOutlet weak var passwordTextField: UITextField!
    @IBOutlet weak var signupButton: UIButton!
    
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        let emailIsValid = emailAddressTextField.rx_text >- map (isEmail)
    }
}

In fact, I can even alt-click on this and see that its type is an observable of bools. This is where the Swift thing comes in, where you get type safety at compile time. It’s just something that ReactiveCocoa could never do, which is why I’m really excited about it. Next I’m going to say, isPasswordValid, and this is going to be fairly predictable at this point, passwordTextField.rx_text, and map into isPassword.

let emailIsValid = emailAddressTextField.rx_text >- map (isEmail)
let passwordIsValid = passwordTextField.rx_text >- map (isPassword)

Now I have two streams. What do I do with them? I want to combine them, so let’s see if there’s anything that’ll combine. There is, and it takes two sources, isEmailValid and isPasswordValid. This is actually taking two streams of bools and turning them into a stream of tuples. At this point all we need to do is and them together in order to figure out if the form is valid, because the form is only valid if both email and the password are valid. Now we’ve taken our stream of two bools and turned it into a stream of just one bool.

combineLatest(emailIsValid, passwordIsValid)
            >- and
            >- signupButton.rx_subscribeEnabledTo
            >- disposeBag.addDisposable

All right, the next thing we need to do is bind that to our signupButton enabled state and add it to our DisposeBag. That’s only half the story though - remember that when I hit the submit button, stuff has to happen. What do we do? It’s actually not that complicated. We’re going to take our signup button, and it actually includes rx_tap. This is a stream that sends values whenever the button’s tapped. What’s interesting about this stream is that it sends void; the values don’t actually exist. We don’t really care about the values, we only care that they’re sent.

At this point, we just need to put that into a signup, which is a function that takes an observable of void and spits out an observable of text. It’s going to be a response from the API. I want to probably display that response to the user in some way, so we’ll type that into display. Finally, we’ll add it to our disposeBag by writing disposeBag.addDisposable. In ten lines of code, fewer if you take out the intermediate variables, we have an entire form validation network request. If I actually go back to the simulator and hit the signup button, it actually goes to the network and says “signed up”. From these demos, I hope that you can see the benefits of Functional Reactive Programming in the context of iOS Apps.

class SignupDemoViewController: UIViewController {
    @IBOutlet weak var emailAddressTextField: UITextField!
    @IBOutlet weak var passwordTextField: UITextField!
    @IBOutlet weak var signupButton: UIButton!
    
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        let emailIsValid = emailAddressTextField.rx_text >- map (isEmail)
        let passwordIsValid = passwordTextField.rx_text >- map (isPassword)

        combineLatest(emailIsValid, passwordIsValid)
            >- and
            >- signupButton.rx_subscribeEnabledTo
            >- disposeBag.addDisposable

        signupButton.rx_tap
            >- signup
            >- display
            >- disposeBag.addDisposable
    }
}

Pragmatism & Idealism (19:26)

Now, we’re going to talk a little bit more about the steps that you need to take next. One of the biggest things that we see when we talk about Functional Programming in software development is this false dichotomy between pragmatism and idealism. This really is a false dichotomy. The idealism says that Functional Programming is the best, it has no side effects, is pure, stateless - yay. You have the idealists who say, “Hey man, I really have to do my job. I can’t spend three weeks learning Pascal in order to get ‘Hello, World’ out”, but we can do better than that. We’re smart people. We program computers for a living.

Reject that dichotomy, because it is false. Functional Reactive Programming to me embodies the rejection to that false dichotomy. It’s a perfect blend of two things that are independently really awesome, but when they come together, they’re more than the sum of their parts. Peanut butter and chocolate is better than peanut butter or chocolate on their own.

MVVM (20:30)

One thing that I would love to talk about today, but don’t have time to, is Model View View Model, or MVVM. MVVM is this really amazing architecture paradigm that is a way for you to separate your logic from your view controller.

In our previous code demo, we saw that our view controller was aware of what happens when the button is tapped, and it’s aware of how to map things from strings into validation logic. MVVM says no, put that in a separate object. Call that object a view model. The only thing the view controller is aware of is the user interface, not the model itself, and not the logic.

This does two things. First, since the view models aren’t aware of the user interface, the part that makes testing view controllers hard, view models are really easy to test. The second thing is because the view controllers aren’t aware of the logic, the other thing that makes them hard to test, the view controllers, are really easy to test because you can just pass them a stubbed view model and they’ll behave exactly the way you want when you do your test.

By extracting these two concepts, presentation logic and presentation, from one another and putting them in separate object, you can actually have code that is way more testable, far more cohesive, and less tightly coupled. It’s a really great thing.

Help: Getting Started! (22:05)

FRP is pretty straight forward, pretty beneficial. Where do you go next? Where do you go for help? Well, getting started is pretty simple. There’s sample code from this talk on GitHub. I have a book, written for Objective-C, boo 👻. But don’t worry, I’ll be writing one for Swift.

You can just pod try something. ReactiveCocoa is awesome. RxSwift is also a great choice, as is ReactKit. Go with whatever you like. Just try things and see if they work. A Lot of these libraries are still pretty nascent. They’re still in development, which means that if you try it out and it’s fun, then you have a really cool opportunity to have a huge impact on the future of iOS development.

If you have questions, post on Stack Overflow because there’s a lot of us there…looking for reputation. [speaker laughs] If no one answers your question on Stack Overflow, send me a tweet. I’d love to take a look at it. Send Justin Spahr-Summers a tweet. I hope I can tell you to do that and he won’t get mad at me. Use Twitter to your advantage - there’s a whole bunch of really cool people on Twitter who would just love to help you, me included.

Finally, GitHub issues - if you have a question about something, something didn’t work the way you expected it to, if you have an idea for something cool or something that would really make your life easier, open an issue for it. You saw Justin Searls’ talk earlier this week. We see library maintainers as these rock stars, but they’re not. They’re just people, and it’s so awesome when people open up issues on your project because it lets them know that you’re using it and that you care about it.

So if you do care about it, open an issue. It’s not bothering us. I swear, we really want to help you. The entire FRP community wants to help you because we’re really, really selfish. If we help you get started, if we come to AltConf and give you a really messy presentation on how to do FRP, if we answer your question on Stack Overflow, all of that increases the likelihood that in the future when we’re colleagues, you’ll already know what FRP is, you’ll already be convinced about the benefits, and you’ll already be using it. I won’t have to convince anyone to use FRP because they’ll already know that it’s a great idea.

If you’re still interested, there’s a wonderful website called RxExtensions. What’s really cool about that is that it has documentation about the different transformations and operators on streams, without reference to any program language or any implementation. It links to Rx.rb and RxExtensions on .NET, but it exists completely independently of those and only talks about the ideas behind Functional Reactive Programming. There’s demo code on all of these GitHub repositories, like on RXSwift or ReactiveCocoa.

I’ve got an app on the store called C-41 for developing photography film, which is probably not something that you’re going to be doing, but it’s also opensource on GitHub, so you can check it out. It uses ReactiveCocoa, MVVM, and Core Data. It’s fully unit tested. Let me know what you think. I’ve got another one called Functional Reactive Pixels, which is kind of cool because it uses the network, also unit tested. The crown jewel of all of my sample code is Eidolon, because it’s not sample code. It’s an actual production application, something I helped build at Artsy. It’s written in Swift and ReactiveCocoa. It’s marginally unit tested, and test coverage is increasing every day. It is fully open source. The really cool thing is that we have this application that has been in production for months now. We’ve had a lot of fun building it and we’ve learned a lot.

Wrap Up (26:10)

Let’s do a little wrap up and review what we learned. Functional Reactive Programming is here, gaining popularity. It’s awesome and useful - if you add even a little tiny bit of FRP to any code base, things are going to get simpler. Finally, Functional Reactive Programming is community. When Aristotle said that Functional Reactive Programming is more than the sum of its parts, he didn’t mean just the programming bits, but that there is a community behind it. Together we are more than we are individually.

With that in mind, think back to the beginning of this presentation. I described to you the evolution of computer programming, and how along the way some people weren’t very happy about some of the progress that we’ve made. They resisted for totally understandable reasons, reasons that I would resist. But progress happened anyway, so you have a choice. You can be grumpy and unhappy, and you can choose to have us drag you kicking and screaming into the future - or you can help us, have a lot of fun, and be happy. It’s up to you. Thank you very much.

Q&A (27:33)

Q: What do you thinka bout the MVVM conjunction with Viper? Can they be used together, or are they just different paradigms?

Ash: Viper is this other way to structure your code. Conrad Stoll from Mutual Mobile wrote a fantastic article in objc.io about this a few months ago. I don’t really believe in one paradigm being fundamentally better than another. If you saw Graham’s Lee talk at UIKonf, he talked about object oriented programming and how we really cheated ourselves out of really exploring it to its full potential because we were afraid of losing out on imperative code. It’s okay to mix and match. It’s okay to try things and decide that they’re okay in limited quantities. As long as it works for you and helps you write safe code, helps you write code fast, and helps you ship, then go for it.

Q: How does Viper get along with RAC (ReactiveCocoa)?

Ash: To be honest, I’ve not written a full scale application using Viper, so I can’t give any specifics on that. Conrad is a really, really friendly person and if you ask him on Twitter, I bet he would have an opinion on that. I think RAC and MVVM go together.

Q: Can you see a future in which there is a language we use that has the FRP primitives baked in? Do you see any advantages in a world in which FRP isn’t something that we opt into, but is the fundamental model that we use to write the majority of our code?

Ash: What I like about Swift is that it enables us to program in the way that is most comfortable to us. It doesn’t enforce functional thinking, functional reactive thinking, object oriented thinking, procedural thinking, or any of these thinkings. You can really do what you like with it. I don’t think that languages should specialize to the extent that they enforce FRP, or even have FRP baked in. Maybe that will change in the future, but for now, I’m more excited about Swift as a language that lets people program however they’re most comfortable right now.

Q: In your demo, there was a greater than dash operator (>-). Is that part of RxSwift or RAC, and could you show us the definition of it?

Ash: Sure, I can show you. It’s a little bit complicated, but it’s actually fairly straight forward. If we open up the Email Validation View Controller, we can see this is actually a custom operator of Swift. It takes a left hand side In and a right hand side that goes from In to Out, and it produces an Out. People who are familiar with Functional Programming will recognize this. It takes the stuff in, applies the right hand side to the left hand side, and spits the result back out.

When Swift first came out, you had to call count on an array, or whatever data structure. This solves that problem, so you would actually be able to put count as a count function itself, and be passed as a parameter. Different people do different things. There’s the pipe greater than operator and the dash greater than. What I love about open source software is that I can actually go in and take a look at this and read the actual source code. The term for this particular operation is apply.

Q: Do you ever worry about tying your implementation so deeply to a third party library that’s outside of Apple’s purview, like ReactiveCocoa or RxSwift? Is there anything that you do to mitigate the risk that things will crash and burn when a new version of iOS, XCode, Swift, or anything comes out?

Ash: If you had asked me a year ago, I would have said it doesn’t concern me at all. Today, yes. I’m not fanatical about it. If you talk to Justin Searls, he wraps all of his dependencies in wrappers so that he can throw them away at a moments notice. With Eidolon, we used the ReactiveCocoa API, the Swift API was so new at the time we wrote it. We actually used the ReactiveCocoa Objective-C API which is the same in 2.0 and 3.0. At this point we have a code base that’s written in Swift. It has a lot of casts around it. Migrating that to ReactiveCocoa through Swift can be a considerable amount of work. Eventually, I think I’ll probably use a weekend and just hack on it or something.

The way I mitigate this is not very good. I just kind of hope it doesn’t happen, I guess that would be the biggest way I mitigate it. What I really like about RxSwift compared to the ReactiveCooca approach is that they want to keep their library as small as possible. I’ve been talking with them, and they’re really great people who want to keep things small. In the future I’m going to be exploring ways to mitigate that. I don’t want to wrap RxSwift, for instance, because it’s already pretty small. I think what I’m going to try and do is use smaller libraries.

Q: In your Signup flow, you had a call to Signup function which then went off to the network and ended somewhere. Suppose you wanted to do something like that and be able to cancel that operation in flight, how would you implement that here?

Ash: I actually haven’t implemented it. I’m using a network library called Moya. We wrote it for Eidolon for when you call a request, and it’s basically like a wrapper for AFNetworking. So we call a request and get a cancellableToken back. We can call cancel on that token in order to cancel a request. What we do is when we return the thing that represents our work here, it’s called a Disposable. Remember that DisposeBag got rid of all the bindings when it was disposed of and it was deallocated. If our view controller is deallocated before our network request returns, we’re going to grab the cancellableToken and actually call cancel on it. So, this actually supports cancelling inflight network requests.

I wrote the ReactiveCocoa version of this, and this is something that was contributed by Andre Carvalho. That’s a really cool thing about open source software - I didn’t have to write this, I just had the idea that someone else took and ran with it. If we look back at the simulator we can see that if I hit the back button before it finishes, their network indicator goes away and we don’t get a crash or anything because the request was cancelled and the binding was disposed of.

If you wanted to explicitly cancel it, that is very imperative of you. Not that there’s anything wrong with imperative programming, but when you’re using Functional Reactive Programming, it’s like having Google’s Chromecast in an Apple ecosystem. Your life is a little bit harder. When you’re doing Functional Reactive Programming, the more imperative code you use, the harder your life is. If you buy into this ecosystem of FRP, just like when you buy into the ecosystem of Apple, things get easier.

If we go back to the code, I’m going to get rid of this Disposable so now I’m responsible for manually disposing of it. If I look at the type, it’s actually of the type Disposable. It actually has a dispose function on it. You could call it manually if you wanted to. This is kind of discouraged, because ideally things would be disposed of based on the activity of other streams. You can certainly do it if you want to, and I’ve had to do it before. Sometimes you have to write imperative code, or you want to write imperative code. Functional Reactive Programming lets you do that as much or as little as you’re comfortable with.

You can read more written by Ash on his blog, or feel free to Tweet him!

Ash Furrow

Ash Furrow is a Canadian iOS developer and author, currently working at Artsy. He has published four books, built multiple apps, and is a contributor to the open source community. He blogs about a range of topics, from interesting programming to explorations of analogue film photography.