David Khourshid

Making Application Logic Visually Collaborative (Infobip Shift)

Conference talk at Infobip Shift 2021. 27:18 long, 651 views on YouTube. Topics: visual modeling, statecharts, state machines, xstate, event-driven architecture.

Watch on YouTube (Shift Conference)

What is this talk about?

Logic is much more than just code. It is the user flows, the diagrams, the user stories, and the business logic that are shared with developers, designers, project managers, and other stakeholders. In this talk, we'll explore tools and techniques for unlocking application logic and making it acce (From the video description.)

“We do this via code, and so the computer reads that code, and that code is supposed to represent the application logic that we want.”

“We have portable application logic, we have visual application logic, and we have executable application logic that we could use pretty much anywhere.”

From the opening of the talk.

Key takeaways

  1. We do this via code, and so the computer reads that code, and that code is supposed to represent the application logic that we want. 2:00
  2. We have portable application logic, we have visual application logic, and we have executable application logic that we could use pretty much anywhere. 8:00
  3. Instead of just having your application logic live in your code within your team, you could share it and you could visualize it. 23:00
  4. Anyway, diagrams are extremely useful for you to understand your application logic and your business logic at a glance, but ultimately, we do want diagrams extracted from code. 25:00

Quoted from the transcript.

Full transcript

From YouTube auto-captions. Punctuation and capitals were restored automatically. Technical terms were normalized; some errors remain. 4,548 words.

0:00 Introduction

[Applause] all right, so let me get this set up first. Hold on, don't look at my password, trying again. All right, can you all see my screen? All right, good, I'm. I'm tired of saying that too. So ask 10 developers how their application works, what is its functions, how can it break? What can people do with it? And you're going to get 15 different answers. This is one of the biggest problems that I have been talking about for the last few years, and it's one of the biggest problems that I desperately want to solve. So today's talk is about making application logic both visual and collaborative. So my name is David Khourshid, I'm on Twitter at David K. Piano. The piano stands for the instrument I play, which is not relevant at all to me. As a developer, and I work at Stately I, I found it Stately. It's a startup, I also work there too. So, yeah, you might have heard that code is read a lot more than it is written, so plan accordingly now.

At first, when I read this quote, I took it as sort of a mandate, as a okay, so my code. I'm going to write it in 10 minutes, but it's going to be red, so make it really nice. With comments and type declarations and all sorts of stuff like that, but it's not a mandate. Code is read much more than it's written, because that's what the reality is. We're writing code and there is a disconnect between how we express our application logic and how it actually is manifest in the code. And this is a huge problem that, you know again, I wants to solve. And so the way we could think about it is like this. We talk about application logic at first, in very human terms. So we're going back and forth between our co-workers, designers, project managers. Saying like, this is how the app is supposed to work. And then when it comes to actually implementing it, we have to create some sort of way of providing that logic to the computer.

And so we do this via code, and so the computer reads that code, and that code is supposed to represent the application logic that we want. But notice how far apart these two things are both. Human and computer. So when you're actually trying to show, I mean, have you ever tried to show a designer or a project manager the code? In order to be like, Hey, this is how my application works? There's absolutely no understanding there, and there's a huge disconnect. Also, I think C plus is like, very close to the computer side of things. But ultimately, my dream is that we have both human and computer together, that there is no disconnect. That the exact same logic that we're writing is also expressible by the computer. Is that glitching? Awesome? So we would call that an impossible state that should never happen. Yeah, hold on.

Wow, all right. So please, if you're epileptic, you know, you could leave, um. But how do we bridge the gap between, the ideas and code? This is really weird. So, the first thing we do is we remove the code parts. And um. By doing that, we instead formalize our ideas so that our ideas become executable. And we're getting someone to fix that. Thank you, you're saying. And so, by doing that, we no longer have to bridge a gap between our ideas and our code. But instead, we just have to figure out the problem of how do we communicate these formalized ideas?

Play from 0:00

4:00 The cashier would tell the barista to make an order…

And so the way we do that is by creating diagrams, which a lot of you are used to doing. But we do know that diagrams are never completely in line with the actual application code. And as soon as we change the application code, the diagrams that we created are completely out of sync. All right, so how do we make accurate diagrams? Well, there's two building blocks first is events describing everything that could happen in a system, and the second is behaviors, also known as states. Which is, how should the system React when different events are sent to it? You know, uh? And these could be expressed as modes, statuses and other things. And so these events and behaviors together describe the overall behavior of a part of, part of your application. And so you have many of these parts of your application talking to each other too, which I'll get into in a bit. But, we also describe these not only as diagrams, but also as text.

So when? We're talking to a project manager or designer about how certain things should work in the application. We, we typically have user stories. Where, you know, given a precondition, when an action happens, then some post condition, should occur, you know, given when, then behavioral development, all of the stuff that you're used to. So, for example, given the pandemic, when the government says it's okay, then we can have an in-person conference. And apparently they forgot to write a user story for the Delta variants, but we'll just push that aside. So how can we express these user stories in a more cohesive way, in a visual way? Well, you might be used to, user flows and flowcharts as a way of describing these things. Designers love these, developers use these to understand. Okay, if I'm in this app screen and the user does this now, I should be in this other app screen too.

And so user flows and flow charts aren't just for design. We could also use them to describe just how a system should behave, even if it's not completely visual, for example. There's also sequence diagrams, too, and these are extremely useful in not only describing the behavior of a single thing, but the behavior of multiple things together. For example, if we're ordering a coffee, we would ask the cashier, Hey, I would like a coffee, please? The cashier would tell the barista to make an order, and then the cashier would at the same time request money. Don't take euro here, I think you take krona, maybe you do take euro, but I put euro here anyway. You would request money and then you would give money to the cashier, and the cashier would then give you a receipt. Then the barista will hand the coffee to the cashier, and the cashier will hand the coffee to the person who ordered it.

Now, this is all really understandable by, you know, humans. We don't need to know how to code to understand how these interactions work together.

Play from 4:00

7:00 I want to show you an example of why state machines…

All we have to do is follow the arrows and look at this individual way now. State machines and statecharts are another example of diagrams that are not only, you know, useful for people to look at and follow the arrows and understand what's going on, but also useful. For developers. And so I want to show you an example of why state machines and statecharts are so useful. You might have seen this before, this is a citizen watch, and if you have seen it before, then you might be a little bit older than me. Because apparently this was in the 1980s. But this diagram, sorry, this one, this diagram at the bottom is a statechart that dates back all the way to 1987. it. It was made by David Harel, who was the creator of statecharts, and it describes the inner mechanisms and workings of the statechart. Now notice, there's no code here. It's all pretty understandable if you zoom in. Like, obviously our alarm could be disabled, or it could be enabled, and depending what happens, the alarm goes back and forth between these disabled states.

And so, using that exact same statechart, let's insert the battery here, we could, play around with it. And again, if you know this watch, you'll understand the different behaviors of it and how it could work. But the amazing thing is that this diagram, which is more than 30 years old, this diagram, still works today. It could be used in the exact same way in this watch on the web. And so now we have portable application logic, we have visual application logic, and we have executable application logic that we could use pretty much anywhere. So I think that's really cool now. The formal term for this is called a visual formalism, which David Harel describes as a diagrammatic and intuitive, yet mathematically rigorous language. Now, visual formalisms are useful because they're exact descriptions of what can happen. They're not just some fancy illustrations showing like, Hey, this could sort of happen, go figure it out. From there, it's more like it is code, but it's visual code. Now, a lot of things on the web are moving towards, like a no code movements and the low code movements.

And I think that this is going to be extremely useful for developers. Which is why I think that using visual formalisms in our development process is actually going to be really useful. Not only for developers, but for communicating your logic with designers and project managers, and other people too, all right, so what is the current state of things? Right now, well, this sort of diagram, and this is not a formal visual formalism, it's just a random diagram. This shows the state of our code as we normally code it. And we do what's called a bottom-up approach, where we just insert code and we insert application logic where it occurs. So, for example, we could have it in event handlers, or we could have our logic just spread out in random callbacks, or we could just have ad hoc logic. Either in those event handlers. Or if you're using React and hooks, or just in random places throughout your application.

And so, in order to fully understand how all of the logic in your application works, you have to dig through all the code and figure out. Okay, this part goes with that, but when I click this, this is going to happen. Unless this is true, maybe I'll add a boolean in there and make sure that doesn't happen while that's happening, it gets really confusing now. Many years ago, we had Flux and Redux and all of these, different paradigms, where it became event oriented. And so all of our logic was consolidated into reducers. Now, a reducer allows us to take any event that comes in and change the states based on which events come in. And so this was really useful because now, instead of looking all over our applications to figure out, Okay, how does this work? We have a single place, we have our reducer, and we could have multiple reducers combined into one reducer, we could have local reducers on components, global reducers for the entire app.

But we knew exactly where to look for our logic. But the problem with that, if you could see over here, the, the application states, is still mixed. You know, we have blue, green, red. These are all just different concerns in our application, but it's still in one place. And we don't know. Unless we add lots of if statements and lots of booleans, we don't know like what's going to happen and when it should happen. And so enter the state machine. State machines make this a lot clearer because now we could separate concerns or behaviors into different, what are called finite states. Now, if you don't know what the finite state machine is, then. I have a million talks, on that. But the state machine is basically we could only be in one state, or the app could express one behavior at any given time. So we can't have, like, multiple states at the same time, much like in the conference, you can't have three talks at the same time.

But we're sort of violating that rule, that's okay. Statecharts make state machines a lot more organized, too, because now we have the ability to group states and have them be sub states. So that, depending on common behavior, things can react to the same events. So you could see, for example, these two states are both going to react to the same event if the event inside those states isn't handled. So, statecharts are just a different way, in a better way, in my opinion, of organizing state machines. To make them, visually clearer and less prone to bugs or logical faults. And then we have what's called the actor model, so whereas a state machine and the statechart describes the behavior of a single actor. We have multiple actors that are talking to each other through events. And again, we can use sequence diagrams to describe the behavior of these apps talking to each other. And so that's why I created XState in order to bring state machines, statecharts and the actor model to the web.

Now this, this talk, I don't want it to be exactly about X8. Because what's more important is the concepts and the idea of just visually communicating your application logic. But in this one, regardless of if you code or not, it's visually clear that you know, you could start in an idle state. And so when a search happens, now you're in the searching state. So what happens if you have a button that says search and the user just clicks, clicks it a bunch of times? Nothing's going to happen because in the searching state, that event's not handled at all. And so two things can happen that we could see, we could either resolve or we could reject. And each of those go into separate states. And so we could see from those, success and failure states that we could search again, and then we're going back to the searching state. And so, if you wanted. To add functionality or remove functionality, like, let's say that you're not allowed to search again.

Once you have a success, you could just delete that transition, and so it becomes really clear what all the features are in your application. You're literally just following the arrows. Now in code, it's represented like this, so that same search machine. So, for example, if we're in the searching state, you say on, and then you give it the event and you give it the next state. That it should be in a sort of JSON format. And so this is saying that when I'm in the searching state, on the resolve event, I'm going to go to the success date. And so now we move to the success finite state, and so on search, we go to the searching state. So, uh. X8 works very similar to a reducer, like a superpower reducer, because you have the machine.transition function, which takes you know your expected two arguments. You have the state and the event.

And it's going to return the next state, but, additionally, it's going to return actions and the events that happened and any actors that responded. A whole bunch of other things that are really useful, when you're working with complex application states, you could also interpret this machine. And so now this works sort of like in events emitter, or like an observable that you could send events to. And so this truly becomes framework agnostic. Just because it's using those same concepts of a reducer and an observable slash event emitter that could really be used anywhere. So I want to show you a demo of how exactly this works to make your application logic a lot more collaborative.

Play from 7:00

16:00 If I go through here and I click checkout securely…

So over here, I have a sample checkout app, hopefully you could see that. And, this represents like I, I copied the styles from the LeGo store because I love LeGo. And over here, you see, we have a Millennium Falcon, which I'm trying to buy. And so we could check out securely, you know, do a shipping address. And so this is just basically your typical wizard form, which Eric is going to talk about more tomorrow morning. So please don't miss that talk. But so here's the interesting thing about this checkout app that I. Made it's all created with a state machine. Now. I don't expect you to read all of the code over here, but just understand that. This code describes how this application works in all of the different states that it could be in. And you might also notice if I zoom in that. We also have descriptions over here, so I have a description for this event.

Enter the VIP code. I also have a description for the cart state, and, you know, just saying it's a shopping cart, I have a description for. What each of the buttons do, and this is just metadata in that object, so all of this logic describes this shopping cart. And so what we could do with that? Like, I know, this is all from code, so how do we go from code to a visual diagram? Well, there's something called XState inspect, where if you're using XState. It basically takes that machine and it turns it in to an actual visual state machine. And this is using the new Stately visualizer. And so we could see that we have a cart here, we have shipping contact with all of that metadata displayed right here in the you know, in the visual diagram. And also this supports markdown, so you could throw images in there if you want, or links, or, you know, bulleted lists, whatever you have.

And so you could show this to designers, you could show it to project managers and say, hey, this is how the application works. You know, we have cards, shipping, etc. And notice this big arrow over here too, we have this PayPal arrow. Because we're assuming that when we click PayPal, it's just going to take you straight to the payment screen. Because PayPal is already going to provide your shipping and your contact information. So if I go through here and I click checkout securely, we're in the shipping address state and so we see that it's over here. In the application too. So, you know, we could, I have to enter data for that. So if I click here, continue the contact information, you're going to see that the state gets changed. If I reload it, still have time. They're scaring me. Okay, so if I click checkout over here in the state machine, it's.

Also going to change the state over here as well. So it's a bi-directional visualizer. And so this is what I think of as the future of application development, as having dev tools that allow you to visualize this app logic as you're working on it. So, even if you change the code. But that's not the only thing that we could do. With visual diagrams, we could also know not just what happened, which is what the visualizer is showing, but we could actually show what will happen. So this is probably a whole other conference talk in its own. But because we have this directed graph over here, we could traverse all of the paths and figure out what are the best ways of getting all the way to the confirmation stage. And so remember that meta information, if I show the checkout steps over here, it's actually going to auto generate the steps over here based on that metadata. So it's saying on the shopping cart, click pay by PayPal, click agree the terms and conditions and then you will reach the order Confirm state.

Now what it's doing is it's finding the shortest path over here, and so that's why it said, all right. If we click the PayPal link, then we're going to find the shortest path there. But if instead I say, I want to find the shortest path to the confirmation state, where there is a shipping address. I say that it will regenerate those steps and say, okay, now you have to do all of these things in order to get to the order, confirmed states. And so we could take that even further, because this is React. We could pass in the state as a prop. And you could do this with Vue or Angular or anything else. But, in short, we could also auto-generate each of the different views for these steps, you know, at different times, so this is the first step. Second. I was not expecting applause for that, but thank you and all the way to the confirmation page.

And so all of that is possible because we're not just doing state management, with X8 and hopefully other libraries in the future, we're doing state orchestration. So the biggest difference between this is that state management gives you a nice, convenient container to put your. State in and to manipulate it, however you want, maybe use events to do it, but ultimately the logic is up to you. State orchestration takes a different approach, so it's not just events based, instead it's event and state based. And we're also managing basically other reducers, if you could think of it that way. So we're saying you should be active at this time unless this event happens. Now you're active and now you two are active. And you are responsible for this part of the app, and you are responsible for that part. That's what state orchestration is, and while you could do state orchestration with any state management tool, it's really a good luck.

Figure it out yourself type of scenario with state orchestration tools like XState. Now you could do this, you know, using X8 itself, and it provides you the ability to do that, so currently with XState. There's a lot of modules. If you're using React, View, Spelt, you could use XState with that. If you're using Angular, you'd be surprised to know that X8 just works with Angular, and there's a whole bunch of other utilities. For X day two and in the future we're going to be working on X84 and X8 Router, X, JQuery and a whole bunch of other utilities. To really take this idea of visualizing your application state and seeing how far we could take that directed graph that X8 creates of your application logic. And doing some really, really useful stuff and useful analytics based on that. So I really recommend you check out Stately..ai slash biz.

We just released this.

Play from 16:00

23:00 You have those diagrams to really help you understand the logic…

And if you, uh. If you use the old X8 visualizer, this is a complete upgrade because now we have a custom layout engine we have Monaco built in. You could do a whole lot more things with it, and also this visualizer works as an inspector as well. So this is something that our team has been working really hard on and I really recommend you check it out. We also have a registry. And so this is going to be another idea for the future, where we want application logic to be collaborative. So instead of just having your application logic live in your code within your team, you could share it and you could visualize it. And you could say, Hey, look, this is how my app is supposed to work. So we're basically taking the exact same code that you're using to code your application and creating these visual diagrams for it.

So that it doesn't just live in your developer's head. And you might be thinking, Okay, what good is that I'm a developer that only works with other developers? Well, one of the biggest benefits is that even if another developer is creating application logic, there is a good chance that you're not going to understand it. Remember the the quotes from the very beginning. Code is read much more often than it's written. Because even other developers, we take weeks to understand. When we're first onboarding into a code base, we take weeks to understand how that code base even works at all. And so this is a really difficult problem to solve. And so we're trying to bridge that gap, not only with developers and non-developers, but with all the developers in your team. And so in the future. We're also working on the Stately editor so that you, don't have to just, you know, code all of your state machines and code.

But you could also drag and drop and just create these connections between different states and do it in a visual way. So that, anyone can edit the application logic, not that's recommended. I mean, that should still be developers implementing user stories, but at least it makes it a lot easier for you to not only visualize, but to modify your app code. So, again, to recap everything, the current state of thing is that, things is that we represent all of our application logic in code. And so this makes it really hard to understand everything that's going on in our app. And so the solution to this, a lot of this we know. Documentation, keeping our docs up to date, diagrams, like just having that visual component, just makes your documentation so much easier. Because words don't tell the full picture, you might have heard a picture or photo tells a thousand words, or I probably got that quote wrong.

But anyway, diagrams are extremely useful for you to understand your application logic and your business logic at a glance, but ultimately, we do want diagrams extracted from code. So that we don't need to manually make those diagrams and manually write that documentation that quickly goes out of date. Instead, we should have executable diagrams where we're creating those diagrams, transforming it to code and going the other way around, too, taking your code and making it visualizable in diagrams. And so that's the future that I want. We don't just want to make your code work and be like, Okay, here it is, it works, all the unit tests pass, ship it to production. And then in the future, understanding that code becomes really difficult, so that becomes legacy code, and also the code is unsafe because we don't know exactly where it could break. So we also want to make our code always work, no matter what happens in our app.

But I also want to take that further. Make your code communicate, so again, make your code so that, even if it's read much more often than it's written. You have those diagrams to really help you understand the logic that is actually represented in your code that's running on production and in general, make your code do more so with that. Thank you so much Infobit shift for having me. I'm David and yeah [Applause].

Play from 23:00

Related talks