This talk was filmed at JS Monthly London (May event).
[00:00:10] Welcome, this is a talk called, “Learning how to ride” and it is an introduction to Cycle.js, which is a very nice framework. Show of hands, how many of you have heard about Cycle.js before? Okay, better than I expected. Nice, nice, nice. It’s a framework. It’s similar to, for example, frameworks like you would expect Angular or React or those kind of things, which I’m hoping you’re going to be familiar with. It’s different in many ways as well. We’re going to go over some of those differences. Brief index, introduction to how it looks, what the code looks like. Then because functional and Reactive programming are a huge part of Cycle.js, I’m going to spend a bulk of the presentation going over the Reactive concepts that you will meet in Cycle.js, especially a framework called, RxJS which is quite cool and it’s the building blocks of cycle. Then I’m going to go over the good, the bad, and the beautiful of Cycle.js. I’m not here to preach you to start using it and to leave all other things behind. I, myself, have been using React for quite a while now and I love it. I love this as well. It’s just giving you guys a taste of what it is and hopefully encouraging you to try it out because it’s quite cool.
[00:01:38] Introduction
What is it? What does it look like? Why should you care? In the words of the creator, Andre Staltz, Cycle.js is a functional and Reactive JavaScript framework for cleaner code. Cleaner code being the keyword there, it removes everything that you don’t need. Functional and Reactive, simple, concise, extensible. Very testable which is a good thing for those of you who want to do unit testing, which you all should be doing, by the way. Explicit data flows, so you can trace how the items are coming into the application and out of it. Composable, so you can build smaller components that then make up bigger components that then make up huge components. It’s pretty cool as well, that last one was mine, everything else came from the website.Brief expectation assessing, this is an introduction to Cycle.js; it’s learning how to ride. You can go and do that by yourselves. I wish I knew how to do that and I wish I could teach you, but for now we’re going to stick with the basics. To talk about Cycle.js is to talk about the interaction between humans and computers. The guy who created this framework likes to think a lot, likes to feel a bit philosophical about things. He talks about human computer interaction and how humans and computers communicate in a cycle and a human’s output, i.e. clicking on the mouse or something are the computer’s inputs. Then the computer’s outputs displaying something on the screen, playing a sound or something are the human’s input through the senses. He was thinking about this and he said, “I’m a programmer, so I can write this as a couple of functions; one called “computer” that takes inputs and returns outputs and another called “human” and the outputs of the computer function go into the human functions as inputs and vice versa.” This is quite cool but those of you who look at this for a minute can probably tell that we have a weird recurrence problem here. How can I call a function that needs another function that depends on the first function to run? That’s pretty much what Cycle.js solves.
Cycle.js takes this architecture of a cycle with sources that are inputs into the program, does magic with it, which is what you program, of course, and then it releases things which are the outputs that then get translated using drivers into DOM elements, into HTTP requests or other side effects. What can I do for you in a nutshell? Cycle.js is simply an architecture for building Reactive web applications. A set of ideas about how to structure an app using RxJS. It’s not something like React or jQuery or Angular that it gives you a huge toolset and it’s a massive library and it has ways of coding. It’s more about it’s a different way to think about your code and to structure it, and to help you out, it provides some very useful libraries, like I told you about the recurrence problem before. There is cycle/core which is something that you import via a node, which solves those problems, but it’s mostly a way of thinking about things.
Let’s have a look at that brief example. If you go to the side. It’s smaller than I wanted it to be. It’s this example, it’s a box where you can type anything and type “London” and it’s “hello London”, so it’s literally a “hello world” on steroids or something. That’s a cycle program behind it. I want you guys to see what the actual code looks like before I kick off. At the top, you’ve got your inputs, again, cycle/core is the main thing and then you also input all your DOM elements from the cycle.DOM driver. Then you’ve got a function called, “Main” that takes in sources and returns syncs and this is where all the magic happens. It’s a pure function, so given one input, one same input, it will always return the same output for that given input. That makes it very easy to test. Then at the very bottom, we’ve got the cycle.run function, which is the one that solves the recurrence problem. It just connects it to your actual app div in your HTML, in a similar way to what React does, for example. You write your code to render the DOM elements inside the main function, it’s similar to JSX in the way that it’s a virtual DOM, so it won’t actually write HTML code out to your HTML file, it will just pretend there exists an element there. Similar to React, it also does differences, so when something changes it doesn’t re-render everything, it just re-renders the parts that change, which makes it quite fast on performance and that kind of thing.
You take in an input as a stream, you map it, and then the variable that goes into your map then gets printed out below and that’s where the cycle happens. I’m going to go over this in more detail later, don’t worry if you don’t understand it fully now. I just wanted to show you how the code looks like before we start.
[00:07:31] Functional Programming
Now, functional programming, scary word for some, beautiful word for others. Who here has done some kind of functional programming before? Okay, great, great, great. For the benefits of those who haven’t done it before or who forgot it a little bit, I’m going to give a very quick example of what functional programming entails, because cycle is very, very functional. Imagine you’ve got a robot nanny, and you’re got your children, Andy, Blaine, Charles, a, b, c, I couldn’t think of anything else. You want the nanny to call them respectfully, Master Andy, Master Blaine, Master Charles. You want to do a program that will log a variable called, “Family” it will print it out. The not so functional way would be you saying, “Our friend, four loop” this is like a dumb robot nanny that needs to get told everything. It’s like the imperative programming paradigm. It’s like, “Okay, you’re a dumb robot, I need to explain how things work, how it works.” An array called, “Family bmt” then go ahead and count my children and take a counter in one of your hands and then put a mark every time you run through this and then for every child, as long as you still have children left in your counter, go again and Master through the beginning and add that to the file you created in the beginning.It works but you’re telling her how to do every single thing and the functional way is a smart robot. You trust that she will know how to do it if you just tell her what you need her to do. You do not specify how you’re going to go about counting it and reiterating over it, you just say, “I want call something family, you’re going to take my children, you’re going to map then and for each item in the children array, you’re just going to add Master to them.” This is the Cycle.js way, it’s the functional way. The benefits are that it’s way more readable. It’s less lines, again, makes your code concise but it’s also way easier for other people to understand it, to extend it, and part of the magic of it is that operators like map, you can chain them, you can chain many, many, many operators and that’s how the main function in Cycle.js works. If we go back to the example I showed you before, this is an observable, which we’re going to look into a bit later, you map it and the you say, “Start with an empty string” and you map it again. All of those operators are functional, so it’s easy to add another one in between, it’s easy to move them around without messing up your code, as if you had a four loop, for example. That’s quite cool. Plus, again, because we’re using pure functions, whenever you have the same input you’re going to get the same output. Not only is it extendable and easy to read, it’s also quite testable. Yes, happy robot.
[00:10:32] Reactive Programming
Now, the other big, big paradigm that Cycle.js depends on, even more so than functional programming is Reactive programming and Reactive programming is a term that has been floating around for a few years but it confuses people sometimes because take React.js, the big framework that Facebook creates that some of us know and love. That’s not really Reactive programming but it’s called React, so it may be a bit confusing. Reactive programming is something pretty cool and programming Reactively is the main idea, the main architecture behind Cycle.js. Let me give you an example because it’s easier to show than to just tell you about it. A non-Reactive way of building a button that prints a logo when you click on it is you have a function that prints “hello”, you have a button and the button has a clicky button that says print “hello”. Who does this? I do this a lot. I’m guessing many of you do this a lot. It works because printing hello is printing hello, but then what happens if you change the name of “print hello” to be “write hello”. Well, code breaks because you need to update your button because your button no longer knows what print hello is. Not only will it not print anything, it will throw an error and a grumpy cat as well. You can then change it back to “write hello” update it and it’s all fine again, but then what happens if a few months down the line your requirements change or something and you end up deleting the function. Again, not only will the button not pint hello because that may be the intent but it also breaks the code because it’s still there, it’s still part of the button. Grumpy cat, again.What’s the Reactive way of doing this? If we think about a Reactive approach to do this, we have the same button, pretty much the same function but the difference is that the button doesn’t really care about the function at all. There’s no unclick code, there’s nothing. It doesn’t need to know. It’s only concerned with the view with rendering how the button looks like and what, according to Cycle.js, that’s exactly how a program should be. Things that are concerned with the view should not be concerned with anything else because regardless of what you do up here, it’s still going to work. Then on the function we’re got an event listener, which says, “I’m going to stay there listening to this particular button and whenever someone clicks on that button, I’m listening and I know and when I see that, then I’m going to do some magic and print “hello”. If I were to change the name of this to “write hello” “print hello” “write hello” nothing happens, no grumpy cats because the button doesn’t know about this. It still works as long as you call it.
Again, if I get rid of the function, yes, it won’t print anything, of course, but it doesn’t break the code because the button is separate from the function. That’s the main idea behind Reactive programming. It’s making your functions React to events that they’re listening into, rather than making your buttons and you HTTP requests and all other parts of the application call your functions.
[00:14:00] More
You might have seen my roads at event listener, which is like an easy JavaScript way of doing things but it’s not the best way of listening to events. Cycle.js uses a very cool library called, “RxJS” to listen to events. RxJS is – have you guys heard of RxJS before? Okay, I see a few nods but mostly confused faces. Basically, a group of very, very smart people got together one day and said, “Hey, we need to make programming languages more Reactive” because there are many programming languages out there but not many of them address the Reactive programming elements as well as they should. They got together, they created a library for composing asynchronous and event based programs using observable sequences. Asynchronous, big scary word, so it means just running different things at the same time, which the experience, if you may know, it’s hell because you know one thing may depend on another thing and if it hasn’t finished then it may throw an error or do something weird with your code. They create observables, right, which we’re going to go into more detail in a minute but observable is just like a stream of events and each asynchronous stream is an observable, so you listen to them.Again, RxJS is just like one of many Rx libraries for many other exciting languages like Scale and Python and other slightly more questionable languages like Java and C++ but yes, it’s something very cool for dealing with asynchronicity. Again, observables are the core of RxJS and it’s also the building blocks of Cycle.js. everything in Cycle.js is an observable. You think about things as observables because observables are things you can listen to and React. Again, they’re less even streams, which can emit one or more event and may or may not finish. If we draw a line through time, I just drew green bubbles as events and that stream of various events at different points in time, that’s an observable. Why even bother with this? Well, the main reason is there are simple and very nice operations like we saw before, like maps, like reduce functions, like the sort of things you guys are familiar with, program with. Functioning and programming would do with Rx, for example, with objects or with other collections. Well, RxJS lets you use those operations with the streams, which is quite cool.
Again, I’m going to give you an example, let’s say you’ve got a program and this is literally a real Cycle.js mark-up. You’ve got a check box, a blue checkbox that says, “Off” and when you click on it, it’s going to say, “On”, it’s a light switch. Yay! If you go about programming this in Cycle.js, you would start by thinking, “Okay, my checkbox is going to create a stream of checkbox events and every time a user clicks on it, it’s either going to throw a checked or unchecked event.” That’s this, it’s sources.DOM is one of the helper things that Cycle.js gives you. It’s just a way of targeting DOM elements. I’m going to select inputs, which have a change events. Whenever any input changes, it’s going to come into this here observable. Then I’m going to run operations with it to create my program. Let’s dissect this a bit more. Again, the stream is empty to begin with because nobody has clicked on anything before because the program doesn’t even exist yet. The program says, “I’m going to listen to inputs who change. Then I’m going to map that because I only care about events that are checkboxes, right? I’m going to map each of these events and I’m going to return whether the target is checked or not, because I only care about whether it’s checked or not. I want to see a true or false, I don’t care about the position of the checkbox in the page or anything else.”
Then I’m going to say, “I’m going to start with false” because if we don’t give it an initial value, it’s not going to render anything. Then I’m going to map, again, those events that are either true or false, I’m going to pass them in as toggle, that’s the variable name I choose to use. I’m going to render a div that has the inputs of typed checkbox and a paragraph that’s either toggled or not, because it begins with false, it’s not toggled, it will display off. Then user comes in, clicks on the checkbox, what happens? Well, an event comes into your stream, you listen to it and the map runs. It’s like waiting to run patiently and when it sees an event come in, it runs. It’s checked, it’s true now, so it displays on. Another one comes in and it’s off now, it turns off and so on. It’s a program that’s just there actively listening to events and when they come, it Reacts and prints out DOM elements.
That’s the basics of it, it’s all about dissecting your program, dissecting your requirements and saying, “Hey, how can I think of all of this as events? What can I observe? I’m going to observe the checkbox. I’m going to observe a HTTP request; I’m going to observe user inputs.” Then it’s just about knowing which operations to run with it and that’s pretty much the basics of this. Now, if we have a look at this, which is what actually renders the thing, guess what? For those of you who know React, it works with JSX as well. It’s cool. I’m very familiar with JSX because I’ve been working with it for months, so I’m quite familiar with that syntax. That creator decided to go for this as default because JSX adds unneeded tags that look like HTML and stuff and he said, “No, let’s just get rid of that and make it a bit simpler.” Yes, you’re one NPM install away from being able to use JSX. It’s quite cool as well.
Going back to what I said at the beginning, Cycle.js is simply an architecture for building apps. It’s a set of ideas about how you should structure them using RxJS. Again, the guy who invented it said, “I really want to program functionally and Reactively but I’m running into too many troubles, so I’m going to create a framework that addresses that” and that’s pretty much it. Again, the simplicity of it is you say, “What can I observe? What do I need to see happen in my DOM or by the user or from the backend to React to?” Once you get your list of observables, it’s just about chaining two or three, maybe four operations to them and the magic happens. All those operations were, again, created by the RxJS folk and they’re quite powerful. Average Cycle.js function will probably only need two, three, maybe four operations chained together, rather than having a massive list of hundreds of four loops and if conditions and stuff like that, so it makes it quite simple in the end.
[00:21:41] The good, the bad, and the beautiful
Let’s now move into the good, the bad, and the beautiful of using Cycle.js, in my opinion, of course. Let’s start with the good, positive note. It’s very easily testable, as I’ve said before, it’s pure functions so there’s nothing that you can test more easily than a pure function. I’ve literally, literally broken my head so many times before in my projects trying to test a React component where I’m trying to mock it, render it into the virtual DOM and then see if I can mock a click event and observe for a class name changer something. Here it’s just so pure function, if I put this in, I expect to get this out. Does it work or does it not work? For those of you who like to do test driven development. It’s very lightweight, again, because it’s more of a set of ideas rather that a huge library. Cycle/core, which is the one that gets rid of the little circularity problem. That’s pretty much the only thing you need other than the drivers. Cycle/core is about 100 lines long. If you compare that with massive libraries like perhaps React, Angular, or even jQuery and those things of the past, it’s cutting down your load time. When a user loads the page, it’s going to be way faster and also when they click on something, because it doesn’t need to go through a massive library, it all just functions a bit better. It’s also way less intrusive than having to deal with a completely different system or set of functions that come from the library because you’re not inheriting much. You can still write pretty much vanilla JS but just hype it up to the next level.It’s compostable, which is a word that my software wasn’t really happy about. It gave me a red squiggly line but it basically means you can create components out of it. Everything in Cycle.js is a component, even your who app is a component. You can put your whole app inside a bigger app and it will work. Again, it’s all pure functions, it’s all pure functions so you can nest them together, you can nest many components inside a bigger one and then if you want to create a page where you want to display all of your app, you can do it as well. It’s quite cool. It keeps your code short as well, you want your components to be small. You don’t want a file that’s going to be over 200 lines of code or anything, you want to keep many separate components to make it sensible. Something I didn’t really have the time to go over today but it’s worth a look is the recommended architecture for Cycle.js is called, “MVI” it’s similar to MVC, for those of you who know MVC from object oriented programming. It’s just called, “Model viewing tense” and it’s just a very nice way that’s very simple to use in Cycle.js or separating your view concerns, your model concerns and your intents. Each of those will be a set of pure functions, again, that are very easy to think about, very easy to understand and very easy to put together into an application.
What am I not telling you? What haven’t I told you? The bad things. I don’t really see them as uber bad things about Cycle.js, it’s more like drawbacks, it’s more like paradigm shift for example. You need to think about programs Reactively. Probably the most difficult thing to adopt Cycle.js, there are no funky syntax you need to learn or anything, it’s just about rewiring your brain to think of things Reactively, think about observables rather than trying to put a function inside a button that we all do sometimes. Obviously, it’s a different architecture, it’s not really a drawback of Cycle.js but it’s definitely a corridor you need to jump before you start with it. There’s a smallish community. When you compare it with the likes of React and Angular, it’s obviously going to be way smaller than that. pretty much all respectable JavaScript people today, I think, have at least heard or React and Angular and they haven’t heard of Cycle.js, not all of them. Again, let’s make it bigger. The only way the community is going to grow, the only way we’re going to address this drawback is by actively making the community bigger. It’s worth saying as well, even though it is not a huge community, it is a very active one. I’m going to tell you about this bit later as well.
Again, it’s not a huge name, there may not yet be a lot of tailored NPM installed packages, for example. There are quite a few and there are enough to get you started but you won’t find the same number as you would for a larger library. Again, as a community gets bigger, as people like you guys start hearing about it, start using it, it’s all going to get bigger. It’s like a cycle, really. The bigger the community gets, the better the situation gets, so the bigger the community gets, again. Just to finish off with a few beautiful points. That code you write, it’s quite sexy, it’s clean, it’s succinct. Again, the aim is for you to not write any unnecessary words whatsoever. It’s quite cool. Again, smaller pages, shorter load times, more performance for applications. It’s pretty powerful. Yes, that’s pretty much it.
No comments:
Post a Comment