049 iPhreaks Show - ReactiveCocoa with Terry Lewis
The panelists talk to Terry Lewis about ReactiveCocoa.
Show Notes
The panelists talk to Terry Lewis about ReactiveCocoa.
Transcript
CHUCK:
Hey everybody and welcome to episode 49 of the iPhreaks Show. This week on our panel we have Pete Hodgson.
PETE: Hello, from San Francisco.
CHUCK: Jaim Zuber.
JAIM: Hello, from Minneapolis.
CHUCK: I'm Charles Max Wood form DevChat.tv and we have a special guest this week, Terry Lewis.
TERRY: Hi, this is Terry and I'm in Houston!
CHUCK: So you're our Houston guy because Ben’s not here, huh?
TERRY: Yeah, I guess I’ll pretend to be Ben.
JAIM: There always had to be one.
CHUCK: Yeah. I thought it was, “There can only be one.”
PETE: You actually work with Ben, right?
TERRY: I do, actually. We work at the same company. I don’t work directly with him on a project right now, but yeah we’re in the same office.
CHUCK: Do you wanna introduce yourself and get all the gory details?
TERRY: Sure. I'm actually not an incredibly long time developer. I worked retail for a long time and I was like, “Hey, I don’t wanna work retail anymore. I'd like to make more money and do something more interesting.” And so I decided to go to school for computer science and I did that about a little over two years ago. I started doing iPhone stuff right after I started school because I didn’t wanna write Java command-line applications and so I've been doing iPhone stuff ever since. I did some contracting for a while. I recently moved out to Houston for a job – that’s Ben and the company. We both work for it now.
CHUCK: Cool. Well I’d ask you how you like it, but Ben is a regular on the show. You sound pretty happy though, so we’ll just leave it at that. We brought you on today to talk about Reactive Cocoa?
TERRY: Yup. So I'm guessing we’re going to go at this from, I guess, a lower-level perspective, as in you’ve not really heard of it before or you’ve heard of it but haven't really messed with it. Reactive Cocoa is an implementation of functional reactive programming. Functional reactive programming, when you break it down, you have functional programming – which is languages such as Haskell or Scala and the focus is on functions, with functions being first class citizens in the language. You can create them anywhere, you can pass them to other functions, you can return them and so forth and so on, and we have this with blocks and objective-C though they're not quite to the level of first class functions and true functional languages. And then the reactive part is simply what it says – it’s reacting to change in your app. You can just think of Excel or spreadsheet for this; you put in your formula and you put in numbers, and it updates itself. You don’t have to say ‘reload’ every time you change a number – it just updates for you; it’s reacting to the changes. You had probably not used Excel or a spreadsheet if you had to manually update it. So the reactive part, not only does it give as good of a good paradigm to work with at the codelevel as developers, you can actually create much better user experiences for the users of our apps. Again, Excel, you wouldn’t use it if you had to manually reload changes, and so you can translate this into better user experiences. That’s sort of the high-level overview of the functional and reactive part.
CHUCK: So I'm kind of curious what is the traditional approach to the problem that Reactive Cocoa solves as opposed to doing this functional reactive programming? What do most people do if you update, say, a field in your UI and you needed to update some other text or something further on in the app?
TERRY: Well for iOS, you might have delegates, you might have a block – call that; you might have a notification – there's any number of methods to do these things and the things that you do in Reactive Cocoa aren’t impossible to do with normal, imperative code, but looking at it just – it’ll give you a cleaner way to do it. Like you said, you use notifications, I update this UI element, and now this model element, now update this UI, let me press notification, or a delegate or whatnot. So, there are various and sundry ways of doing that imperatively that we’ve all used. And they're all effective, but Reactive Cocoa does things in a different way.
PETE: I guess maybe another analogy that maybe would get the idea across the imperative versus declarative thing is using sequel instead of looping through stuff directly, so you could clear your database by, say, I wanna get all the list of developments, and then I wanna loop through them, and then if the thing is less than this, then I wanna grab these five [inaudible] and do it all imperatively step by step. Or build it with sequel, you can kind of raise the level of abstraction and be more declarative and just say, “I want this collection filtered by this criteria. You figure out, computer; I just want the results.” I kinda feel like reactive functional stuff is kinda the same, but the UIs are rather manually [inaudible] sticking callbacks on things and saying, “Okay, this has happened, so I'm going to get this thing over here and put it over there.” You just kind of set up the flow of information and then let the computer or let the compiler figure out all of the details.
TERRY: Yeah, and that’s a good analogy; it’s very declarative. Another one I like to use is auto layout, [crosstalk] auto layout as you should be, but with auto layout you say, ‘here are the constraints for this view, and viewLayer yourself out.’ You don’t worry about actually setting the frame of the view; you just set some constraints and the view handles all its layout. It don’t matter in the order that you specify these constraints, so as a higher level, it’s a declarative thing. Reactive Cocoa and functional programming in general provide the style of programming where you say more of what you want done rather than how you want to do it.
JAIM: So how does this work in like a typical viewController? Seemed like a very different way from how we’re used to developing our UI?
TERRY: Well you still have, say, the canonical example that I use when I've got some examples of these views are of text fields. Say you have a login form and you have a name and email and a password field, well you might plan on how you do it imperatively. You might set those fields and you have a lot of [inaudible] know do some action log in when one of the fields are done, and you might validate the fields, perhaps, when you hit the login button you might grab all the values from the fields, maybe do some validation, set them on your modelObject and then send it off. The way you do this in Reactive Cocoa, you could set up connections from all your fields, which you would get signals – they call them the classes RACsignal. So you get signals from all these fields, and you would transform them, and do validation on them before you actually set them on your model object or let their request be fired off. So yeah, it’s definitely different. And you can do all this logic with Reactive Cocoa; you could just declare it in viewDidLoad. So for a small viewController you can have the entirety of your logic in viewDidLoad and it would all just work.
JAIM: Okay, I think we skipped past a little bit on exactly what Reactive Cocoa is. This is a library that you can download from GitHub or something?
TERRY: Yeah, it is completely open source. It does have a CocoaPod, thankfully, because installing it the manual way is a little bit more of a pain. It’s a completely open source library, and it lets you do functional reactive programming in OSX or iOS apps.
JAIM: Okay, so typical use case would be in our viewDidLoad, we would wire up some validation-type logic that we would assign this somehow with the Reactive Cocoa framework, and as the text changes in the text field, we could kinda enable or disable buttons. Does that sound like a [inaudible] use case?
TERRY: Yeah, that’s basically what you would do. You would take the text, and you could transform a text into, say, a Boolean that would indicate whether the maybe the ‘create account’ button was enabled or not. And you can take the text from all the text fields, say you don’t wanna be able to create an account till all the text fields are enabled, and you combine all those values into one Boolean that says ‘the field is enabled’ or ‘the field is disabled.’ And so yeah, you do a lot of transforming of your data; you'll see a lot of map, and filter, and reduce going on in Reactive Cocoa.
JAIM: Okay, what's the map filter radius for those who may not be kinda familiar with that?
TERRY: Well, we are sadly missing these methods and foundation that are available in Ruby and many other languages, but Map is what we call a higher order function and it’s a better way to transform a list. You usually see it on lists and instead of writing a forLoop, taking some data from an array, doing something with it, transforming it, adding it to a new mutable array. And then using that new mutable array map, you pass a function to the map method and you’d get the element from the array, and you transform it and return that, and map returns a new array of the transformed elements. So it’s a higher level way of basically iterating through an array and changing the values to something else and getting a new array back.
JAIM: Okay. So I’ve got an array of strings; I wanna add ‘iPhreaks Rule!’ to all of my strings, so I would use a map for something like that. Is that right?
TERRY: Yeah. You could call a map, call NSString, stringReformat, and ‘iPhreaks Rule!’ into the string and just return that. And you would get a new array with those transformed strings.
JAIM: Okay, very cool, yeah. That's something that’s available to us in a lot of different frameworks. I do a lot of C#; Link does a lot of that, kinda MapReduce type stuff; Ruby does it, but yeah, that’s one thing I definitely missed coming into doing objective-C. I like having those types of operations that could really help clean up your code. But at this point I got so used to doing these four loops, for 40 i++. It’s hard to step back, but it’s very cool.
PETE: That’s a really good app – the map [inaudible] I think it’s like a really good – it’s an example that everyone can understand of what we mean when we talk about functional programming, kind of changing things from imperative to declarative. You just say – you capture the essence of what you wanna do, I wanna add this string to this other string, and you let the library or the framework or whatever take care of the boring stuff of maintaining counters and moving through things. It means that the code’s easier to write, but it also means it expresses its intent better so it’s easier to understand and easier to maintain.
CHUCK: Now are those functional constructs built into Reactive Cocoa, or do you get them from somewhere else? Are they part of objective-C?
TERRY: They are built into Reactive Cocoa. So you have map and filter and reduce – these are all methods in Reactive Cocoa and you deal with these on the signals that you get from Reactive Cocoa, so you're not operating on collections like they normally do in other languages, but they're operating on what Reactive Cocoa calls signals, so you don’t just get it for random objects in objective-C when you pull in Reactive Cocoa.
CHUCK: Okay.
PETE: So the difference there as I understand it is that in the traditional, not traditional, but in the kind of the way the map signal I think a lot of people would be familiar with looping through an array – you take the whole array, you loop through it, and you get another array. Whereas with these signals, you're not necessarily going to do the work there and then; you're just kind of setting up this – you're kinda slotting together a series of connected types and you're just saying when something happens, flow it through all of these operations and map this to that, and then filtered by that, and blah-blah-blah. But that operation isn’t necessarily going to take place right now; it’s going to take place at some point in the future when someone interacts with the system.
TERRY: Yeah, and that’s a pretty good analogy. Like you said, you can get a signal from a text field, and that signal will send a new value every time the text field changes. So you can set up all these transformations on this signal kind of text field, but the text never changes – if no one ever enters anything into the text field, then none of that work will ever be done. So you're setting all these pipes up, like you said, and all these chains, but they’re just waiting on data. And so you can set all these up and they may or may not actually do anything depending on if they actually receive data.
JAIM: So what [inaudible] that’s kinda interesting – so we’re taking a signal to a text field? How does that work? What's going on under the hood there?
TERRY: The main class you interact with on Reactive Cocoa is called RACSignal. You can generally think of signals as a pipe – it’s just a wrapper around your data, any data – and it carries this data along and lets you transform it, and filter it, and do all these operations to it, and it just ferries it along wherever you want it to go. So for a text field, you get – there's some category methods on some UIKit classes. And UI text field has one and it’s called – you just access its property on RAC tech signal and that gives you back a signal that sends a value every time the text field changes. You might think this is voodoo, but under the hood, you look and you're just really getting a target action on the text field that says ‘sent an event for value change,’ or value DidBeginEditing, I believe, and it’s piping all these values through this signal that you get. So it’s not some super crazy – there's more to it to make the signal work, but that’s basically what's going on under the hood. It’s setting up this target action and then feeding values to the signal.
PETE: What other things are generating signals can you – are there signals so things like scroll events [inaudible] or things like that?
TERRY: You can create signals yourself and you can create them for pretty much anything. You can observe properties; there's a nice macro called RACObserve – you just queue a property or [inaudible] with a key pass, and then it'll give you a signal that will send values whenever that property changes. And so, this much nicer APIs and say, KVO, which is terrible. Say, you can create signals that send whatever you want; you can observe properties that will give you signals whenever those properties change; so yeah, you can manipulate these and create these basically however you want.
PETE: That’s pretty neat. So this isn’t just things that you attached to the UI; you could [inaudible] attach this to a domain object so whenever you update that domain object, then it would magically – you could attach a signal to that property and then wire that signal to the UI and whenever you change the property in the domain, it would just update in the UI?
TERRY: Yeah, and you can do that both ways. Your modelObject updates your UI, like you have a settings view and you want to update fields based on some user thing, user object, and your UI could, in turn, update your modelObject. Say, you can go both ways and you can make a signal out of basically anything. So it’s not – yeah, it’s definitely not just UI stuff. You can model all your interactions with signals.
JAIM: Okay, so we’ve got a model class – where would you typically put a signal [inaudible]? Would that go on to model, create a category for it – what's worked well?
TERRY: It sort of depends on what you're doing. You might have a person class and this person has a name, and this is what we’re going to wire up to the text field. Trying out what you're doing with it, you might just have the person object in that viewController, and just [inaudible] that text field to that person in that viewController, because you might only be using it in there. You could have a signal that goes to the modelObject – there's many ways to do it; there's not only one way. It sort of depends on what you're doing, but I've sort of have done smaller things, so I try to keep the viewController small, and I might put my modelObject just as a property in the viewController and do bindings there from UI to the modelObject.
JAIM: Okay, very cool. So [inaudible] voice of reason here. So we’ve been creating UIs with the standard imperative method, doing this for a long time, why do we want Reactive Cocoa? Why would we do this?
TERRY: I've thought about this a lot, actually. I thought about, generally, software engineering and tools we use, and I guess the future. And yes, we have these tools – iOS, objective-C – we have these nice SDKs, we know how to program this way in the imperative style, and this Reactive Cocoa is this new thing, it takes some learning, it’s got a learning curve, so that’s a valid question. Why would we do this? I think – and you'd probably find other people that have different opinions – but a lot of people think that imperative code is bad. Writing in imperative style is bad because it’s very low-level and it’s very hard to reason about. You get up into higher abstractions, higher abstracted languages, and your code becomes easier to reason about. And we’re building bigger, and bigger apps, and with more and more states, and so it just becomes really hard to reason about all this state and this size of the apps that we’re building. And so using Reactive Cocoa, or some higher language, some functional language – these things will become easier to reason about for us, and easier to make these larger apps. It gives you a higher level of abstraction and it gives you easier ways to reason about what you're doing. And so that’s sort of one of the selling points, is it’s just easier to reason about, which allows you to not worry so much about the various states you have to be in and just write, again, more of what you want to do rather than how it should be done.
PETE: I'm totally stealing this from Josh Abernathy who’s one of the guys that created this – he did this awesome presentation at Cocoa Conf a couple of years ago kind of about Reactive Cocoa, but also just more about kinda blowing your mind. And what he talked about was state and what makes this kind of stuff really valuable is it reduces the amount of state that you have to think about and this kind of shared state you have to maintain. And reducing the amount of shared state in your program is an awesome way to reduce the complexity, because you stop having to reason about all of the interactions between different bits of state, and you can just start thinking about how things flow from one function to another function. It makes a really big difference in how it means that you can hold small parts of the program in your head and understand them rather than having to hold the whole program in your head all at once so that you can remember all of the different things that are touching this kind of shared state. So I think that’s one of the big wins.
TERRY: Yeah, definitely. And it’s impossible to hold the entire program in your head, unless it’s a very small program. I mean, there's so many states that you have to be in – what is it doing here, and this property might change here – it really becomes basically impossible to reason about at some point. There's so many different branches, and so yeah, reducing state is definitely a huge win.
JAIM: Yeah, I've been doing client development for a long time and [inaudible] desktop applications way back to MFC and Windforms, things like that, and you end up handling all these different button clicks and text enters and you left it separated out in different parts of the application, and eventually you kind of got to a point where you'd have one monster method that kinda handles all the different enabling, disabling, things like that. And this is a way to kinda split that up, which I think works very well for large applications, so you can concentrate on [inaudible] aspect of it, of when this button should be enabled, or this validation strength should be visible, something like that. So I think it’s a really powerful paradigm, if you can sell it to the rest of your team, or if you're like me, you work by yourself, you know.
PETE: That’s a really, really good question. That’s a very good practical question. If I wanted to start introducing this into my current application that I was building – even if let’s say I'm working on my own, but I have this existing application, do you have any suggestions as to places to get started? Like a place where you can dip your toe in without having to buy into its entirety?
TERRY: Yeah. One of the things when I first started learning this, I was pretty sold on it. I was like, “Man, this is awesome!” and I wanted to make everything with Reactive Cocoa. I'm going to Reactive Cocoa all the things – and that did not work out very well. What I realized is that some things you may understand better in the normal style – you just wanna write it and get it done; some things you'll – if you work with it, you'll begin to see the patterns in your Xcode and how to use it. So, if you wanna try it out, I would just pull in the framework and just start playing out with it, use just little bits where you're like, “Oh, seems like a good candidate” and just use it there. You don’t have to write your entire app in Reactive Cocoa. It can exist side by side with your other code. So that’s something that, I would say, if you're going to start out is pull it in, just program a little bit, use some of the methods, see how they works and just use it in little places. And as you start to understand it, you use it more and more. I think that’s an easier way to get into it and try to write an entire app in Reactive Cocoa.
JAIM: What's one thing that you tried that didn’t work out the way you thought it would?
TERRY: Well the one thing – again, you have this nice macro that’s RAC observe, and really it’s just wrapped around KVO. And so maybe you'll think that you wanna observe, when you use this, like, “Oh my gosh! I can reserve property changes this easily?” and so you're just starting to try to reserve all the things, but as a wrap-around KVO, you might not be able to observe everything like I was thinking, “Oh my gosh, I can observe anything I want!” But UI Kit is not KVO-confined, so you might want to try to observe a UI property and it might work, or it might not; it might just break. Or you might want to try to observe something like there's something being added to an array – these are the things that you might think that you can do with this when you first look at it [inaudible] but not everything works like that. There's various things that you might try that’ll just fail, and they’ll most often fail because you don’t have a good understanding of the framework, and that’s what I found when I was first laying it out. “Why is this not working? This should totally work!” and I would think maybe it’s a bug, but it’s never a bug. It’s always me.
JAIM: Okay. So one thing that you had to make sure that the class that you're observing are KVOcompliant. I still have to discuss with a lot of my other developers that don’t wanna use their properties; they just like their ivars, so it’s good to know. So, should be KVO-compliant.
TERRY: Yeah, and people are still using just ivars? That’s crazy.
JAIM: So one thing that kinda interested me – I started hearing about Reactive Cocoa maybe the past six, twelve months or something like that. But this is more of a pattern that I always associated with Windows and [inaudible] WPF stuff that people were doing maybe three or four years ago, and people were starting to do all of these cool things where you could do all these really complex UIs and their actions. How did this kinda end up in the Mac world? It seems like kind of a strange chasm to jump. How did that happen?
TERRY: Well again, I don’t know the entire origin story, but Reactive Cocoa is based on the RX extensions, which comes from the Microsoft world and these guys at GitHub decided to basically build this up for Cocoa. Because we didn’t have it – there's RX extensions for .NET, there was RX.js, I think there was even RX Ruby. So with all these things – there's RX Java – but we didn’t have it in the Cocoa world, and I actually was sort of surprised someone didn’t get that over sooner when I think about it, because RX extensions aren’t exactly a new thing. So I believe it started with the development of GitHub for Mac app and that’s sort of the origin as I know it.
JAIM: [Inaudible] GitHub app? Is that open source? Can we view that?
TERRY: No, the GitHub app is not. A lot of the components are, which one of them is Reactive Cocoa. So again, the full source of Reactive Cocoa is out there and you can look at it and see how it’s done, but the actual GitHub app is not.
JAIM: Okay. Are there any example projects that’s using Reactive Cocoa out there? So that we can kinda see some examples of how it works?
TERRY: I actually have a project that I did that is out there; it’s on my GitHub page and I just called it the RACExample. [inaudible] it’s really good. There are some other ones – there were some on the Reactive Cocoa wiki page, I don’t know if there's any more. We’ll have to find some other ones, but there's definitely some out there. And also, Flamingo. I don’t know if you're familiar with that somewhat new chat app that’s out for Mac, but that also uses Reactive Cocoa.
PETE: So that brings me to a question I was going to ask, presumably – this [inaudible] segue so I apologize. Presumably, a chat app does need to do a lot of talking to back end servers and network-y stuff. Does Reactive Cocoa claim into that as well?
TERRY: Yeah, and that’s one of the really great things about Reactive Cocoa is that you can model pretty much everything with signals. And so when you work with enough APIs, you'll see that this API likes to just post notifications; this API likes to have a delegate; this API takes blocks, and so using Reactive Cocoa you can model everything with signals and you can work with whatever your network requests, talking to back ends –. So yeah, it plays nice with basically everything and it allows you to have one unified API to deal with so many various things.
PETE: Does it have adapters and out of the box so that I could kinda plugin signals to AFNetworking or the existing kind of network stuff that’s available on iOS?
TERRY: There are some extensions for AFNetworking you can find along CocoaPods. You search there – they're not official extensions but people have made them up. But you don’t actually need really an extension. You could write the extension yourself incredibly easily. It says when you create a signal, what you do is you do a block and this block passes in a what they call a subscriber and the subscriber simply has three methods, which are sendNext, sendError, and sendComplete. So you have a networking class and you don’t wanna do all your network requests in there, and you want to be able to do that to a viewController somehow instead of doing the normal maybe success/failure block. In the networking class and the success or failure block, you can say sendNext whatever the successful data is, or sendError, if there was an error, and then you can just get a signal that will carry along [inaudible] response, whatever you wanted from the network or that'll send along error if there was an error. You can get either way from the success/failure callback thing that you might have in your viewControllers.
PETE: So, let me see if I can kind of work through an example that will toggle this together. Let’s say I wanna allow a user to update his password. I can have a UI with a current password, a new password, confirm New Password or whatever, right, those three fields. So I can plug signals in my viewDidLoad or something; I can plug in signals to those text fields changing, then once they’ve all been filled out and they're all verified, then I can kind of take those three different pipes and merge them into one pipe, which is like an update password thing, and then take the send button and merge that into the thing. And then once all of those things kind of send a signal together, then I can condense that into one thing that would then go into the network and make the actual update request. Does that sound like I'm vaguely getting it right?
TERRY: Yeah, you can basically do some of that – you have the text fields; you can say enable this button while the text fields are correct, and when the button’s enabled you can have it fire off this network request and you could have a method that would you would pass it in the [inaudible] fire off the network request, and this method can return you a signal that represents the network request. And then you could transform that request however you wanted. So yeah, that’s basically [crosstalk]..
PETE: Would I have to still have some kind of procedural code in the middle that kind of bridges the gap between then UI kind of signal-y stuff of things changing, and then me creating this signal in the network or this RAC subscribe on the network side of things? Do I still need some imperative code to do that, or can I just set all of that stuff up declaratively at the start of the program and just let it all just kinda float through whenever those changes happen?
TERRY: In working with what is basically a framework built in a language, so yeah, we’re still going to have some imperative stuff. You're still going to have to use AFNetwork in making a request, have a success and failure block, maybe view some stuff to the response subject, maybe there's a dictionary you wanna get some certain keys out of it – so you're still going to have some imperative code. When you do a map function – you're going to return something from this map function, but you might be doing sort of an imperative thing within that map function. I could say, take this value, trim the white space [inaudible] white space and check its links and then if that link [inaudible] or return a bool, otherwise return another bool, so there's still imperative code in here, but it’s less.
CHUCK: One thing that I'm kind of wondering about here is you mentioned that you can have a signal that basically triggers a call down to a back end on the internet service, and then you have another signal that’s generated when it replies? Where do you set up that signal for that reply? Do you just put it into the callback, or is there some other approach to that that I'm missing here?
TERRY: Where would you deal with the signal that you get for the reply?
CHUCK: Well how do you get the reply and turn it into a signal?
TERRY: For that, say, you have AFNetworking and you say get [inaudible] success and failure – you have this success and failure block. What you would do in your networking class, you’d have a method that says, make a request with the params but you wouldn’t have as success/failure blocks that you would have this method. It would return a signal, so you can create a signal with a class method on RACSignal called create signal. And you would do your network request within this – it gives you a block – you do your network request within this block. And in this success block, you have this subscriber and you say, ‘subscriber, sendNext the response object.”
CHUCK: Okay.
TERRY: Or in the error block, it says there, ‘subscriber sendNext the error object.” And then this method which simply returns the signal that would encapsulate this network request, and then you could get access to the Next, which would be the response object or the error, which would be the error, if it errored out.
PETE: So these things are kind of – this RAC subscribe is almost like promises in JavaScript or one of those another language that has promises. Except rather than firing once, rather than promises to resolve or fail once, these things can kind of send a stream of data over and over and over again, so it’s still the idea that you create a thing and then attach things into it to say this is what I want to do when this succeeds, or this is what I want to do if this fails, but it could succeed over and over again as it were every time someone touched the button. Does that sound right?
TERRY: Yeah, that’s a good, very decent explanation. You can think of signals as a pipe, and a one-way pipe, data flows down the pipe, and a subscriber is the end point for that pipe. You can subscribe to different events the signal sends, so signal – you can get a Next, an Error, or a Complete. So in case of the checks field, it’s going to send a next many times, or as many times as the text field changes, so it’s going to call this next event many times. But it will only call completed or error once. So yeah, you're going to get – you could potentially get many Next events or you could get none, but you only ever get one completed or one error.
PETE: Got you. So you mentioned earlier, I think we mentioned a couple of times [inaudible] this origin – this history – the origins for this are kinda based on or inspired by the RX stuff that Microsoft did in .NET. One of the advantages that, I think, .NET has over objective-C with this kind of thing is Link and Landers and all those kinds of things are actually pretty first class in the language now of C#, so you can kinda create the numbers function. You kind of can do that in objective-C with blocks, but it’s always felt a lot more clunky to me. Is it the fact that blocks are a little bit clunky – does that kinda show up when you're doing this kind of programming? Do you end up having to do some housekeeping to remember what stuff needs to be blocked, marked as a block variable and all that nice stuff or does that tend to not happen when everything is set up as functions?
TERRY: I haven't really noticed that or had any sort of annoyance with that. A really large amount of these methods that you're going to deal with with your Reactive Cocoa take blocks and so just what you're doing and I haven't found too much annoyance with it [crosstalk].
PETE: This suspicion that blocks are annoying to deal with when bridging the gap between a functional style and a state-based style, and that’s when it gets into lots of pain of garbage-collection [inaudible] and all that kinda stuff. I'm guessing maybe because you are just using blocks all the time and just using essentially functions without state existing outside of the functions, then maybe it means that they’ve become a lot unpleasant to deal with.
TERRY: You still do have to worry about retaining cycles, and when you pull down Reactive Cocoa, you'll get this nice macros – two macros – called Weakify and Strongify. They basically do the strong self, weak self dance for you. So you say, I weakify self outside you block, and then inside your block you say, I strongify self, and that’s equivalent to doing weaktypeofself, self, strongtypeofself, weakself, and so you do have some easier methods for dealing with retain cycles, and you do still have to watch out for them.
PETE: Okay. That’s a shame. That’s nice that they make it easier [inaudible]. And the other thing, like around kind of the language support is a lot of the pure functional languages are built around this concept of immutability, so you can’t change something – you can’t change the properties of a thing; you can just create a new thing if you wanna change it. Does that show up in reactive functional stuff for Cocoa? Is it bad form, or does it lead to confusion if you start mutating objects as they're flowing through these pipelines, or does that not show up?
TERRY: Well, the signal itself is immutable. Once you create a signal, you can’t change it. Any operator – mapFilter, reduce – whatever operator you do does not actually affect the signal, so signals are immutable. Any operator on a signal returns a new signal. You are transforming data like when you do a map function; you're obviously mutating the data somewhat. So yeah, you're mutating the data inside these functions, but the signal itself can’t ever be changed – it is immutable. Yeah, you want to avoid mutability as much as you can; without any mutability, we have a very boring, boring app, so we just want to limit placing where we mutate things.
JAIM: Okay. One thing that kinda confused me when I started changing my development approach from a comparative to a more declarative is that the techniques that I was used to doing for debugging didn’t really work. Like I'm just listening for an event handler and kinda stepping through stuff and stepping into things. Can you give us any advice for debugging reactive stuff?
TERRY: It’s definitely harder; when you have simple stuff, it’s simpler. You can say maybe your data’s coming out wrong; you could set a break point in the map method, make sure you're transforming things right. When it gets larger and more complex, it gets a bit harder. A lot of the signals, when they're created entirely, they get a name set to them, so if you get a crash or a runtime error, they’ll have the signal and they’ll have a name attached to it so that makes it a little easier. Some things [inaudible] compile time, so I don’t have any specific debugging strategy, really. But again, sometimes there might be something that you're doing, maybe in a function that you just break on, or there may be something in runtime that you're trying to assign a signal to a text property because you're sending a signal and not text, and that'll break it runtime, it usually gives you a pretty good exception for that
PETE: Does Reactive Cocoa offer [inaudible] method where you can kind of insert like a T into a pipeline as it were?
TERRY: Not that I know of. They might be in there; it’s a fairly expansive framework so it could be in there and I might now just happen to cross it.
PETE: Gotcha, because I've always found that useful. If you’ve got a long chain that have kind of – if you basically got a bunch of stuff that’s stuck together a pipeline of operations, you can kind of insert – and things aren’t working the way you want – you can kind of insert a T into the middle of that pipeline and use it to kind of sample what's happening without disrupting the flow. I kinda think of it as like attaching a probe or a tap, like a wire tap, into the sequence of events or signals that are flowing through the system, so you can see what's happening without actually changing the system. I would guess maybe there's something – [inaudible] you could just do a map that doesn’t actually transform anything, it just has a side effect of just letting you see what's happening inside of the pipeline?
TERRY: Yeah, I would imagine. It might be in there, I might not have just seen it yet, or you can do it like you were saying just have a map and look at it there.
PETE: So the last question I've got is around testability. Does this lend itself to more testable code, like more automated, more test automation, or is it tricky to write tests for this kind of stuff?
TERRY: I would say it can be more tricky because of the nature of it. What are you testing, exactly? You’ve got your signals, and you're not testing the signal; you really want to test what it’s sending. A lot of this stuff can be done in blocks, and it can be done asynchronously, and testing asynchronous code, testing blocks is a little harder, so it is possibly a little harder to test. That’s why I haven't done too much testing with it; I've only done little, so that’s what I have on that.
CHUCK: Alright. Any other things that we should talk about related to Reactive Cocoa? I know that next week we’re going to be talking about the functional reactive programming book.
TERRY: Is that the one that Ash Furrow did?
CHUCK: Yes.
TERRY: That one’s pretty good. [inaudible] enjoyed it. If you wanna see a language built for functional reactive programming and not simply an extension, there's a language called Elm and it’s for web programming. It compiles down to HTML, CSS and JavaScript, and it’s built from the ground up for functional reactive programming. If you wanna see what that actually looks like natively, then you should check out Elm.
CHUCK: Alright, cool. We’ll put a link to that in the show notes. And let’s go ahead and do the picks then. Jaim, do you have some picks?
JAIM: Yeah, I've got one pick. My wife has type I diabetes, and so she’ll take an insulin shot. She got a pen, and every so often she’ll forget she took a shot or not, which, if you're trying to manage your insulin, that’s kind of a big deal. Like I'm the type of person who forgets if he shampooed his hair, [inaudible] not too bad, but there's something that [inaudible] diabetes takes too much insulin; your blood sugar goes very low, and that's kind of bad. This company called Timesulin made a thing you put on your insulin pen and they're [inaudible] in many other countries that are not the US, but they’ve got an indiegogo campaign to try and get through the FDA, which is trying to keep us safe by not letting us buy this thing. But they’ve got an indiego campaign to help raise money for the FDA process, so it’s seems like a pretty cool thing. You get it for $30, kind of a preorder thing. So that's my pick – Timesulin. If you have people that kinda have diabetes and take shots, this is actually a very cool product for them.
CHUCK: Cool. Pete, what are your picks?
PETE: I'm being a little bit boring this week and I'm going to pick things mostly to do with the topic at hand. So my first pick is a write up on Reactive Cocoa from the inimitable Matt Thompson. NSHipster has an entry on Reactive Cocoa, which is a good read. It talked about the basics – I didn’t read the whole thing, but I just assumed it’s good because he always writes good stuff. My second pick is the slides from this talk that Josh Abernathy did called Better Code for a Better World. I'm not sure how well the slides are going to get the point across; I'm not sure if there's a video recording of this talk anywhere, but it was a really good talk and it talks about some of the details about how Reactive Cocoa works, but mainly the first part of the talk [inaudible] was just talking about why these principles can lead to a saner developer life, which I'm a big fan of sanity, in general. And then my last pick is a tool that Facebook just released called Chisel. Chisel is pretty cool; it’s a bunch of LLDB macros that you can kind of insert into your debugger, into the LLDB debugger that Xcode uses by default these days to help debug what's going on with your application. So you can – once you're in a break point and you’ve got the debugger in the command line, you can use all these little commands to print the view hierarchy into the debugger or show or hide views to show what's underneath them, more like highlight things so that you can see which view is where, so loads of really useful things for you to mess around with the visual hierarchy of your application, kind of [inaudible] debug it to kind of try and figure out what the heck going on. It’s a really cool tool. It’s kinda one of those things that seems obvious in retrospect, but I guess no one of these things before. So check it out, Chisel. And that’s it for me.
CHUCK: Awesome. At Mountain West – I think it was Mountain West JavaScript, or it might have been Mountain West Ruby Conference – somebody gave a talk about iBeacons and the way they set stuff up and made it work and hooked it up to their app. My picks are going to be related to that. Before we do that though, I just wanna mention that we did a functional reactive programming episode on JavaScript jabber and so I’ll put a link to that in the show notes as well. Anyway, so he was talking about using Estimote iBeacons, and the problem was, I didn’t really wanna get it and hack it and I tend to like to do things on the cheap. And so I wanted some more flexibility and I wanted it – I wanted the little bit, less expensive thing, and I had this Raspberry Pi sitting on my desk for a while, and it turns out that you can actually get some hardwire, and build your own iBeacon out of a Raspberry Pi. And so since I had that sitting on my desk I just bought the other couple of things that I needed to make it work. I got a link I there to a Bluetooth USB – it’s not really a dongle in a sense that it hangs off of your machine, but it is a little nut that you plug into your USB. You can hook that in there and then you can – you probably want to get the Raspberry Pi with the power supply and the operating system. It’s the Raspian Operating System; it’s kind of a stripped down Linux for the Raspberry Pi, and that’s all pretty inexpensive. And the Raspberry Pi does a whole lot more stuff, so it’s kind of a fun little kit to have anyway. But then there is a post on how to build iBeacon with Raspberry Pi and I’ll put a link to that in the show notes as well. But yeah, that’s kind of what I've been looking at lately and so yeah, I’ll go ahead and just pick that stuff. Terry, what are your picks?
TERRY: I am going to go with two. The first would be SimPholders. If you haven't heard of it, it’s a nice little utility that sits on your mini bar. It lets you quickly access the folder of apps in the simulator, so you're working with core data and you want to get to the actual sequel light file and maybe view it in some sort of viewer. SimPholder makes it easy to just select the app, and it’ll open up the directory and you can pop in the documents right there, and there's a sequel light thing [inaudible], so SimPholders is a great little utility. My second one would be AppCode. If you haven't used AppCode, that’s sad, because AppCode is incredible and as much as I love Xcode, AppCode is just miles ahead in pretty much everything – in writing code, refactoring – just everything. Do you use AppCode? I do.
PETE: I always get annoyed because I end up going back to Xcode accidently when I'm editing what's it called – nibs. I'm just a big fanboy of what's called a – those guys.
TERRY: Intelli-j–.
PETE: Yeah.
JAIM: Jetbrains.
PETE: Yeah, jetbrains are awesome.
TERRY: Yeah.
JAIM: They do good stuff.
TERRY: So yeah, AppCode. If you haven't used it, try it and you'll hate Xcode unfortunately.
CHUCK: [Laughs]
TERRY: Except Xcode looks better. It does look a lot better than AppCode, but other than that – the writing code and refactoring is just miles ahead in Appcode.
JAIM: When do we get the Native version of AppCode?
TERRY: Probably never.
PETE: Probably never.
JAIM: I want it; I don’t want Java.
CHUCK: [Laughs]
JAIM: Yeah, it does feel like a Java app, even though it is awesome. If you know you're using Java.
CHUCK: I see. I was going to make a couple of coffee jokes but I passed. Alright, well thanks for coming, Terry. Really appreciate you taking the time and sharing your expertise and if people wanna get a hold of you, or find out more about Reactive Cocoa, what's the best way to do that?
TERRY: You can get me on twitter; my twitter handle is @tlewisii, Terry Lewis II, and if you wanna learn more about Reactive Cocoa, you can go to the GitHub repository, the official one and they have a ton of great documentation there. I also have two projects, actually. I have an Example project on GitHub that’s open source. It just shows various examples of using your Reactive Cocoa, and so [inaudible] in it, shows different things that you would normally do in an app and just shows how I've done Reactive Cocoa. I also have another one called RACTraining and it’s sort of a step by step walkthrough of getting started with Reactive Cocoa, and so it just builds up with tags. You start with tags at 1, and you got a tag 9, and then you see sort of step wise how this works and how to work with it.
CHUCK: Alright, cool. Well then we’ll wrap up the show. Just to note to those who haven't started it yet, we are reading Ash Furrow’s book, Functional Reactive Programming. And thank you all for listening, we’ll catch you all next week. [Hosting and bandwidth provided by the Blue Box Group. Check them out at BlueBox.net.] [Bandwidth for this segment is provided by CacheFly, the world’s fastest CDN. Deliver your content fast with CacheFly. Visit cachefly.com to learn more]
049 iPhreaks Show - ReactiveCocoa with Terry Lewis
0:00
Playback Speed: