Brutality of Behaviour (with Carson Gross) - podcast episode cover

Brutality of Behaviour (with Carson Gross)

Apr 29, 202546 minEp. 38
--:--
--:--
Download Metacast podcast app
Listen to this episode in Metacast mobile app
Don't just listen to podcasts. Learn from them with transcripts, summaries, and chapters for every episode. Skim, search, and bookmark insights. Learn more

Summary

Jared interviews Carson Gross, creator of HTMX, discussing Locality of Behavior (LoB) as an alternative principle to Separation of Concerns (SoC) in web development. Carson explains how HTMX leverages hypermedia for simpler, more maintainable front-ends, critiquing traditional approaches that lead to "spooky action at a distance." They explore trade-offs with principles like DRY and the importance of pragmatic software design, advocating for deeper modules and simpler APIs.

Episode description

In this episode of Dead Code, Jared interviews Carson Gross, creator of HTMX, about the principle of Locality of Behavior (LoB) and its role in web development. Carson explains that HTMX enhances HTML rather than replacing it like modern JavaScript frameworks, offering a simpler, hypermedia-driven approach ideal for use cases like e-commerce. He critiques the traditional emphasis on Separation of Concerns, arguing that keeping behavior close to markup improves maintainability and avoids “spooky action at a distance.” Carson acknowledges trade-offs between LoB, DRY, and SoC, emphasizing the importance of context-based decision-making. He and Jared also discuss broader software trends, advocating for deeper modules, simpler APIs, and a pragmatic, less ideological approach to coding as the industry evolves.


Links:


HTMX Website

HTMX Essays (especially Locality of Behavior and When to Use Hypermedia)

grugbrain.dev

Hypermedia Systems Book

Richard Gabriel’s “Worse Is Better” Essay

Mozilla Developer Network (MDN)

John Ousterhout’s A Philosophy of Software Design

The Uncle Bob vs. John Ousterhout Argument

Big Sky Software (Carson’s Company)

Hyperscript


Dead Code Podcast Links:


Mastodon

X


Jared’s Links:


Mastodon

X

twitch.tv/jardonamron

Jared’s Newsletter & Website


Episode Transcript

Hosted on Acast. See acast.com/privacy for more information.

Transcript

Intro / Opening

how old are you what do you mean what do you mean by that

Intro & Guest: Carson Gross

Welcome to Dead Code. I'm Jared. And today, our guest is someone that I've wanted to have on since we started the podcast, finally made it happen. Today, we are talking with Carson Gross of HTMX fame about locality behavior, what that means for the code we write, what that means for HTMX, what that means for the web and hypermedia. So let's get into it.

Carson's Work: HTMX and GregBrain

Carson, welcome to the podcast. Thanks for having me on. I'm excited to be here and to talk a little bit about some ideas and software. So for our listeners who might not be familiar with you, what should we know you for? Probably the most famous thing is HTMX, which is a web front-end, sort of an alternative front-end library that's...

It's for building web front ends, but it's hypermedia oriented. So it tries to enhance HTML the way HTML sort of works rather than what I would call a replacement model, which is what... for example, React, which is what I'm sure most of your listeners are familiar with. React is a great tool, but it really replaces the web model with the hypermedia model with a data-oriented model. HTMX tries to sort of play in the hypermedia world. So that's what I'm probably most known for.

They may also have read gregbrain.dev at some point in their life. And that was an essay that I wrote on sort of simplicity and software development. So I teach. at montana state um and the computer science department and sort of run a consulting company as well so that's that's sort of my my current state of affairs

HTMX: The Hypermedia Approach

Very cool. So I come from the Ruby on Rails community, and HTMX definitely caused a little bit of a stir there because we've always been very sort of oriented towards... minimal JavaScript front ends. We don't, you know, there's a certain distrust of React there. And when HTMX came out, a lot of people, I saw a lot of people using HTMX.

with Rails. So I guess my question is, what's it like building with HTMX? Does it restrict the kinds of things we can build or how is it different from building on other JavaScript technologies? Sure. Yeah, so I'm actually an old Rails guy too. I don't program in it much these days. And HTMX, the predecessor to HTMX was Intercooler.js, which is...

It's been around for over a decade now. And that was, I use that entirely on Rails. And it is a different way of thinking about things for sure. The hypermedia model is... It's just a different way of doing web development. You know, it's sort of that old school stateless. The URL carries the state along with it rather than a highly stateful client. And it does restrict what you can do from a UX perspective, which is not always a bad thing.

HTMX Capabilities and Limitations

you can do quite a bit with it. So the example that I often give is active search where someone's typing and you're bringing up search results as you go and that's entirely achievable. That's a pretty dynamic user experience and it's pretty easy to achieve using HTMX. But there are limits that you're going to get to with the hypermedia approach. And I have an essay on the HTMX website at htmax.org slash essays.

um called when to use hypermedia i think and that uh sort of outlines like here are the places where this approach makes sense and here are the places where it doesn't and i have noticed some people who come in to start using HTMX, and they try and fit it into sort of the React model, and they're frustrated by it because it's a little restrictive. But there's a quote that I really like from Orson Welles.

where he said, the enemy of art is the absence of limitations. And I think that's a good quote and is a good quote for web developers to keep in mind, like sometimes limiting yourself a little bit is actually where you're.

best art comes from when you're programming. And it's okay to not be able to do everything. And I often feel that way when I'm using sort of modern SPA-based web apps that have all sorts of... crazy crap flying around and i'm like man i just want to i just want a table i can search

If you could give me a table I could search, that would be great. So, you know, I think it is, it's not something, it doesn't overlap 100% with what you can achieve with React in any way, but you can achieve a lot with it. And often it's a much simpler approach than the React alternative would be.

Hypermedia for E-commerce

But it depends, as always. Yeah. Yeah, no, it's definitely, I've yet to actually play with it, but I work on a lot of e-commerce websites. And of course... Page performances and page speed is super critical on those kinds of applications and more minimal, less JavaScript-y front ends tend to perform better. So I think it's really aligned with that. for the opportunity to try it out on something.

Yeah. E-commerce is a great example of where hypermedia, HTMX is, you know, a hypermedia oriented library, but there's lots of other ones. So like Unpoly is an old mature one that was somewhat popular in the Rails community. Obviously Hotline. which is the 37 signals thing. Those are all hypermedia oriented. And e-commerce is just absolutely perfectly set up for it because what is e-commerce? It's text and images. And that's like...

wheelhouse for HTML and for hypermedia in general. You want to be able to look at stuff and then click on something and go and look at it. That's the core functionality of the web. It's always been a little bit strange to me. e-commerce has been held up as like, oh, we have to have these fancy SBAs for it. Because, you know, just in the abstract, that seems like a perfect use case for hypermedia and the hypermedia approach.

Yeah, absolutely. Absolutely. I've seen too many projects come across where people have horribly over-engineered their e-commerce websites. When it comes down to it, you don't need... a ton of layers of complicated text to let someone buy something on the internet. Yeah, I agree.

Introducing Locality of Behavior (LoB)

So, the reason I invited you on is because your essay on locality of behavior came up in something I was reading or listening to. I don't actually remember now. And I took a look at it and was like this. This really resonates with me. So I'll start by asking, what is locality behavior?

So locality of behavior. I don't know if you've noticed this, but one thing that I've noticed about software development is that you have to have an acronym. If you want to have an argument with someone, you better have an acronym. And so if somebody comes at you with an acronym, you better have something.

sort of acronym and response and I have you know over my life as a programmer, which is the color of my beard indicates has been a little bit at this point, I have heard separation of concerns an awful lot. And it's sort of a fundamental idea in web development. Hey, we need to separate our concerns. And the sort of canonical example of that is let's separate our scripting, our markup, and our styling into different files to separate those things. And I've never really liked it.

Defining LoB and Locality Principle

I've never really liked that idea. And I finally was like, you know what, I need to come up with my own acronym. So when someone says you're not, this is violating SOC, I can be like, ah, but it's actually. I'm following LOB instead and so that's where locality behavior came out it was just sort of this

realization that, unfortunately, technical arguments often hinge on these sort of three-letter acronyms. So the idea with locality of behavior is that, and it comes, this idea of locality is not new. So I've got to, if you go again to the... Essays page on htmx.org. You can find Locality of Behavior Essay there. And I quote Richard Gabriel. And Richard Gabriel was a lisp, still is. He was, but he was very popular.

Lisp programmer in the 1980s. He wrote another essay that I can recommend to your listeners called Worse is Better, which is an essay on basically why did C win over Lisp? was his question. He was a Lisp developer and he was like, how

Can something as terrible as C have won when compared with Lisp? And that's his analysis of it. And I think that's a great essay because he's arguing against his priors. He's explaining why something he doesn't want to be true is true. So I think that's a great essay for everyone to go on. And but he and another another.

I think it's a book called, I think it's called Patterns of Software Design. He has this to say, he says, the primary feature for easy maintenance is locality. Locality is that characteristic of source code that enables a programmer to understand that source by looking. at only a small portion of it and so the idea really with locality is like i should be able to understand what this thing does by looking at it

just by looking at it. I don't need to look in a bunch of different places to understand what this code is doing. And so I took that. sort of general statement and derived the idea of locality behavior from it, which was behavior of a unit of code should be as obvious as possible by looking only at that unit of code.

LoB vs. Separation of Concerns (SoC)

And to make that concrete, that's a little abstract, but I'm pretty old school. So I came from the days back when we all use jQuery to hook functionality up. And so you'd have a button and that button would have an ID on it. And then over in your JavaScript file, you have a selector that looked that button.

up by its ID and then hooked in some behavior. And really what I was thinking about when I was writing this essay was that pattern, which was considered good because we have to separate our concerns. We have to separate our markup. the button from the JavaScript like what it actually does. I've come to the conclusion over my career that that's actually bad. That makes it very hard to maintain because you end up

tying things together with strings. And I go and look at a button and it's like, what does this button do? I don't know. Like I've got to go and find some reference to it, maybe by ID, maybe by class, like whatever it is. And it's somewhere else. And now to understand that button, I've got to bounce back and forth between a couple of files and so forth. And I just, I really disliked that.

The argument makes sense in the abstract of separation of concerns, but in practice, I found it unwieldy to the point that I started just like inlining, clicking, just writing JavaScript in the button directly, unless it got out of hand. And then maybe you extract it to a function and then call the function. But still, I know we're not supposed to use OnClick. And actually, MDN, the Mozilla Developer Network.

still to this day recommends against using on click and on whatever attributes. But I don't agree with that. I think they're wrong. I think they're wrong to discourage people from using those because it's better locality. When you have a button with an on click handler on it like you can see what it's doing and it's right there and if it calls out to a function sure you can probably control click to jump over there but

But the behavior is on the button. And that's the locality that I think that Gabriel was getting at with this idea. It's easier to maintain. Separation of concerns has turned out, in my opinion anyways, to not deliver. on its promise of easy maintenance and independence because they're just, these things aren't independent from one another. So that's sort of the basic idea. That's the basic idea.

LoB in Practice: Styling and Data

Yeah, it's very compelling. I've certainly found in plenty of situations in my career that I've had to... make this argument without a name, for example, building a quick one-off page for something, and someone's like, oh, why did you just inline these styles on this?

uh, in this template, why didn't you like make a style sheet and stuff? And it's like, well, cause these styles are specific to this one place. They're never going to get reused. This page is probably going to get deleted and someone's going to forget to go delete those tiles. There's lots of different situations where...

We've even seen conventions around this. I've seen a lot of projects where they use data attributes in their HTML that have JS prefixed on them to try and indicate to someone reading that, that there is some JavaScript somewhere. that does something with this piece of markup.

Yeah. And I mean, you're seeing that with tailwinds now, for example, people are kind of throwing their hands up and just saying, okay, screw it. We're just going to jam all the styles in, but we'll do it with classes instead of the style tag to give us a little bit more semantic power.

just raw styling, but it's pretty close to raw styling in a lot of cases. And I have to say, I've never used tailwinds and I still don't like the look of it. My understanding is that's a common experience. People kind of don't like the look.

of it and then they start using it and then it's like okay this works pretty well um so um that's one area where like you know i think tailwinds is very much a locality of behavior sort of uh situation and but i'm not sure like i'm not there yet I might get there at some point.

So I think that, you know, all these things like separation of concerns isn't a bad idea. It can just be over applied. Locality of behavior isn't like the idea. It's an idea and it can be over applied as well. Like you can write too much JavaScript.

in line in an HTML file and said, okay, this is not going to be maintainable. But I think there's other mechanisms, like if you're going to separate your concerns like that, then I think they're rather than the old sort of jQuery approach and even Java just... You're supposed to have it in a script file and you're supposed to look stuff up by a selector and hooking behavior. I think those are bad ways to...

to integrate the scripting layer and the markup layer. I think instead you should have on attributes. that invoke functions. Maybe the function is stored over in your JavaScript file and that's fine. But the invocation of that function should be called out on the element. So you used the phrase spooky action at a distance in the essay. What's spooky action at a distance?

So it's a quote from Einstein. He was, I think, was incorrectly arguing against some results in quantum mechanics. I'm not smart enough to understand that stuff. And he was saying there was no spooky action. at a distance. So no dog in that fight. But I just remember that phrase. And that's what sort of struck me when I was looking again at the way in Vanilla JS and in jQuery.

this culture of like putting these handlers in another file that you had to know about. And you just had to know exactly how the selectors are working. Maybe as you pointed out, maybe they're using a data prefix, which. could help a little bit, but now there's this data prefix and people might be using string concatenation to actually look the things up and hook things in. It can get really tricky to figure out where this logic is coming from.

And I think avoiding that, like if you if you have an on click handler, for example, and you call a function, that is not spooky action at a distance. That is just. Okay, I can see on click, do this thing. I can probably control click on that thing and go see what it does if I'm interested in the details. And that's in contrast with this button that's just sitting there with an ID. It's like, okay.

What's this button do? Nobody knows. You got to go and figure out exactly where the actions that are associated with the button are coming from.

LoB, DRY, and Engineering Trade-offs

So I would call that that spooky action at a distance that I disliked in code bases. So how does locality of behavior, how does this principle relate to HTMX? And was it a foundational idea behind HTMX? I think it was an idea that I had in parallel with HTMX and Intercooler before it, where, you know, with HTMX, so just to give your listeners, if they're not familiar with it, the way HTMX works is you say, okay, let's go back to our button example.

we've been hammering on here. I want this button to issue a web request to the like URL. And so to do that, if you wanted to issue, for example, a post, what you do is on the button, you would say HX post equals slash like. And that would indicate to HTMX is a JavaScript library that finds that attribute and then says, OK, I'm going to issue when this button is clicked, I'm going to issue a request to that endpoint. And this is where. HTMX gets a little different than other JavaScript libraries.

Other JavaScript libraries would typically expect that JSON that would then be update a model and maybe reactively update your UI or whatever. What HTMX does is it expects HTML back. When that HTML comes back, it says,

Now, where do you want me to put this new HTML? Do you want me to replace like an image, maybe a thumbs up or thumbs down image that was below the button? Or maybe you want to replace the button with something. And so there are other attributes that you can put on the button to indicate exactly.

how to swap that HTML into the page. What's the target element? We use CSS selectors if you want to pick, like, here's the element I want to target. And then we also use HX swap to say, here's how I want you to swap the content around.

that like maybe i want you to replace it maybe i want you to put it inside the element maybe i want you to put it at the end of the element all these different options are available but it's all specified there on the button now i was complaining previously about oh people using attributes to hook in behavior right and here i think the difference what i would argue

is that HTMX moves the abstraction hierarchy up a little bit where you understand these attributes specify an HTML or what I would call hypermedia-based interaction, and they're very similar. to like href and the actual there's a target attribute in html it's kind of obscure most people don't know about it but it works kind of the same way as those things and so because of that your mindset is sort of at that level and so

So therefore, the behavior is specified pretty clearly in line on the button. And so I think HTMX has good locality of behavior in that. and from that perspective. So, and that's one thing I really like about it is when you look at a button, you say, okay.

Here's what that button does. It's going to issue a post to this URL and then it's going to replace stuff in the screen. Now I do have to say HTMX has a feature in it called inheritance where you can move some attributes that's documented in the documentation. move some attributes to parents. And so children will inherit attributes from parents. And that can be useful, for example, if you've got three buttons that all need to target the same element. It's annoying to have to repeat.

you know, the target on all three of those elements. And so I made the decision early on, like, okay, for some of these attributes, we'll let you put it on the parent so they can share that behavior. And that is better from a code reuse standpoint. but it is worse from a locality standpoint. So that feature of HTMX violates to an extent the idea of locality behavior. And that's to me, like, this is just a classic engineering trade-off.

Some people really dislike inheritance to the point that we let you disable it in HTMX if you don't want to have that because people dislike it so much. But some people, you know, they get really annoyed if they have to repeat Target, like, you know.

five buttons or whatever. So, so it's all trade-offs and you just have to make the right trade-off for your code base and for your style of coding. And so I think HTMX does sort of follow locality behavior, but it's not, it's not doctrinaire about it. has features that violate it. And that's, you know, so the design, what I want to say, the software design principle here is don't repeat yourself. right like dry keep your code dry which is a big ruby on rails thing if you have the same target

and on five buttons right next to each other, you're repeating yourself. And so, so locality behavior sort of unsurprisingly, it's, it's sort of anti separation of concerns, but it can also be, I don't want to say anti dry, but it can be. it can be in tension with that. And so what makes us hopefully good and mature software developers is that we can make those trade-offs appropriate.

between those various you know good there are various goods in your software system that you just have to trade off between times so you just mentioned you know that LOB sometimes conflicts with dry or... SoC, we're collecting all these acronyms. What are some other common objections developers raise when you're advocating for better locality behavior in a piece of code?

Misconceptions About LoB

I think the biggest one is when, so what people mistake locality of behavior for is we should inline our implementations. Like you should write all the JavaScript in an onclick handler. And I don't think that's true. That is not what I'm advocating for. I think if it's a small, if it's relatively small functionality, like if you're toggling a class on an element or something like that, then it might make sense to do everything in line.

but locality of behavior does not mean that your implementation is necessarily all in that button. Instead what it means is that it's obvious what the button is doing when certain things happen. So it's perfectly acceptable to take a large amount of code, put that in a JavaScript function somewhere, and then use an on-click handler to invoke that function.

That's, you know, that's totally reasonable. And that still is satisfying, in my opinion, the locality of behavior because it's the behavior that matters. Okay, on click, this happens. What this is, like, it doesn't make sense to inline everything. Maybe you want to reuse it and keep yourself dry or whatever. Like you can make these sort of trade-offs, but it doesn't mean inline everything. And I have to say, again, I'm not a big...

I just have not used tailwinds in anger and like gotten over the hump of like this looks. But it feels to me to an extent at times like with tailwinds, like you're inlining behavior. Like I always look at these big chunks of tailwinds and I'm like. It seems like it's a class to me.

Like that should be a class or something. So I can put the class on this thing and then have that defined somewhere else. And that's probably a skill issue on my part. Like I just haven't used, I just haven't used Tailwinds enough to like.

grok it but that's to an extent it feels to me like that like that's because with javascript when i'm advocating you know use javascript uh inline handlers uh when you can um then you always have that option to sort of refactor and pull stuff out to a function and i just don't maybe i'm again i don't know tailwinds in depth enough to say whether or not that's an option.

Yeah, they do. You know, I've seen that argument sort of made on projects that use Tailwind where they're like, you know, you can add custom classes. And some people do that. Some people are like, oh, no, we just got to do the pure using what we got here. thing and you know a lot of a lot of the reuse comes down to whether you have a good sort of component library to to build really fine grained components but even then you still end up with with some amount of

duplicated sets of CSS classes. And when you decide to do that, it becomes a trade-off. So we can see these trade-offs playing off even in that space as well. Yeah, I will say over time, I've become less and less concerned with dry, with keeping my code dry, because what I've seen in my career is a lot of situations where in order to make code dry, people have created.

very complicated object models or very complicated callback mechanisms or, you know, get into these situations where you're passing a callback or closure around like three levels in order to not. repeat some code and you get to a point where it's like guys just just do it the normal way just copy and paste and make a slight modification and it would be less code or it would be less complicated code and less clever code in the long run and for simple enough code maybe it isn't so bad

that there's a little bit of duplication. So I'm a fan of dry. Separation of concerns I've become pretty soured on, although I think there's something to it. But I don't find it nearly as compelling. as I do dry, but even dry to an extent as I've gotten more into my career, I've just become less enamored with the idea. If you go to the grubbrain.dev essay, there's a section on dry.

Who is it? Leah Beru. Someone made a really funny chart of like what's important to developers over time. And basically like doesn't work sort of starts at 100% when you're first starting and you're worried like it's kind of worth it. make it work and then that goes down over time as you're like okay

Like I know it'll work eventually. And then there's another line for dry. And that gets really important at like year 10 of your career and then starts to go down and finishes at about 50%. And I found that to be very true. And then the last. wine is does it read well and that just sort of like increases linearly

throughout your career. So it's a really funny picture. And I think it captures a pretty deep truth about software engineering. And certainly that's been my experience in my career. So it's a funny chart.

Software Design & Deep Modules

Yeah, I think that and sort of a bunch of stuff you said sort of reminds me of, there's a book by John Osterhout called A Philosophy of Software Design. And in it, he makes an argument, sadly, without an easy... three-letter acronym attached to it, that trying to break stuff up into lots of tiny objects, and especially little tiny methods.

is actually quite harmful in a lot of cases and uh that larger methods where it's just obvious what's happening are frequently far better than lots of tiny methods and uh you know i think there's There's definitely a trade-off there, but we're seeing sort of the same idea as locality of behavior there, where he's saying like, you need to know all these things to understand this. So just put them all in one damn method so that I can see them all.

He was the first person that I'd seen make that kind of argument, though. Like I said, sadly, no three-letter acronym for me to attach to it. Yeah, he would say modules should be deep. Yeah, you should create deep modules. And so it's funny you mentioned that book. I'm actually I teach that book in the software engineering class here at Montana State. And I'm like right in the middle of teaching it.

yesterday. But yeah, so modules should be deep. And his idea there is that a module of code should have, if you think of it in two dimensions, if the X is the API and the Y is the functionality provided. The ideal world is one with a relatively high X, so lots of functionality, and a relatively low Y. Let me rephrase that. So a low X. So you don't want much of an API to it. And then you want a high Y. So you want a deep module. You want it to be sort of skinny and deep.

And the reason for that is that then people get a lot of bang for their buck. They learn this relatively shallow API and they get all this bang for it. for their buck. And the problem that you're getting at, I think the term that I use and I've heard people use is over decomposition. which is when people take problems and they just decompose it down into this little into into muck

classes. And I think I'm a, I'm a Java programmer. That's what I mainly program in, which I apologize for that to your listeners, but, and the Java community has, I think a culture of over decomposition. We tend to just create like. hundreds of classes when it's... we can probably get away with like five or 10 classes at times. And in fact, clean code, I don't know if you saw that argument between uncle Bob, who's the clean code advocate. He advocates for lots of little methods and classes.

And he and John Osterhout have an argument, which John put online on GitHub. I'm sure if you Google John Osterhout, Uncle Bob argument, you'll find it on GitHub. And they basically, it's a pretty funny... two old guys arguing and they're like they refuse to give up so it's a pretty funny argument um but uh basically they they're having this disagreement is it better to

decompose everything or is it better to leave some things together? And I'm definitely in the John Osterhout sort of school of thought on that. I think we tend to over decompose and, you know, it's not. It's not surprising. Abstraction is how we make our living. That's what we do. And so it's easy to over abstract things and sort of tease things apart too much.

I wrote another essay. I hate to keep referring to the essays page. There'll be lots of links in the show notes today. Yeah. There's another essay called Coding Dirty. Because I was responding to this idea of clean code. I don't want to throw any shade at Uncle Bob, but I do think that there's a tendency in software development to use language that is like, how could you object to that?

you know like clean code who could object to clean code agile who could object like i want stiff and you know creaky software not like let's So, you know, terms are often used where it's like it's got some moral weight behind it. When you disagree with it, if you disagree with the idea, then you're at some level, you're a bad person.

And so I responded to the clean code ideas in an essay called Code and Dirty. And I have an image in there that gets at exactly what you were talking about, where... When you have clean code and you have what would be called dirty code, what I would call dirty code, when it's clean, what you've got is a million teeny little pieces.

And it's hard to know what's important and what's not important because everything looks the same. Every function is like maybe an if statement, maybe a loop and that's it. And like, okay, what is this? How does this all hang together? Whereas if you're willing to have larger functions and large. classes, then yes, those functions are maybe a little bit harder to get your head around, but it's also your larger functions tend to be more important.

And so, you know, I don't think you should be splitting your code up just to split it up. I think if there's reuse to be achieved, then OK, maybe now it's time to talk about splitting code up. But so that's, you know, I think that's. I definitely am in the John Osterhaus school of thought when it comes to, you know, I think it's okay for things to be a little bit bigger. I actually, I had an email exchange with him the other day.

like a couple of weeks ago. And I was like, I think you should have, I said this about classes. I was like, I think you should minimize the number of classes in your system. And he was like, Whoa, buddy, pump the brakes. crazy but i do you know there's something to me like i think just shooting for a minimum number of classes even if that junks up some of the existing classes especially in your api you know like yeah

Pragmatic API Design

What I was saying to my students the other day, I was setting them up for an API design class or lecture I was going to teach later. If you say what you want to do, then your API should be that, what you just said. And so the example of that that I give, just because it's super annoying to me, is the API for watching a directory for changes. in Java. So the API for watching a directory in Java involves like a directory watcher and like these keys and like all this crazy crap.

I was like, okay, look at this thing. Look at all this code you have to write to watch a directory in Java. Let's say what we want to do. I want to watch a directory in Java. Okay, so our API should be, there should be a directory thing or maybe the file, like there should be a directory and there should be a watch method on it and it should take a callback when something changes. That's the ideal API, and that's one class and one function and a callback, and that's it.

All this other stuff, I'm sure it's driven by the underlying domain, like the operating system. It's exposing the operating system to the end user who doesn't care about it. crap you know and okay maybe like there are situations where the end user does have to care about that and so i talk about this in grub brain where i think you should be layering your apis and have like a really simple api and then a more complicated api one more

complicated stuff is called for um but it's that same idea like let's just you know we don't you don't want to have a thousand classes to get something done job is famous for this unfortunately it's one aspect i dislike about the language so but Yeah, no, and that's, you know, you see that reflected in other approaches, like a lot of people really like outside in design or outside in TDD. And a lot of that is saying like, okay, what object do I wish I had to get my... logic done here.

Let's pretend I have it and it has the API I wish it had and see if we can just make that work. And hopefully that aligns with reality and we end up with something that's easy to use. I really like that.

yeah i really like that approach the the api driven design like what do i want the end user to have to think about rather than here's my domain and expose my domain to the user now the user has to learn all this additional stuff that's got i mean maybe they care about it but often they don't um again i mentioned this if you read the grub brain essay there's a api uh section where i complain about some i complain about java so I spend a lot of time complaining about Java.

Yeah, I mean, you don't really know a language until you have lots of complaints about it. Right, that's what Strauss have said. There's two types of languages. Languages people use and languages people don't complain about.

Practical Steps & HyperScript

So what are some practical first steps that maybe our listeners could take towards improving locality of behavior in their code bases? I think the first thing is getting over the moral objection to like, you know, if you're a web developer, like just use a click handler. It's okay. You don't have to look it up with some crazy selector over in a JS file. It's okay to use OnClick. It's going to be supported forever. It's never going away. I think it's widely used in React.

I don't program a bunch in React, but I think React, when you use GSX, they just say, look, just use the on-click handler. The one thing I dislike about... The on handlers in HTML is that they're restricted only to the events that the DOM fires, and so you can't use them with custom events. And I disliked that so much that I went out and created my own scripting language called HyperScript, which is based on an old scripting language called HyperTalk, which came from HyperCard.

It's a lot of hypers. And it's a scripting language for the web that's influenced by hyper talk. Yeah, hyper talk. And so that is and that's a general it's a tool for like. Basically, it's very event-focused. It's an event-oriented programming language, and it takes the ideas kind of sitting there in the on handlers in HTML, and I would say it generalizes them.

real easy to do a lot of sort of dom oriented things, event oriented things. It's not for everyone's taste. A lot of people look at it and hate it because it's got an English sort of style language to it. But I actually. I think at some level that is better than JavaScript for HTML because Hyperscript looks more natural. When you have a button that, for example, you know, in Hyperscript what you would say is on click, toggle.

dot foo on me. That's valid hyperscript, believe it or not. And what that'll do is it'll toggle the foo class on the current element that it's on. And I find that less jarring to have in line on a button than JavaScript where you've got to like, you know, say this dot class list dot toggle, you know, and then, you know, so it.

The English syntax, I think, embeds better in HTML visually. That's an aesthetic judgment. So I don't know how you could argue one way or the other about it, but that's my opinion on it. And so Hyperscript, even more so than HTMLX is very... area, locality, behavior oriented.

We're going to put even more of the implementation on it. You can have functions and you can invoke JavaScript functions and all that stuff from it. So it is again, not necessary to put the entire implementation on a button, but because it's relatively. terse and powerful and it's an english syntax here it's actually you can get away with putting more of your implementation on the button so it's another thing for your listeners to look up and hate that i made

Future Trends: Pragmatism Over Ideology

So as we look towards the future of software development, do you see principles like locality behavior evolving? Is there a vision you have for more maintainable software that's maybe... I think we're in a retrenchment phase right now. I think the last 10 years have been very JavaScript maximalist and pattern maximalist.

cool, crazy, new, whatever, you know, stuff is going to change everything, you know? And I think they're tried and true principles of software development that have kind of gotten lost in that. And maybe things have gotten a little too ideological in general, just across the entire world. And so my hope is that we don't have a reaction that's like, okay, throw all these ideas out.

But instead, what we do is we go back and say, OK, what are some ideas from the past that are actually interesting and useful for us to integrate into our current understanding? So that rather than this sort of like crazy back and forth. you know, swings where like, okay, let's actually learn from this and synthesize these ideas. Like the idea of locality is good. The idea of separation of concerns is good at times.

The idea of being dry is good at times, but we need to make informed and judgment calls. That's what being a good software engineer is being able to make good judgment calls between those. And I really think there's an aspect of aesthetics to it. You know, like there's there's what's the what the right thing is, is like it looks right to me. And what looks right for one project.

It might not look right for another project. It's one thing I stress to my software engineering students is it's important to, when you go into, especially when you go into a big code base, you want to vibe match that code base. You don't want to go in and impose your style on another code base because the styles at some level are.

I don't want to say that it doesn't matter. Like there's a difference between someone who's dressed super nice in a suit and someone who's dressed, you know, super casual like we do here in Montana. But when you try to mix, like if you go into a business meeting and everyone's wearing suits, like wear a suit.

If you're in Montana, like don't show up in a suite probably. And so, you know, I think vibe matching the code base that you're going into is important. And it gets at that idea of like, we don't need to be doctrinaire about these things. We need to make good decisions. And every once in a while, it's worth it to push back and be like, OK, look, guys, we need to really think about this because it's hurting. We're over.

I see a lot of over decomposition in this, in this code base. So let's talk about that. Let's see if you guys, if I can get you guys to a place where you agree with me. But I, again, I think maybe coming a little bit out of the ideological, like. And this idea that the new thing is always the better thing. Let's go look at ideas like hypermedia and locality from Richard Gabriel and so forth and see if we can integrate those into today's practices and less like.

Finding Carson and His Work

Here's the one way to do it. Well, it's been a pleasure having you on the podcast. Where can people go online to follow your thoughts? I am taking a break from Twitter until the end of Easter. So I'm not on Twitter, but you can find me on Twitter usually at twitter.com slash HTMX underscore org.

And then htmx.org is the website and .org slash essays is where all the essays are. I also have a book called Hypermedia Systems, which is sort of about hypermedia and how to build stuff with HTMX and so forth. forth at hypermedia.systems. You can read it all online for free, but you can also purchase the book there if you want. Then grubbrain.dev. is another kind of somewhat popular website that's just a collection of my thoughts on development.

I'm actually going to be releasing a book version of that in about a week. So this is actually, I think the first time I've told anyone about that. So that'll be coming out in a couple of weeks as well. And then my company is. bigsky.software. So you can go there and that has links to all my products. And if you want to learn computer science, you can come to Montana State. I teach three or four classes here. Awesome. Well, thanks for coming on the podcast.

Yeah. Thank you. Appreciate it. I mean, there's a ton to unpack. in that interview. But I really just appreciate that this idea of locality behavior, which is, I think, extremely important to the software we build. It has a name. I for the longest time didn't know. There was a name for it. I've been thinking about this topic for a long time and certainly have discussed topics around this with people since Carson's essay.

came out, but didn't end up on my radar. So I was really excited to talk about it. And now when I inline some styles on some random admin page on an e-commerce website, I have a nice three-letter acronym. 2.2 to say that i was justified in doing that so that's perfect so i encourage everyone to go check out

Carson's essays. There's a ton of awesome stuff in there. He's got some really great ideas about how to build software and make it more maintainable and how we can build for the web, not just on top of it. This episode was produced and edited by Mandy Moore. Now go delete some.

This transcript was generated by Metacast using AI and may contain inaccuracies. Learn more about transcripts.
For the best experience, listen in Metacast app for iOS or Android