Two's Complement - Weird Webapps
Episode Date: August 15, 2022Matt and Ben discuss the idiosyncratic way that they learned to build web applications for trading. If latency and correctness were paramount, and you could tell all your users which browser they had ...to use, what would you do? Here's what we did.
Transcript
Discussion (0)
I'm Matt Godbolt and I'm Ben Rady and this is Two's Compliment, a programming podcast.
Hey Ben. Hey Matt. How you doing? Doing great. One of these days we're going to have to come up with a better way of starting these podcasts than that,
but we just seem to have fallen into it and it works, so I guess why not stick with it?
Yeah, that's what we did on the very first one.
It was like, all right, that's...
Absolutely, we just shot from the hip and it was like, oh, I guess that's our intro then, but this is no good.
I mean, with the exception of...
Classic programmer move of like, why do you do it this way?
Well, that's the way we've already done it.
Exactly, yeah, right.
Why would we change that?
We've always used three spaces and a tab as indent.
Okay, all right.
Spaces and a tab?
I think I have probably triggered everybody now.
Oh my God.
You have no words for that, I know.
I'm just going through in my mind
all the terrible things I would do.
I think I met someone once who mentioned that they had some
kind of compromise space tab thing
it was a bit like that
so like everyone was equally
offended by that setup
this is probably the quickest
we've ever gone off any kind of script
that we had
it's worth it compromising on This is probably the quickest we've ever gone off any kind of script that we had. Oh, my goodness.
It's worth it.
So worth it.
Compromising on three spaces and a tab.
It wasn't exactly that, but it was something to do with that.
And I mean, yeah.
Well, we've never really talked about spaces and tabs here. And I don't propose that we do now because we should leave some things to the reader's imagination.
Yeah, we'd have to do a two-parter on that so instead let's talk about vi or emacs no right yeah no enough enough yeah
so what we were going to talk about in fact what we are going to talk about today was
our own particular unusual experiences with web development in particularly in the industry that
we we have found ourselves both in and how we've learned web development and particularly in the industry that we we have found ourselves
both in and how we've learned web development and then how we've taken that on into
other aspects i mean i certainly have in terms of things like you know compiler explorer has
definitely um learnt um stuff but it comes essentially from the trading industry and
actually indirectly through the same person who taught us both yes his particular flavor and brand of how to do web development so should we
talk a bit about let's talk about joe let's talk about joe he's a person worth talking about he is
a person worth talking about so i i first started working with joe many years ago when we worked
together at google and then when he left,
he's the guy who brought me into finance effectively. But did you meet him first
when you were at the trading company we first worked together at?
Yes. Dr. W.
Dr. W. Yeah. In jokes. No in jokes. Yeah. And Joe is one of those rare individuals
who just gets stuff done.
He's an ideas person and has an amazing ability to just crank out stuff so quickly in a really, really seemingly impossibly short amount of time.
And that's awesome.
And part of that comes down to the techniques that he uses.
And one of those is how he hacks together.
And I'm going to say hack, and hopefully he won't be offended if he ever listens to this which i'm sure he won't um hacks together websites
so what are your experiences with the the joe approach or what do you what what is your
definition of joe because we haven't really thought about yeah yeah quantified it and
why well i think rather than trying to define it in sort of any like specific terms, I think at least for me, it makes more sense to sort of talk about how I learned it and sort of the evolution.
You know, we talk about like learning from other people a lot on this podcast and sort of the way that you do things. And I have this memory of Joe giving a presentation,
sort of like a Geek Lunch-style presentation at this trading company,
talking about how he was building trading apps and other tools in Chrome.
And the approach that he was using was very different from anything that I'd seen before.
All the web development that I'd seen before had been extremely framework heavy.
So you would go and you would get some web development framework,
and you would try to build your application in that framework and do whatever the framework did.
And oftentimes the framework would make promises about like,
oh, well, this will now work across different browsers,
so you won't have different problems in different browsers, which always turned out to be false.
You had other problems in different browsers. It was just harder to figure out what they were
because you had this framework there that was, you know, trying to do things for you and was
maybe sometimes doing some things for you, but, you know, wasn't always doing everything for you.
And so he sort of presented this thing and it was like you know a very simple approach
where it's like actually and this was like in 2011 i was gonna say it's about a decade ago isn't it
yeah um he's like actually if you just use chrome and you don't worry about other browsers
um which uniquely we were placed to be able to do, for what it's worth.
Right, exactly.
Which is a blessing that most people don't have, but simplifies.
I mean, this whole approach is very, I think, a little idiosyncratic to the industry that we work in,
the fact that you can get away with this.
But he's like, we're just going to use Chrome.
We're going to tell everybody, like, hey, if you want to use these apps, you should use them in Chrome.
You can put a little check in the app and say, like, hey, you're not using Chrome. I'm not going to do anything for you until you install Chrome. We're going to tell everybody like, hey, if you want to use these apps, you should use them in Chrome. You can put a little check in the app and say like, hey, you're not using Chrome. I'm
not going to do anything for you until you install Chrome. But if you just use Chrome and you just
use the APIs that Chrome gives you, which are all web standard APIs, because at that point,
and certainly today, but at that point, the web standards had kind of grown up. They sort of gave you a lot of things that you needed.
You didn't really need a bunch of extra stuff.
It was sort of like it's all there in the browser.
So if you just use that and you use some very simple techniques
for HTML templating and a few other things,
you can build web applications without anything else,
and they work great and they're
extremely simple right um and the and advantage that that has at least in the trading industry
is that you know if you're building like a especially like a click trading application
I mean this is also true true for tools and other things but especially in click trading you know
hundreds of milliseconds matters a lot and just just for those who don't know,
click trading is for like a manual trade
where a human is deciding to make trades.
Obviously, you and I have worked in industries,
parts of the industry
where everything's completely automated,
but a click trader is like the UI
for somebody to place orders
and they're going to be human quick,
which is not high frequency quick,
but it's still, if you click
and it takes two seconds to respond
because of whatever right then you're going to get a very awkward question asked of you
right come the the miss uh of not actually yeah not getting that trade done yeah yeah why do we
miss this because this button didn't do anything um and then the other place where i think this
matters a lot is in control systems which I definitely do a lot as web apps
which again was kind of novel at the time
like the fact that Joe was sort of presenting
this and saying like hey you can do this
you know
to say like you know oh the button to stop
the trading system is here
and like if you click that button and it
doesn't work
really really really bad things are going to happen
so you need to make sure that you understand you click that button and it doesn't work, then really, really, really bad things are going to happen.
Yes.
So you need to make sure that you understand,
you know, basically the whole stack of like,
okay, I click this button, this event fires,
this bit of JavaScript runs, it sends a message up this web socket to this other thing,
which then turns off the trading system, right?
So like, if you can't, you know,
sort of lay your hands on every little bit of that and make sure that you understand it all, it's harder and maybe not even wise to use web apps to build these things.
But that was the brilliance of Joe is that he sort of saw that you could do this and showed people how to do it.
And I learned how to do it and a bunch of people that I worked with how to do it.
And to this day, I still know a lot of that uh are there and build apps this way and use them
this way um but it is a it is a little bit of an idiosyncratic method because you're just you're
not using you know you you might use some sort of light libraries like jquery yeah well i mean even
even jquery i think is mostly out of my canon as well. And I've mostly dropped out now.
I don't need it.
There are a couple of things I occasionally go, oh, I wish I had jQuery for this, but I just can't be bothered to bring it in.
And, you know, when your web page is an HTML file, which is all of like a dozen lines, and then a single JavaScript file that has no external dependencies, that's kind of a nice place to be for a lot of little systems that you're running.
And you can do quite a lot with that.
Tables can be made to work, buttons, updates, status bars,
things like that.
And effectively, you're using – the way that I think of it is
I'm using the web browser as purely a simplified canvas
for my application to sort of render to.
And most of the time, it's – not in an actual canvas sense, the the web browser as purely a simplified canvas for my application to sort of render to and most
of the time it's it's we're not not in like an actual canvas sense right but like there's right
hey there's about half dozen buttons that need to be able to update the text on and for that i don't
need react and i don't need these other things now occasionally you do find yourself going down
the path where you know you're like well if i edit the the value in this text box and hit enter
and meanwhile someone else is editing the same text block box
how do we deal with this kind of like state thing if there's a server all those kind of issues and
you know that frameworks do sometimes have solutions for you along those way but you
have to think about them so i don't know if it is that much of a a saving grace there and maybe i
haven't been exposed to the right framework to be able to have that opinion
which is but i think you know again uh this is now going a bit wider than what we're talking about
like frameworks in general are kind of can be an issue because if they do what you want that's
amazing but if they don't you're in trouble and you're kind of stuck right and i i'm not fond of
that inversion of control thing you know where yeah where framework calls you, you know, in Soviet Russia.
Yeah, right.
Yes.
So anyway, that aside.
But yeah, for me, sitting down with Joe and Joe back in 10 years ago, we would just, jQuery would be the thing that we would do just to unify and make a whole bunch of stuff relatively straightforward.
And, you know, especially CSS selector type stuff is really, really straightforward in jQuery would be the thing that we would do just to unify and make a whole bunch of stuff relatively straightforward and especially CSS selector type stuff is really, really
straightforward in jQuery. But then going, how am I going to write, how am I going to make this
table populate with all these rows and columns and things? Because I don't really want to be
doing it in code. And you mentioned HTML templating, which I think is another amazing trick.
Well, we'll have a single CSS tag that another amazing like trick well we'll have a single css tag
that says template and then we'll have the single piece of css that says anything that's template is
display none and now i can find that template and i can clone it and add it to its parent which means
now i get another row in my table and then i can remove the template css tag from it and now
suddenly i have used uh the the thing that i've written out
in html with just the class template as an a template and i've got a new row of my table and
now i can just fill it in i can find all of the things and find you know the second uh thing that's
marked in a particular way and that's where i'm going to change the text to be whatever
and that was an eye-opener for me is like oh how simple and elegant it is to be able to
in almost one continuous line of javascript just with continuation like dot this dot this dot
remove class dot whatever dot find this thing and dot text new new line and you're like oh
it instantly reacts and um and i have a web app that is that's responding to me straight away.
That's great. I love it.
Yeah, and one of my favorite parts about that
is that it means that you're editing HTML in an HTML editor.
You don't have this weird thing where you've got HTML interleaved
inside of JavaScript and you have a very smart editor that knows,
it's like, oh no, this string is actually like an HTML snippet.
And so when you open one you know uh element it's going to automatically close on the end right
like it's like no it's just html you can load it in pretty much any writer and if you just delete
that template tag of it as well you can actually load it up and without the javascript and see what
a single row would look like so you have got a little bit of the like this is what the placeholders
would look like so that works pretty well too so yeah that was an eye-opener for me and then um
the web sockets you mentioned there which is i don't know how many folks have actually done
anything with web sockets but like the the other sort of take home for me was um just using web
sockets for everything like you go to a web page, the web server's responsibilities are to give you the HTML,
to give you the JavaScript,
and then, and the CSS maybe,
and then sit there.
And as soon as you connect back through WebSockets,
it gets out the way.
And now you're talking pretty much directly to your server.
Forgetting the fact that there's a web browser there at all.
And now you're just exchanging messages with the web page directly and that was again another eye-opener
all this restful stuff i'd done before you know in query parameters and you know do i put it in the
in the hash string or do i put it as a query parameter i post or get or whatever all that
goes out the window because once you've got your app the app is loaded and now you're just doing
client server stuff like it was a tcp connection and that's amazing and one of the tricks that we used to
do as well i mean this again is something you should never ever ever ever do unless you are
100 in control of everything like we are when we're saying about this but um what um what i've
seen done before and with joe Joe was to have a with block
that says with
some
I can't even remember how it works now in JavaScript
it's been so long since I've done this but essentially we just evaled
whatever the text was that came
down the web socket
so that meant that the server could do
literally anything it wanted to
and if you wanted every sort of command
in your RPC was just like literally calling a
JavaScript function that you had previously arranged um but you could also send down things
that were like alert and anything anything at all which of course is terribly dangerous you know you
should never let your server execute directly the code but it meant that you didn't actually have
to write a protocol document that was it either um so that's eye-opening as well and it's really
really really powerful to to be able to do those that of stuff. And in fact, I was so enamored of this approach that when we started, when I moved on to C++ trading systems, I ended up writing, there weren't many things that were around for WebSockets at that time for c++ and so i just wrote a web server that had websockets thing uh support and um
embedded it into all of our trading systems and then very quickly it was like no more are we kind
of sshing onto boxes and poking around with processes or kill you know kill minus hop to
sort of shut down the trading system or having text files whatever it's like no you just go to
the web page and there's the big red button exactly as you described and then very very
quickly you're like well wouldn't it be cool if we could visualize exactly what the internal state of the
trading system was?
And then quickly it becomes this beautiful web page with all these beautiful
like CSS things that are going on and GIFs that are lights that go red.
And yeah, it just felt like, oh,
this is a natural way of extending my application.
And yeah, it just all came out of like a web socket
connection there's no there's nothing really clever behind the back of it yeah that's csox
right that's csox yeah which is a terrible name but yeah that's a that's a very clever name i
don't know it's not as clever as i thought but yeah csox is is uh pretty good i mean there are
plenty of other ones out there now that are that are better than more c++ 17 and 20 or whatever but this one was made to work and it's about it's been running for
about 12 years now and in fact somebody managed to port it to work on windows the other day which
were i was surprised because it's just a linux thing that i was wanted to just have work to say
relatively low overhead um yeah good fun and yeah the world is your oyster once you've you've got uh a web server
and javascript general purpose programming language on both sides or on one side
so yeah what about you what about your experiences with this kind of stuff i mean
i did basically the same thing the one thing that i sort of realized as i was learning this stuff
from joe that again was a huge departure from anything that I'd seen.
Because I've done some web development stuff before starting,
you know, before working with Joe.
But all of it was just super painful.
CGI bin.
I don't like it.
I don't like anything about this, right?
And, you know, yeah, all of the arguing about, you know,
which HTTP verb is the right one here.
Is this a put or a post?
Yeah.
But the two
additional things that I
got out of that were
A, if you build
web applications this way, they are extremely
testable.
Extremely testable. And I still
have carried this on to this day where it's like
when I'm building web applications,
my standard for unit testing is maybe even a little higher than it is in server side languages like, you know, Java or Python or Ruby or Clojure or stuff like that.
How does that work?
How do you, how do you, what makes this testable?
I'm genuinely intrigued now because I don't know.
It mostly gets back to that whole templating approach, right?
And you can expand on this and you can add lots of cool things to it.
But the fundamental of it is when I want to show some content on a page,
the way I'm going to do that is I'm going to have a function.
And that function takes some amount of input, and it returns an HTML element. And that HTML element is almost certainly a template that has
been cloned and then populated with stuff. And that stuff could actually be data, or it could
also be click handlers. But none of that matters. Because if all I've got is a function that returns an element,
then I can pass stuff into the function, get the element back, say like, hey, is the value of this field the string foo?
Cool.
What happens if I trigger a click event on this element over here?
Does it change to bar?
Yes.
And now, fundamentally, all you're doing is testing a tree.
It's just a tree data structure that's all
it is right with some handles associated with it but not but but yeah it's just uh yeah i don't
so you actually use the dom objects themselves as sort of like the the conduit by which you can
interrogate and say did you do the right thing and not did you do the right thing because of
the state of the program change with you but but like, did the tree contain the right information
and does it have the right behavior when I,
and treat it effectively as the testable object.
That's amazing.
Yeah, I'd never thought of doing that.
Yeah.
That's so cool.
And really it was like, you know,
Joe like did some stuff with this.
Joe was never, I mean,
few people are as bananas about testing as I am,
but you know, it was never like his main thing,
but I sort of saw what he was doing.
And I was like, oh, I could write tests for this.
This would be great.
And this was going back all the way to 2011, 2012.
We started working on the Monocle project and other things like that at DRW.
We started writing tests this way.
The team I was working with started writing tests this way.
And I've kind of done it that way ever since.
And it creates this really great seam, which I had done a lot of work when I was right out of school with Java and Swing, right?
I was actually hired to be a QT developer.
And like a month into it, they're like, oh, you're not going to do any C++ or QT.
You're going to do Java Swing instead.
I'm like, rock.
I don't know. Buster QT, you're going to do Java Swing instead. I'm like, rock. And I spent probably
two or three years, a little more than that
actually, building 2D
graphics tools
in Swing. So this was a lot of
2D canvas stuff, but also just
user interfaces, buttons and forms
and things like that. And all
of that stuff, I mean, even back then I was
super test infected.
And I always had a really hard time testing any of that stuff, I mean, even back then I was like super test infected and I always had a really hard time testing any of that stuff.
And part of the problem was this sort of like fundamental issue that you have with testing UIs, which is there's no such thing as a cert pretty, right?
Yeah.
You have to look at it.
As a human being, you have to look at it and be like, is this intuitive?
Does this make sense?
Does this communicate the ability
of the software to a person who would use it?
A normal human being, of which I am a reasonable
approximation.
Yeah, close enough, right?
Anytime you
see an open source
tool with a user interface
in it, I guarantee you that user interface like
nine times out of ten maybe eight times out of ten it's just going to be terrible it's going
to be absolutely terrible because it's designed by programmers have you seen my website
just saying i mean it's not the best from that point of view it's utilitarian that's what i tell
myself user experience designed by people who at best are able to synthetically replicate human emotion.
Right.
I barely passed the Turing test.
Yes, right.
Exactly.
But the problem with testing is you always have this thing of like, I have to look at it.
I have to look at it to know that it's right.
Yeah.
And one of the great things that sort of came out of that experience, you know, building these web UIs and being able to build things this way is I found a seam.
I found a line between that was very clear that I could explain to people between the stuff that you could reasonably unit test and the stuff that you just had to verify as a human being.
Right. that you just had to verify as a human being. And that is the stuff that's just the tree, the DOM,
all completely testable.
All the events that you can trigger on there,
all the everything, all the classes that are on there,
everything is completely testable.
It's just a tree data structure.
That's it, you can test it.
It's super simple.
The place that you can't is the CSS.
It's the styling.
How it looks. So you have the tree.
And how it reacts in terms of the browser's representation of it.
Right.
Right, right, right.
But the semantical thing that says the input box, it's an input.
And I know it has two fields.
And one of them has this tag and one of them has this other tag,
and the content should be this and that.
And then it's up to the styling to make them look how it's presentable
to a user, but I'm sure that I put the right information there.
And now I can kind of – the responsibilities of the program
have finished, and the responsibilities of the styling take over
at the point where you hand over and just agree on class names or whatever.
Yeah, and it creates this sort of like very clear boundary between I'm writing code and I'm writing tests to manipulate the DOM versus I'm basically acting as a UX designer now. And I am styling that DOM.
And I am choosing colors.
And I'm choosing fonts.
And I'm maybe doing...
If you're right, yeah.
I suppose the thing here is this is like asserting, you know, if I get an error, if I send an error to this thing, does it look red?
And if you're writing your test like that, you're doing it wrong.
Because it shouldn't be that it looks red. It's that it has the style class associated with it yes it has the error
style it has the error class on it and that's the only thing i'm asserting in the test because you
don't know whether or not that yeah it's a bit like we're doing localization actually now i'm
thinking about it you know like again you want to put the the semantics of what are important
and the thing that comes afterwards is the presentation layer which is you know what does
it actually come out of uh yeah yeah right right yeah that's a really good
it's a great point is it is it's a little bit like localization it's a lot like localization
actually but that separation being able to have that separation um was was a was a game changer
for me and we and i got i've gotten more sophisticated with it over the years you know
started using different...
You'll have classes on the DOM
that are strictly for styling.
You'll see this a lot now with a lot of CSS
frameworks where you get these
classes that are like
MT5, right? Margin top 5.
Oh, yeah.
Stuff like that. And I like that stuff a lot.
But that is purely for styling.
And I'm putting that
in the templates. I'm almost certainly not writing unit tests to assert that it's there, unless I've
got something where it's like, oh yeah, when this event happens, you need to handle that event by
adding some margin to this element. In which case, I might write a test that says, hey,
after the blur event happens
does this element now have the mt5 class cool great but you should also never do that please
like if you if you're changing the styling when it when somebody loses focus then i'm going to
come around with a club yeah i think i showed you a website the other day that where it was like
wantonly on mouse move would like make a whole bunch of stuff appear on the screen that moved everything away to the point where right it was impossible to
click one of the yeah bugbear is over the input just like runs away from your cursor yeah exactly
it's like one of those things like come here oh my god um but yeah so and and that was that was
sort of a natural evolution out of that and it it tied into the whole thing of like, you know, and a lot of things that I did at aforementioned company was,
was building like these quick trading apps. Like we built them for a couple of different trading
desks there. And, you know, they are, some of them are like, actually, it's weird to say latency
sensitive, but it's like, that's what it is. Like speed really matters. And obviously correctness also matters a ton because, you know, you're acting in transaction
You're sending millions of dollars worth of trades into the market.
Yeah, you wouldn't want to do that.
So the combination of those two things, like, really led me to this place of building applications
this way, testing applications this way, and having this super clear separation
between here's the styling,
and honestly, we're probably not going to change it that much.
We're going to write the CSS,
we're going to put a couple of classes in there
for the things that we need,
and we're going to mostly leave it alone.
And then primarily what we're doing
is just getting messages from WebSockets,
sending messages to WebSockets,
calling functions, creating elements, and putting them in the dom yeah that's it that's cool how do you so one of
the things that i always found difficult with the limited amount compared to what you're describing
of testing i was doing in the front end and anyone who's used compiler explorer knows that there's
not much in the way of front-end testing um uh despite some of my my friends helping very much on that
but like how does one in general do testing when the only thing that can really give you a dom that
acts the way that well maybe maybe you tell me this isn't but my my instinct is the only thing
that will provide a dom interface that is a true to life is a web browser which is not something that i can script or debug
in the same way it's a very heavyweight thing uh compared to um you know like what i'm used to with
like hey here's an assertion it's a framework that i just literally call assert on it and it's like
you know call square root square root of 144 is 12 end of story yeah how do you how do you how do
you test it so lately what i've been doing i mean i can go
back and give you the whole history of how i got here but lately what i've been doing is i've been
using just headless browsers usually headless chrome got it and i run all of my tests in ci
and on the command line just with the headless chrome um there's a particular tool that i've
been using more in the last couple of years,
which I actually like a lot, called Karma.
Okay.
And what Karma will do...
I think that might be what we're using.
I might have to go check it out and see.
I like Karma.
It's good.
I mean, it lets you run...
You can run multiple headless browsers at once,
so it's like...
And it has the whole continuous testing model
of whenever you change your code,
it'll automatically rerun your tests,
and it can rerun in multiple browsers.
If you want.
I'm still,
you know,
if I'm building internal apps,
I'm still doing the thing of like,
Hey,
use Chrome.
But you know,
if you have multiple browsers,
you need to test against.
Cause yeah,
I'm with you.
Like I've never been satisfied.
I've tried.
This was more five,
six,
seven years ago.
I've tried to all like,
you know, the no JS simulated dom stuff and libraries and all that or even you know having the web browser open and like just having
to manually eyeball the green on that and like reload the page and it's actually running in the
browser like as a thing and it sets up and i've never felt satisfied with that because it's like
unless unless some unix process returns a non-zero exit value,
I don't think that my tests are testing anything.
Yeah, yeah.
And I mean, in fairness,
what I used to do is I would set up
some kind of live reload setup.
So this live reload is actually a library,
but it's also kind of a technique
of like every time you change, you know,
a bit of markup or JavaScript or whatever,
whatever browsers you have open that are connected to that app automatically reload reload right there's a hot reloading thing that yeah sort of hot reloading thing and i've done that for a long
long time and when i would just run my tests in the browser that was fine because i just bring
the browser window up and i'd see the test results there but in the last few years i've the tools
have gotten good enough to where i i feel like you can just do it entirely
on the command line right now, and it gives
you what you want. And if something goes wrong,
there's still a web server running
there. So the headless browsers
are connecting to it. You can just
connect a regular web browser to it, and
you can debug it. So if something
weird happens, you just open up
a browser, go to localhost 9876,
and there's your test runner, and you can open up the console go to localhost 9876 and there's your test runner and
you can open up the console and you can see what's wrong and you can step through the code and you
could do all the things that you normally do daft question what exactly does the headless chrome
do you know what is it like you run headless chrome and give it a web address and then it
returns when the web page calls exit or how does that work where did well you know where does the output of it go and
how how yeah yeah so the the the karma tool that i've been using recently the way it works is it
launches the headless browser for you right and it communicates with it right so it is serving up
this like generated html file that has all of your tests and the, you know, testing framework and a bunch
of other stuff in it to communicate. And then it just opens the headless browser and points it at
that thing. And then, you know, executes your tests and then gathers the results. And then
if you're running it in continuous mode, it just prints the results out to a terminal. And every
time you change it, it reruns the test. If you're running it in batch mode, it just returns you that non-zero error code or zero error code that you want, prints out the
results of the test as it's doing it, and you can run it in your... I have a couple of projects
right now where I'm running it in GitHub Actions and it works great. Nice. So I'm a huge fan of
that. And it's definitely a... It's been a long evolution because, you know,
back in 2012
when we were doing this,
it was literally like,
well, we're going to write these tests
and we're going to just
put them in the browser
and we're going to just reload the page
every time we make a change.
Right.
I remember we deployed
like a test.html
that you could go to.
So we would deploy it
and then go to test.html
and make sure that the actual
deployed system
passed all the tests
before we tell the traders, yeah, okay, you can use it.
Which is unsatisfying, you know, but necessary.
And I mean, obviously, there are things like, and now I'm blanking, WebDriver, Selenium, I think are the two.
Oh, they may be the same thing now.
I know Simon Stewart, who also knows Joe, incidentally, through the strange sort of like set of people that we we know um are involved with that and
and that was very much more as i understand it would like run a full web browser and then write
tests in terms of interrogating the dom kind of exogenously to say like hey there should be a
thing somewhere on this entire page that says hello world and if there isn't then we
didn't load the web page properly or things like that those kinds of assertions are what you could
run and i'm sure i remember having conversations about like snapshotting and doing like pixel level
yeah comparisons about like well it ought to look something like this you know give or take 20 of
error which immediately is like well that's a very brittle test that you've just designed for yourself.
But also, it is a way of locking in a very specific behavior if you require it, which
seems a little bit too much for me.
And obviously, it's not what we've been talking about now.
Yeah, I think if you have a lot of money to spend on testing and you have a system that's fairly mature and not changing that
much then those kinds of approaches can can be effective they can be better than not doing them
yeah and and you know especially if you if you had no front-end test you're trying to retrofit
them I think that's the city's I mean if you cast your mind back however many years it is that we've been going now, when we had Claire on the program and the golden tests.
Yeah, yeah, yeah.
Not golden tests.
Oh, gosh, that's what I always called them.
Golden image.
Sorry, what did you say?
I said golden image.
Yeah, golden image.
That's right, yeah.
And now I can't – oh, darn it.
I can't remember the name of the term that she uses.
Oh, yeah, yeah, yeah.
Oh, gosh, yeah.
I can see the color of Ben's face has changed as he clearly all tabbed away.
Acceptance tests, I remember there without even looking.
It just happened.
Anyway, sorry, sorry, Claire, for listening.
Approval testing.
Approval testing.
Approvals.
There you go.
Approval.
Even better.
Sorry, I got it wrong.
There.
So approvals tests, which are a great way of retrofitting um tests into a system that has none at all
when you can just go to the far end and say well okay if i feed this text file into my compiler i
should get this executable out the end and i'm just going to do a bitwise comparison it's a great
starting point for doing no harm similarly presumably this kind of test where you
say okay simulate an 800 by 600 image render the screen and then kind of go it ought to look like
this that's that's a equivalent of an approval test but probably just too too um uh what's the
word too brittle yeah um i want to talk back a bit about performance because, you know, if you like testing, then it's in character for me to talk about performance.
I remember at the time that we were first looking at integrating some of these Chrome-based trading apps, they were displacing some C-sharp applications like thick clients that were going and the concern was that with you know a couple
of hundred if not a couple of thousand uh stock tickers and all of the information about them
that there would be no way that the ui could keep up with the torrent of information that's coming
down the the line if you're a trader and you're saying what's the trading volume in your little
graphs you can imagine little sparkline type graphs and then a huge giant monitor full
of these things all being updated in real time you might imagine that it it wouldn't be fast
enough to keep up and um amazingly it was i think that was the first surprise is that joe was like
actually the chrome people are pretty smart and this was again a decade ago they've done a really
really good job of of only updating the
parts of the screen that actually changed and if you're not daft in the way you write your
javascript if you're not always looking things up with like complicated css queries you know you
you know whatever internal representation you have is you know you've got your array or your map of
stock ticker to some object and that some object contains the actual dom element references of like where the hell things are then it's really quite quick to sort of update the text of them or to
to manipulate a little canvas tag associated with them and that was super super surprising to us at
the time we did hit some level of uh limiting factors uh when we were doing uh live views of a particular uh stock tickers market so
hundreds of thousands of orders that were being added and removed from the market and a graphical
representation of them and one of the limitations was was uh bypassed by using canvases directly
which was one thing rather than having lots of dom elements that you were manipulating
in this particular case where they were very very specialist uh objects so it made sense to take the time to actually draw them and undraw them
ourself um but um another thing was not using uh jason com comms between uh the server and the
and the client like literally having like well there's a one character which says whether is
this a new order is it the change to an existing order or is it a deletion of an order
it's like one character and ascii followed by a space followed by a couple of other space separated
things and like hard coding our parser to you do that was quite a win back then but maybe nowadays
evaling a json object is faster i actually did a test on this just about a year ago.
And I found, yeah,
because I was thinking about this exact scenario where it was sort of like, you know, we were
communicating using
these custom protocols instead of JSON.
I'm like, is this still worthwhile?
So I had like a five
field message.
And so I was like, I'm just going to take
this five field message and I'm going to delimit
it with some character.
And I don't even remember what character I picked, probably colon or something like that.
And I'm going to have an equivalent JSON message with five key value pairs.
And I'm going to see what the performance difference is just splitting the string on colons versus parsing the whole message.
And it was more than 10x.
It was more than 10x faster in more than 10x faster uh in chrome uh
and i was honestly surprised by that um no i'm still surprised now i mean i think despite bringing
it up i thought it may have you know separate come together yeah part of this may have been
the way that i had these messages structured is um the just the nature I forget exactly what I was doing but there was
something where it was like four
like reasonably small
messages or fields in the message
and then one big
field at the end that was like a
1k field you know
and I did take
advantage of a little bit of a trick to say I know
there's five fields here I'm always going to
put the big field at the end and I'm going to only split up to the first four uh colons so that
after you found that last one you can just assume the whole rest of it so you don't even have to
escape colons or anything that were in that blob at the end or whatever yeah yeah it's just it's
just all in there and so that was a little bit of a hack but but with that it was like significantly
faster to not use jason which was surprising to me yeah i guess so i mean obviously jason is in there and so that was a little bit of a hack but but with that it was like significantly faster
to not use jason which was surprising to me yeah i guess so i mean obviously jason is the right or
something like it is a very good choice almost all of the time because it's self-describing at
some level it's human readable for some level of some definition of of human readable and um
and certainly if you have to if you're in the unenviable task
of having to bust out Wireshark
and look at some kind of communications
between a client and server
to work out what the heck happened,
you've got more of a hope of understanding it.
But for things where you have a very specific
client and server
that just need to be very performant,
it's still, I'm surprised,
but maybe I shouldn't have been.
Well, and the dev tools just treat JSON so much nicer too.
That too, yeah.
You can go and you can look at those WebSocket messages going back and forth,
and it'll parse them for you and do all the nice things for you.
The other performance thing that I got from Joe,
and I don't know if this is still true,
but it certainly was true back then,
is just avoiding DOM layout
and just using fixed positioning for everything.
Oh, interesting.
And I remember him talking about this,
and I think it was with a ladder that he was building,
where he was just like,
yeah, I just absolutely position these things on the screen
in the places where I know they are,
and I can verify in the profiler
that it's never triggering a layout when I change things.
Got it. Yeah, that's an interesting one.
And it never has to relay out.
And that was a huge thing.
I don't know if that's still true, but it was certainly true back then.
And that was one of the little tricks that we used to make it.
As you say, you've got this giant monitor with all these different graphs and charts
and position tables and things.
And you just got to make sure that it can keep up.
Yeah. and position tables and things, and you've just got to make sure that it can keep up. Yeah, and we also experimented,
although never came to any firm conclusions at the time,
with using GL-style things.
You've got WebGL that lets you do hardware-accelerated things.
So if you've got...
And obviously, you might naturally think of that as being a 3D thing,
and indeed, that's a lot of fun, making a huge model spin around and be lit and everything.
But you can use it for 2D operations as well.
And that might fit the bill for certain things.
We really have gone off of topic here.
I don't know.
I can't even remember what the topic was.
It was just like web development our strange way, I suppose.
So that kind of fits into this category.
Yeah, it's sort of our strange model of web development that we both, I think, learned from each other.
So let's sort of do a, let's recap where we are with this.
We both come from a luxurious position of being able to dictate which web browser people can use, right?
Right.
We don't advocate the needless dependency on third-party libraries jquery might get in there but maybe not
anymore maybe underscore now maybe make them in there i certainly that's very few and far between
that i would add libraries and that's more to do with being able to explain what the system is
doing obviously once it hits chrome you can't explain what's going on in there but then there
are chrome dev tools and things that do help you can't explain what's going on in there. But then there are Chrome dev tools
and things that do help you there.
But if there's any amount of inventing
framework-y things in between,
then maybe that's fuddish on our part.
But certainly, we haven't had to.
Yeah, it is.
I mean, it's a little superstitious.
It's a little fuddish.
But at the same time, it's sort of like,
if I don't add those things,
there's this whole category of problems
that I can guarantee I won't have. Right. Now, would I have had those problems if I had added it in? I don't add those things, there's this whole category of problems that I can guarantee I won't have.
Right.
Now, would I have had those problems if I had added it in?
I don't know.
Have you booked in different problems by having to write, reinvent wheels yourself?
Maybe.
Maybe.
So, minimizing your dependencies, I think in the sort of pre-conversation before this, you said, unless it brings a 10x benefit, then you don't bring it in.
That seems like a not unreasonable thing to say.
Similarly, with that performance kind of thing. If it's 10 10x faster then maybe it's worth doing it a different way if you need the performance rather than just sucking it up and
using json whatever um testing the dom that was another thing we brought up uh using the dom as
the kind of unit of uh what functions return and mutate
and that kind of stuff.
And, yeah, that's sort of a weird way of developing web tools,
but it works for us.
Yeah, yeah.
I'd be interested in what other people think of this
and whether they're horrified at the fact that we're not using React.js
or $framework here or jQuery. this and whether they're horrified at the fact that we're not using react js or dollar framework
here or jquery actually i i'm gonna i'm gonna sort of take a walk this back a little bit i've had some
very good success with knockout as a framework which is extremely extremely thin framework it's
not really a framework at all yeah but um that has that's like the the least frameworky framework that i've had good success
with and certainly for slightly more complicated interactions and dom uh manipulations where things
you've got sliders that need to update numbers and uh like in another field or vice versa where
they're sort of bi-directional communications between like widgets then something like knockout
it can be a good thing uh but but yeah i haven't used
it for a long while and compiler explorer is mostly handwritten for what it's worth a similar
deal right oh everything inside of it we do use a third-party component called golden layout
which is like the windowing system oh yeah and it coincidentally was written by a bunch of folks who
were at a trading company and open source so you know if you need a big old
window full of like sub windows that can be moved and repositioned and uh scaled and whatnot then
you know it turns out that uh the trading industry apparently needs that more than most other
industries yeah yeah you talking about knockout had me thinking i i have used a i don't know if
it's a library or framework depends on what word you want to use there, called Backbone.
Oh, yeah.
And specifically, we used it for data binding.
So this is this problem that we were just talking about, like, okay, you've got your
template, right?
You've just cloned your template.
You're inside the function.
You got your data as an argument to the function.
You've got your template.
Now what?
And that goes two ways.
One is you got to put the data into the template,
and then you might also want to have what some people call
two-way data binding where it's like, okay,
I put the data into the template, I put it on the screen,
now someone's changed it, I've got to pull it back out again.
Yeah.
Right?
And you can do a lot of stuff yourself.
You can do a lot of stuff with some very simple conventions.
Yes.
Like I'm going to name the field conventions right like i'm going to name
the field this and i'm going to use the same thing on the class so i know and i'm going to select it
and i have my generic on on change thing that just connects the two together or whatever yeah
yep yep so you could do it like that um but there are also libraries and tools and things that will
do that for you and and backbone was one that i remember using and remember not hating so i don't know how much of an endorsement that was that's uh um but we definitely yeah right
but we definitely like recognize one of the you know one of the downsides is you're just saying
like solving problems yourself that you maybe don't have to data binding is one of those problems
where it's like i'm going to put data into these dom elements i'm probably going to have to pull
it back out again in other instances are you going to handcraft all of that I'm going to put data into these DOM elements. I'm probably going to have to pull it back out again. In other instances, are you going to handcraft all of that?
Are you going to have some simple mechanism for that?
Are you going to use the library for that?
And especially when there are some stupidities in the DOM
where sometimes it's a dot value on something
and sometimes it's the dot text and you're like,
which one is it? I don't know.
Oh no, the number of times that I've marked that up
and ended up with like an empty string or a and like escaping and dealing with um i mean certainly jquery is capable
of handling this stuff but it's sort of like escaping things so that you don't get like
javascript injection attacks oh do you see yeah you know uh on purpose or otherwise right definitely
have some things where it's like where where is the text of this thing?
It's like, oh, there's some square brackets, or there's some angle brackets in there.
That's not going to show up.
That thinks that's a tag.
So one of the internal tools that Joe was responsible for at DRW that we won't talk about what it is specifically,
but it did have a way of naming some of the little tabs that you could put up.
And rather unfortunately, because Joe rolled it all himself,
it was totally exploitable.
And so I used to embed my JavaScript emulator
running Sonic the Hedgehog in a little pane.
And then I would send,
you could bookmark links that would reproduce them.
And then I would send it out to the traders and say,
have you seen this?
So don't ever take that out.
That's great.
Yeah.
Cool.
In summary, then, don't use a framework unless you have to use a framework.
But you sometimes use a framework.
Well, I would say this.
Again, based on my experience, and again, we have this sort of weird background and this weird experience doing this, but I don't feel particularly wrong
in saying you should learn the web standards.
They're there. They're always there. They're going to be there for a really long
time. And it never hurts.
If you think of yourself as a React developer, you think of yourself as somebody that maybe knows
a lot of different frameworks and is a
web developer,
there's a lot of knowledge there that you have, and that's
great. And you will definitely not
diminish that at all by
learning how the web standards
work and learning how browsers
work under
one layer below you.
Because there's just so much gold there.
There's so much great stuff there, and you basically get it for free.
So you should know about it.
You should at least be aware that it exists.
I am absolutely loving this.
You've seen me grinning like a fool at you while you've been telling me this
because this is the argument I use,
but as you substitute framework users with C plus plus or compiled language
people with and web standards with the assembly code yeah and
we're making the same argument it's like you don't have to use it but you should know it's there and
i have a working understanding of it so that you know how the tools that you use are built on the
layers and layers and layers above and i mean it goes all the way down as well you can keep going
down it's great that's what makes this job so interesting and working in the field.
There's always another layer.
Every time you think you've hit the bottom, there's another layer.
Yeah. Absolutely.
Yeah.
All right, my friend.
Well, until next time.
Until next time. you've been listening to two's compliment a programming podcast by ben rady and matt godbolt
find the show transcript and notes at twos compliment.org
contact us on twitter at two cp that's at T-W-O-S-C-P.
Theme music by Inverse Phase. Inversephase.com.