In this episode, we talk to Bruce Hauman about Figwheel, Devcards, being present in the moment and other good advice.
You can send feedback about the show to firstname.lastname@example.org, or leave a comment here on the blog. Thanks for listening!
EPISODE COVER ART
In this episode, we talk to Bruce Hauman about Figwheel, Devcards, being present in the moment and other good advice.
CRAIG: Hello, and welcome to Episode 102 of The Cognicast, a podcast by Cognitect, Inc. about software and the people who create it. I'm your host, Craig Andera.
Let's see – a couple of meet-up and activity type things to mention to you today. The first is the Tri Clojure meet-up at the Adzerk offices in Durham, North Carolina. Tri Clojure is the Durham area, Durham/Raleigh/Chapel Hill, I guess, area meet-up for Clojure. Like I said, that'll be at the Adzerk offices. That's May 26th. This is 2016. At 7: 00 p.m. You can find them online by looking for Tri Clojure meet-up.
A couple ClojureBridges to mention for you: Of course, all information about ClojureBridges can be found at www.ClojureBridge.org. The two coming up that I see on their calendar are in Oulu, Finland. That's June 3rd and 4th. There's another one in Berlin June 17th and 18th.
I think that's all we're going to mention today. There are a million things going on in the Clojure universe. We love to talk about them, but we will go ahead and get on to Episode 102 of The Cognicast.
[Music: "Thumbs Up (for Rock N' Roll)" by Kill the Noise and Feed Me]
CRAIG: Great. I can't think of anything else before we get started. Are you ready to fire it up?
BRUCE: Yeah, let's do it.
CRAIG: Awesome. All right, well, welcome, everybody. Today is Tuesday, March 15th in 2016, and this is The Cognicast. I am very pleased today to welcome our guest, Bruce Hauman. He is the author of Figwheel. You've probably seen his name a lot in conjunction with ClojureScript and a bunch of other things that we're going to talk about, so welcome to the show, Bruce.
BRUCE: Well, it's great to be here.
CRAIG: Well, we're certainly thrilled. Your name has come up a bunch of times over the last few months in a variety of contexts, but certainly in the discussions around the office of who we should have on the show, so I'm glad we're making it happen.
We always start the show with a question that I warned you about, which relates to an experience of art. We kind of like art on this show. We think software is about people. Art is certainly about people. And so, we always like to ask our guests to relate some experience of art they've had, whatever that means to them. Hopefully you've had a chance to think of something you wanted to share with our audience today.
BRUCE: There are a couple things. A couple things come to mind. Art: I would say my most important experience of art is when I went to Chicago, went to Second City for two weeks, and then I did iO Improv for two weeks. It was basically – no, for seven weeks total. I basically studied improv in Chicago, and there were a lot of interesting experiences there.
** But, the most compelling one that came to me through it all was this idea of being present and facing the world as it is. And, when you're doing improv, you know, the enemy of facing the world and being present to it is resistance, right? Like**: I don't want to do this, I don't want to be here, and various other narratives that go through our head about what we don't want, and so, yeah, that. There were some sublime experiences with that.
Actually, one story in particular, this incredible instructor who studied French clowning had us all stand on stage one at a time and walked us through a relaxation, and made us actually just reveal ourselves and become more vulnerable in who we are on stage in front of people. One of the most interesting, compelling moments was watching somebody like that. It's somebody vulnerable, on stage, all by themselves, not saying anything, but just being very real and very present is compelling in itself.
And so, the instructor stopped us and said, "Look. This is compelling by itself. If you do anything in addition to just being present, make sure it's worthy of the space." I'll never forget that.
CRAIG: That's really interesting, and it's funny because, in a way, it sounds like the opposite of comedy, right? It sounds very, very serious. I will say I understand, a little bit at least, that being serious and comedy are not really opposites. But, at the same time, there's a juxtaposition there that really strikes me.
BRUCE: Oh, yeah. Yeah. I mean when you're there it's very serious. When you're there, you think of it as all fun and games, but I went there not to become a comedian. I went there to just kind of wake up again and get out of the whatever rhythm, current rhythm my life was in day after day after day, which tends to make things – you know, life can take on a pall if you just keep going through the same motions and the routines, so I went there to shake it up because I knew it would. It's like there's no way in heck you're going to get out of this without being affected.
But, it's hard, right? You get on stage, and there's instant feedback whether you're being present and available to what's going on. I mean instant feedback, right? Like somebody says something to you and you just crumble into a million pieces. You know that you're not present for what's going on and that you're kind of caught up in your own drama.
Yeah, I don't know. These people do serious work, you know, Steve Carell. All these people who seem like they're just playing around have worked tremendously hard and tremendously seriously - if I'm using serious in the right context.
CRAIG: Yeah. It makes sense. I'm curious. Did it work? You wanted to shake it up. You said you knew it would. It sounds like it did.
BRUCE: Oh, yeah. Absolutely. Yeah, you can't. It's just one of those things, like you know if you sign up for this event or go to such-and-such a thing, ahead of time, you're going to come back affected. Yes, I was affected. It's good to be present for life, and that's kind of what improv teaches in that there's a lot more there. There's a lot more there available to you than you actually think.
BRUCE: These are all big thoughts. I don't know what else to say.
CRAIG: No, no. That's great stuff. That's great stuff. Okay, well, that is a really cool story, but I think we will shift gears slightly and maybe ask you about some of the other interesting things that you have been doing. I don't know where to start. I actually have to admit the two things that I've heard your name in conjunction with, or the several things I've heard your name in conjunction with, are actually not things that I have been spending a whole lot of time with.
One of them is certainly Figwheel. I will say right now my colleagues at Cognitect are quite impressed. People have just been dropping praise on it in our HipChat rooms or whatever, but I've never used it myself. I just haven't been doing any ClojureScript work. I wonder if you wouldn't mind explaining to a Figwheel ignoramus like myself what it is and then maybe give us some of the background on how you developed it and how you see it helping people, et cetera and so forth.
BRUCE: Figwheel: it's both a tool to help you develop ClojureScript, and it's kind of a proof of concept. It's kind of a proof of concept in that what does a workflow where your code gets automatically loaded for you as you're coding look like. It started as an experiment.
Figwheel engages the ClojureScript compiler on file changes. So, if a file changes, it compiles your ClojureScript code. It then sends a message through a Web socket to the browser, and the browser does some calculations. The client code does some calculations and then tries its best to reload the appropriate files in the appropriate order. It does its best to deliver a fast, seamless, reloading experience. Does that make sense?
CRAIG: Oh, yeah. Totally. Yeah, absolutely.
CRAIG: It's not terribly dissimilar to some of the things that we have on the JVM side.
BRUCE: Yeah, it's not. Not really. It came about because, initially, working with ClojureScript, it was challenging. It was new, and it was supposed to be challenging. The REPL was difficult to get going, and I found that development experience intolerable. I loved the language. I loved, and I wanted to see it work well, and I wanted my flow to be fun.
Yeah, it started from that frustration, but then the experience I want is I want to be able to change my code and see the changes immediately in the browser. This is the experience I want. I think it's the experience – it's an experience that most developers want. And, it's something that Clojure delivers pretty well.
ClojureScript has some advantages in that, once you redefine something, it's redefined. ClojureScript doesn't have VARs in the sense that Clojure has VARs. Everything is redefined and presents kind of a unified landscape, a consistent landscape, whereas if I redefine this function, everything that refers to this function should get the new behavior. Does that make sense?
CRAIG: Yep. Gotcha. I'm following you.
BRUCE: Yeah, yeah. Yeah, it turns out it worked pretty well, and it's been working really well for me, and I think a lot of other people as well. I don't know. It makes me really happy that a lot of people are embracing this live reloading workflow.
You know, something about it that bypasses that REPL interaction. It's nice to have the REPL interaction to do testing functions and seeing if this phrase of code works and testing if that phrase of code works. But, to see how the whole application is behaving, as a result of this change, immediately is really nice. It's something that fits the particular landscape of working in the browser pretty well, I think.
CRAIG: What is it about the particular landscape? What are you referring to there?
BRUCE: Yeah. What were you going to say?
CRAIG: No, no. That's it. Go ahead.
CRAIG: Somewhat. I guess I wonder if you could take me a little bit deeper on that, because I could imagine sort of arbitrary state that I've built up in the course of building an application, and I can't imagine that any utility, Figwheel included–maybe I'm wrong–would be able to recover me to some arbitrary point that I've somehow navigated to in the course of development.
BRUCE: I hear what you're saying, and yes. If I hear what you're saying, the encouragement, like Figwheel comes with a cost. This development style, whether it's Figwheel or another tool comes at a cost, and that is you need to be conscious of the load time side effects of your code. Does that make sense?
CRAIG: Oh, yeah, totally. Yep.
BRUCE: You don't get reloading for free, and I don't think anybody gets it. I think maybe some day a Haskell or an Elm might get reloading for free, something a lot more pure. Now, if I understand your question correctly, I think you're saying that, yeah, arbitrary state can get built up in your browser, and it can cause inconsistencies, just like the REPL.
CRAIG: Yeah. That's exactly it. And so, I guess what I'm trying to understand, as someone who hasn't used Figwheel, is I'm going along and there is some implied workflow, and it's one that fits well with how people tend to write. Based on hearing my friends say this is awesome, it obviously fits well with what they're trying to do. What is that workflow? You're going along, and you're doing things a certain way. That way is what that Figwheel fits well with it?
BRUCE: Okay. Just to draw a caricature of an architecture that people normally work with is a single atom, right? I have single source of truth like an atom. Then the views are derived from the atom. Then events basically fire transitions on that atom. The atom fires a watch, and then the page is re-rendered. Does this make sense?
CRAIG: Mm-hmm. Yep.
BRUCE: Now, if most of your code on this page are functions, React components can be considered pure functions, in a sense, because of the way they're rendered into the DOM. That's a whole slew of your code that can just be reloaded. Right? Then your functional transitions on the add-on is a whole slew of code that could just be reloaded. Does that make sense?
CRAIG: Mm-hmm. Mm-hmm.
BRUCE: Even code, even side effect firing code, can be reloaded whole hog if it's based on a name space identifier, a VAR. As long as it's attached to an identifier in a name space, if it gets reloaded this new behavior is available normally across the board, unless you've captured an honest to goodness hardware from … somewhere.
CRAIG: Okay. All right, I'm following you. That makes sense that that's all pretty general, not especially limiting. The idea of, as you say, having an atom and transitions on that atom and dealing with events, that encompasses a lot of stuff.
BRUCE: It encompasses, yeah, a great deal. In fact, the places where people seem to have the most trouble with Figwheel is they want to make a go loop, and they want to make it reload. A go loop is a particular thing with its own state as it goes through its state machine. They'll either define it top level with a single def that'll say, "Here. I've created this loop," or they store it somewhere. Then they want to modify it, and they don't understand. They just don't understand that it can't just be reloaded. That seems to be the most confusion that people seem to be having, but I'm not watching everybody use Figwheel. Yeah.
CRAIG: I actually wanted to ask you about that. You said you're not watching everyone use Figwheel. But, at the same time, it seems to have become–from my view on the sidelines–quite popular. Were you surprised by the reception of it?
BRUCE: Oh, of course. I was surprised by two things. Initially, I was surprised by the slow start. It seemed really anonymous at first. Then I expected people to use it, but I didn't realize that it was going to just take off like this. I guess take off in terms of our relatively small community. And, it pleases me to know end that that's the case.
CRAIG: Very cool. Have you heard any especially interesting anecdotes or stories from people or gotten any especially interesting feedback, I guess I'd say, about their use of Figwheel or the things it's enabled them to do or anything like that?
BRUCE: There is a lot. I don't know. I feel very lucky because, if you look at my Twitter feed or people calling out my name, they're constantly saying thank you. They're constantly saying, "Wow, I can't believe I'm having this experience," "Figwheel Rock."
It's really nice, and I really appreciate that feedback. Some people tell stories. Somebody told the story about they found a bug, they told their workmate about it. He integrated the change by doing a pull from GitHub, and then the change showed up in his browser. Right?
The components he's working on, the browser, had a bug. He left the browser open, pulled the code into his code base, and the change just showed up right in front of him. So, I don't know. That's fun.
CRAIG: That is pretty cool, actually. I don't know what it is. I mean it's not any different, right? You git-pull, the code changes, it gets reloaded, but somehow that seems magical when a stranger on the Internet can modify your browser, effectively.
BRUCE: Yeah, exactly. It seems magical. I think it's mostly – I don't know there's anything terrific about Figwheel itself, but I think what it's competing against or the juxtaposition is reloading your browser every ten seconds, right?
CRAIG: To what extent is this linked to React? Again, knowing nothing, is it the case that, without React, Figwheel wouldn't exist, or they play well together? Where is it on that spectrum?
BRUCE: Basically, React made hot reloading much, much, much – there's a cost to thinking about the load time side effects of your code. If you're working with jQuery or directly with a DOM, you're going to have to carefully segment your code into "this is not reloadable" and "this is reloadable." Right? You're going to have to make sure. You make some blocks that are def once. The first time the file loads, the setup code runs and blah, blah, blah, blah, blah. Right? So, you have to put a lot more effort into it.
But, since you can just call React render, you know, I want to render to this DOM element, and it's an item potent call, yeah, that changes that dramatically. All your listeners, all your event listeners that are in the Dom, all this stuff is just handled by React. And so, it made it from being something that cost a lot to think about the load time side effects of your code to something that really costs very little.
CRAIG: Gotcha. Yeah, it makes sense.
BRUCE: React is, yeah, a huge piece.
CRAIG: Yeah. I mean we've talked about React before on the show, and I think everybody is starting to become familiar with the advantages there. Certainly, if code reloading is Figwheel's wheelhouse–fig wheelhouse–then it makes sense that those two would play well together.
CRAIG: Where does the name come from? I haven't even read the "Read Me." Obviously I'm a terrible host. Yeah.
BRUCE: That's what your research assistants are for.
CRAIG: Well, right.
CRAIG: I am thrilled beyond thrilled that I get the already incredible amount of help that I do. I don't want to even seem moderately ungrateful. I could at least go read the Read Me and I haven't done that, so mea culpa on that one.
BRUCE: Okay. I think the name came from – oh, my gosh. I'm going to have to look at the Read Me. Now we're getting to the point where I'm going to start tripping over my tongue in this interview.
Instead of a REPL, it's not a REPL, right? It's not a real eval print loop. It's a file eval GUI loop.
BRUCE: Right? You can almost get there from there, right?
BRUCE: File eval GUI loop. I said it out loud: fegl. Then I added the GUI: fegwheel. Then Figwheel. Then I looked it up, and there are literally no references to anything.
CRAIG: Always a good thing.
BRUCE: I was like, you know, that sounds good. Unfortunately, it's really hard to type.
CRAIG: Is it really? It doesn't seem like it would be.
BRUCE: It's the H. Your fingers want to put the H before the W. It's just a very strange juxtaposition. For some reason, G-W-H-E is a little strange, and so your fingers aren't used to it, and so you could type it wrong.
CRAIG: Interesting. I won't even bore you. I'm kind of into keyboards and typing, but I won't even bore you with that. I'll have to think about that one, though. That one has got my brain going.
I want to make sure that we cover some of the other things that you've done because you're a very productive guy. We may have to come back to Figwheel at some point, but the other thing I wanted to talk to you about, at least one of the other things I want to talk to you about, is Devcards.
CRAIG: Which is another thing that you've put out in the world. Hopefully Devcards is easier for you to type. But, this is another one that I haven't used, but again that I've heard people say this is a cool thing. So, I wonder if you could take me through from the beginning on that one as well.
BRUCE: The idea for Devcards came shortly after the idea for Figwheel. It's funny because Figwheel came out before I even really became remotely aware of React. But, it was quickly thereafter that I became aware of React. Then the idea for Devcards came along. Basically, again, it's kind of born out of experience. My experience of working with ClojureScript initially was I love the language. Functional programming, immutable data types, sold. But, the experience was difficult and it was staccato and it was hard to stay in the flow of things - the flow of creativity.
Since I was focused on what was constraining my experience and what's the experience that I want, since my mind was in that frame, I quickly got to the point where, you know what I really want is I want to be able to create snippets of DOM examples or React examples and raise them up into an interface irrespective of a containing application. I want a work area. I want a Web app that's a work area for creating Web apps. I want latitude. If I want to just try something crazy, I want to be able to type it out really quickly and see it as an independent code example in a Web application. Does that make sense?
CRAIG: Mm-hmm. Mm-hmm.
BRUCE: In the same sense that a REPL, you can try out a function independently of the rest of the functions, you know, of the functions it doesn't call, obviously. In a Web app, what we normally do is we develop and we've gone through the work of setting up an environment where we can see our rendered application in the browser. Since that's kind of a heavy lift to set everything up, we tend to stay within that context, which is a highly limiting context if you want to just try something out.
Well, I want to just hang this DOM in the middle of my page and see how. I want to just hang this tree of React components in the middle of my page and see how they're behaving. It's kind of hacky, and a lot of times the context, the surrounding context doesn't actually allow you to do the thing you wanted to experiment with in the first place. Another thing is it's transient. Your little experiment, you tried it and it's gone. But, what if you liked it and you want to grow it. Then you have to bite the bullet and create an environment for it before you keep going. Anyway, Devcards is to basically create freedom of expression around all of this. It kind of grew into, well, you can write documentation, and you can write your thought process, and kind of a literate tool. It grew into testing and stuff like that.
CRAIG: From a visual standpoint, the idea here is that I would have a page that would have little, I guess, chunks of self-contained ideas in it, and that I could individually manipulate and modify them. Is this correct? Does this sound right?
BRUCE: Yeah, that's exactly it. That's exactly it. I hope my explanation was clear. I've actually had a hard time, initially and throughout, trying to explain the reasoning behind it, but hopefully my pitch is getting better.
CRAIG: I think it is. It certainly made sense to me. I guess the part I'm not clear on yet is, so it certainly makes sense from a sort of prototyping standpoint and from I have an idea and I want to mess around with it. How do Devcards, if at all, take me beyond that? In other words, is the thing that I wind up with something that I can then drop into an application or, even better, multiple applications in some way? And, is that way more aligned with copy and paste, or is it more aligned with a finished component? What's the experience there?
BRUCE: It's more, I would say, if I'm understanding what you mean by a finished component, a finished component could be many things. A finished component can compose your whole application. Does that make sense?
CRAIG: Mm-hmm. Yeah.
BRUCE: Right? If you're building up from components, you can get to a pretty high level before the Devcards environment becomes limiting, so you can get pretty far into an application before you're like, okay, I really need to put this into its own environment. That's been my experience. But, if somebody was going to back into it, like somebody already has an application running and they wanted to start using Devcards, the experience would be more like: I'm going to work on this component independent of the application and then I'm going to drop the component in because it's going to be very hard.
Devcards encourages extremely independent components, and so it's really hard to back. It's hard to back out of an application that's probably pretty tightly "coopled" - coupled. I always "coople" just to sound sophisticated.
CRAIG: You were so smooth it went right by me. I wasn't going to comment at all. You know it's funny. I feel like there's–and maybe you'll agree, maybe not–a theme at least between Figwheel and Devcards, and maybe other things, in the following way: We've said on this show a lot, and certainly I'm not the only person to say it, by far, that software is about people. I look at your work as you've described it, and I say, "Okay, well, what Bruce has done is kind of recognize where people were running into walls in terms of the sort of subjective of qualitative experience and knocked down those walls, put a door in, or whatever metaphor you want to use." Do you know what I mean?
We have this idea that Rich articulated a long time ago, relative in Internet years anyway: simple versus easy, or simple made easy. I guess he wouldn't say simple versus easy. I don't think he would say it's an either/or situation. But, there's very much an element of: let's take some of the simple and make it easy in your work, if that makes any sense. I don't know. Does that seem like a thing that you have aspired to is to smooth the way or to add some easy into our lives? Or, am I putting words in your mouth?
BRUCE: Yeah, I would say absolutely. I would say that it's an empathetic response to things that seem difficult. You know it's both that, and I wanted to create tools that I think solve real problems for people, which I think is just another way of saying what you just said, tools that solve maybe problems that we've become unconscious to. Right?
CRAIG: No, you totally did. It raised another question, though, which is: As I think about some of the people I've talked to that are doing really interesting work, like yourself, it occurs to me that one of the things that they're able to do is to perceive the pain. I think everybody has heard that boiling a frog analogy, like the water temperature comes up slowly.
BRUCE: Yeah, yeah.
CRAIG: I kind of feel like, to some degree at least, maybe a large degree, I'm like a frog.
CRAIG: Someone will come along and say, "Hey, man. Why are you doing this thing? You're using this tool that makes this thing really hard?" I'll be like, "Well, I don't know. I learned it and then I just do it now." I just that I kind of accept this pain, this cost, this price, whatever.
BRUCE: Yeah, yeah.
CRAIG: Yet, you and other people have been able to make cool things certainly by coming up with good solutions, but also by noticing the problem in the first place. I wonder whether you have any insight as to how you've been able to do that. Do you know what I mean? Why is it that you look at a situation and go, "This is unacceptable," whereas someone else, like me maybe, just accepts it? Is there some key that you have that lets you do that?
BRUCE: That's a good question. I think any answer would be conjecture and/or boasting, so I feel cornered here.
CRAIG: I'm sorry. No, I mean I don't think it's boasting if you say, "When I look at a problem I see this." That's just your process.
BRUCE: I feel like I think it was having – so I got out of a stint in industry, and I had had enough. I'd had enough Ruby. I had enough Rails. I had enough of programming, and I was highly sensitive to the suffering and the pain that the process can cause.
And, after basically a year and a half of not programming, Clojure – you know, Clojure was in the middle of my radar, and I started working with Clojure, maybe less than a year and a half, and I really enjoyed it. But again, I think part of me was just waiting for, okay, where is the pain? Maybe I was just in the right – like, if there's too much pain in this, I'm leaving.
BRUCE: But instead of leaving, I was like, well, I can fix this - or whatever. Another thing was just, actually, I think that period of time gave me enough space to actually do – you know, yeah, I think this is a better answer to the question. That period of time gave me enough space to just do what I wanted to do. Does that make sense?
CRAIG: Was this when you went and did the Second City thing?
BRUCE: No, no, no. This is long after. This is years after that now. This is just before writing Figwheel a year and a half ago, so like three years ago or four years ago I left the industry and took a big break. Again, I think the time of just not doing anything and being okay with not doing anything provided a lot of space, no pressure, no "I have to be this," "I have to do that." I think the space allowed me to see things more clearly when I started playing with computer programming again. Does that make sense?
CRAIG: Mm-hmm. Yep.
BRUCE: Yeah. Yeah. I would attribute it to that, probably, because I had the idea for Figwheel and the Devcards, like, back-to-back; they just came along. Actually, we continue on in this vein. My next thing that I'm working on in Figwheel is very, very good configuration validation in contrast to the configuration validation we have for anything. Kind of like, "Hey, you misspelled this word. You misspelled this key, and it's in the wrong place. Maybe you should put it over here. And, by the way, here's the documentation for that key," kind of a thing. Again, I think it's: Wow, people are really, really struggling with this. What would it look like if we just kind of illuminated it?
CRAIG: I thought I saw a tweet from you the other day that was pretty much exactly that. Hey, wouldn't it be great if this error message, "Failed to locate–" right?
BRUCE: Yeah, yeah, yeah.
CRAIG: –turned into, "I think you meant this. If that's what you meant, then you should do this."
BRUCE: Yeah, yeah.
CRAIG: Is that what you're talking about?
BRUCE: Yeah, that's what I'm talking about.
CRAIG: What's the key to that? In the limit, that sounds like strong AI, right? Obviously it's not that.
BRUCE: No, no, it's not strong AI, but it's a tradeoff. My initial expectations are not met by any. My initial expectations for this tool are not being met yet, but no, it's more like I'm using basic type interference algorithms, like Hindley-Milner or stuff like that, or Hindley-Milner-like.
I'm not pronouncing that right, so that's how much I know.
CRAIG: That's okay. I don't know how to pronounce it either. I know what you're talking about though.
BRUCE: Yeah, yeah. I know as much about it as I know how to pronounce it. But, I'm using type inference and basic probability to be like, okay, this key. I have a missing key here, or I have an unrecognized key here. Well, let's look at our available space and see what's most likely to be the case, right? Just by defining types, by defining types for the various configurations, the nested configuration space, you can get pretty far. You can get to a place where you've surpassed people's normal experience, which is like a stack dump - stack dump. That's the normal experience.
People check for a few things in a bespoke manner throughout their code, but normally, like for example for Figwheel. Let's just take Figwheel for example. If you mistype Figwheel, which is very easy to do, and it's in the top level of your project's CLJ, Figwheel, that is not a required configuration key for Figwheel to run. It doesn't need to be there. Figwheel will still run.
CRAIG: A couple of things caught my ear there. One is, you mentioned types, and I'm wondering what exactly you meant by that. Are you simply talking something like schema, essentially, a structure?
BRUCE: Yeah, like a schema. Exactly. Exactly that. Yeah, yeah.
BRUCE: Exactly. Yeah.
CRAIG: Are you using–what are they now–Plumatic, formerly Prismatic Schema, or is this something else that you're doing, or something like that?
BRUCE: I wanted to use Prismatic Schema, but its structure–as far as I could tell from my using it for the trial period–is I couldn't really get in there and iterate through the various paths, especially in an "or" situation. You could have this type or that type, and I wanted to be able to reach in there and get that data and query it.
BRUCE: And so, Prismatic, it's optimized to be fast. It's not optimized for introspection, and so I kind of had to, of course, write my own. Yeah.
CRAIG: Well, it makes sense. Prismatic seems like they're a little bit–this isn't strictly true, but it seems like–more oriented towards a binary yes/no, is this thing one of these.
BRUCE: Yeah. Yeah, and with simple error, with errors that are like this key is not recognized. This required key is not there, and things like that, which are extremely helpful. If you have a Leinigen plugin that you're the author of, you should, at the very least, throw Prismatic Schema on your configuration so that people can get a real quick readout if they did something wrong.
CRAIG: You wrote your own thing. Is that something that will be coming to light as its own independent? Maybe it already has.
BRUCE: No, no.
CRAIG: Okay. All right.
BRUCE: Only if it works.
CRAIG: Okay. That's a good criteria. I wish more libraries would use that particular heuristic.
BRUCE: Only if it works. I have to say I'm pretty sheepish about it right now because I've worked on it for way too long. I started with core.logic because I thought, wow, this could be a great, fun thing to do with core.logic. Core.logic provided, actually, a lot of insight into the problem. Yeah, I banged back and forth through a few things trying to balance speed and actually a comprehensive view of what the possibilities are.
Yeah, right now the code is in that middling state. It's functional, but it's the result of a harried search. If you consider programming a search problem, it looks like I searched everywhere but the right place.
CRAIG: Okay, well, it's interesting nonetheless. I think, regardless of how the search goes, I think the goal is an admirable one.
BRUCE: Thank you.
CRAIG: If it serves that end, fantastic, like better error messages is clearly something people care about based on the State of Clojure survey. It consistently comes up, again and again as a thing that people stub their toes on.
** The other thing I wanted to ask you about relates to that as well, which is**: I guess it comes down to how you're determining what to say. I could imagine, on the one hand, you're like, "Well, I'm going to write a tool that's going to have a set of rules that cover all the cases." That are like, okay, there is a general case of a key missing, and I have something to say about this error whenever there's a key missing. Versus–and you kind of alluded to this earlier where you said–you could embed, instead, very specific rules. Oh, the foo key is missing. I will print a message that is specific to the foo key missing.
I guess what I'm wondering is where on that spectrum did you land, and did you use things like, "Well, I know that on the mailing-list or GitHub issues or whatever feedback mechanism that people are running into this particular thing a lot, so I've got to make sure I handle that particular scenario"? Does that question make any sense?
BRUCE: It makes a lot of sense, and the answer is simple. There is nothing. Right now, there are no specific rules for specific keys, for specific schema. There's no rule in there that says, "Hey, if somebody does this particular mistake." No, I tried to make it general for obvious reasons. Does that make sense?
BRUCE: Yeah. Yeah, so far it's a general tool. Yeah, yeah.
CRAIG: You said you think it's functional. Is this something that's in the latest builds of Figwheel? Are people going to start seeing this soon? Are they already seeing it? Where is it at?
BRUCE: No. Really, by the time this podcast comes out, for sure, it will be. It will have been released because it needs to get out there. I have to get this in people's hands.
CRAIG: All right. Very cool.
BRUCE: Because it's been in my hands way too long. Yeah, yeah, yeah. People should be experiencing this by the time this podcast comes out.
CRAIG: Fantastic. That'll be interesting. Sorry. Interesting is a word that people often use to mean "good luck, buddy."
BRUCE: No, no, no.
CRAIG: Actually, given your track record, I think that I'm really, really interested to see. I think that type of thing is really important, like the human psychological elements. There's so much to explore in that space. In Clojure, nothing is perfect, but we have the technical side of things covered really well.
CRAIG: The technical qualities are just really, really well done. Rich, Alex, and all the people that contribute to Clojure are killing it, and ClojureScript, obviously, as well, are killing it on the technical side, so it's really cool to see people like you coming along and addressing some of the other important factors in the development story.
BRUCE: Oh, yeah. Yeah. The thing that comes to mind is that hopefully the work is going to be done on errors, especially macro errors. I don't know if you saw Colin Fleming's talk.
CRAIG: I did. Yes.
BRUCE: I agree with you in many ways. To me, that is the frontier. I feel like we've got the technicals down and some of these other problems are very challenging. Error messages on macros: It's a challenging problem. It's one that's been solved in other communities and–I don't know–based on people's responses to the State of Clojure 2015 survey, it seems like this is extremely important for people. Actually, if you look at the whole State of Clojure survey, it seems like it's a referendum on: We want tools with great feedback, right? People list the REPL, the interactive experience.
They list as being extremely important to them, and they also list errors as being extremely important to them. Then Figwheel also made a debut, which again is like, "Hey, we want quality feedback, quality human feedback from our tools," because it only helps us because programming is hard enough as it is. It's so hard. Yeah. Does that make sense? Am I answering the question?
CRAIG: Absolutely. Oh, yeah, I totally agree. I was commenting to somebody just the other day. I don't know what the actual number is, but let's say there are ten different types of feedback that are important in development, and we have–I'm just going to again make up a number, but let's say right now we have–it feels like we have three of them. We've got some subset and some of the other ones we don't have at all in Clojure.
CRAIG: We have the REPL. The REPL is amazing. It's like I type something and it immediately exists, and I can play around with it, et cetera. You've done similar things with Devcards and Figwheel. But, there are other things too. I know people have taken cracks at this, and I haven't surveyed the landscape, so maybe there's something out there that's awesome, but in terms of the sphere or things that I personally use on a day-to-day basis. Visualizing large data structures: I don't have a tool in my hands that let's me do that, and it would be useful every single day that I program Clojure.
BRUCE: Absolutely. Every single. Absolutely, especially if it was available with a quick key combination on an existing, defined data type. That would be amazing, right?
BRUCE: That would be amazing.
BRUCE: Yeah. I have a question. We have these wonderful persistent data structures, which have a tree of their existence. When I first used Clojure, I looked for the history function to apply to a map. I was like: There's got to be a function that gives me the history of its values. I was disappointed. I was like: Oh, darn!
CRAIG: Well, there's good reason for that, though, right?
CRAIG: Garbage in particular, right?
BRUCE: Yeah, yeah, yeah, yeah.
CRAIG: Yeah, I mean you know, but I think, nonetheless–
BRUCE: But even the last ten frames.
BRUCE: I want it to be collected, but the last ten frames, as a programmer. You know the last–
CRAIG: Yeah. Yeah.
BRUCE: –would be extremely valuable. We're lucky that we don't have this – how did this global – how did this state and this object get to this point? We're really lucky not to have that in Clojure as much as other languages. But, we definitely have the: How did this function get this value? You know?
BRUCE: How did this value come to exist, because I'm really curious right now, and I would love to know the last–I don't know? I would love to know what were the last 10 steps this value took in its lifetime, or 20 values.
BRUCE: I think tools could have a heyday with that, especially if trace it, like tracing was built into it in terms of like file line numbers and stuff like that.
CRAIG: Oh. Oh, yeah, or combine it with visualization.
CRAIG: Right. You can picture it, right? You could say, "Okay. The code went here."
CRAIG: "Then here was the tree before, and here is the tree after with the new parts in green and the parts that went away in red." You could imagine that being super useful.
BRUCE: Absolutely. Absolutely. And again, to me, I feel like we're agreeing in that, to me, this is more of a frontier. I don't know. I feel like there's a lot more opportunity here to invite people to Clojure. There's a lot more opportunity to gain a lot more Clojure users with things like this. Yeah.
CRAIG: That's a fascinating discussion. We probably should start to wind down here, so as not to make the show the two-hour discussion that I would love to have with you. You and I talked. I think it was at Strange Loop. That's where we last saw each other.
BRUCE: Yep. Yep, yep.
CRAIG: Yeah, it was a fun conversation, so I knew that today I could easily fall into having another one of those, but we do like to keep the shows under three hours just out of mercy to our listeners. But, I can't let you go without asking you about one more thing. I think Kim, in particular, said you've got to make sure you ask him about geodesic domes. This is something that you have an interest in, right?
BRUCE: Yeah, yeah. Temporary shelter, in general, I've always had an interest in. I'm a minimalist, and not by discipline. It's neurotic. I don't know why, but I'm kind of a minimalist. I don't like to have tons of stuff. I don't know. But, I've always been fascinated with temporary shelter, and I was a carpenter back in the day. I've always liked building things with my hands, as you do.
BRUCE: I'm aware of.
BRUCE: And, temporary structures have the advantage in that you can build them and live in them without it being a huge production, right? You can experiment. You can try things out, and so much like programming. Programming is accessible in the sense that your raw materials are always available. Well, temporary shelter has the same experience. You can design. You can think about it. But then, when it comes time to build it, you're not going to break the bank.
I don't know. I've always experimented with it. I've always had various dreams and whatnot. But, I did settle on this one design, the one that is currently my bedroom, my glorified bedroom of sorts. Yeah, it's kind of simple. I mean you can read about it online, my website.
I don't know how much to say about it or what to say about it other than it's a geodesic dome that has no frame. It's basically corrugated plastic sheets on the inside, corrugated plastic sheets on the outside with two layers of, let's say, blue board Styrofoam insulation, if that means anything. The skin is very thin, but actually, for around here, the insulation value is really, really high.
It's kind of amazing, synergistically. All the materials work together to keep it up, and we're talking about a quarter of an inch of plastic on the inside, a quarter of an inch of plastic on the outside, and two three-quarter-inch slices of Styrofoam between them. They all kind of work together to create structure and strength, and so there's no wasted material.
CRAIG: That's very cool. I know exactly what you're talking about in terms of being surprised by the strength when you think about the individual materials. I've done some cabinetry, bookshelves and things like that.
BRUCE: Yeah, yeah.
CRAIG: I'm always amazed. You take, like a bookshelf, it's basically two sides and a top and a bottom. If you think about attaching something like that that's a rectangle, it's really quite weak, right?
BRUCE: Absolutely. Yeah, yeah.
CRAIG: One good shove on the corners and you can destroy the whole thing, until you put either what's called a face frame on it, which I'm sure you're familiar with–some people might as well–and/or you nail on the back. Even though I've done it enough times to know better now, I'm always amazed that when I do either of those things, this whole thing suddenly becomes almost indestructibly rigid.
BRUCE: Rigid. Yeah.
CRAIG: It's a quarter inch of plywood on the back or these little thin, inch and a half wide pieces of wood on the front, and it just makes the whole thing crazy strong. It's very cool.
BRUCE: Math is cool.
CRAIG: Math is cool. Math is definitely cool. Stay in school, kids. Well, awesome. Bruce, we still have a few minutes remaining if there's anything else today that you think that we should talk about. If not, I will say to you what I say to all of our other so interesting guests, which is, come back again and talk to us some more some other time about Figwheel or about whatever else. But, like I said, we certainly have a little more time today if there's anything that you're especially excited about that you want to talk about on the show right here.
BRUCE: Oh, my goodness.
CRAIG: You can always save it for our next conversation.
BRUCE: Yeah. Isn't there an advice question or something like that?
CRAIG: Oh, yeah. We're going to come to that in a second. I do have the one quick question for you.
BRUCE: Oh, okay.
CRAIG: You bet.
BRUCE: Let's skip to that.
CRAIG: All right, no problem. Then we will go ahead to that part, which is the part we always end the show on. It's our last question for you. The question is that we ask you to share a piece of advice. This could, as we always say, be a piece of advice you've been given or one that you like to give. I've actually expanded it recently to say it could also be bad advice as a sort of counter example. But, whatever you would like to share is, of course, the rule.
BRUCE: Well, yeah. I'm pretty conscious that any advice could be bad advice.
CRAIG: That's true.
BRUCE: Even no matter how good you think it is, you know, taken out of context. I think one of the things I've suffered from the most, I think, in programming and professionally and in life is just the incessant self-criticism. Some people identify with that and understand what I say when I say that. If not incessant self-criticism, there's always a monkey of some kind on our back: Oh, you know, just work on it for another three hours, you'll be done. It's almost done. It's almost done. Keep going. Keep going.
This sense of pressure that–I don't know–I've experienced it so much as a programmer to where my expectations of myself are somehow actually hiding a lack of self-worth. Right? These high expectations we have of ourselves where we said we'd get it done, it should be done. Why isn't it done? Well, it's not done because it's hard and it is what it is and/or we made a mistake, which is human. And so, I think, especially for programmers, but everybody else. Let's assume there are only programmers listening to this show.
CRAIG: Probably not far off.
BRUCE: Programmers and 12-year-olds who are programmers. We're all human. Take it easy on yourself. If you feel like a clenched fist or stress just creeping into your shoulders, there's no way it's going to make you produce better work. I say that as an absolute. I guess, for some people, it really works. It doesn't work for me, and it appears to be very destructive for a lot of people I see and know. So, just take it easy on yourself. For people who already are, that's great. But, yeah, do you have anything to add to that?
CRAIG: No. I think it's great advice. I know exactly what you're talking about. Maybe this is projection, but I don't know. I suspect that a lot of our listeners do as well.
CRAIG: I just don't think that that is that uncommon because, let's face it, it's the case right now that if one is doing Clojure, you probably sought it out on your own.
CRAIG: It's unlikely that you did it because that's where all the jobs are or because your boss said you have to. Maybe that's true for some people. It's more true than it used to be. But, I think the majority of people I talk to chose it. They're self-driven, and I think that there is a real correlation between seeking to improve, seeking to learn, to stretch yourself, and what you were talking about with being unable to kind of contextualize it appropriately, to say I want to be really, really good, and today I got better, but I'm not perfect. That's the ideal, and I think a lot of us – I'll only speak for myself. I know that I fall short of that sometimes. Some days I want to be better. I'm not better. That's not good, and I feel bad about it.
BRUCE: Yeah. Yeah, exactly. Yeah. I mean I can't agree more. And, I don't know. It's just funny. It's funny because I think most of the people who I see suffer from this are such hard workers.
BRUCE: And they've done so much good work, and it's not that they deserve to have an ice cream cone or this or that. But, at the end of the day, or even during the day, you don't need to feel like you're doing it wrong all the time. It's almost impossible to do it right.
CRAIG: All right.
BRUCE: You know?
CRAIG: Well, that's great advice, and so I appreciate you sharing that with our listeners. I hope that some of them will find it helpful, as I have. It's always good to be reminded of that.
Well, Bruce, thank you so much for coming on the show today. Like I said, your name came up frequently as people we should talk to, and I'm glad we did because it was super fun, so thanks a boatload for coming on the show. We'll have to have you back some time soon.
BRUCE: Oh, man, Craig. Thank you. It was an absolute pleasure. Yeah, thank you again, man.
CRAIG: Absolutely. I hope you're going to Strange Loop, so that I'll see you there as well this year.
BRUCE: I hope I'm going too.
CRAIG: All right, cool.
CRAIG: All right, well, I'll run into you somewhere anyway, but we will go ahead and call it there.
BRUCE: All right.
CRAIG: Thanks again to Bruce. It's been great having you, and this has been The Cognicast.
[Music: "Thumbs Up (for Rock N' Roll)" by Kill the Noise and Feed Me]
CRAIG: You have been listening to The Cognicast. The Cognicast is a production of Cognitect, Inc. Cognitect are the makers of Datomic, and we provide consulting services around it, Clojure, and a host of other technologies to businesses ranging from the smallest startups to the Fortune 50. You can find us on the Web at cognitect.com and on Twitter, @Cognitect. You can subscribe to The Cognicast, listen to past episodes, and view cover art, show notes, and episode transcripts at our home on the Web, cognitect.com/cognicast. You can contact the show by tweeting @Cognicast or by emailing us at email@example.com.
Our guest today was Bruce Hauman, on Twitter @BHauman. Episode cover art is by Michael Parenteau, audio production by Russ Olsen and Daemian Mack. The Cognicast is produced by Kim Foster. Our theme music is Thumbs Up (for Rock N' Roll) by Kill the Noise with Feed Me. I'm your host, Craig Andera. Thanks for listening.