
Sign up to save your podcasts
Or


Jay Phelps: @_jayphelps | jayphelps.com
Show Notes:
Resources:
Transcript:
Coming Soon!
Jay Phelps: @_jayphelps | jayphelps.com
Show Notes:
Resources:
Transcript:
CHARLES: Hello everybody and welcome to The Frontside Podcast, Episode #84. My name is Charles Lowell, a developer here at the Frontside and your podcast host-in-training. With me today is Elrick Ryan. Hello, Elrick.
ELRICK: Howdy.
CHARLES: You and I have actually been on a roll lately, podcasting the hell out of these podcast.
ELRICK: Yeah, I know. That is very true.
CHARLES: It's been you and me but it's feeling great. It's good to have you on the show again.
ELRICK: Yes, wonderful, man. Let's keep it rolling.
CHARLES: All right. We will keep it rolling. Today, we are going to be talking about redux-observable and to help us understand and plumb this topic, we have someone who's very qualified to talk about it. Mr Jay Phelps, who in addition to having been the co-creator of redux-observable, also is on the core team of RxJS, which is a fascinating library on which it's based for many years and is currently a senior software engineer at Netflix. Welcome to the podcast, Jay.
JAY: Hey! Good morning, everyone. I guess it's not probably morning to the people listening but good morning to you all. Thanks for having me.
CHARLES: I'm excited about it. I know that kind of starting with the fundamentals, RxJS is something that was on my radar for a few years and it definitely [inaudible] once we started using redux-observable but the whole concept, I often feel like the world kind of is turned upside down when I'm working with observables, when I'm working with RxJS and I'm curious, how did you come to be a part of that project and what are the things that you use it to solve? Why did the solutions that you generated shake out that way?
JAY: Sure. I actually was not introduced to Rx until I started working at Netflix. Netflix does have a fairly solid reputation for their usage of Rx, not just in the JavaScript world but also in the server world. Netflix wrote the original implementation of RxJava and it's used heavily on our backend systems.
CHARLES: For some reason, I had this impression and maybe I'm mistaken that Rx originally came out of Microsoft.
JAY: Let me continue with the story. It's confusing and I can actually take a step back and clarify that point in particular. Rx itself was originally came from Rx.net, which was indeed created by Microsoft many, many, many, many years ago. I don't know the exact date. I think it was at least 10 years ago. They, at the same time created or about the same time, Matt Podwysocki who was working at Microsoft and still is working at Microsoft, created Rx.net and RxJS. Then many years had passed and originally, it wasn't as popular as it got in the coming years. After several years, some employees from Microsoft ended up coming to Netflix. Jafar Husain is one of those employees. He came from Microsoft to Netflix and he brought that Rx knowledge and that advocacy.
Rx is very ingrained in the Netflix culture and is used a lot by various teams for various purposes. Then when I joined Netflix and I got really exposed to it. One of my coworkers at the time, Ben Lesh was asked by several people at Netflix to consider and look into rewriting RxJS. At the time, the version was RxJS 2.0 and while it was great, we had some specific requirements for our website and some of our other applications that we were hoping for a better performance, smaller bundle size and better debugability and --
CHARLES: Also, when I first evaluated it many years ago, it felt very much like a port from another language, in another culture as opposed to something that from the ground up, considered as a JavaScript library. Is that a fair statement?
JAY: Yes, somewhat. Definitely, there were more considerations this time around when it was rewritten and originally, it was going to be Version 3 but the rewriting process took quite a while as these things usually do. By the time we got a version out, it was Version 5. We started when RxJS was at Version 2 but it already released Version 3 and Version 4 by the time it released for the new version like a rewrite had been able to get out. When I say a rewrite, I mean like from scratch rewrite.
Matt Podwysocki who was the maintainer, almost the sole maintainer of the previous version, also is now on the core team of the new version of RxJS and has been instrumental in pushing back forward as well, he has far more experience with this than either Ben are I so he's been invaluable. Sometimes, we'll think to make those decisions. We'll be like, "Why was this decision made? Was it made because of .net?" and we'll just assume that and we'll want to change it but Matt has the history involved in that. He knows why things were changed the way they were.
For example, we changed one of the operators, flatMap to mergeMap. We know somewhat we go at least, I don't want to speak for the entire team but I regret that decision. Depending on the day that I've been talking to Ben, I could convince him to regret that decision as well. But we thought that mergeMap would make more sense and that very few people in practice would have heard of the word flatMap before and had experience with that so --
CHARLES: I have to say both of the terms coming at it were pretty opaque. I think there was a bout of equivalence in opacity.
JAY: Yeah, good to know. That's just an example. I don't want to stick too much on that topic. Maybe someday we'll go back to flatMap and the flatMap still exists. If you're a purist, you can use it. Ben was the primary person who was working on this. He wasn't working on it full time but pretty close to full time to get that initial version out. Even though I used it, my involvement with it was fairly low at that point and then my involvement after it was released got increased. I found more time and started to get more involved, particularly there wasn't a lot of code to write. I have some PRs and stuff like that but particularly on the planning and the issue triaging and PRs and stuff like that, which is a pain in the butt. It's just massive.
Particularly, around the same time that the rewrite was getting finished that Angular decided, "You know what? We’re going to bet on Rx. We're going to depend heavily on it," so you really can't write Angular without writing some Rx these days. You can get away with not knowing Rx very well. You could just call subscribe and then just do a bunch of imperative stuff but for the most part, the paved path is observables in so many fashions. Now, there's this ngrx. I don't know if you have any exposure to the Angular community. I have quite a bit.
CHARLES: I haven't recently. Certainly, since that kind of heavy investment in Rx, I haven't been exposed to it.
JAY: I think that was your question, right?
CHARLES: Yeah. It sounds like there's a Java implementation that gave rise or a .net implementation or Java implementation gave rise to a JavaScript implementation and that's the one that you got involved with but it suggests very strongly that Rx is an idea and it's played out in a bunch of different languages but really, there is a shift or it's an idea about the way you think about your programs. It's clearly been compelling to you so what is that idea and what is that shift from the way we normally think about things?
JAY: The idea was realized very early on --
CHARLES: Yeah, both 10 years ago, right.
JAY: Yeah, exactly. They dubbed it their reactive extensions, which is what Rx stands for. Pretty much, name a language and it's been ported to that. There's RxSwift, which is super popular. There's even things like RxCpp and stuff which if you look at it, it's awkward. It seems like we got less language in the world for doing this sort of thing. I actually like C++ in a lot of ways but it was awkward stuffing that stuff in there. It's a really popular pattern and the idea is just basically going all in on the observer pattern, saying that like, "Most people are building things in which you want to be pushed information." You want to be pushed events and the data should stream to you.
Modeling most problems in the world as a stream, once you get over the initial barrier of getting away from your normal historical way of looking at things and you look at everything as a stream, it comes very natural because you can actually model literally anything as a stream because it could be a stream of one, it could be a stream of nothing, it could be a stream of infinite number of events or it could be a stream of 10. You can model anything as a stream.
Once you start thinking about that, it just becomes very natural and particularly on the UI side of things, I think there's been a lot of success in RxJava stuff at Netflix but RxJava is also used in Rx.net for client-side stuff as well, for mobile development.
CHARLES: I remember when I first was introduced to it, I think there was a lot of confusion for me around an observer in the context of Rx and an observer in the context of classical MVC. One particular manifestation of the MVC architecture where you have these kind of mutable objects and you're observing their properties. Like key value observation, which factors heavily into certain UI frameworks. Backbone is one that comes to mind or if you're familiar with Java, basically the JavaBeans, like the property model listeners. I kind of had that conception of what an observer was versus Rx has a very, very different take on observable things. Do you think you could maybe show where they're different?
JAY: You can get the normal classic observer pattern using Rx, using a subject basically. But there's a subject class, which you're not going to use super often but there are certain cases where it makes sense. Also, it depends on what libraries. It is used more often in the Angular world because you want to get a stream of clicks or something like that but --
CHARLES: So what would be the subject in that case?
JAY: The subject in that case would be you're going to pipe, you're going to emit. Every time they click on something, you're going to 'next' something into that subject, like 'next the event' into the subject. Basically, a subject is a really great way to go from some imperative world to the observable world. Without having to write all sorts of custom glue, you can just basically say, "I've got subject. Any time I 'next' into it, just notify anyone who's listening to this." A subject is hot observable and that's the closest to the typical observer pattern because Rx, it's usually like observables and are usually lazy or cold. That's also what people call it. In the normal observer pattern, there is not necessarily any concept of laziness like you listen to something and that producer is already producing usually.
CHARLES: Right. You hit on that and I think that was something that was surprising and kind of delightful when I first started using observables is to realize that they were lazy. Let me make sure I understand it. What was cool is like I was going through some of the demos and I had this observable and is part of, forgive my terminology but when you create a new observer, you pass the function that will get called every time something subscribes to it, right?
JAY: When you create a new observer it passes a function --
CHARLES: When you create a new observable, you pass a function that gets called when an observer subscribes and the thing that you can pass is the thing that you can call next on, right?
JAY: That's exactly right. When it's a lazy observable, that only get called... Actually, you know, continue. You had a point.
CHARLES: I was going to say what was a surprising and cool for me was that every single thing that subscribe to that observable got its own history of that observable from the very beginning. It got its own function invocation so the first example I did, I wanted to iterate over an array and just send 10 items to the observer. Then when you subscribe, you're starting from one every single time: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10. It's not like I subscribe and one gets five of the elements, then I subscribe to another one and that one gets the next five or those two get the next five together. It's like they each get their own version of that observable.
JAY: That's exactly right and then that's the main difference between --
CHARLES: -- The whole thing, yeah.
JAY: Yeah. This is still observer pattern because the observer pattern, at least to my knowledge, I'm not an expert on this or anything but my understanding is that the observer pattern does not necessarily dictate hot versus cold, per se but traditionally I would say, people interpret it as typically the hot type of thing or also the multicast, if you want to be like these cool buzzwords.
CHARLES: Right. What you're thinking of it is when you've got this mutable object, you just dive in wherever it is at that moment and you're now observing events from it.
JAY: And that's traditionally because the observer pattern was mostly created for that model view controller type of pattern as well. You can think of like a stream of clicks: the users clicking on things where a stream of keyboard events. That is inherently a hot or multicast stream. You can't tell the user, "Start clicking," or, "Start typing. Don't type." You can tell them that but it's futile. The point being is that you can't control the stream. It pushes data to you and it's already pushing, whether you're subscribing or not, the data is flowing so the traditional observer pattern works really well for that. Then the observables, it's usually lazy,
Now again, with subjects and with multicasting, you can get the same behavior. You can get that observable that is hot and shares its subscriptions so that when multiple people subscribe to it, they all get the exact same underlying subscription that is already producing data.
CHARLES: I see. That makes sense with to call of multicast because fundamentally, there's really only one observer. There's only one stream and you just happened to be entering in at a certain point.
JAY: Right. Then the other one is called unicast but not everyone calls it that but that's usually what it's called.
CHARLES: There's a lot of terminology. With subjects, is that just a fancy way of saying a hot observable?
JAY: Not necessarily but almost always. If you include them together, you're not wrong 99% of the time. But as a quick drive by definition, it's totally fine. If you're teaching someone really all the things and then they want to fundamentally understand it, it's good to have some distinctions. A subject is hot and multicast but just because something is hot and multicast does not mean that it necessarily has a subject backing it. Maybe from the pattern perspective, you could call it 'the subject' or 'a subject' but in the Rx world, it's not necessarily a subject.
CHARLES: Then for cold observables, what are good things that they model, like the execution of an algorithm or something? there's an instance of that algorithm, I'm going to add two numbers or I'm going to reduce this tree of numbers into a product or a sum or something like that, where you start from the beginning, there's a clear beginning, there's a clear end --?
JAY: Right. The observables are really good at modeling side effects, for example. Things you want to do like make an Ajax call or read a file or something like that. In fact, reading from a file is actually not a great use case for observables just because you want to be able to control the back pressure. We can talk about that next if you want but --
CHARLES: Yeah. Back pressure is a concept. It's crazy to me and when people use it, I'm like, "How do you even do that?" You can say it and sounds good in practice but it sounds really, really complex.
JAY: I think I can summarize it for you. The back pressure stuff is basically you have a data producer and you want to be able to control the rate in which it is producing so that you do not overwhelm the consumer. You can consider two servers. You've got Server A and it's sending events to Server B. If Server B can only process 10 events per second but Server A sends 100 events per second, what's going to happen? There’s a deficit. There's a huge 90 events per second deficit and that means that the Server B is going to get more and more behind. Eventually, it will just fall over and run out of memory, CPU or whatever happens.
Back pressure is basically just being able to control that somehow. There's lots of ways, there's several policies of back pressure. There's buffering, there's dropping and then there's the pull model where it's like, "I'm going to tell you when to give me the next event," or, "I'm going to tell you to give me six more. I can handle six more, give me six more," or, "Here's the next one." Those were --
CHARLES: Then polling would have to be combined with buffering or dropping still, right?
JAY: Possibly but it becomes one of those like you use it just as a rarity. Because the problem with buffering is that it becomes usually unbounded and that means you can --
CHARLES: It's blowing up the producer, right?
JAY: Well, you risk money out of memory, mostly. It just becomes completely unbounded. You can bound that buffer and then it becomes dropping. Then if it's dropping, that means it's lossy. In a lot of scenarios, it's important not to drop information.
CHARLES: They're useful stuff.
JAY: Right. At the same time, there are a lot where you can drop it. Like at Netflix, we have this data pipeline thing for these logs and I got a good talk on this actually. This data pipeline is called Mantis job platform where all this data flows through. It uses RxJava almost exclusively and we have a lot of different back pressure mechanisms but the one of the most popular is dropping data. If the consumer is being overwhelmed with the number of logs and events that are matching to it, we just start dropping them because they're logs. We want to keep them but we make a best effort and it's perfectly fine to drop them.
In the observable world, it's usually going to be either buffer or drop. You're not going to usually be able to control the producer’s rate. In RxJava, there is something called the flowable, which lets you control the rate by basically saying, "Give me N number. I want N number more." It's become more important on the server-side end of things but a normal observables --
CHARLES: That makes sense.
JAY: Yeah and there's even a library that's brand new that Matt Podwysocki came out with called IxJS. Instead of RxJS, it's IxJS and it's iterator. It's for async iterator and regular iterators, which is good for that other end of the spectrum for back pressure. If you want to be able to control the producer, you're saying, "Give me the next five." That's what an async iterator is incredibly perfectly suited for.
CHARLES: The async iterators are kind of like the logical inverse of the observables?
JAY: That's exactly right. It's the dual, if you want to use the computer science term, I assume you knew that already and it was that was just a plant.
CHARLES: Actually, I didn't terminology, the dual but it's like through the looking glass world, right?
JAY: Yeah, that's correct.
CHARLES: One hand you got Alice in our world and she's looking in the looking glass world. I'm not saying which one is which but one is observables and one is the async generators. When you would want to use async generators is when you want to have the consumer driving the entire stream.
JAY: That's right. A lot of people, when they discover async iterators, they'll ask me, "Jay, why wouldn't I just always use that? It seems like they're more flexible of the two." The reason why is because you can't always control the producer. The fundamental example that I was giving earlier like mouse events or keyboard events, you cannot control what the user does so an async iterator would be a very poor primitive to model that because what happens if you decide to give me one keyboard event at a time and one per second. You're like, "Give me the next keyboard event." If you did that one per second and someone is typing on their keyboard, what do you do with all the events while you're waiting? You could buffer them but that's a back pressure problem. You have to choose and it's a very poor primitive model to that.
CHARLES: Yeah, that would be a terrible user experience. The users want the consequences of their actions to be realized at the soonest possible point.
JAY: That's exactly right. The other benefit of observables is a slight increase in performance because when you subscribe to an observable, it sets up the chain and then now only data needs to flow through that chain. Whereas an async iterator, every time you call next, you're going to get a brand new promise. If you used it for something very high volume, you might be able to see how now you've got a lot of excess allocations: CPU cycles being used, garbage collecting for each one of those promises. In Netflix, we got a lot of streams, which are hundreds of thousands of events per second. If you do that, those allocations of those promises can certainly add up. It's just not the most efficient primitives for that as well.
CHARLES: I thought that async iterators used essentially continuations under the covers and not promises.
JAY: Under the covers, I'm not sure how you would describe what --
CHARLES: I'm not super familiar --
JAY: It's basically an --
CHARLES: You're talking about like yield, right?
JAY: You're talking of generators maybe?
CHARLES: Uh-uh.
JAY: Iterators and generators are although related because a generator is basically a factory for creating iterators. Does that make sense?
CHARLES: Yeah.
JAY: Every time you call that factory, you get a brand new iterator out of it. But then when you have an async generator, it's basically the exact same thing except for the iterator returns a promise. You're basically saying, "Give me the next thing." You call next on the iterator and the next will return a promise and that promise will resolve with a value. Why is that useful to standardize? Because you can have syntactic sugar like the [inaudible]. I don't know if you've seen that yet but it's like a loop primitive, where you can basically loop over an async iterator without needing to deal with the whole thing and all that stuff. The same way normal async/await is helpful. This await is helpful at the same time.
CHARLES: It's way above my pay grade but maybe you're using both. I'm trying to think with async the way that works with promises, right?
JAY: That's correct.
CHARLES: So you got both the continuation and a promise. That's even more overhead than the promise because you've got to stuff away that whole call stack and the promise and yield to it. But anyhow...
ELRICK: This is very interesting. RxJS is a very deep subject. What I'm interested to know is you have RxJS, you have observables and you have redux. Where's the union? How did that come to play that you guys came up and said, "You know what? We need to create redux-observable library?"
JAY: Yeah, great question. It came about fairly organically and over many month period of time, actually. We bring Rx people as I mentioned and we were using redux at the time and we're still using redux but my team that I was on was using redux and we were using redux thunk and the thunks were getting incredibly out of hand. It was very hard for us to do things that we were used to doing that were very simple like debouncing. We were like, "This is really hard. It's just to do something so simple that in Rx, it's so simple." We try to stuff Rx into redux thunk and try to make conventions around that. It just didn't work out well and then we initially made something we called thunk-observables --
CHARLES: We really wish you would have stuck with the name even you didn't --
JAY: Yeah, so thunk-observable is probably what you can expect. You dispatch a thunk which returns an observable and that observable will be subscribed to and that was it. Basically, that was the primitive so that let us have our debouncing but in practice, we found that the thunk stuff cause way more confusion and then also did not let us do composition as much as we wanted to. We then extended thunk-observable thing to get receive a stream of actions so that you could compose the different thunk-observable together and then receive new actions to cancel things and stuff like that.
We eventually just figured out that having basically the idea of thunk-observables but having of them be like almost static factories that are like process managers, that's the pattern that we ended up on today. That we coined calling them epics. Basically, an epic is a function, which receives as an argument, a stream of all of the actions. It gets an observable of every action that's going to be dispatched and it was a hot observable so that means that if you happen to subscribe to it later, you're not going to get all the actions from before. It doesn't replay them. It's just all actions from the time you subscribe and continuing.
Then what that function is expected to return is a new stream of actions and that stream that it returns of actions gets subscribed to by the middleware under the hood and basically, it just calls stored dispatch on anything you emit. You can imagine the simplest epic would be a function that gets streamed of all the actions, it applies a filter operation on all of those and looks for a particular action and then based on that action, it performs some side effect and then when that side effect comes back, it emits a different action. Basically, to notify redux like, "Here's the results. Here’s the change. I'm done," or what have you. let you just make arbitrary side effects but isolate them in a way that fits very naturally with your UI layer that you're using and with redux itself with the purity of the reducers.
CHARLES: Right. For example doing an Ajax request, I think that's a good example. You get some action in, you're getting every single action that's dispatched to the store, the first thing you want to do is you want to filter that stream to only the actions that are user click the save button so I want to save off this form. To some action, that's my save action so then my job is to now map that eventually. Out the end of that stream, I want to have like the save either succeeded or the save failed. There's two forks on an Ajax request.
The fundamental mapping that's happening is either from the user click save, whatever you want to call that action, I want to map that to the user if the save was successful or I want to map that to the save failed or rejected. The hard part then is executing those side effects and then putting them back into the stream. How would you do that then with redux-observable?
JAY: If I'm following correctly, the typical almost all epics, not all of them but almost all, they're going to have a filter at the top of the epic, they're going to filter out looking for the action they want and then they'll have some sort of merging strategy operator like mergeMap, aka flatMap or they have something like switchMap.
CHARLES: I feel like that's one of the harder concepts for me and I want to actually going to be a little selfish here and try and bounce my understanding off of a bit so you can be like, "No, your mental model is incorrect," but we'll find out how it's incorrect. With the mergeMap, is that a way of saying, "I can take other observable streams and inline them inside this one stream." That's the way I've been thinking about it. I can go out to the rest of the world, I can have some other stream and I can inserted into the processing chain of this other stream.
In this case, I do a mergeMap of the actual fetch or the actual post but it's not a straight chain of implication like do a filter then I do a map then I do this. I've got to take this other observable, this thing, this other asynchronous process, which really represents another stream and I want to merge it into this one stream. Then once that's done, I get the result. now, once that happens outside the mergeMap, now the Ajax results whether it's a success or failure, the result of the request, now it becomes the next item in the stream, which then I have to map down to another redux action.
JAY: That's right. The mergeMap operator has an alias and it also used to just be called flatMap so you can envision that you are creating an observable of observables, a higher order of observable. With mergeMap, you want to flatten that. You're saying that every time I get an event, I'm going to call this projection function and it's going to return a new observable, an inner observable and I want to merge each one of those into each other so that it becomes one stream. That means you can have concurrency. That means you can have multiple and simultaneous concurrent Ajax calls that can finish it arbitrary times.
I think it's important then to contrast that with some of the other merging strategies like switchMaps or concatMap. With switchMap, as the name implies, you switch between observables so at any point in time, you can only have one observable subscribes to at a time. If a new event comes along and you call the projection function, it returns a new observable. If the previous observable has not yet completed, it will get unsubscribed to and anything it was doing gets cancelled.
In the example you're talking about, if you've got an epic that goes and fetches your user model every time they click this button, let's say that they can click that button multiple times and you don't want to make 50,000 requests. The quintessential example is actually the auto suggest stuff. As you're typing key strokes, if the request is in processing and they type another keystroke, you don't want to wait for them the previous request to come back and process it. It's not only wasteful because you'll process the JSON and all that stuff. It can introduce bugs because it may come back out of order. It may come back actually after your new one comes back and that can cause all sorts of crazy weird bugs. That's what switchMap is really great for. I call it implicit cancellation.
Ben doesn't like that because he's saying that in a switchMap, you are being explicit about it but you're not calling unsubscribe on it yourself, which is why I call it implicit. It happens automatically. There will never a new event pipes through there. Then there's the third one which I don't --
CHARLES: So this switchMap ever make sense outside the context of hot observables?
JAY: I would say that it makes more sense usually on hot observables but there are certainly cases like let's say that you've got a web socket observable and every time you get an event, based on that event, it make some other request and that other request may or may not take a really long time. But if you get another thing back from the web socket, you want to cancel the previous one. That's somewhat not a great example as well because sometimes people use multiplexing for the web socket so that it becomes multicast.
But the point being is that there are definitely times where you will use merge, switch or concat. That concatMap being the third one where as you might imagine, you are concating the observables, you line them up. If I get a new event, I'm going to call my projection function, create that new observable but I'm not going to subscribe to it. I'm going to keep it but I'm not going to subscribe to it and tell the previous observable I was subscribing to has completed.
In a way, you're buffering the observables and because you're offering them, you can get in trouble where you end up buffering infinite observables. Let’s say the first one never completes for some reason because of a bug, you may infinitely buffer them. ConcatMap is not used that often. I'd say it's very rarely used. Its use mainly when you don't want lossy behavior. You want, at most wants semantics like you're only doing one per time.
CHARLES: The difference between mergeMap and concatMap is what?
JAY: It's you're not going to do concurrent. That's probably the best way to explain it. You're going to do that in sequence instead of concurrently.
CHARLES: I see. Maybe an example would be like file uploads or something. You probably want to do your file uploads in parallel but let's say, you want to conserve bandwidth or you're working where you've got a browser that only supports 10 connections or five upload connections but when someone selects 30 files, you don't want to just drop those files. You want to be uploading 10 concurrently but as soon as one finishes off of that 10, you want to start up another one.
JAY: That's absolutely right. Another example would be like you are going to hit some API and it could be used as one mechanism to kind of throttle yourself. If you want to guarantee that you're only connecting at most once to this particular end point at a time, no matter what the upstream tells you to do.
CHARLES: Right. I could see that. That makes sense.
JAY: I can tell that you're a little bit struggling to see the use cases, which is totally normal. ConcatMap is not used very often. It's for of those fundamental operations, which primarily why it's included is it's non-trivial to implement yourself.
CHARLES: Are there any other mapping operators that we should know about?
JAY: Those are the three primary ones. There's a couple of other like boutique variations but they're all variations on the exact same thing.
CHARLES: Right.
ELRICK: Do we have like mergeMap, switchMap and concatMap that are specific to management of observable and that's specific to redux-observable. There's people out there using something like redux-saga or they're trying to compare and contrast these two libraries. How do these things contrasts? Because I don't think you would use either of these mapping operations inside of a saga. Is that correct?
JAY: I just want to make a minor clarification. The Rx stuff and these operators that we've been talking about: mergeMaps, switchMap and concatMap, they are not actually related to redux-observable really in any way. The only thing they're related is that you just might happen to use them. Redux-observable is actually a very tiny library and it defers pretty much everything to just normal idiomatic RxJS code and that's really the biggest pro in comparing it to say redux-saga. Redux-saga came significantly over a year before redux-observable and without a doubt, were influenced. The pattern is very, very, very similar but there are some just fundamental differences and one of those is that difference.
The most obvious thing is if you already know RxJS very well, without a doubt you're going to want to use redux-observable. I could tell you that, it's not possible but it's very unlikely you'd choose redux-saga over redux-observable if you're already a really big Rx fan because you basically know how to do it. You just have to think that the items you're modeling, the events you're modeling are actions, which just happens to be a convention really.
There are some other differences though between redux-observable and redux-saga and the biggest difference being that redux-saga takes this effects as data approach, which is like Haskell if you're familiar with that. In a lot of ways, it's identical with the IO monad but it basically just means that you're not actually performing the side effects yourself right then and there when you call their operators. There are special utility functions, instead there's like an engine or a middleware underneath that performs the side effects on your behalf.
You create a generator and that generator is the pattern that is called a saga is what they call it. That generator yields these objects, these effects objects. One of the effects objects might be to call some particular API to make an Ajax request so you're going to yield that object that basically describes the side effect you want to perform but doesn't actually do it itself. It's just an object. In the middleware will form it for you so why would you put that indirection.
The indirection helps when you want to do things like testing. If you want to test it, you don't actually need to perform any of the side effects. You can just call next on the iterator that you get back from the generator, you call next on it, you will get the side effect object, the effect as data that you want to perform and you can just assert based on that. You don't need to do mocking in all of that stuff. You just have to assert that the effects that were yielded were the ones that you expected.
Now, I don't like that approach personally because I actually use redux-saga quite a bit, not lately. It was like a year ago. You end up implementing almost all, not all but a lot of your business logic in your actual tests themselves. Your test become less about testing the behavior or the outcome of a particular thing and more about testing how it gets to that outcome and what steps it takes to get there. Some people think that's fine. For me personally, it felt like any time I made a change in my saga, I had to make the exact same change in my test even though the behavior of the saga did not change. The actual observable outside side effects did not change in any way but I may be refactored or renamed something. It felt very redundant and to me, felt brittle because I started to wonder who tests the test then.
If the tests are in a lot of ways are reimplementation of the saga, how did I really test that the behavior of what I was trying to accomplish really was accomplished. I'm not an expert on it so certainly, I'm sure there are people who have patterns around this that can mitigate some of my concerns. But for me, I'm used to testing Rx and I'm used to Rx in particular so the pattern for me of using observables just made a lot more sense to me. Also, with either of these libraries, the learning curve is really steep. If you don't know redux-observable, let's say you don't know Rx, learning Rx just to use redux-observable is a pretty huge undertaking. I would usually recommend people to not do that.
A lot of times these days is spent me helping people who are frustrated because they dug themselves in a hole by using all these new technologies. They'll pull in TypeScript and [inaudible] with every all of the cool new hotness and I don't blame them because they've been told that this is all the cool stuff.
CHARLES: We got some great advice on that that you can have one vanity technology on every project and live it yourself. Indulge in that coolness, in that hotness and do something exciting but make sure you have one vanity technology and one only. Everything else, be very comfortable with and one is just crazy experimental like this is the coolest new thing and we're going to just drop it in. But if the rest of your chassis is solid, then you can support that crazy experimental engine that requires you to stand up on the front of it and feed gas in with your mouth like they did in Mad Max.
JAY: And there are exceptions obviously but for the most part, I subscribe to that. I answer a lot of questions on Stack Overflow and redux-observable. I actually get sad and frustrated when I see people that it's very clear that they shouldn't be using this. Their use case is not complex and they haven't learned Rx yet. It’s one thing if you're like, "I'm learning this and I know that I'm going to have pain." That's totally acceptable. There’s plenty of times where it's like, "It's totally okay that there is no concrete deadline and I can take my time," but a lot of times and I would say, a majority of the time, you're slipping on the deadline and that's not a good thing. The people who are coming to me are just frustrated.
They’re like, "Why is this so complicated?" You're right, it is really complicated but its complication helps with some of the more complicated use cases. That's the irony behind both redux-saga and redux-observable is that they're both really complex for the trivial use cases like all I want to do is make an Ajax call. That’s it. I don't want to cancel it, debounce it, I won't do anything. I just want to make an Ajax call. They are the biggest hammer you could possibly think of. Don’t use them for that.
CHARLES: The thing is if you're not sure, whether you need redux-observable, then you actually don't need redux-observable.
JAY: I would say that usually that is the case, yes. The same with redux-saga. They’re in the exact same league. It’s basically, "Do you need complex side effect management?" With the redux-saga, the complications, even though generators have been around for a little while, a majority of people still are not familiar with them because they're just not used all that often. They’re kind of mystifying. I would say, they're not super hard to learn. They’re just alien. Then to add on top of that, the effect is data and you've got multiple curveballs. Same thing with redux-observable, they could never use observables. It's pretty alien. The reactive programming idea and model is pretty alien.
I would advise, if you're not using redux, don't even consider redux-saga and redux-observable personally. If you're already are using redux and you think that you might need something like this, experiment with the primitives, try and see how well your team can pick up RxJS just by itself. Just learn some of the regular RxJS tutorials, don't even look at the redux-observable docs because it's not useful in any way when it comes to this. Just try and learn a little bit Rx and see does it click. Because some people is like, "I don't understand why everyone thinks it's complicated. It's easy." But a majority of people, it takes a while before they get that like Neo in The Matrix, I-know-kung-fu moment.
CHARLES: All right. We're almost at time but I hope that that moment comes to everybody. I think we've certainly enjoyed a lot of success with it already and I think once you do get your head around the basic use cases and you know how to do an Ajax request, you know how to do just simple saves and gets and what have you, doing the trivial things becomes easy because you know which pathways to travel. But before we head out, is there anything that you've got coming up in the near future, any talks, appearances, meet ups, anything whether you or otherwise that people should be aware of?
JAY: I would say on this topic, there's a new beta for RxJS with this new way of using operators. It's being dubbed lettable operators, like the 'let' keyword but it's not related to that. It's basically just a way of finally being able to import operators and to use normal tree shaking that people have asked for forever. Because the problem with observables is that they're prototype-based methods and you can't reliably tree-shake methods or prototypes. We've been trying to experiment with ways to have [inaudible] and the lettable operator stuff is interesting to check out.
It’s a stopgap measure until JavaScript has something like the pipeline operator, which just actually moved to stage one. It's a brand new operator. If you're familiar with a lot of functional programming stuff like F# and a lot of the functional programming language is actually have the pipeline operator, it'll make it so that you can basically have syntactic sugar to apply a function, basically to pipe the result of a function into the first argument of the next function, etcetera. You can pipe the argument and return values through a series of functions.
If you do that without this syntactic sugar, you've got this massive nested function invocation, which is incredibly hard to read and hard to maintain. That's why the pipeline operator is so great. I would encourage people, that's in beta right now. I think it's 5.5 but it's in beta right now. I encourage people to check it out, find bugs and get feedback. Maybe this is completely off base and it's not the right direction that the team should be going but it's based on a lot of collaboration, particularly with the Angular community. They've been, in particular asking for this because they're pretty big and they've got to use the Clojure compiler and all sorts of things for trying to make their bundles incredibly small.
For me personally, I don't have any Rx talks coming up. I've been pretty obsessed with web assembly here lately. I'm an armchair compiler nerd. I don't do compilers for a living but I have done them personally for a number of years so I'm obsessive with web assembly. I have number of talks in web assembly coming up but just nothing related to Rx at this point.
CHARLES: That's totally okay. I'm actually, also have been obsessed with web assembly.
JAY: Have you guys done a podcast on that yet?
CHARLES: I don't know.
ELRICK: No, not yet.
CHARLES: I actually started out to write my own list compiler in web assembly and they got totally derailed on the list compilers. Actually I ended up switching tracks on the whole web assembly thing but I was really, really excited about it. Probably, it was about three months ago or something like that but I'm still excited about it. I just haven't been working on it actively so I'm very curious to hear about those talks. Let's post them on the show notes and who knows? We do a lunch and learn every Friday here and usually, it's one of us getting up there but sometimes, we'll just watch a talk. One of us has been wanting to watch.
ELRICK: And you're always welcome to come back to any time and geek out with some web assembly.
CHARLES: I'd say, we haven't podcast web assembly, you know? All right, you guys, we've been at this for another hour. Let’s go. Everybody listening, strap your headphones on, we're going down for another hour. Changing the subjects: web assembly. It starts right now.
ELRICK: It's going down.
CHARLES: No, but we will have to have you on for that. Thank you so much for coming on and talking with us about observables, Rx, redux-observable but if folks want to continue the conversation with you, they can get in contact with you how? On Twitter, email?
JAY: The best way is going to be Twitter probably. I'm at @_JayPhelps. Thank you guys very much for having me on today. It was a blast. I love talking about this stuff.
ELRICK: Thank you.
CHARLES: Thank you and for anybody out there, we can also be reached at @TheFrontside on Twitter or just drop us a line and [email protected] and have a great week and we'll see you next.
Julie Moronuki: @argumatronic | argumatronic.com
Show Notes:
Resources:
Transcript:
CHARLES: Hello everybody and welcome to The Frontside Podcast, Episode 83. My name is Charles Lowell, a developer here at the Frontside and your podcast host-in-training. With me today on the podcast is Elrick also. Hello Elrick.
ELRICK: Hello. How you doing?
CHARLES: I'm doing well. I'm glad to have you on this one. I'm glad to be doing this podcast in general. We have someone on the podcast today who I've been following for, I guess probably about two years because she published a book that has been very, very helpful to me. It's one that I recommend to a lot of people. It is learning Haskell from first principles. With us on the show is Julie Moronuki, who is co-author of that book. Thank you so much, Julie for coming.
JULIE: Yes, hi! Happy to be here. It's nice to finally get to talk to you.
CHARLES: Yeah. One of the reasons I wanted to have you on the podcast was because I feel as though you have one of the most unique origin stories because of programming and entering in the tech world. Most of us are curious, we either come from video games or maybe we just start fiddling with the web browser. You enter the maze from the entrance that is like hidden from all, I would say. You went straight to writing a book on Haskell, is that --?
JULIE: That is what happened. In 2014 on Twitter, I met my co-author, Chris Allen and he has been trying to figure out better ways to teach people Haskell because the on-ramping, I guess of people to Haskell can be quite difficult. The materials that exist are not always accessible and people felt like they need the advanced math degrees before they can write Haskell.
He was trying to figure out better ways to introduce people to it. Since I was this person who's never programmed before -- I have no background -- and then he thought, "This will be a very different experience, trying to teach Haskell to her." Because I have a linguistics background and stuff he thought, "That would be interesting too and maybe, she'd be interested eventually in doing NLP." I said, I'm not --
CHARLES: What's that? Acronym alert.
JULIE: Oh, yeah. Sorry. Natural Language Processing. I said, "You know, I've never done any programming and I don't play video games and I never have had any desire to learn computer programming. I don't think I'm going to like this. I don't think this is going to last but sure, I will try," and so I did a little bit. I read a little bit of 'Learn You a Haskell for Great Good.' I've read some other things.
CHARLES: This was before you guys had the idea of actually writing a book.
JULIE: Yes. He had the idea of turning some of his thoughts about teaching Haskell into a book and as he would explain things to me, like the questions I had about 'Learn You a Haskell,' I'd be like, "We should write this down," and he would say, "It's so hard to write it though. It's easy when I'm explaining it to you and it's so hard to write it." Initially, it started that I was helping him at things that he was teaching me and then as we got further into the book and I started reading a lot of other Haskell stuff on my own and figuring stuff out, I was writing more and more of it. Then we were kind of equal co-authors after not too long. That's how it happened. I really didn't think that I would stick with Haskell or with programming. I'm still sometimes I'm not sure about programming. I'm not sure about this whole making software thing. But Haskell is so interesting to me that I'm still here.
CHARLES: That is fantastic and it's a great story. I'm curious, when you were doing the proto-research to learning Haskell, coming from really truly first principles and having no experience of programming, what made a good resource versus a bad resource? What are the things that you gravitated towards and say, "This is really instructive." What was the tone there?
JULIE: One of the major problems ahead of most of the Haskell resources that exist is they assume that you've done programming before because nobody learns Haskell as a first language so they all assume that you have done some programming before. They would make references to things that if you were a programmer, you would know what they meant but I didn't. That was one of the hardest things for me. Even 'Learn You a Haskell' does that to some extent.
CHARLES: What's an example of that?
JULIE: I had learned a little bit about recursion from linguistics because that's a thing in human language so I really understood recursion but most of the Haskell resources explain it to you primarily in terms of, "This will be like your loops in other languages." I'm going to be like, "I don't know what a loop is. This isn't helpful for me." There are a lot of things that I didn't understand so when people talk about Haskell as being a pure functional language, neither pure nor functional necessarily, I didn't have anything to contrast them with so they didn't necessarily make sense to me as things that make Haskell different from other languages.
I didn't know what imperative programming was and people would say, "In contrast to imperative programming, functional programming does this," and I'd be like, "Okay, but I don't understand what the imperative programming way is so this contrast isn't making any sense to me and same thing with purity." There were a lot of things I had to learn, in fact about mutable state because I didn't know anything about it. I had some understanding of how computer memory works but still some of the ways that people talk about it were not obvious to me.
CHARLES: Do you find that seeking out that contrast actually wasn't helpful? Is it noise since at least at the beginning, it's something you'll never do. It's like saying, "Over in France, they wear these kind of socks." Since I'm going out into the street in front of my house, I don't really care.
JULIE: Right. In the beginning, it was a lot of noise and I understand why they do that because they are making the assumption that everybody who is learning Haskell has come from some other programming language, probably an imperative one so I understand why that happens but in the beginning, it was very much noise for me. I noticed a lot of Haskell resources, one of the first things they tell you is that in Haskell you can't do 'x = x + 1'. I was like, "If I'm reading this like it's mathematics, why would I think I could do that." If you come from a different programming language, you might well think that you can do that but in Haskell, we can't so making that contrast, when I didn't have that background was really just confusing for me.
Now, because I teach people and most of them do have some background in an imperative language, understanding the contrast is more helpful to me but in the beginning it was just confusing and noise. When we wrote Haskell book, we tried not to make those kinds of references and like, "Let's assume that everybody is just like Julie, doesn't know a different programming language that we can contrast it with and let's try to write a book like that."
CHARLES: Right. I think that's a key insight because some people would say there's a lot missing or that difference might stand out. Now, that you pointed out, I can see it but I don't think I noticed it while I was reading it. But one of the things that I like is because I also tried to learn Haskell through 'Learn You a Haskell,' and I didn't find it very helpful. I found it entertaining and it's not a knock against the authors. Some of the sketches were really cute but it was still more explaining... I don't know. It was explaining more of the how, than the why, if that makes any sense where I felt as though in your book, there were a lot more analogies to actual human experiences, using the visceral language saying, "A mono is something you can mash together or squeezed together." That really connected for me. Whereas, explaining it in terms of concatenation and laws and stuff like that. Those things seem cited to the secondary resources to the primary resource.
JULIE: Yeah. I think that's kind of helpful for me too. There are different Haskell books that have, I think different things about them that are good. I forget the name of the book but Graham Hutton's book, the way he talks about recursion was really helpful to me. The way he explains recursion and of course, folds but folds are things that he's known for so those parts of that book are helpful for me. But really the best book other than my own of course, for me is Simon Thompson's. I think it's called ‘The Craft of Functional Programming’ and I think it does better at explaining things just in terms of Haskell. Real World Haskell, I guess is really good. It was harder for me because I hadn't been a programmer before. I think it's got so many practical exercises that --
CHARLES: Was that the O'Reilly book by Irish gentleman whose name eludes me?
JULIE: Yes, Brian O'Sullivan. It makes more sense to me now but there were things in it that are sort of programmer things. Because I'd never made software before, that were really confusing for me. But Simon Thompson's, because his book does have exercises and they were ones that I could understand and do. They were fairly self-contained. My first experience actually in writing a program that does IO was from his book and I was just so thrilled. I was like, "I got it. I did it." That was really helpful book for me but I don't see people recommend that one as often but that was probably the best one for me.
CHARLES: Yeah, it's always a balance because the Real World Haskell didn't really worked for me, almost because the examples were too pragmatic or too complex and I picked this up when I was 10 years into my programming career and I struggled to follow the JSON parser example, which is parsing JSON is something that I've actually done several times in multiple languages and I still struggled with it.
JULIE: Whereas for me, I don't even know what JSON is. This is not something I've ever dealt with. I know what it is now sort of, but it's still not something that I deal with very much. I was just like, "What is this? I don't even know what to do here." It wasn't quite as helpful for me. I've heard a lot of people have success with that one but I think they don't share quite the same richness of programming experience with Brian O'Sullivan. I think it's a little bit more difficult.
ELRICK: These are a lot of amazing resources that I wish I knew about when I try to learn Haskell. I took an online course with, I think it's like Eric Meijer and that class was very intense. Looking back, what would you say are some areas that someone should, either start to look into before they step into the Haskell world, being that you didn't come from a programming background but connecting to dots backwards now? What would you say are some areas that people can slowly ramp up into to get into Haskell and functional programming?
JULIE: When I teach people Haskell, the people who have the easiest time are people who have been writing Scala for a while and they've moved over to the FP in Scala side. When I first started Haskell, I heard a lot of people make jokes about how Scala is a gateway drug to Haskell. I think there's actually might be so truth in that because I certainly have a lot of students that were Java programmers, then they got interested in Scala because maybe Scala is better for some things than Java and then they start moving more and more over to the FP in Scala side. Those are probably the students that have, I think the easiest time making the transition to Haskell that I've had anyway.
But you know, I think even JavaScript, trying to write in a more functional style and there are some resources for that and really, there's a very good tutorial about monads that uses all the code examples in JavaScript. I think a lot of the concepts that you can start to approach them from other languages. Haskell is still going to be weird in a lot of ways and another thing that works for a lot of people is going to Elm. Elm is similar to Haskell but different. I think that that has worked also for a lot of people getting them into understanding more functional programming concepts but with the much easier... The word easy is so --
ELRICK: It's like a relative term like, "Oh, this is easy."
JULIE: It is.
CHARLES: Easy to say, right.
ELRICK: That's what I thought when I step into learning Haskell and functional programming. I was like, "How bad could it be?"
JULIE: Right. Learning Haskell can be very bad. I'm not going to kid around about that. It's a shame because I don't think that it needs to be that bad but the way it's presented oftentimes, for various reasons, I think why Haskell gets presented the way it does but I don't think it needs to have it like that. The designer of Elm, whose name I'm not going to try to pronounce because I don't know how you say his last name, he really made an effort to for example, the error messages in Haskell can be very intimidating. The situation there has improved since I started learning Haskell but they can be quite intimidating and he really made an effort to make very friendly error messages, very helpful error messages.
I think that it shows and then it makes a difference for people who are learning. If you start with Elm and then you do want to see what Haskell or PureScript, which is also frontend language, mostly. It compose of JavaScript but it's very Haskell-like, then from Elm, let's see if we can get a little more hardcore Haskell. I think the transition to Haskell or PureScript is easier from there.
I think it does help to move in the functional direction from whatever language you're in, if you do FP in Scala or try moving to more functional JavaScript or even Elm. Then Haskell will make it more sense from there or be a little easier to approach.
CHARLES: Yeah, and I definitely think that for, at least from my perspective, I've been able to take a lot of those concepts that I've learned from Haskell and then apply them, even inside Vanilla JavaScript. There are things that have become indispensable like mapping and folding and they exist in JavaScript. You can reduce arrays, which is a similar to a fold and then you can map arrays but understanding that map, the key insight for me that I got from learning Haskell is that there's a whole class of values that you can map, not just arrays.
The standard JavaScript object is essentially a Functor and will get a little bit to that because for people listening what that word even means and the meta around the fact that they're all these weird words and how do I go about something I want to ask you about. But the trees can be mapped and the objects can be mapped and all of the sudden, it's like this one concept that I use so much for lists, it's available on all these different data structures and it's get me thinking like, "What other data structures can I use this operation? What are the things are Functors that I'm working with?" Really, it's changed my perspective to think about the type of the data structure, in terms of the operations.
JULIE: I'm in favor of keeping the terminology that we have but just explaining it much better. That's the approach that I take but it can be very hard, especially it was your first learning Haskell. I don't know if you've seen the Haskell pyramid but to get sort of productive where you can write programs in Haskell is not a very high bar. It feels like it is when you first start but it's not really very high bar but Haskell just keeps growing and growing and getting deeper and deeper so you're always approaching new libraries that you've never seen before and you feel then you've been learning Haskell all over again because they're written in a very different style of Haskell or they have even more terminology, even more kinds of Functors that you've never heard of before or something like that so you're always approaching these things over again.
It can be a very intimidating feeling and it makes a lot of people very uncomfortable and I'd say, if you like Haskell and that does make you feel uncomfortable, then you don't actually need to do that because a lot of people write Haskell very happily every day in their jobs even and don't do that. They don't mess with some of the newer, super cool libraries that have all this funky terminology and stuff. Some of them don't mess with them at all.
CHARLES: But certainly, there is some concepts that are core. I'm thinking of like applicative and Functor and all these things that I'm learning about and I'm curious to hear about your experience as you climb that pyramid. What is the pyramid entailed? First of all, I'd love to hear more about it because this is actually the first time I heard about the Haskell pyramid.
JULIE: Say you understand monads, then you can write really a lot of Haskell programs. Probably at some point, you will need to understand monads transformers but if you just get to the point where you understand monads pretty decently, you can write a lot of software so after that, then learning more is maybe going to improve your Haskell, maybe let you write some things that you couldn't write before but a lot of it above, not that these things are necessarily in an hierarchical progression. We cover monad transformers in a fair bit of detail in Haskell book but if you get anything beyond what's in Haskell book, one of those things that some of them are very interesting, some of them can make you much more productive but some of them are also people do them for fun to explore the space and some people love them and some people hate them. Haskell lets you do a lot of things for fun and exploring mathematics in ways that are interesting and exciting and may influence and in fact, have influenced other languages like [inaudible] in PureScript but not really necessary for basic Haskell programming.
A nice thing happened while we're writing Haskell book. I was writing, I think it's chapter six, which is about type classes. I was writing that chapter and at the same time, my co-author had started writing the Monoid chapter. The type classes chapter comes in chapter six and we introduce a lot of the basic type classes: num and eq and some of those in that chapter because I do think it's important. Type classes are very special thing about Haskell so I think it's important to, at least start coming to groups at them early. Some people disagree with me about that and think they can ignore them for much longer. But at any rate, it is where it is and I felt that that was important.
Maybe the real motivation for type classes, really until we started writing the Monoid chapter so he started writing that while I was working on type classes chapter and he sent me the beginnings of the Monoid chapter to look at. At first I thought, "We've got addition and multiplication and list concatenation and this just doesn't seem interesting. What is this generalization of a Monoid that I'm supposed to get from these three things? And why bother making it a type class," because additional and multiplication are already in the num type class and then list concatenation is just for list so why make this into a type class and what's that motivation there. With eq, we want a quality --
CHARLES: Is that how you pronounce 'eq?'
JULIE: That's how I pronounce it because 'equal' or equality.
CHARLES: Okay, so this is a type class for doing what? Making sure to being able to compare two values on the same value.
JULIE: Yes and it's a weird one because for most data types, you can have an eq instance and you want probably, in a lot of cases to have that but we don't want because function is a data type in Haskell so you don't want to have an eq instance for functions and that's why equality is not implemented generally for everything. That's why it's a type class so there's no instance for functions because that's not decidable. You can't decide if two functions are equal, generally. Some functions you can but in the general terms, for datatype, you can't.
CHARLES: That's actually a pretty profound statement. Proof of which is left as an exercise for the listener.
JULIE: We got to the Monoid and I was like, "What is the [inaudible]," or something. It turns out that there are Monoids everywhere. There's all kinds of things that you want to, either concatenate or make a product of. Then having this as a type class and thinking of it in terms of like, "We've got this abstraction. We've got this category. We've got this algebraic structure. Now, we can look for in all these other places," because once you've named the thing, then you can talk about it and think about it in a little bit of the different way. It's like, "Now, we've got this group of addition, multiplication, list concatenation." Now, we've got an abstraction of that and we can think, "Where else can I see this pattern?" and it turns out it's all over the place.
For me, that was one of our thought like, "Type classes are actually really cool and powerful and interesting thing." For me, that was when it seemed like, "The terminology is worth it because, now I want to think about finding these algebraic structures and in all these other places."
CHARLES: Right and like a Monoid, it could essentially be called, if you're using a Java interface, like 'mashable togetherable' or 'concatenatable' or something like that. But there's a kind of one-to-one correspondence but it is a vocabulary that just needs to be learned.
JULIE: I don't know much about category theory or anything but the other cool thing about Monoid for me was that there are almost always two because there's almost always one that's destructive or additive or concatenative and there's almost always one that is conjunctive or a product or multiplicative. It's often across product that would be the zipless Monoid that exist in base and it's a cross product of the two lists.
There’s almost always two, whereas when you think of Monoids in the very abstract looking category theory, it doesn't matter if it's addition or multiplication. The operation doesn't matter, whether it's addition or multiplication or concatenation or cross product because you generalize the actual operation to the extent where what it's going to produce. It doesn't matter anymore. For me, I still think of Monoids in terms of like set theory or Boolean Algebra, then that's one of the things that I think is difficult with Haskell where people talk about Monoids in terms of category theory but I think that's not very helpful for the actual programmer who has to actually deal with the two different instances like sum and products or concatenation and zipping are going to actually act different in a program.
CHARLES: Right, they're going to yield a different set of values.
JULIE: Yes.
CHARLES: Is there a baseline vocabulary? I kind of think of it like learning a new language, right?
JULIE: Yep.
CHARLES: When you're learning Haskell, you're not just learning a new language. You're literally learning a new language. I could go and I could learn Japanese but it's going to be a struggle at some point. People say certain languages are hard and certain language are easy. I don't generally subscribe to that. I think that most of it is just going about and living in a place where they speak this language and you'll absorb it and it's the decision to go and live there -- that's kind of the primary one.
But let's say, you're a foreigner and you're travelling to this country called Haskell that's got this strange language. Like other human languages, it's just got different names associated with different concepts and some of the concepts might even just be unique to that country. Just like when you're travelling and acquiring a human language, there's a certain level of vocabulary that you need to achieve before you can do things like buy groceries and be able to transact financial exchanges or have a conversation about the weather. What are the kind of the levels of vocabulary that you need to acquire to be operational in Haskell or I would say, even in functional programming because now that I've been exposed to this, I see it in Clojure. I actually see people doing this JavaScript and in Erlang, in Elixir and what have you.
JULIE: Yeah, I don't really know how to answer this question. How to buy groceries in Haskell?
CHARLES: Let me let scale that down because I had this horrible tendency to spend five minutes asking what I say is going to be single question but it's actually like 30. Let's take down the scope. When you were learning this vocabulary, at what point did you feel like you're really gaining traction? We're you really starting to connect the dots?
JULIE: For me, I think when I got through Functor. It was when I felt like --
CHARLES: Functor and what comes before Functor?
JULIE: Monoid. I think once you understand Monoid and Functor, then a lot of other concepts in Haskell will start falling into place because this is not obvious to everyone but I think once you really understand Monoid and once you really understand Functor, then applicatives are monoidal Functors and that's not obvious to everyone. Like I said, it's not obvious at first certainly, and monads have characteristics of both Monoid and Functor as well. Then you start saying, "There's all these other Functors. There's profunctors and bifunctors. I think once you really understand Monoid and Functor, a lot of the rest of Haskell starts falling into place and then type classes like alternative. Alternative is another kind of Monoid.
We have all these other names that if you can see the general pattern of Monoids and Functors, I think to me anyway, a lot of it then just started falling into place. Applicatives to me seemed, I don't want to say obvious or simple but in traverse, it's same sort of thing so we have these other names for it -- traversable -- and I was like, "Why was it called traverse. I don't understand this word at all." But once I saw the type signature and what actually happens with what the function traverse does, I was like, "Okay, I see what's happening here." For me, those were the two big hills. Once I got through Monoid and Functor and really understood them well, then a lot of other stuff just come and fell into place for me.
ELRICK: This is really interesting. How was a Monoid explained to you when you were first starting to learn Haskell? Then now, how do you explain what a Monoid is to someone that's learning Haskell?
JULIE: When Monoid was first explained to me, it was the pattern of there's addition and multiplication and list concatenation so it generalize out that pattern and that was really hard for me to understand at first because list concatenation and addition are similar but multiplication is different. I was like, "What do these three things have in common?" What they have in common is that they take two values of a certain type and return another value of that type and that's the type signature of the main function, that's in the Monoid type class. But that doesn't really tell you very much. A lot of functions could do that, in theory at least. How you combine them is really what's interesting about Monoid and also what makes concatenation and addition different from multiplication.
Fortunately in college, I had had a fair bit of exposure to Boolean Algebra so figuring out that like, "There's actually two basic genres or varieties of Monoid and they are disjunctive or additive or they are conjunctive or multiplicative," and figuring that out, to me I always think that Monoid should really be, maybe two different type classes, one for the additive Monoid like list concatenation and addition and things where you are adding two things like a set union.
Then conjunctive, which would be this intersections or multiplication or cross products. I always think there's maybe should be two different type classes but there's not a good way to do that really in Haskell. Instead, we have this one type class and then we do this ugly business of wrapping them in different type names.
CHARLES: Is that why you'll have a constructor for some so it's just a wrapper for an integer?
JULIE: Yeah.
CHARLES: I don't know if that's so bad.
JULIE: I don't like it but --
CHARLES: Yeah. You know what? You do a lot more than I do so I'm going to take your word for it.
JULIE: Yeah, that's exactly why. Sum and product are the wrappers for integers because integer doesn't have a Monoid. It has two Monoids over it.
CHARLES: I see. There's lots of ways to combine integers.
JULIE: Yeah and those are the two basic ones. Then because Monoids also have an identity so with semi-groups, then you get even more semi-groups for integers because you get max and min, because they don't have an identity so there's semi-groups.
CHARLES: There's always risk getting down into the weeds with the vocabulary but I think that there's a message here because your answer to the question is really, "When I understood Monoid and I understood Functor," from that point on, the overhead that you had to expend to get other things was lower than the overhead that you had to expend to get those initial two things. For anyone listening, Monoid and Functor are probably opaque terms. You have no idea what the hell they mean. We've been talking about in things like that a little bit but then it's okay because they're a finite set of opaque terms and they're very achievable and once you can achieve those, then you've done 90% of the work and now, you're just combining them into interesting and novel ways.
JULIE: Yes. I will say it that a lot of people do tell us about Haskell book that applicative is actually the hardest chapter in the book, not monad but applicative.
CHARLES: Really?
JULIE: Yeah. A lot of people do tell us that. Because that's the first time that you've taken the concept of Monoid and the concept of Functor and combining them into a new thing so then, once you've done that with applicative, then after that, really it's all downhill.
CHARLES: Right. It seems like there's a couple of key insights. As you're climbing that hill, I like that analogy is like one, just understanding that there things like type classes so you've through attacking Monoid and through attacking Functor, you realize, "There is such a thing." By recognizing there is such a thing as a Functor, you recognize that there is the potential for other type classes like it. Then through combining it with Monoid, to get applicative, you can see, "I can actually compose these things into new instances of those things," and then that's either the crest of the hill or the Pandora's box, depending on which way you look at it. I think there's a hopeful message in there that if you can invest the time to learn these opaque terms and making them transparent to you, you can really, really, really lean heavily on that knowledge in going forward.
JULIE: Yeah. I'm writing a new book now called 'The Joy of Haskell.' The idea of The Joy of Haskell is meant to be an intermediate book. For people who already know some Haskell but we want to make words like Functor more general, like in Haskell book we really focused on the type class called Functor when it's actually a concept from mathematics or actually originally from linguistics oddly enough but we really focused on the type class in there, rather than trying to explain what a Functors are generally.
In the new book, in The Joy of Haskell, we're going to try to take a lot of these terms like Monoids and Functors and catamorphisms and all these other words that Haskell has used all the time and try to explain them generally. Then also give examples like interesting uses from different libraries and stuff like that. It'll service both, hopefully a guide to the vocabulary of the Haskell ecosystem and also some documentation and examples for libraries and things like that that are useful because these things do have uses. They do get used in interesting and exciting or terrifying -- maybe those are related -- ways. That's the goal of the new book is to try to make a guide to all of this vocabulary that Haskell use all the time. We're trying to do that.
How do I explain Monoids, you asked. You've got two values of whatever type. It doesn't matter the type and in general, there would be two ways you can think of to combine them, either making a sum or a union of all the values in them or making some product of those values, if they contain multiple values or even if they only contain one. That's how I explain them now. I'm not certain that addition and multiplication are actually the best ways to start with that because addition and multiplication don't act quite like set union and intersection do. I'm actually thinking of them in terms of and this is how I explain monoids to the people now, I start from set theory and that sounds really heavy but it doesn't have to be because I think a lot of things about sets are --
CHARLES: They're very intuitive, especially if you have visuals.
JULIE: They're very intuitive, for people to think about. Yes, exactly. I explain Monoid now more in terms of set union and intersection. I'm actually giving a talk in October. It's coming up in just a couple weeks at Haskell eXchange in October 12th and 13th in London and I'm giving a talk there called 'A Monoid For All Seasons' and I'm going to try to explain the theoretic motivation for Monoids and try to explain them in those terms. Semi-group is a little bit different because lacks the identity but I'll try to explain the alternative type class and monad plus this really the same thing as alternative. These things are also just Monoids so we have these different names because it's a different type class alternative but it's really just another kind of Monoid. I'm giving that talk about set theory in Monoids in October, in a couple of weeks. People keep asking me on Twitter, "What's your obsession with Monoids," because my name on Twitter is Monoid Mary so I try to explain why I love them so much.
CHARLES: Actually, it's an awesome point, which I've just gotten to experience it is what you see like, "Oh, there are these abstract things," you start searching for them. A lot of times, you'll uncover them and it'd be a real timesaver. There's the thrill of unearthing it in the first place and then when you could say, "Now that I've identified this thing as a Monoid, there's so much less that I have to write." There's like less work that I have to do. It's the same reason that we write frameworks for ourselves in software. It's like, "We love Ruby on Rails because of all the work we don't have to do." Now, you have to expend a lot of energy to work with it, using Rails an example but there's lots of software frameworks.
It's like, "If you can find a good persistence framework or you can find a good thing for making a library for handling HTTP requests and responses, why would you write it all by hand in the first place?" I think the thing that's exciting for me as a developer is being able to see, "Monoid is a thing. Functor is a thing and I can now actually use this and I can use it almost as a looking glass to explore the world around me. When I see something in the landscape that just leaps out through that lens is another great one." I've been on a big kick lately but being able to say, "This is going to save me so much time because of the thoughts that I don't have to think and the code that I don't have to write." I think connecting it back to the pragmatic, I certainly have become really obsessed, maybe not about Monoids but having a type class large in your mind.
JULIE: I think it's a really powerful thing. Sometimes that jargon is really useful. It's useful in a sense that it like compresses a bunch of information into a single word to remember. It's like teaching my eight-year old multiplication and we were talking about like, "It's like addition," and for us adult, I'll just go ahead say, "It's associative and commutative," but showing him that you can do those things and that addition is like that too and we're talking about that and he was so excited to learn that there's this word 'commutative' that encapsulates this idea for both concepts so he doesn't have to think like, "Addition does this thing. Multiplication does this thing." He doesn't have to remember both of those things, like he just remembers, "Commutative and they're both like this." It kind of compresses that information and what you have to remember and think about.
Then it does make it easier to see that pattern in other things, then we can find commutativity in other things because now we have this pattern that we can look for and we got a name for it. We can talk about it and really, there's a lot of stuff like that in Haskell where we find some pattern that we find useful or we want to be able to talk about or easily translate to a bunch of different types, not translate is quite the right word but you know what I mean, I think. Then we give it a name and we make type class for it and then it's, "Now, we find it even more place for us."
CHARLES: Right. It's about thinking less, right?
JULIE: Yeah.
CHARLES: That's a big misconception is that it's not about thinking more, it's about thinking less.
JULIE: It really is. I think it's because there's so much kind of upfront work, where you have to learn all this new stuff upfront, then people mistake that for how much work we're always doing but in Haskell it's like, "We did all this work upfront and now we're now we're not going to think about these things anymore."
ELRICK: That sounds like a good title for a book, 'Learn Haskell and you will think less," but it's true. When I struggled through that online class, I came out of that just being able to pick up any functional programming language and just hit the ground running. It is definitely a plus and you will think less.
JULIE: Yeah, in the long term, I think that you do. Haskell is not a perfect language. There are things that probably can be improved.
CHARLES: Now, before we go, I wanted to ask you, having had this very unique on-ramp into programming, which apparently you're still not convinced about. I'm curious what it would take to actually convince you but the real question that I have is there any advice that you have for someone who does not have a stereotypical background in programming who may not think that they would find programming interesting, who might have any number of roadblocks in terms of their own conceptions about the path forward. What advice would you have for them?
JULIE: I am a bit joking when I say that I'm still not sure about writing software. I don't feel like I'm good at it and I think this is really the key. There are a bunch of domains in programming that I don't personally care about. I don't want to make web apps and I have nothing but respect and admiration for people who do. To me, it's very, very hard.
CHARLES: Mostly because our tools aren't the same.
JULIE: Yeah and there's just so many things outside your own program, there are just so many things that you have to think about and deal with because there's the network and there's other people's computers and they might be doing in other people software and what it might be doing. It is insane so for me it's very hard. There's a lot of domains of programming that I don't care about and when I thought about programming, that's the kind of thing I would think about. I certainly knew a lot of people who are web developers or the common programming jobs, I guess. Some of them just weren't that appealing to me and I'm not interested in making games or graphics so those are the kinds of things that I thought about for programming.
There are things though that I am interested in doing. I'm very interested in natural language processing and I guess that's related to machine learning. I've recently taken up an interest in things like the raft protocol, the consensus protocol. Those kinds of things interest me a lot and there's a lot of the theory that interests me. I'm reading a dissertation right now about implementing a non-strict lambda calculus, which is what Haskell is. It's a non-strict lambda calculus and this guy's dissertations are theoretically implementing a non-strict lambda calculus.
To me, the theoretical side is really interesting but then I am also interested in certain kinds of software. For some reason, I have developed quite an interest in making Twitter bots. I think that the advice I would give -- I'm rambling a little bit -- to people who think they're not interested in programming so why should they learn or whatever, is just find the thing that you are interested in and there's probably a way you can make software for that and maybe that will be the thing that will get you interested. It might not be Haskell, maybe you are interested in making web apps, in which case I would say go for Elm or PureScript, obviously because I like functional programs but Haskell might not be the best first language for you in that case but find the thing that you're interested in and there probably is a way to write software to do that. There's probably something in programming that will interest you. It's such a vast field.
CHARLES: All right. I really, really like that answer.
ELRICK: Yeah, that's a beautiful advice. Find your domain.
CHARLES: Yeah, it's bigger than you think.
JULIE: It's much bigger than you think.
CHARLES: And there is a place for you. Thank you so much for coming on the show, Julie. I really, really, really enjoyed our conversation.
JULIE: Yes, so did I. This is a lot of fun.
CHARLES: Thank you. Now, before we go, I understand that you are going to be in London, was it roughly very, very soon, you said you were giving a talk.
JULIE: Yes, the 12th and 13th of October. It will be recorded for people who can't get in. It will be recorded, I believe.
CHARLES: You will be talking on 'A Monoid For All Seasons.'
JULIE: Yes.
CHARLES: And then you've also got The Joy of Haskell book, which you're hacking away right now, right?
JULIE: Yes.
CHARLES: With that, thank you so much for both of you. Thank you all for listening. What's a good place for people to reach out for you?
JULIE: If they're on Twitter, I'm very active on Twitter so I'm @argumatronic on Twitter and my blog is also Argumatronic and that has more contact information.
CHARLES: Fantastic. We'll link to those in the show notes. For everybody else, thank you for listening. You can get in contact with us at @TheFrontside on Twitter and [email protected] over email. We'd love to hear from you. This just in, we're running a special. If you go to our website and enter the promo code 'ELRICK20,' you can get that 20% discount on your next custom developed web application. Go check that out. Take it easy, everybody. Bye-bye.
JULIE: Bye-bye.
Chris Chuter: @Chris_Chuter
Show Notes:
Resources:
Transcript:
CHARLES: Hello, everybody and welcome to The Frontside Podcast, Episode 82. My name is Charles Lowell, a developer here at the Frontside and your podcast host-in-training. With me is Elrick Ryan. Hello Elrick.
ELRICK: Hey, hello.
CHARLES: And today, we are going to be continuing our series on the Internet of Things and we have someone on the podcast today who's going to talk to us about the Internet of Things. His name is Chris Chuter and he is the CEO, inventor and founder of Peeple. Hey, Chris.
CHRIS: Hey. How is it going?
CHARLES: It's gone well. Thanks for coming on the program. Peeple, what is it? Why don't you give us a quick overview of the product? Obviously it pertains to IoT, what is it and how did you become involved with it? Let’s delve into that.
CHRIS: Yes, sure. Let me give you the elevator short version first then we can dive deeper. Peeple is caller ID for your front door. The idea is when you get a phone call and you don't answer the phone, what happens? It goes to your voicemail. You know someone called you. But today, if someone comes to your house, you have no idea that they came unless you're there. This is the central problem that we solved with Peeple.
It’s a little device, a hardware device, an Internet of Things device that fits over the peephole in your door in the inside of your house. When someone knocks or doors open, you get a push notification on your phone. You can open up the phone and you can see a live view of your peephole. In a nutshell, Peeple is a smart peephole.
CHARLES: Is it more for the case when you're not home at all or do you find the people use it for what you would traditionally use a peephole.
CHRIS: It depends on the person. Now, my personal use case is for keeping track of wandering kids and that's actually inspiration for this invention. I have two boys and when one of my boys was three years old, he managed to open the door, walk out, go on to the street and walk down to the end of the street. Now, I live in Austin and I live right off the edge of a very busy street.
Now, my kid didn't die or anything like that. It's not a really sad story but a neighbor brought my kid home and it was one of those moments as a parent where you're like, "Oh my God. I'm a terrible parent." But being an inventor and an engineer, I was like, "I'm going to hook something up that just tells me when my door is opened or closed," and it morphed into this invention. We showed it to people at South by Southwest almost three or four years ago. That's when we realized we were on to something that didn't exist. It was just a little camera on the door.
CHARLES: Tell me about those first versions. I'm so curious. It sounds like there's a lot of layers of functionality that you've been through, a lot of iterations so I'm curious about that. What's was that zero iteration look like?
CHRIS: Version 0 was made in 24 hours. It was a hackathon for... I can't remember the name of it. There was a hackathon group that recently imploded and we won this hackathon. The hackathon thing was to make something... I'm not sure if this is for Internet of Things but we were all making that kind of stuff. I made this little Raspberry Pi demo with a little mini door and I had talked to my wife and this is how I was able to make this invention, to keep track the kid as I was busy doing other stuff but I talked her into giving me 24 hours to make this one thing. Then me and another guy, David we won this hackathon. We were like, "We've got to turn this into a real thing," because one of the awards of the hackathon was you go to Silicon Valley, you show this off and you do all this cool stuff with it. We were like, "We've got to actually turn this into something that's presentable." That was Version 0. It was just a little Raspberry Pi.
CHARLES: Now, what were you doing to detect the state of the door?
CHRIS: That's the crazy thing. The first version of the device had more sensors on it than the final version. The first version had everything. It had a doorbell, it had a knock sensor, it had a motion, it had a speaker that played Paul McCartney's 'Someone's Knockin' At The Door,' but it had an accelerometer. I threw everything in there the first thing and half of it worked for the hackathon demo but it was good enough to win. This is something that, I guess I could call wisdom now but the real thing I learned is you start with everything and then you narrow and get it more tuned and highly focused and more precise as a device, like the difference between the iPhone and the Samsung phones. One of them is to throw everything into it and then the iPhone is just really specialize into a few things really well. The next three years, we're pulling stuff out.
CHARLES: What are some examples of that calling that you're describing where you're saying, "I'm to take this out? I'm going to take this out. I'm going to take that out."
CHRIS: We got rid of things like the doorbell and some of the other sensors, mainly because it was just a wiring issue and as well as we wanted to keep track when the door was opened and closed. It didn't make sense to have the speaker on there at the time so we really focused more on the accelerometer and the knock sensor for the first version of Peeple.
CHARLES: That is not the final version. Is it mostly just the accelerometer? What if someone doesn't knock? I assume there's some sort of detection that goes on with the camera.
CHRIS: That's the next version. That's something that we've been working on right now, what we're going to be delivering. We have delivered our first, I would say Version 1.0 of Peeple devices to our customers. There's a thousand of these or so in the wild, all around the world and the next version we have added -- and I guess this my first real announcement of this -- a motion detection module. It's not a camera-based. It's more or less magic and it just works through the door. That's the most I'm going to say on it right now because we're probably the first hardware device that it's actually using this technology.
ELRICK: That's an excellent pitch. Everyone loves magic.
CHRIS: Yes, it's basically magic. It works through the door.
ELRICK: As you were going to these iterations, were you doing like user testing to see what users wanted? Or did you internally say, "This doesn't make sense. Let’s just take this out."
CHRIS: Absolutely. That's the second part of this story. After this hackathon happened, we prepared to go on the road show to go and show it off to Silicon Valley but in the meantime, this hackathon group, I think it was called AngelHack, it imploded. One of their founders made all these disparaging comments about homeless people and what essentially happened is we lost the award. They said, "We're sorry. We can't give you the award," but we had spent about three months fine-tuning, making something pretty and putting a pitch together.
I went in and I pitched at a TechCrunch Meetup in Austin and we came in second at that but during that meetup, I met one of the reporters and said, "You really need to talk to these guys in San Francisco called Highway1," so I did. We eventually ended up moving to San Francisco. Now, the reason I mentioned that to answer your question is they understand this idea of user testing, I think better than a lot of people. Even though they were focused on working on hardware and getting an IoT device that works out there, they were drilling it into our heads is, "You have to get this in people's homes now. I don't care how bad it is. I don't care if you have to hire people, to sit at a peephole and just look through it and pretend like there are hardware device. You got to do this and you have to find out what the problems are, what works. I want you to look at your biggest fears of this thing and you quash them and you do that before you put any Silicon down," so we did that as best we could.
CHARLES: So you did that with the Version 0 and Version 1 devices?
CHRIS: Exactly, just a Version 0, I have all these pictures. We put them in about 12 to 20 homes and we have these long extension cords powering this thing because we didn't have the batteries to figure out. We had these huge lag problems. It would take like 30 seconds to a minute before something would happen. We had all these issues but in the end, people were still like, "It had these issues. You couldn't do this," but the fact that I had a door log, a door diary as what we're calling it now, that's something I never had before. That's where your secret sauce is so we ran with that.
CHARLES: Yeah. That's the kind of thing it never even occurs to you.
CHRIS: Exactly. In the app, or at least the early versions of the app, is you have these versions like a calendar that are like, "Okay, I got 10 visits yesterday. I got 20 visits today. No one came to visit me today. I'm so sad," but I have a calendar of, I think it was May of last year when I got visited by three or four magazine salesman in one week so you could correlate that with, "Did we have any break ins?" or something like that.
CHARLES: Yeah, it would be interesting to be able to share that data with your neighborhood or somehow coordinate that. one of things I'm curious about too is you did this user testing you were talking about, doing the wiring and the installation, it's a conversation that always comes up when you're talking about custom hardware because there's always the drive to be small, there's always the drive to be have a small form factor and then you have challenges of power like how do you power this device. How cumbersome is the installation onto someone's door?
CHRIS: Yeah, we had it all. That's a big difference, I think between San Francisco or Silicon Valley and other towns is there's this acceptance and there's this readiness to participate in the tech scene. We did a call out for volunteers and we had no problems finding them. They didn't mind us coming to their house and hooking up these big, bulky things and just being real intrusive. The fact that we found these people and they were the key to this early stage of, "Do you become a product or do you not?"
We were only there for four months but by the end of this time that we were there, there was this legitimate tangible feeling of we're not a prototype anymore. We're a product and we didn't have a product. It was just prettier but we could see the light at the end of the tunnel. I don't think that would have happened had we not gone through this very painful experience with all these poor people that we inflicted our device on.
CHARLES: This actually is fascinating because obviously, you're back in Austin now and I never heard of programs like that, like sign up to have someone come up and test it at some alpha stage prototype in your home. That sounds crazy and yet, it sounds like they were just going out of the woodwork.
CHRIS: In San Francisco, it's not a problem. If I put the call out now, I probably have to really like, "Here's an Amazon gift card." I have to start doing a little bit of bribery.
ELRICK: I think I would sign up just to see the cool tech.
CHRIS: Yeah and those people exist. I think we don't have the means to really find them. That infrastructure already exists. In Silicon Valley, you just go down to Starbucks.
CHARLES: There ought to be some sort of meetup for people who want to experiment with very early stage IoT devices here in Austin. Maybe, we'll have to look at it. If that doesn't exist, I would love being a guinea pig. I actually think there is an untapped willingness here but there's just not --
CHRIS: I think you need a critical mass of hardware people and hardware devices that are ready to be put in doors or put in the houses. There's definitely some in there. I have a lot of friends and there are hardware meetups that we go to but this stuff takes so long and it's so hard as hardware is hard. There's that small window of, "We got this little idea of a water sprinkler. Do you think anyone want to try it out?" or something like that and then the moments gone. Then six months later, there's another one.
CHARLES: Yeah. I wonder if there's a way to really decrease that iteration cycle so that you can get feedback more quickly. I guess the problem is when you need a physical device, you just needed a physical device.
CHRIS: We're talking about the Maker Movement and the MakerClub. If you're part of those, these people are hard to find. People that go to Maker Faires, that's the people you're looking for.
CHARLES: Right. Now, transitioning because ultimately your target customer base is not makers, not people who are willing to put up with wires and cabling and people doing protracted installation. What does the kind of 1.0 product look like? Because what I'm curious is what immediately jumps to mind is this thing sounds like it's going to probably consume a lot of power. How do you get the power to that and what are the challenges and what are the tradeoffs that you have to make to try and get that power consumption down or get the installation complexity down? How complex is it today to install?
CHRIS: I guess, I'll toot my own horn a little bit but I think we have one of the easiest IoT devices on the planet to install. You can possibly not even need tools. You can use your fingers but the biggest challenge for any IoT device is getting that home network connection. If there's been a few technologies through the years in which they've tried to fix this problem, basically just like self-pairing or things like that, like how Bluetooth can sometimes be really cumbersome. Now imagine that with Wi-Fi, it's the same thing but now you've got a password you've got to throw in there.
That’s really the only real hiccup with the installation on our device and we tried a few things. We went through about three different Wi-Fi chips before we settled on what we were using now. The first Wi-Fi chip was a TI one, which offered this nice pairing capability but it just didn't work half the time. Then we switched to a Broadcom chip, which was really solid and stable but turned out to be the most expensive component in the whole device so we had to get rid of that.
The Wi-Fi issue was something we had to solve early because it goes also toward your power consumption. We have a camera and a Wi-Fi chip and both of those take up to 140 to 200 milliamps of juice when they're on. We had to be really smart of when this thing was going to be on and that's essentially when we went in parallel with the knock accelerometer. This device stays asleep most of the time and that's how we get the many months of battery life out of it. We put a rechargeable battery inside, it only turns on when it needs to and it's just hanging around waiting for an event for the rest of the time. Those were the things we were solving to get the Version 1.
CHARLES: Now, it's waiting for some event but in order to receive the event, doesn't the accelerometer need to be on? Or is there some motion detector that --?
CHRIS: That's a solved problem. good news was that accelerometers are extremely low power in the nano or picoamps but that's also another reason why the motion detection was going to be a hard problem because that is not, unless you're using what's called a PIR that is not a low power solution.
CHARLES: Acronym alert. What is a PIR?
CHRIS: It's an infrared proximity detection. That's how almost all motion detection cameras work. They have one hole for the camera and another hole for the PIR. The problem with these are is they don't work well in sunlight, outdoor-light and things like that in one of our use cases so we were kind of stuck. That's why we've recently come up with this new motion solution that doesn't rely on that technology -- the magic solution.
CHARLES: All right. When we're going to find out about the magic solution?
CHRIS: As soon as I ship this next version because it is being used in a few products but it's not really stateside yet and I want to save my thunder but it's something that I think is really cool. It really is magic. It's just amazing to me that it works.
CHARLES: Well, I'm eager to see it. You were talking about Wi-Fi being one of the biggest challenges. That's a perfect segue. The connection to the network for something that we're always curious is discovering a new and interesting device is always a pleasure and then the next thought that almost funnels immediately after is how can I integrate this with other strange and wonderful devices to make something even more wonderful? A question we ask everybody is have you thought about how this might be a participant in an ecosystem so if there were other devices around the home, how would they even talk to the people? How might it offer information to someone looking to, maybe do some custom integration in their home?
CHRIS: That's a lot of questions in one. Essentially, there's two ways of looking at it. You can look at it from your customer's perspective, what kind of customer do I think is going to have this or is going to use this the most. Back when we came up with this, there were a lot of do-it-yourself types and If This Then That protocol was out there but we really wanted to focus on something that was incredibly easy to use and didn't require you to program anything.
I was really frustrated with the whole idea of Internet of Things because it almost implied that you had to be a programmer to use it. I didn't like that at that time. I've since come around to it because there's all these great tool kits out there. We initially looked at integrating with HomeKit. We thought they'd be perfect but what a lot of consumers don't realize is early HomeKit -- I don't believe it does that anymore -- made you modify your hardware to put in this special Apple hardware. When you're making a device, it is so hard just to get the hardware down. It's so expensive. To add anything or to put anything else in there, it's a huge friction point. It's really something that small startups just can't afford to do.
A big Nest or a company like that have no problem but when you're making a one device, this is a big deal so we weren't able to really leverage something like HomeKit for an API. But we do have our own cloud-based API. We're RESTful API but it's just not documented and put out in a way where we want to have people programming it. But the good news is we did leverage several APIs when we were making things like the app and doing things like the push notifications and things like that. Now, it turns out that a lot of the case we used are now integrating with things like Alexa and other device protocols so we essentially get those for free. This whole ecosystem is forming around us. Just most important is to get your device out there because you have a vision for what the device will be used for. But then your customers tell you what the device is really useful for and that's when the real work starts.
CHARLES: Right. I guess, it's true you have your first line of customers and I guess the use case what I was thinking of is me being a developer. I'm thinking what products could be built then using this as a component, so to speak. Have you'd given any thought to that or have anyone had approached you to say, "This is amazing. I'd like to build this meta product that integrates that," or is it kind of early days?
CHRIS: Early on, that was the approach of the Internet of Things and it merged away from that in my experience. Early on, it was all about building blocks. You got to understand, these are old Zigbee Z-Wave programmers and that was the whole concept. Then it got turned on its head by, "I really have this problem that I need to solve and I don't want to have to make a bunch of building blocks to do this." For attacking it from the other side, like you're saying, building up into pieces, I really recommend you talk to the Twine guys -- super mechanical -- they're here in Austin as well.
A year or so before, we came out with Peeple. They put out this device which was exactly what you're talking about. An Internet of Things type hub where you just add in all the pieces and then you integrate with everything. They can better give you a story of how that lifeline goes.
CHARLES: Yeah, because it's always something you think about because you've got all these wonderful things.
CHRIS: Yeah, some would say, an Internet of Things.
CHARLES: Yup, or at least a floor plan.
ELRICK: When someone gets a Peeple device, what is the full installation story and set up? What is the walkthrough for that?
CHRIS: We have a little video of that. What you essentially do for Peeple when you're installing it on the peephole in your door, you unscrew the peephole. Now, the way Peeple's work is they need to handle doors that are variable width, depending on where you live. There's no real standard. All of the Peeple's work by having a shaft that you screw onto another side so it's basically two pieces. Now, one of those shafts holds this bracket that we include in the package. You screw that onto your door with the peephole holding it to the door, then you turn on the Peeple device and you connect it to your home Wi-Fi and then you're ready to go. That's it.
CHARLES: That's the hardware side of the onboarding and then what about the software? How do I go and look at my door diary?
CHRIS: You do this during the installation. You go to My.Peeple.io and there's a little button to add your Peeple device. UI-wise, it's one user interface among all the platforms whether your Android, iPhone or on a browser. You just go to that webpage and associate your account to your Peeple devices. You will have to log in. You can log in with Gmail, Facebook or just a regular email. Then you add your device and any time you go back to that page, it will show you only the videos from your device so you have a list of all the events from your Peeple device on that page or in that app.
CHARLES: That is interesting. I'm looking at the videos right now online. Although my problem actually is I've got a glass door.
CHRIS: Yes, we got you covered as well.
CHARLES: You do?
CHRIS: Yes. The reason you have a glass door or a peephole and many people don't realize this is it because it's required by law. If you ever plan to have run out your house as a multi-family unit, you have to have a peephole or a window surface to where people can look out. Once we figured that, that's when we realized we were onto something. The first versions of Peeple came with these little adhesive pads that we called gecko skin and this is where we learned a valuable lesson. No matter how sticky you make your stickers, they're not sticky enough.
We included three of these little tabs in every device to put on a glass door, if you had glass so the Peeple device would work the same way for glass door, except that you would use a sticker, instead of unscrewing the peephole. The only problem with the stickers were is they were not sticky enough. If there was condensation or a weather event or something like that, these things would fall off so we made a modification. We found better stickers and I mailed those out to all the people. But this is why hardware is hard. You're going to make these mistakes. In all our testing, we didn't find this but of course, once you have a thousand testers, you find a little more.
ELRICK: That's interesting that you brought up the laws about the peephole. Were there any particular building codes or anything of that nature that you guys had to be concerned about when having Peeple installed things on their doors that you had to figure out before shipping them out?
CHRIS: Not really. The Texas property code is more geared among making landlords do the right thing. In case you're wondering, I think it's Texas Property Code 94-152 that covers this. There must be an external viewable portion for all multi-family units to the front entryway. Now, this is just the Texas law. We had to look this up in a few other states and it turns out there's one in San Francisco, there's one in Virginia but they're all different. But so far, we haven't had any issues with any property codes or building code issues.
CHARLES: This has been an almost four-year odyssey for you that you've been on, right?
CHRIS: Right.
CHARLES: You've been involved in this scene and working with hardware probably for a long time even before that, it sounds like. For people who are just getting into it, because I feel like there's this wave cresting now, where these types of startups and these types of side projects and hobby projects are just starting to enter the mainstream. Do you have any advice for anybody who would want to get into this space?
CHRIS: Well, that's a great question. Of course. Now, contrary to what you just stated, I didn't have much of a hardware background. I'm a software guy. I can personally attest to the pains of becoming a hardware guy. Now, the irony of this is I do have a master's degree in electronics engineering but electronic engineering is so huge. It's such a big field that you can spend your entire career not doing much hardware. But I always had the ability to go back and build some circuits but I would say the number one thing, if you're not a hardware guy is go to some of these meetups or get involved in a community and find yourself one, someone who has experience doing hardware because coming from the software room, you're used to this flexibility of changing a few lines of code and being everything changing.
Now, when you get a hardware guy onboard and our hardware guy's name is Craig, when he comes to work --
CHARLES: Or gal.
CHRIS: Yeah, or gal, of course. When they look at the same problems you're looking at, they're like, "Hold on a second. Let’s step back. Let’s test this." There's this quantitative slowing which you need to have as hardware because once you build a PCB, a circuit board, you are now stuck with that board for the next month or so because it takes a while to make another one so get that right before you jump around and do all these changes. My first advice would be is get help. There's no shame in going out there and you might be surprised. There are so many people out there that want to join in. If you have a good idea, there's plenty of people who want to contribute.
CHARLES: Would you say that there are communities out there like the software communities where you have meetups? Some of the software meetups are just fantastic, where people are so welcoming and they're just so excited to share the information that they themselves are so excited about.
CHRIS: Yes and there's the same thing as on the hardware side. You would definitely go to a few hardware meetups, there are several in Austin. There's at least one every week and it's a great chance for people to tell these kinds of stories. This is a maker type community so they welcome these ideas because that's what fuels their enthusiasm. Every time someone is doing something new, they want to hear it. That's the change now. This decade has happened to where you can go out and buy a few modules and make your little device.
Then there's the next big step of turning it into going from prototype to hardware but you can get all those kinks out without having to make your own printed circuit boards, without having to have a huge firmware background. Just knowing a little bit of tech and a Raspberry Pi, you can test out your inventions at this early stage without having to invest all this money and these other things. There's never been a better time to do it. I would leave your listeners with is if you got something swirling around your head, get a Pi, get a little Arduino and do it. There's nothing stopping you.
CHARLES: Yeah, it's shocking how affordable they are.
CHRIS: I don't even touch on China, by the way but that's the next step.
CHARLES: That's the great thought that I want to leave everybody with but I actually have more questions so we won't leave everybody with that. We'll keep on going because I want to talk about China and I want to talk about something that was in there. You've touched on it a couple of times when telling your story how you go from this just do it, get it out there, get it into people's homes, just get the Version 0 out, just buy an Arduino, slap together something terrible, that is at least one millionth of the dream that you have and you've taken your first step on that odyssey. That's a very common story in software.
The way that we develop software too is have these agile methodologies and these techniques to reinforce them, testing, continuous integration, continuous deployment. How does that play out? A fascinating subject to me personally is how do you do that in the context of hardware. A question that I love to ask is how do you do things like ensure quality? How do you do integration testing? How do you have a deployment pipeline if you've got these Peeple devices out there on tens of thousands of doors globally? How do you push out a bug fix or a feature update? What’s the automation around that look like?
CHRIS: The over-the-air updates are your friend. If you're going to make a hardware device, I recommend making a Wi-Fi enabled device because then your firmware is not locked, then you can do over-the-air updates. That has been a lifesaver. We've done maybe a dozen software updates to our device to date, sometimes little changes, sometimes big changes. But what happens is any time the Peeple device wakes up, it says, "Hello, server," and the server says, "I got an update. First, let me give you all these images." Give me the code. The devices are constantly upgradable, just like you'd expect with software.
Now, with some of these Bluetooth devices, you can't do that. You've got to go out the door being ready to go with no issues. It's a friction point to tell someone, "Your headphones can't work now. You need to plug it into a computer. You need to download this firmware upgrade. You need to update the firmware doing it by hand." That just isn't going to fly in today's consumer market so I would recommend if you can, make your device a hardware Wi-Fi device, get a Wi-Fi module in there and that opens up the world to you on doing a lot of these updates, to answer the last part of your question.
CHARLES: You mentioned China, since you're touching on the manufacturing process or just the market over there or --?
CHRIS: Yeah, be ready to fully commit. I've been to China, maybe four times now. I have a 10-year visa. It took a while to find the right partner and you've got to be boots on the ground in the factory for a couple of weeks just getting the whole line up. It's a whole another product when you're at the manufacturing stage. You're making all these little test things, they've got to hook up the boards to certain devices, they've got to put the firmware on it, they've got to do these things. It's a whole another job. That's why when you do these Kickstarter. They say, "We're going to be out in three months," and then six months later, "We're still working on it."
I have a lot of empathy for this because I've lived it. You think, "I've got everything done. My hardware works. All I have to do is team up with someone to just make it and with them, we'll ship it." There's a whole another level to just a manufacturing piece and you can't really learned. There's no real textbooks to learn this because every factories are different. Our factory is right north of Shenzhen and we talked to some US manufacturers but they just weren't competitive to be in the discussion so you pretty much have to go overseas and then you have to sit down with them and just a little bit of communication difficulties can bring down a whole manufacturing line so it's very important that you're very hands on and you see your product all the way to package.
ELRICK: That's interesting. I know of it but I never really thought about it because I was really not in that position. What are some of the higher level of things that you should look out for when evaluating a manufacturing partner?
CHRIS: We talked to about a half a dozen before we decided on our manufacturing partner. The big one for me was cultural fit. I talked to some of the big ones like the one that makes the Apple phones, we talked to them for a while and I just found that I would say, "We would like to do this or we need this," and then the next week, they'd be asking a question, "What about this?" and I'm like, "Oh, you didn't understand what I was really asking," so you would lose weeks just by tiny misunderstandings.
I found a manufacturing partner that has a subsidiary here in the US and my main contact grew up in the United States but he also goes to China every other week. Having that kind intermediary made everything so much easier. The communication was never an issue. I was able to get things done almost twice as quick with the other manufacturers I was talking to. In the end, they also came up with a great price so it turned out to be a win-win.
I would recommend talking to the bigger manufacturers but spend a lot of time on the smaller ones and really figuring out is the communication up to snuff to really make your product. It's huge.
CHARLES: What a story. I'm really glad that we got to have you on the podcast, Chris because you have the story that starts from literally slapping a Raspberry Pi and an accelerometer and speaker and apparently a bunch of other things on your front door and with an extension cord and walking a continuous path to where you're flying back and forth between China and Austin to inspect and ensure your assembly line and making a real product. It demonstrates that it can be done by the fact that you have done it so I think it serves as an inspirational case for a lot of people out there who might think that this is something that they might want to do. Or think that they're capable of. Thank you so much for coming and talking about Peeple. Everybody, you can go ahead and check it out. It's Peeple.io, right?
CHRIS: That's correct.
CHARLES: All right. Also, is there anything else that you'd like to announce other than the magic, which you're going to keep a lid on?
CHRIS: Yes, I know I'd appropriately teased everyone about that but you can go to our website. If you go to Shop.Peeple.io, we're taking preorders for this next magical version, the Peeple Version 1.1, I guess I'll call it. I would like to add just before we go is if you're going to endeavor to do something like this, make sure you have a very understanding family because they couldn't have done it without a wife and kids that understood my craziness and allowed me to have just a complete mess of our house for, I guess, for three years now.
CHARLES: Thanks again and thanks everybody for listening to this episode. You can get in touch with us on Twitter. We're at @TheFrontside and you can always find us on the web at Frontside.io and there's a contact form and we'd love to hear from you, for any reason whatsoever. Thanks, everybody and we'll talk to you next week.
John Boyd: LinkedIn
Show Notes:
Resources:
Transcript:
CHARLES: Hello, everybody and welcome to The Frontside Podcast, Episode #81. My name is Charles Lowell. I'm a developer and your podcast host-in-training here at the Frontside. With me today is Elrick Ryan. Hello, Elrick.
ELRICK: Hey, how are you doing Charles. Welcome back.
CHARLES: Yeah, thank you. It's good to be back. Today we're going to be continuing the ongoing series that we've been doing intermittently on the Internet of Things. It's a really fascinating, almost to a person fascinated with here at the Frontside. Today, we have with us to talk about this, someone who's very, very knowledgeable on the subject, John Boyd, who I got an opportunity to talk with, I guess it was about a month ago and I wish that we had the podcast recording equipment there in the room because it was just a very, very well-versed engineer, exactly the person you want to be the CTO of your company, which is very lucky for Knocki, the company that he works for, because he is in fact the CTO there. Welcome to the show, John. Thanks for coming.
JOHN: Yeah, thank you very much, Charles and I'm excited to be here. I'm excited to join the conversation this week.
CHARLES: Yeah, why don't you start by what it is that you do at Knocki? Most of our audience comes from software and design and product management backgrounds. You've got a very strong hardware background. How does that play in to what you do at Knock?
JOHN: Yes, certainly. As you previously mentioned, I'm CTO at a startup called Knocki, which you can mount onto any surface and turn that surface into a user interface. We're recently funded on Kickstarter so we're in the process of actually trying to develop this hardware but the central concept is any surface that you mount this on will now listen for touches and vibrations so you can say, mount it on a desk and tap three times on your desk and control your smart home around you. If you have smart speakers or TV, you can tap three times out of four times and control those devices with a really natural interioractive interface made out of anything in your home already.
CHARLES: Tabletops, mirrors, I assume you've tested this on a lot of different services.
JOHN: Yes, I’m sure we'll talk about that more a little bit later but the goal is to be able to turn any surface into user interface. That means if you really wild and you want to use it on the window, I recommend it. But we're thinking desks, walls, doors. It has a lot of applications for disabled and handicapped individuals. Think of a child or someone in a wheelchair that can't quite reach a light switch, if they have a Knocki mounted on the wall, they can still knock on the wall to control the lights. We feel like it adds a new level of user interface to people's lives that can be helpful.
CHARLES: Definitely. Seeing the product and hearing you talk about it, I definitely got that impression. Now, the device that you actually brought into the office because you did come in and talk to us, like I said it was about a month ago but it was extremely tiny. In our explorations into the Internet of Things, we do things like control our lights from within the office. At least, we're trying to control our lights within the office. For us, we're using the standard kit.
We’ve got Raspberry Pis that we're using, that are have access to a plug and they've got a full Linux install, just a really powerful processor and by comparison to the things that you were talking about, that's energy hog by comparison. We think of it as being very lightweight but if you're talking about making some small device, it's actually really, really wasteful of resources, so to speak. What is that transition that spectrum which you moved from these one-off hobbyist things where you're using high-powered equipment to these really custom devices? How do you make that transition? And what is the difference between the two?
JOHN: Our devices are about the size of a hockey puck, which is much smaller if you can think of a Raspberry Pi. Pretty difficult to fit that inside of a hockey puck, especially when you want to start adding some sensors to detect knocks and taps on a surface. I don't hate or dislike the Raspberry Pi or BeagleBone Black or any of those really quick SBCs that can get you started with IoT. But they have --
CHARLES: Acronym alert. What is an SBC?
JOHN: SBC, single board computer. It's any of those credit cards size computers.
CHARLES: Okay, great. So nothing against the SBCs like BeagleBone Black or Raspberry Pi.
JOHN: Exactly. It's a great way to prototype ideas and get in a proof of concept out there and there are some cases where actually, they're great choices for a full-fledged product. A lot of cases in IoT, people are more concerned with things that you carry around with you so they have to be battery powered and you need to be a little bit more conscious about energy economy. You need to be very cost-effective with your components and it doesn't make sense to buy an expensive Raspberry Pi for each unit.
CHARLES: Did you actually start with a Raspberry Pi, when you were developing this product or something that's like an SBC?
JOHN: I actually went straight to a microcontroller dev kit. I started with Texas Instruments' CC3200 LaunchPad. It's a little bit lower level than SBC like the Raspberry Pi. It doesn't run Linux. The firmware I started off writing as a proof of concept was still embedded C bare metal software.
CHARLES: How much complexity does that add? There’s just a lot of nice things about having an operating system and being able to have your compilers, I guess you have a compiler tool chain, but having being able to install big programs like interpreters so that you can run Ruby and JavaScript on there. There's just nice things like scheduling. If you've got a bunch of processes running on this device, you don't have to worry about them, saying who's going to get what processor time. I assume that you're having to deal with all of that if you're writing the firmware by hand using C, right?
JOHN: That's 100% true. There's definitely some great advantages to using a little more powerful system that can run a full Linux stack or full OS. As you mentioned, the design complexity is reduced a lot because you can import other people's code and you have a full operating system to handle most of the drivers in the system. You're right. There's a lot more complexity. We have to write all of that ourselves in C. But that's the fun part about it to me. I love getting down there and writing drivers that can communicate with accelerometers and set them up.
As far as scheduling goes, for getting concurrent software running on your embedded system. There are RTOS’s -- real-time operating system that can provide basic scheduling. For the brave, you don't even have to use that. You can use a lot of the embedded timers inside the microcontroller itself. But to answer your question, it is a lot more complex but one of the tradeoffs to get a device that small, beautiful and also has a battery life that can last many months or a year.
CHARLES: Yeah, it almost sounds like the complexity but you're not going to save yourself any time prototyping it in tools that have all those things because you're essentially going to have to be rewriting your system from scratch, because those things are just a nonstarter if you want low profile devices.
JOHN: Yeah, there's definitely a lot of rework would have to be done but those SBC systems are still very useful for prototyping the cloud side. Internet of Things is hardware and internet when it comes to building out your cloud interface.
CHARLES: Yeah, that's definitely true. You're running a bunch of software on this device. The software that you've written, how do you actually distribute the software because we're very used to in our world, software distribution is not a problem. That's what made the web so popular. While we were willing to deal with really crappy tools on the web for a really, really, really long time, the distribution model was just so nice. You're also having to deal without that too when you're operating in the device space. But the challenges are still there. If you've got a bug on one of these things, how do you even detect it and how do you get a fix out there?
JOHN: Obviously, any software is prone to bugs. Nobody writes a perfect code the first time. If you do, I'd love to hear about it. Obviously, one of the big concepts in IoT is security and to have a secure product, we need to be able to patch bugs as they arrived. A big really important feature in any good IoT product is the ability to remotely upgrade the firmware or send the patches as part of the maintainability that prevents big software bugs from turning your IoT product network into a botnet.
A lot of our time is actually spent trying to make sure that our remote update capabilities are reliable, always functioning and globally distributed. You'd think this is an easy problem to solve but when you're working on a microcontroller that's not running an operating system, running bare metal code, things get a little bit more complicated when you want to make sure that any device anywhere in the world can install the next version of firmware reliably.
CHARLES: Right. At any time there's a software update, it's always, it bugs me and then do I want to do this and it's always optional. There's none of that, right? It’s just what a new version of the firmware goes out, boom! It goes out there.
JOHN: You can design it in different ways. There are some great products out there. Apply the firmware update through the user's phone so you may open up your products application and it says, "There's an update available. Go update." That's definitely one way to do it but that's the problem if the user is not home and maybe they've set this device up in a guest house and they won't be home for six more months, then you have a device that could be vulnerable for six months, which is a long time in the world of software.
CHARLES: Yeah, that's true.
JOHN: To get around that, obviously our preferred solution is to have the device checked into our cloud servers to see if the device itself has updates available and then go through the download and update process that way, just to make sure even if the user is not home or never opens their mobile app, it will still get those critical security updates.
CHARLES: Sounds hard. You're running a risk of bricking someone's device if that update doesn't go very well or it loses internet in the middle or power.
JOHN: Very true, especially when you go towards a bare metal microcontroller with limited memory and limited processing capabilities, unreliable internet connection, a lot of work has to be done on the device side to make sure if something goes wrong during the firmware download process or installing the image correctly that it has a backup image. If you're downloading a new firmware upgrade and the download gets corrupted halfway through, make sure you have an old image that you can boot into. That's one part of it. The other part is detecting that it went bad if it gets past downloads in your image and then it reboot itself and tries to boot into it, how do you know that that image actually isn't behaving the way you want it to and then go ahead and revert back into that original stable version.
CHARLES: I assume there's some key so that you can verify, not only that the image is not corrupt but it's a certified Knocki image that's coming down the wire?
JOHN: Exactly. We signature verification, again something that I think anybody on the internet should be using when you download new software but make sure that the new firmware update was actually written by Knocki and you're not installing someone else's code. Another important factor is just please use HTTPS secure SSL connections to your server, then that reduces the possibility of someone taking over and giving you their own firmware image.
But there are a lot of low power devices out there that are being used to make IoT products. These low power devices are important for many reasons but they have restrictions and sometimes, their security capabilities are limited. Maybe doing encryption on the device and actually are doing certificate verification. That's a costly operation.
CHARLES: It sounds like there's a lot of cycles that that consumes.
JOHN: Definitely. Most people try to make sure they have the resources to solve these problems but at the same time, there are a lot of developers out there that are cutting corners and that's where you get these big news stories about IoT products getting taken over.
CHARLES: Along that vein, it's your reality but it constantly blows my mind that things that you're living without when you're programming for these devices like Knocki is do you have to write your own network stack? When you're doing these downloads, that's kind of like got it all. You've got the encryption piece that you've got to do to make sure that you're connecting over SSL so you've got to do the whole handshake and you've got to do the key exchange and the certificate verification and then the packets come in asynchronously so your message is arriving asynchronously in bits so the header is being assembled, now I've got the HTTP headers, now I can go ahead and get the body. There's a lot that happens for us when we're making a simple Ruby request. We're basically like resource.get. Boom! And it just comes to us fully assembled in memory. How much do you have to hand roll all of that? Are there libraries for doing it? How do you put that process together of just even downloading the image?
JOHN: Fortunately, there are tons of open source freely available libraries for embedded C software that can help us solve these problems --
CHARLES: Is this like a genre of software like if I want to go look for these libraries, how I look for them?
JOHN: In my example, all of our firmware is written in C or C++. Since we're working on a microcontroller with limited resources, it's important to look for libraries that don't use dynamic memory allocation. That's why it's a really big [inaudible]. Some software relies really heavily on that but --
CHARLES: When you say dynamic memory allocation, you're talking about like Malloc?
JOHN: Exactly.
CHARLES: You are basically are allocating memory on the heap. When you're doing for this, you basically want to do everything on the stack. Now, is that just because the instruction set of the processor doesn't support it or is it because it's just there be dragons like here there be dragons?
JOHN: That particular scenario is actually just due to resource limitations. There's just not a lot of memory on our device. We do use Malloc in some cases but we have to be very careful about when we use it and make sure that it's always going to have the memory required or if it doesn't have the memory required, there's some fail safes involved. If you just use someone else's open source library and they're allocating memory left and right, they could end up causing issues on your embedded system.
CHARLES: Right. Now, just a little bit of background for people who might not be fully familiar with Malloc, it's just when you're executing a program, you have this heap memory, which is where you store random stuff and then you have your stuff on like the call stack. Your variables that are on the call stack are in one place and then your just generic data structures that could be accessed from anywhere are in this thing called the heap. Our dynamic languages that we use like Ruby and JavaScript, the heap is hot stuff. Like everything gets allocated on the heap, that's why they consume these huge amounts of memory and then the things that are on the stack, really are just pointers that are referencing these big bags of data that are on the heap. But it sounds like you've got the exact opposite situation where you don't want to have big bags of memory that are just floating around in a heap and you want to do everything inside that stack.
JOHN: Exactly. I couldn't have said it better.
CHARLES: Anyway, you're looking for libraries that don't do that because it sounds like any time you want to allocate memory on the heap, that's going to be shared for the whole program, that space is very limited so you want to be very, very, very strict. You want to control that process. You don't want any other library that's doing it for you. Is that fair?
JOHN: That's correct. That's also one specific example, dynamic memory allocation of the things that you want to make sure your other software libraries aren't going to be abusing. But in general, you need to make sure that any code that you're putting is compatible with your system. It doesn't have some special hardware requirement that your embedded system doesn't have.
CHARLES: Right. For people who want to get into hardware hacking, is there some golden seal of approval like the people say like, "This library is great for embedded devices." Like I said, a lot of times when you're coming into it, you don't know what to look for so what you're really looking for is some expert or authority on the subject who can say, "This is good. This is not good." It is like, "Don't even look at this library because you're going to find something else because this is not embedded-friendly."
JOHN: That's a good point. I wish there was a golden seal of approval or I wish I knew one, at least. Normally, most of our code that we uses are hosted on GitHub. Usually, we try to find software that was optimized from embedded systems and the author of that code will usually mention --
CHARLES: That [inaudible] me.
JOHN: Exactly. This was designed for microcontrollers.
ELRICK: I was going to ask if there's a golden standard when you're building these type of devices. Is there a checklist of things that if someone's going to build something similar that these are good things on your checklist that you should attempt to check off, if you're building this sort of device or want to build something similar.
CHARLES: Now, you mean things like update and whatnot?
ELRICK: Like updating or like how you were mentioning avoiding dynamic memory allocation. Anything, you can just shoot from the hip, like these are things that you should watch out for a lot of your battery power, you should look out for this or anything.
JOHN: Yes. I definitely think the number one consideration that the biggest check box and [inaudible] before it goes out the door is going to be your security suite. Make sure your internet connections are encrypted: SSL, TLSL, that good stuff. Then as we hit on earlier, making sure that you always have a way of updating the device but don't use back doors. A lot of people think to update your device, you should put a back door access and you can go in and download updates that way. That's not the answer.
ELRICK: That's like the back door that they were looking for in Apple like, "Do you guys have a backdoor to get into your device?" No.
JOHN: No. That can be a controversial conversation.
CHARLES: Yeah, or they're like, "Come on, really. It's okay. You can show us the backdoor." No, there is no backdoor. "I know you have to say that. Blink-blink."
ELRICK: That's an interesting problem that you guys are solving on how to update these devices. You guys are essentially hand rolling or developing custom software to do that.
JOHN: Again fortunately, we're using a Texas Instruments SSC system on a chip. They provide some core functionality, some core drivers that really help us out. For example, they provide a special bootloader that can really assist with a lot of the firmware download back up framework image checking, that sort of functionality. We don't have to write it all by scratch but we do have to write the logic to make sure that the device does check for updates and it doesn't forget to check in and talk to us.
ELRICK: On the cloud side, do you guys have to write any custom software to do diffing, to make sure like -- Oh, do you diffing? Or do you just update everything all complete, like once you're updating, you're going to get a brand new update or do you diff and say, "You only need this."
JOHN: Since we're working on the system that we're using, it just requires a fully-compiled image that gets installed by the bootloader. We can't really send just a patch to one part of the firmware, if that's what you're asking.
CHARLES: But I assume there must be some state that's on the Knocki itself. Just even the credentials for the local Wi-Fi network, what devices it's connected to, part of the system is updating and part of it is not, I assume but how do you make sure that that state is compatible with the new firmware?
JOHN: Yeah, that's another great point to keep in mind. The way we keep most of, we call it nonvolatile memory, every time the device reboot, it's going to forget about everything that was stored in RAM so we need to have somewhere in nonvolatile to store these things. We have a file system on the device that we can create files with different device configurations, algorithm, settings, Wi-Fi credentials, that sort of stuff.
CHARLES: That file system, is that anything that we would even be familiar with like ZFS or is it just a custom file system that you've written or that you found on GitHub.
JOHN: No, fortunately this is just a standard FAT file system. We do have some creature comforts there but that's not necessarily the norm.
CHARLES: You heard it here. Is that FAT16?
JOHN: No, it's FAT32.
CHARLES: FAT32, described as creature comfort.
JOHN: Yeah, we have a different perspective of creature comfort.
CHARLES: There's a couple of things because immediately, what this brings to mind is for people who are familiar with Ruby on Rails, they have this concept of migrations, where you're migrating the schema of your database and as you have to transform the data from one format to the other, you're running these migrations. One of the things that's nice about that is if, let's say I have some system that is at Version 1, but let's say, I have one of the devices that hasn't taken an update, it starts at Version 1 and it needs to go to like Version 100. But you could have 10 format changes in between there. Is there a way to handle that case where you're basically incrementally applying a bunch of transforms?
JOHN: Yes. That's another great point. We take this on a case-by-case basis. Fortunately, being a small relatively simple system, there's not a whole lot of state data to keep track of. But to handle that situation, we've written are own OTA server-side software that manages the devices sending updates --
CHARLES: Acronym alert, OTA?
JOHN: I'm sorry, yeah. Another acronym, OTA -- over the air updates. That's our slang for remotely sending firmware updates.
CHARLES: Sorry to interrupt. It's just we have to unpack acronyms.
JOHN: No, I'm sorry. I use a lot of jargons here.
CHARLES: You know what? The thing is, so do I and I just never even notice it.
JOHN: To handle that scenario, the way we handle it, our cloud knows what devices are out there and what firmware updates we've sent out to it. Furthermore, when the device checks in with the cloud and ask, "Do I have an update available?" It also tells the cloud, "By the way, I'm running Version 1.0." The cloud knows, if it's on Version 1.0, there's going to be some incremental changes that need to be made before we get to that last update and we can apply those changes incrementally.
CHARLES: I see. I feel like we've touched on so many of these concepts that are universal to development but only projected into the hardware space. We've talked about dynamic allocation of memory and data migrations and it sounds like what you're describing in a way with OTAs is continuous delivery, where you have some way of automatically pushing out an update and all the stuff that's involved in that. It's just really cool to hear to view through such a vastly different lens than what we're used to.
ELRICK: We've been talking a lot about communication between devices and back to the cloud in things of that nature. Does that play into the conversation around decentralization of IoT infrastructure and what does decentralization of IoT even mean?
JOHN: Decentralization as a new methodology or ideology that a lot of people are adopting, I shouldn't say new. It's been around forever but the idea is from a high level, looking at the internet, most of the internet is access through some central, server is hosted on you name it -- XYZ cloud hosting provider. The way you do your URL DNS resolution that goes through centralized DNS servers that say, "You want to look at Netflix?" Netflix is stored over here on this AWS server farm.
Decentralization, the idea is we don't necessarily need to talk to this DNS server and talk to AWS just to get content from specific providers. If you look at IoT for example, a lot of times in our case, we want to tap three times on the table and then later on, it will do the cloud, send the message and then turn on your Philips Hue light bulb in the living room. It would be great if the message could just go directly from Knocki to the Philips Hue light bulb, rather than going to our cloud, on some centralized hosting provider, then to Philip Hue's cloud, on their provider then out to the Philips Hue light bulb. Those are some of the really popular technologies that's a lot of people are talking about that really take advantage of the concept of decentralization. But it does --
CHARLES: Let me understand because why these would be necessary. When I get why it's compelling, if I want to have my Knocki talking directly to my Philips Hue light bulb without getting your servers involved, without getting Hue's servers involved, it seems like it's going to be a lot faster and just a lot more robust. There's just less links in the chain but it presents its own problems, like on both ends of the conversation between the Knocki and the Philips Hue, how do they agree that this is sanctioned by a user? That’s just leaps out. That's a hard problem to solve.
ELRICK: That you use some sort of like public-private key type of encryption to say, "It's me. Am I allowed to do this?"
CHARLES: How do you decentralize that?
JOHN: Well, I'd like to preface this by saying I'm not an expert on that particular subject but the goal is, if you're familiar with the bit torrent protocol and how it keeps track of a lot of different peers on a network using distributed hash tables, the idea is if you know at least one other person on the network, that person can say, "There's some other people that you may be interested in talking to, that may actually want your message. I'm just a bystander on the network and I don't really need your message but this guy is interested in it."
In our application, that would be our server. We have to ask our server, who's out there that wants to hear what I have to say. The server is going to say, "Knocki 123, this Phillips Hue is over here at this address, this unique resource identifier, he's going to be very interested when you have two taps or three taps on the desk so just go ahead and talk directly to him. You don't need to talk to me." There's a lot more of that goes into that about making sure that the network can heal itself if somebody goes offline. But as I said I'm not really an expert in that subject.
CHARLES: Right, but it really is compelling. Would you then, maybe have some device that was just kind of your coordinator in your home or multiple devices that would act as these bit torrent trackers?
JOHN: Yeah, I think --
CHARLES: Or would the devices themselves actually be able to do that, like the Knocki could actually participate in the conversation about what other devices there were in the home.
JOHN: Exactly, yeah. I think in a true peer-to-peer network, any peer can talk to another peer and eventually learn where the other node that they want to talk to is. You don't have to talk to any one particular person but you can ask anybody and they can tell you how to talk to the person you're looking for. The really big advantage to decentralization in my opinion is security. A lot of times if everything is controlled through one central point, that's one central point of failure. If someone DDOS's your cloud service, then now your entire network of devices is offline, just because one location got attacked. If it's a decentralized network, there's no one central point of failure and it's very, very difficult for someone to attack your network.
CHARLES: Right, that's true but the tradeoff then is complexity that your decentralize network has to agree, somehow come to some consensus. It's very easy to generate with consensus when you have one process or one point that's driving everything.
JOHN: Exactly. Another big tradeoff is ownership of the data and enterprise today are really big revenue your point for a company is being able to have ownership of data and extract meaningful insights. But if your device doesn't talk to your central server every time I want to do something, how does your server know everything that your device is doing and you lose a lot of that data. There's a tradeoff there in how you're going to get the data you need to run your business but also let your device run autonomously on decentralized network.
ELRICK: Do you think that this is going to be helpful or harmful to IoT? What’s your views on decentralization?
JOHN: I think it could be very powerful. Right now, I'm not aware of any products that are really using a decentralized architecture for IoT and the main reason for that is companies and developers are a little slow to adopt it because they want to have that ownership of every data packet that goes to the network. They own it. They can see it. But I think in the future, people will start to realize that they can still get the data that they need to run this business. They can still have visibility and control over the network the way they need to run their business without controlling every single packet. When that happens, I think it's going to be a revolution for the internet as a whole but it's really going to revolutionize IoT and devices will get lower power. They'll get faster and they'll get more secure.
CHARLES: When you say being able to get the data that they need, is it just being able to asynchronously spool off the data later? I guess I'm trying to understand how they get the data if it's never talking to some central servers? Or is it just you will get the data at the time you want it or there will be some delay? I assume you can also have your server being part of... I don't know. I'm just curious how you see that playing out.
JOHN: I think, every developer is going to have to tackle that on a case-by-case scenario but take for example a big brand smart thermostat company. They have a device that's going to control your AC heating and air and the house and it also collects a lot of the data from when you're home and when you're using it to be smart and adjust the temperature at certain times of day even when you're not home. Again, I don't work for any company that does that and I don't know how they're doing their devices under the hood but traditionally, they tap to a centralized server and they send a lot of this information whenever it's happening, always to the server.
Every time the user adjust the temperature, it sends an update to the server and says, "The user just updated." In a decentralized network, these devices can just talk to themselves and say maybe periodically or every day and it'll just send one update and say, "The user adjusted it." You can still talk to a central server but it doesn't have to rely on the central server.
CHARLES: Right. It's just what we call, an out of band process.
JOHN: Exactly, not mission critical.
CHARLES: Okay, I got it. Talking about the decentralization and interacting with other devices, how do you manage the ecosystem right now with Knocki? It's a general purpose interface to rise. It serves really the role of a keyboard or a mouse or some way of controlling other devices and other systems. I assume that in order to do that, you have to understand the capabilities of those systems or maybe you don't. How do you integrate these two devices? Let’s go with the thermostat and the Knocki or maybe one that you're more familiar with that you've done. Do you all have to write the integration? Can a third party write the integration? Or is there some way to automatically discover and map the existing inputs of the device. I feel like we've got all these new devices are coming out day to day then and now, there's more and more permutations in which to confine these devices into a coherent system and I'm just curious to hear about that integration story from your perspective.
JOHN: Certainly. If we want to configure our Knocki to tap three times and turn on our Philips Hue light bulbs -- I keep using Philips Hue just because that's what I've been actively working on lately. We currently rewrite the integrations in our own backend so the user pulls up the mobile app and says, "Knocki on my desk, every time I tap three times, listen to this Philips Hue," and then we have an integration where in the mobile app, they can essentially set a lot of the parameters that a Philips Hue light would use based on API that Philips Hue would provide us. That's the way most integrations are going to happen with third party products. They expose an API and we can write a little module and the user can configure that API.
CHARLES: I see and as far as making affordances for third party people, if they want to change the behavior or add like intelligence, obviously they can configure it from the app but if I want to say add behaviors or something like that.
JOHN: When you say add behaviors, you mean add new --
CHARLES: I mean like, rather than turning the lights on and off, say I want to strobe the lights or flash the lights, maybe I'm someone who's running a theater or something and during intermission, I want to knock three times to flash the overhead lights. I don't know if that's something that your integration with Hue could do but if I want to be able to add that.
JOHN: Okay, I see your question. We try to enable as much of the products functionality as possible through our own integration on our mobile app but say, you're a hacker and you've come up with your own smart light that turns on any sort of party mode and flashes different colors whenever you want and your Philips Hue or any other smart light just can't quite do what you wanted to do. In the future, our goal is to have an open API that people can access and they can hopefully control their own homemade IoT devices.
CHARLES: Now, what about for existing ones. You can definitely flash the lights with the Philip Hue but you're going have to have some custom software to do it, right? Do you see what I mean? You have to send a series of messages to it in sequence.
JOHN: In that scenario, we currently don't support that and don't have a plan to support that. In our research, that's a really small use case of people that would be interested in that. Also, it's difficult now if we wanted to do some sort repeated command, you knock three times and then every 30 seconds, it's going to send a command in your light bulbs. We have to be careful about having processes that run away and you have a bunch of CPU power forever in the cloud. We may include features like that in the future. I think the most likely path for that sort of stuff is we'll have an open API that people can direct Knocki's inputs to their own server and then their own server can flash their Philips Hue lights as much as they want.
ELRICK: Is there any standardization between the communication and what these API supposed to look, like the communication between devices? anyone can have an API, expecting one thing and someone that's writing software to communicate with that, wouldn't have to go look it up. Do you know of any standardization?
JOHN: Yes. I know there have been a couple of companies out there trying to put a standard on the market and I think a standard would be a great idea.
ELRICK: Yeah, I think so too.
JOHN: It would be wonderful if we could just write generic control structures or information flow structures and anybody can hook their stuff up to it. As far as I know, I haven't seen any that really fit the bill.
CHARLES: It feel like there's something that programming systems like software developers have been chasing for a long time is to have some distributed set of peers that they can look each other up. You can discover the capabilities of a thing without ever having to even know about in the first place. But I haven't really known that worked really well and hit that sweet spot. I'm thinking of DCOM and Java. There's like Java distributed beans or something like that. You have this idea of these objects in the cloud, which seems kind of analogous to what we're talking about now, except we're talking about actual devices, rather the software devices but who knows. Maybe it'll pan out where we'll have some standard for discovery and integration.
JOHN: It's interesting that there hasn't been one already. You look at IoT and it's really ripe for standardization because a lot of the communication between devices takes the same format. You’re generally just passing a small message saying, on or off or, "I read this temperature at 75 degrees. Who knows, maybe someone will solve it.
CHARLES: Yeah, maybe so. Maybe the folks at Kasita. They're active integrators. They were on the podcast two episodes ago and one of their challenges was getting all these 30 things to talk together well. Maybe we can follow up with them and if they could have a standard, what they would like it to look like?
JOHN: If they get on that, I would love to hear what they were working on.
CHARLES: I think, maybe they mostly, have a wish list. It is like, "I wish it did this. I wish it did this. I wish it did this."
ELRICK: Maybe we need to have like a 10-way podcast. It's like IoT companies and we can hash it out like the TC39 of IoT on the Frontside Podcast.
CHARLES: Right, and then everybody punches each other. All right, well thank you so much, John for coming and talking with us. It's always fascinating. You can find Knocki at @Knocki on Twitter and Knocki.com. It's a great product and like I said, always a fascinating conversation so thank you so much for coming on the show.
JOHN: Yeah, thank you very much for having me. It was a great conversation.
CHARLES: With that, we'll say goodbye. Thank you, Elrick.
ELRICK: Thank you.
CHARLES: We are, as always, the Frontside at @TheFrontside on Twitter, Frontside.io on the web or just drop us a line over email, [email protected]. Thanks everybody.
From the publisher's feed