03 Creating a simple 'flow-based programming' feature
5:13AM Nov 21, 2019
flow based programming
Yeah. Hey, how you doing?
Yeah. So I'm Nate, thank you for the introduction. Thanks for coming out. Thanks for having me.
Flow based programming
is what I wanted to talk to you guys about today. This is sort of a technique that we use at conductor x, to enable people to sort of, in a way, customize our product, or use it in novel ways.
And I think that it might be interesting for at least some of you.
If you are going to sit, you can use this one. Thay way you won't have to hold the mic.
Okay, all right. Thanks. Thank you.
Yeah, go on.
What do you use to have that kind of the drag and drop stuff? Is that all Canvas based or is it like some cool DOM manipulation,
There's a syntax error.
Oh, very, very, very, very possible that there is yeah
Yeah, no, that's sharp wherever you found you probably some comma or something like Oh, yeah, yeah, I took a screenshot of the actual thing in memory. But yeah, no, you're right. That would not parse as as JSON.
But you get the, we do get the idea. Okay, good.
let me just show you real quick on the code how this actually works.
So I always
get confused. How do I get?
Yeah, no, but I guess
I have to escape out of here. I never know how to do this. Okay,
let's just start with a simplified version of it. So I've got four versions which I'm going to whip through Really fast, hopefully. So let's just start with a really, really simple list of tasks. There's no hierarchy yet. So as you can see, here's my array. These are legit, I think. And so I've got three items. Two of them are I've typed text, and one of them is a type image. Over here, this is my code that actually runs. So this is just JSON that can be stored wherever you want. And this is of course legal to run. Like, this framework can be used in node or can be used in the browser or wherever. So here are my handler function. So up here, I just create a create an object. There's various ways you can do this. And later on, one of the later version of this uses a class that encapsulates this stuff, but if you just want to get down and dirty, you can just create a set of you know, a hammer object in there create however many functions you need. So here's one called text and that's going to execute when we encounter our notes. With type text, here's one called image. And that's going to be executed if we encounter a note with type image. And then we've got this is our main function. So we just take a list of tasks and array of task, we iterate over them, we grab our handler function by just so each time we go through this, it's one of these notes. So that means that Task Type is text or image. Therefore, it's easy to grab the appropriate handler out of the object. And it's easy to execute the function using apply. Because we're using apply inside of the function, you can refer to this and this will be the object that you're processing. Okay? Does that make sense? So really, really simple. So that means that all you have to do is load that JSON. And remember, I'm not this is just like boilerplate code. Wherever you get the JSON from promise of no importance. You load the JSON here. It's just in a browser. And then you perform the tasks. And that's it. So here's my little demo. And I can reload the page and see that and then like, if I wanted to prove to you guys that it works, we could put some exclamation points here or something like that. And then you see them there. Right? So what I like well, now let's look at the next version of it. So the next version of it is where we implement the hierarchy. So here's basically here's the stuff that we already had earlier.
And as you can see, I've added a few additional
handler functions. Like I've added a few new types to my to the stuff that I'm supporting in our document. Something called check URL program. This is just as an example. Something called pick one and a couple other ones, this one called log just to login message in the JS console. So let's look over here. So the idea conceptually is that when we, when we iterate through, the first thing we're going to is we're going to check a URL parameter. And if the see ID URL parameters equal to 123, then we're going to keep going. If not, we just stop, then we get here, we're going to pick one of our two children. And whichever one we pick, we're going to iterate into that one. And then if we pick the other end, then we just ignore the other one. So that makes sense. So all we had to do to get our thing to walk and recurs is add these lines, right? So this was my function before was it was this but with an All I did was add this little bit, and anybody who's done recursion, I mean, it's pretty simple, right? So no big deal. So now we have something that will inter happily iterate through any document that we want. No problem. I don't know if you guys are interested at all. And like, I think, I think that it's probably pretty obvious to you like how this thing works. It's probably obvious to you how this thing works. So the only the only thing that's of interest here is that both of these the check URL program and pick one, this is sort of like a quick and dirty way to.
Can you biggerize the font a little bit.
Perfect. You got it.
We say we conduct excuses that we say enbiggen. But yeah, yeah.
Yeah. So is that big enough to make a difference?
So is this running running as a middleware. Or is it a script you're stacking onto an existing page.
Yeah. So in a way, I'm trying to keep it abstract. But But yes, what I'm. So let me just let me just show you just to clarify. What I did is
down here at the bottom of the page.
So this is just a normal, ordinary boilerplate page. And all I did was I embedded
offer this to any site, because he essentially stuck it in.
Yeah. So I'm only focusing on the mechanics of This like flow based programming thing at the moment. But yeah, there's a lot more to building one of these things like if you're actually going to use this for a B testing, one, you could use our product but, but if you could use this to roll your own, but yeah, you're gonna have to do a few things you're going to have to, for instance, I'm not addressing in here remembering which variation the person was selected for. So every time we're reloading, which makes for a good demo, every time we reload, we're getting a different selection, possibly. But in the real world, there's an expectation that that's going to stick. You have to deal with ICP and other stuff like that, that goes along with it. And then of course, you have to send some kind of feedback back to some kind of mothership of some kind. So you're counting the number of views, and then you're counting the number of conversion events. So there's a whole ton of other stuff that has to happen in order like actually turn this into an implemented a B test. But you can use this as the foundation for the for the logic that makes any sense
Does that make sense?
Right. So if I have an application, I'm to wait 500 hundred milliseconds to have the first paragraph is have all your configuration and then render something different for another period of so if you have a timeline expand and how this configuration gonna handle that timeline.
Yeah. So in a more complicated case like that, what you probably do is you would probably add some additional parameters to this, which would be you would probably, this is what we use what we do. For cases like this. We use the mutation observer API. If You're familiar with that. So what I didn't, I didn't, I should have put in an example like that. But kind of conceptually, instead of waiting for a number of milliseconds, you can wait for a selector to appear like an element that matches is selected to appear on the page.
I'm asking about chain. Timeline action need to happen. Action happen. Action happen. How this coniiguartion is going to chained..
I'm not sure I'm following
I asking for like a dependency of action
chain action? connection.
So like, you need something to happen after the wait, and then something happens
after that happened, after another wait?
Yeah, well, this will support it because you can keep nesting. So if you again, I only did, I should have arranged this slightly differently, it would probably make more sense. So you can always have with any within any of these things, you can have a tasks array. That's like a magic name tasks. Just In our code over here. And so under this thing, you could have a tasks array within this node, and its children won't get executed until this promise fulfills. And so you can chain like that. And you could keep branching. It's a good question. I probably should have illustrated it better in the example. But does that make sense? So like, these are like, kind of trivial examples that are waiting for a number of milliseconds. But yeah, if you wanted to, like, if you wanted to chain, all you would have to do is items. And this is not legit. But I could just like take this, and like, stick it here, conceptually, and then you can nest a nest nest, and the thing will eventually walk through everything, assuming that the conditions ever actually do materialize. Does that make sense?
so if you using our product, we do all this for you, you don't have to be worried about this stuff.
So if we need a custom handler, to add to your list,
we have to call you. So I'm serious
that our next slide.
The very next slide is, thank you for the intro.
But yeah, I think that one of the one of the really nice things about this pattern is that you can also use it to,
oh, this is actually a mistake, this should be this dot ms. But you get the idea.
so the demo for that is like super painful.
Because it's horrible.
Right, and so if I get selected for a, I'm blinking these things up here, and if I get selected for be, right, I go through that same sequence and I blink these things down here. Yeah, right. But you know, the point is right, you're actually doing something fairly powerful here. for our customers. What this means is that we can ship all the ordinary AV test stuff that you would expect. But if they need to integrate a custom library or something like that, where it's like very common that we're going to AB test whether or not showing a survey, decreases our conversions, that kind of thing. Very, very simple and trivial for people to be able to incorporate, and like using that drag and drop editor thing to be able to incorporate custom functionality. And it gives you a good separation of concerns as well. So
I skipped over just a couple of points, basically done.
And so I started with this one example.
And I just adapted it to our needs. But it was really pretty straightforward. And then like I said, in conductor, it's our product. And this is just interesting that like, you know, people could start off making their changes busy week style, or they can record pages. It's like they can open up their browser dev tools and hit record conceptually and then will record all the changes that you make using browser dev tools and But either way, you end up with just that JSON tree. And to you know, you could, you could do things visually with the wig style to get most of the way there and then finish up by editing the tree in the diagram mode. We didn't get to any kind of value passing, right, so I didn't, and we don't actually do this in our implementation, you might have a situation. And like these, these show more complex relationships between nodes, where they might actually be explicitly passing bits of information to one another. Those are usually called inlets and outlets. So you're connecting an inlet to an outlet or vice versa. And those just really are conceptually named parameters being sent back and forth. It'd be pretty easy to add something like that. But if you're going to go that far, and if you need something that complex, we needed something super lightweight, cuz we have to ship this out to browsers and stuff. But if you wanted something more calm Plex with all of those bells and whistles, then it might just make sense to use a framework. One that's out there is the NO FLOW framework, which is very fully featured, which has a whole fancy editor. And its really fancy. So I would encourage you to check that out if you have any interest in this. Just some inspiration and so on about flow based programming. This guy, Paul Morrison, Jay, Paul Morrison, he was the kind of the inventor of it the invented it in the 60s. And so I'd invite you to take a look at this site, just just google flow based programming. This would be like one of the first things that comes up. It's pretty interesting, far more complex than the stuff that I showed you.
This is his book. Pretty cool. Oh,
yeah. And then just, you know, again, the NO FLOW project. That's an open source project. I think it was funded via, you know, GoFundMe or something like that. So it's Semi supported. Pretty cool. Hope that was helpful help. I'm happy to answer any other questions, but I made from conductors.
Cool. Anyone else have any questions for Nate?
That wouldn't have occurred. So I wanted to say that was really impressive. Also, why is Lana Del Rey your mascot.
cuz she's awesome.
But like each every one of our I mean, not that this matters but like each one of our releases is is named after a lot of Delray song and yeah, so like the release notes always linked to one for videos and I don't know she's all over the code comments and what can I say? One of the problems is that most of your lyrics are not safe for work.
That's really cool. The whole flow design (inaudible). I like it
cool. I like it. Yeah, this is actually the second time I did this. The first time was was my then part colleague, Jesse who isn't here today. But who works with me now at conductor x, and we built it for Under Armour. And that was the basis of their back end. For a long time. It is no longer but they, it was very, very similar conceptually. That's how I learned a bunch of things to avoid. So this is a simpler implementation.
Are you publishing your slides anywhere.
I could Yeah,
Send them to me and I can blast them out.
Yeah. Yeah. It's awesome. Thanks, everybody.