Future of Coding - On The Maintenance Of Large Software: James Koppel

Episode Date: September 22, 2018

How do we maintain millions of lines of code? For example, the Social Security Administration has 60-million-lines of COBOL. James Koppel is building tools to help tame these kinds of beasts. His curr...ent work is on decreasing the costs to build developer tools by allowing the same tool to work on a variety of languages. James Koppel is a Carnegie Mellon CS grad, Thiel Fellow, entrepreneur, educator, and currently PhD student at MIT. We talk about his experience withprogram repair, program sythesis, code comprehension, and many other cutting-edge fields relevant to the future of software engineering. Transcript and episode notes: futureofcoding.org/episodes/30Support us on Patreon: https://www.patreon.com/futureofcodingSee omnystudio.com/listener for privacy information.

Transcript
Discussion (0)
Starting point is 00:00:00 Hello, and welcome to the Future of Coding. Today, I have James Koppel on the podcast. James is a Carnegie Mellon grad. He's also a Thiel Fellow. I think part of his fellowship, he started Tarski Technologies, where they did program repair, which we're going to hear about in a second. He's also worked at a company called Semantic Designs, also in this field of tools for programming languages, which we'll hear about soon. And he's currently doing a PhD in programming tools at MIT and runs a coaching business helping programmers become better, like more advanced. So welcome, James. Hello, Steve. Glad to be here. Yeah, really excited to have you here. I think there's a lot of really interesting topics that you are an expert in that kind of surprisingly to me, I don't know very much about so i i assume
Starting point is 00:00:46 many of our listeners might also know no let know not very much about i think what i'm trying to say is um there are a lot of topics in this field that are kind of trodden ground uh and and there's and there are you're familiar with topics that aren't part of that. Yep. Yes. I always like to joke about some of the fads, like deep learning. No one likes it because it's too popular. And it's definitely me. I'm a counterculture at heart. I like things because they're obscure, because I think they're important, but underappreciated.
Starting point is 00:01:24 And I'll be happy to share a lot of that today. Cool. Well, so I thought because reading some of your writings, I got the sense that you are someone who has been in this field for a little while and you've gone down a lot of paths that proved to be dead ends and then backtracked and then gone down different paths. I thought it would be interesting to follow your story in that kind of more narrative way so we can try and learn some of the lessons you learn the hard way but you know a little bit easier because we just can listen to it as opposed to living it like you did so i thought we'd start
Starting point is 00:01:55 at the beginning um who who are your who or what were your first influences that made you excited about working on improving programming at like the tooling level or at the language level? So probably the best thing that ever happened to me is I don't know what it was, just some combination of having seen the words, this project will be rewritten one too many times. One day in May 2010, I just woke up, and it hit me that the world does not know how to write good software.
Starting point is 00:02:27 And ever since then, I've been very passionate about programming tools. And I happen to be in a very good place to suddenly get that passion. Carnegie Mellon is the world's number one university in programming languages and software engineering. It's one of the relatively few top schools to have a very strong research group in software engineering. So a huge influence in my early development was Jonathan Aldrich, who was my undergraduate research advisor at CMU. What kind of work do you guys do together? And what kind of work is he known for? Funny enough, he is one of the very few people in programming languages research
Starting point is 00:03:10 who actually designs programming languages. He has a pretty famous feud with another type theorist, Bob Harper, about whether it makes a difference to a language. Bob Harper would say that SML and Haskell both had monads. There's no difference. Jonathan Aldrich says it's actually very important to the language design that monads is in the Haskell standard library and has special support for it, but not in languages like OCaml or SML.
Starting point is 00:03:41 So the big thing that we worked on together was the Plaid language or type state oriented programming. Type states become a little bit more well known in recent years because of Rust. Things like the Baro checker and Rust are formed to type state. So type state is all about the idea of... So types let you prevent a program from passing in bad values. It's like basic things like you want a string, can't pass an integer. Also more advanced things like you need a positive integer or you need a valid person. Type state lets you put protocols into the type stem.
Starting point is 00:04:15 And they found in a empirical study, I think the number was 13% of objects have some kind of protocol. That means that methods must be called in a certain order. The canonical example is for files, you must open them before they're read. And in Plaid, you'll actually have separate types of file for open file and not. And a closed file does not have a read method. But when you open a file, it suddenly transitions into an open file. He got a lot of press a few years ago for the Wyvern language. Its big thing is TSLs. You've heard of DSLs, the main specific
Starting point is 00:04:57 languages. These are TSLs, type-specific languages. And the idea is that, so I have a function which takes in a regular expression or some HTML, and so its type is, say, takes in a regular expression. Well, the compiler sees that, and now it switches to a regular expression parser or an HTML parser. And so you can mix many different languages, many different syntaxes into the same file in a way which is a lot more principled and elegant than other solutions. It was funded by the NSA because the NSA does random security things, which somehow that part of the headline got a lot of news. The Monad feud. That sounds fascinating, but I didn't quite catch the disagreement there. At CMU especially, there are some very hardcore theoretical guys who believe that the core
Starting point is 00:05:58 semantics of a language are all that matters. The core types stem. all that matters, the core type's stum. And things like, so if I add a feature to a programming language but that feature is very difficult to use, they would say that programming language has that feature, and that's what matters. And Jonathan actually thinks it's important what people actually do with the language. Got it. Okay. And then these TSLs, I didn't quite catch the difference between them and DSLs. It basically is a DSL, but so you call a function, this function expects an
Starting point is 00:06:40 argument of a certain type, and based on that type, you can just pass in a parameter, declare a parameter with a DSL, and the compiler knows which DSL to use based on the type. Oh, okay. I got it. That makes more sense. So, okay. I got it. That makes a little bit more sense to me.
Starting point is 00:07:03 Okay, cool. There was a quote that you had sent me that the claim was that software maintenance is the number one solvable impediment to social progress. Yes. Did you believe that early on or was that something you came to realize over time? Not exactly when I started to believe that. And back to that a bit, obviously saying the largest is a very hard claim to make because you have to go through every other possible candidate to get compared to a quantifier. I will very much defend the claim that it is a very, very, very large impediment to societal progress and that all kinds of change are at some point limited by our ability to change software. And this change is far harder than is needed.
Starting point is 00:07:50 And there also are very purely technical solutions to the problem. Technical solutions that can reduce the cost of software maintenance by a factor of 100 in a relatively near future timeframe. So over the course of a couple of decades. Got it. Okay, that makes a lot of sense.
Starting point is 00:08:10 I think I want to harp on the word you use, software maintenance. It seems like a word you use a lot. In my mind, software, maybe I guess I'm kind of getting at how broad is maintenance. Like if you have a program that lives for a long time and you're constantly adding to it, is that... Because to me, maintenance is more like just making sure that it continues to run.
Starting point is 00:08:32 But is incrementally adding features also maintenance? Yes, it is. Basically, anything that someone with a job title maintenance program would do is maintenance. So not like an application developer, like if I'm a regular software engineer. I mean, any, any developer does maintenance. So a lot of the examples I have in mind are like any, any policy change.
Starting point is 00:08:57 So the social security administration has, I think it's about 60 million lines of COBOL. The joke is that it's one line of COBOL per retiree. Their application talks to 500 separate databases. So anytime when you want to pass a law that changes Social Security, you throw that over the wall to the SSA, and people there are going to have to modify the 60 million line COBOL program. So that's just one government agency of many. No story there, Cosmetic Design did some work for them on doing programming comprehension
Starting point is 00:09:38 tools. Basically, any change you want to make to our institutions, if that institution runs on software, as does the SSA, then you have potentially a very, very large software maintenance problem that makes the change much harder to roll out. Yeah, that makes sense. I think when I hear maintenance, I think of a much more narrow definition of maintaining the status quo as opposed to the more dynamic definition you're talking about. But anyways, I agree with you. I feel like it's not talked about enough. I think people focus more on beginning new projects, which to me is crazy because that
Starting point is 00:10:20 happens once. And software maintenance is every other kind of programming, and it's like the most important kinds. So anyways, I'm with you. It was a fairly recent development where I realized, like, oh, wait a second. Like, it's big projects. You know, hundreds of thousands, tens of thousands or hundreds of thousands of lines of code are the ones that we should be thinking about.
Starting point is 00:10:43 Yep. They don't get all the flashy announcements announcements but that's where most of the labor is spent yeah um okay so um so yeah continue uh chronologically so it sounds like the first your first real adventure uh post uh university was with your company tarski. Yeah. And you guys did program repair. So maybe talk a bit about what that is and what you tried to do. Sure. So the program repair is exactly what it sounds like. It's a problem of automatically fixing bugs in other programs.
Starting point is 00:11:18 And the general way that this looks is you start with your original program, which has a bug. The bug is exhibited by some failing test case. And you perform some kind of search for a modification to that program in order to make the test pass. Got it. So the genesis of this was really when I started the TL Fellowship, I was looking for things to do, preferably things which would let me keep working in this area once the Teal Fellowship money ran out.
Starting point is 00:11:50 And I was giving a talk at the Singularity Summit, basically trying to argue that advanced tools that can accelerate the pace of programming are possible and coming slash year. So I came across the program repair work and in late 2012, this is starting to become a hot topic because in ICSE that year, ICSE is the International Conference on Software Engineering, the largest academic software engineering research conference. Claire Leques at University of Virginia, she's now a professor at Carnegie Mellon, and her co-authors. They had published a paper called A Systematic Study of Program Repair,
Starting point is 00:12:32 Fixing 55 out of 108 Bugs for $8 each. So I found this paper as I was doing research for my talk, and I was pretty blown away by the results. This sounded like something that could be pretty immediately commercialized. So I started working on this probably a little bit or a lot too fast. Basically, I didn't know all the things you have to check to make sure startup idea is a good idea. People talk about, oh, the idea doesn't matter, it's the execution. And that is totally false. Because, oh, ideas are a dime a dozen. And product ideas are a dime a dozen.
Starting point is 00:13:13 But ideas with the potential to germinate into a business with a sales plan, with a marketing plan, with a growth plan, which are defensible. Things that can be done now, things where you can create a cracky prototype and still sell it and not have to have something perfect in order to work. Those ideas are very rare. So I did not know the kind of rigorous testing of the idea that need to be done before committing to it. There are also some specific issues to trying to build a company based off research, especially research
Starting point is 00:13:46 which is not your own, which is first understanding that academics are usually a little bit pompous. Part of their job is to craft a really nice story in a presentation and to funding agencies about how the work is going to have a huge impact. And often the story is based on a little bit idealized. There's a particular controversy with the GenProg program repair work I was working on, which I can talk about in a minute. And there's also the fact you can never turn a paper into a company. You can turn a research area into a company, but not a paper. Even if you read and understand every paper in an area, that does not make you an expert in the area. It does not mean that you'll be able to instantly respond to different variations of the problem
Starting point is 00:14:40 or modify the work to some existing barriers, know what issues can come up. So much of that stuff is hidden. And it's not really a good way to get it other than hands-on experience. So I was basically in the position of learning three very hard things the hard way all at once, which is business fundamentals, general software engineering stuff, like how to build a distributed cloud of different program repair servers, because this is a very computationally expensive approach. You're running hundreds of thousands of variants of an industrial program, as well as learning
Starting point is 00:15:21 the research side. So that was a bit too much at once. I believe it. So, yeah, you said you were going to talk a bit more about the GenProg approach. Yeah. So GenProg, this is, so program repair has become a pretty hot topic nowadays. There are dozens of papers published in conferences every year about it. So, permanent repair has become a pretty hot topic nowadays. There are dozens of papers published in conferences every year about it, probably in the order
Starting point is 00:15:50 of 10 or 20 research groups working on this. There is now an entire website on permanent-repair.org, which collects all these. I actually used to own that domain because I bought it during my Tarski days, but I sold it to someone who manages it now. So the field has advanced a lot, but I was kind of doing this in the early days. This time, GenProg was the only game in town. And the way it works is almost too simple, which is they have a pretty restricted space of patches.
Starting point is 00:16:25 So they're trying to create a patch script. A patch script has sequences of three kinds of commands, which are copy one line of code from one place to another to delete a line of code. And see, where are they? I think it's insert, replace, and delete. Some variation of that. It's been a while. So later.
Starting point is 00:16:58 It doesn't invent new lines of code from scratch. Yeah, yes. It only copies things from one place to another. Because in their particular approach, if they were to try to invent new lines of code, they did not have a very good way to prune the search space. It would be way too hard. Yeah. way to prune the search space. It would be way too hard. And so something that I discovered, which... Oh. So as a side note, which has actually become pretty important to the research I do now, most program transformations tend
Starting point is 00:17:42 not to work on the original source code. They usually pre-process it into a simplified version first. And because of that, it's actually very hard to render the changes back to the source tree. So for the original system, it was actually pretty hard to understand what it was doing because you get a result on pre-process code. It's not obvious. Like, it entered a line of this preprocess code. That line corresponds to part of a line of the original code. It can be hard to understand what exactly happened. So, even though I had all the results and saw all the changes that it made,
Starting point is 00:18:18 it took quite a while to realize that the patches it was producing were actually quite bad. And a later researcher, who's actually somewhat at MIT, discovered that the main way it worked, that most of its patches actually had the effect of just deleting code until a test passed, which is still potentially useful. I sometimes do debugging just by commenting out half my code, commenting out half of that, but much less useful, especially for something
Starting point is 00:18:54 that's this sophisticated and this expensive computationally. Got it. That makes a lot of sense. And so by the time I discovered that, I'd already quite invested, and I did not have it. And basically I was stuck. It's like, okay, I need to do a different kind of prepared algorithm. And there weren't very many published at the time for me to draw from. So at the very end of the days, I tried switching to a different algorithm based on a paper called PAR, which used a small number of patch templates. Of course, that work had its own problems, which is that it was later pointed out by another guy, Martin Manbrus, now in Sweden, that most of that system...
Starting point is 00:19:41 So their system reported, oh, we can do all these patches, but actually mostly it just fixed no pointer errors. But that was also not obvious from reading their paper. So it's a reason, especially in programming languages where every paper is reporting on a 10,000 line system, reading the paper does not give you a very strong understanding of what actually happened. Yeah, that does seem like quite a problem. And now I can see what you mean that you have to be,
Starting point is 00:20:14 that it's hard to implement someone else's paper in a company setting. Yeah, basically, you should be an expert in the field beforehand, or you should be in an R&D department where you have time and funding to become an expert first. That makes sense. I'm trying to think, I actually have examples that violate this idea. Or like, just trying to think of companies that came from academia. So I'll give you one that might not be on your radar. You've heard of Agitar Software?
Starting point is 00:20:51 Adipar? Agitar. They have an A-G-I-T-A-R. No, I haven't. Agitar was a bit of a big name in the early 2000s. It was founded by a couple people who had previously founded another successful company. Things started with a V, but they already had done a major exit. Two of the founders were Ruben Dume and Alberto Savoia. I've talked about them. They might have had a third co-founder. I believe Rubenko does have a PhD, or at least one of them does.
Starting point is 00:21:37 But their idea was based on a very famous work by Michael Ernst, who is now at the University of Washington, called Daikon. Daikon is dynamic generation of programming variants. And it's an idea which kind of sounds simple, and I've heard random people suggesting similar, but it's still surprising that it worked this well, enough that Michael Ernst's advisor told him that it was never going to work. And then 10 years later, he won the best, most impactful 10-year paper award for it. So the idea is basically, if this function runs a lot, and every single time it's run X greater than zero, maybe X greater than zero is an invariant. And you can then present this to a user and say, is X greater than zero an invariant to
Starting point is 00:22:35 this function? They say yes. Cool. Now you have that. You can use it in verification. You can also generate tests from it. So generate a test at X-egraded in zero. That's essentially what the agitator did.
Starting point is 00:22:49 It would do various kinds of random fuzz testing on your program, present you a list of invariants, and it would generate tests from it. Hmm. That's how it worked. Yeah. So my impression is that they basically had been just directly inspired by that paper without other, when maybe it was a lot of general technical experience, but not exact expertise. I'm also told that there are two other companies that people tried to found based on this Daikon idea, but the other two were much less successful.
Starting point is 00:23:28 Agitar, rating the tens of millions, I think they hit about 25 million in the Anorak Avenue. And then the CEO said, we have 25 million revenue, the market's too small, and they shut down the company. And that's another interesting story. That's kind of wacky.
Starting point is 00:23:47 I guess that might be a, I guess maybe their revenue wasn't sustainable. So when I talked to Ringo, the summary he gave was, just said, let's see, getting there was very hard. But so some things happened. One thing is that when they started the company, I think they started in the 90s or at least around 2000, it was pretty common that companies would pay thousands of dollars for an IDE seat. Then IBM open sourced Eclipse,
Starting point is 00:24:24 and the tools market in general created a bit. Today we have the culture that people are always chasing freemium models or trying to indirectly make money off tools because there's now a culture where everyone expects tools to be free. This is another of my big beliefs right now that that we're in a feedback loop, where people don't want to pay for software tools because software tools worth paying for aren't really out there. And people aren't making software tools worth paying for a while is trying to convince a bunch of open source tool developers to refuse to give away their stuff for free in hopes of breaking this feedback cycle and getting a more functioning tools industry. That's something that I'm not sure will work.
Starting point is 00:25:20 Yeah, that's tricky. I guess a lot of us have been thinking about this question of sustainability in open source. Have you seen Nadia Engelwald's work? Nadia who? No, I don't know how to pronounce her last name. I think it begins with an E. I think on some places she goes by Nafia. She did a lot of work on the sustainability of open source and creative models to fund things. Okay, I'll check that out. Anyway, what I was going to say to your plan is, I agree with you.
Starting point is 00:26:02 It's a tough, it's a hard sell. Price is like a function of supply and demand. And the problem with software tools, from my eyes, is that the supply is so high, like it's infinite, that the price will always be zero. It's similar to how everyone wants to be an actor. So the supply of individual already developed software tools is infinite. But for most software tools that we can build,
Starting point is 00:26:36 it would be very valuable. The supply is zero. This is one of the big driving ideas behind the business model of semantic designs, which is they've spent 20 years building their DMS infrastructure, making these tools easier to build. What does DMS stand for? DMS stands for design maintenance systems. But basically, think of the standard tools that you use to build a compiler, like the parser generator, pretty printer generator, static analysis frameworks, all that stuff.
Starting point is 00:27:17 And just think that they spent, some crazy guys in Texas spent 20 years building this very fancy, very integrated infrastructure that no one else understands. So they can do some pretty crazy stuff in a short period of time. But there's only been a couple occasions when they've been able to sell the same tool twice. Usually someone comes and says, I have IBM COBOL 8. I want you to translate it to Java. And they say, cool, we did that. We built a tool for that for another company.
Starting point is 00:27:54 And then they discover it's a different IBM COBOL 8. And they'd have to build a new tool just for them. And they say, sure, we can do it. Price is a million dollars. And usually people walk away at that point. So most tools that would be really amazing are just not getting built. So supply is zero. That's interesting.
Starting point is 00:28:08 It's interesting because the demand is so high and nobody's stepping up to solve it. Yeah, but that's basically the major motivator of my current research, which is the market is so heterogeneous that amazing things for every problem and every language can be built, and none of them are worth building. So my research nowadays is all about how to make programming tools more general and easier
Starting point is 00:28:36 to build. Got it. Okay. That helps me contextualize your current research. So, but before we go on your current research, do you want to linger a bit on semantic designs and share a few more stories or lessons learned from working on them? They sound fascinating. Yeah. Semantic designs is just completely awesome and not many people know about them.
Starting point is 00:29:01 How did you find out? I actually found it a bit randomly in 2012. I Googled the word re-engineering, and they're one of the first results. And I followed them for a while, and I had a three-hour lunch with Ira in 2014 when I was visiting New Jersey, Texas for grad school. And he invited me to come work for them, and so I spent the summer of 2016 working with them. And basically, I spent those three months trying to download Ira Batch's brain. Because he's been building programming companies since about 1970. He's been doing programming tools since for over 20 years. Actually, really back to grad school over 30 years ago.
Starting point is 00:29:46 So, he has a huge number of more stories that I've tried to download in my brain. Yeah, so where do we start? What can you share that you think would be interesting to maybe one way to filter out the stories
Starting point is 00:30:03 that you should share is like what has informed your own direction the most like what what's what store what things did you learn from him that like you were like oh i thought this was a good idea before but now ira has explained to me that it's a bad idea um so a big thing is his stories and implementing front ends for different burman languages semantic designs has over 100 language front ends a language frontmese languages. Semantic Designs has over 100 language front ends. A language front end, it's not like a GUI. It's a language front end refers to the parser, the pretty printer, basically anything that deals with the raw input of a language, which is usually the source text, and converts into artifacts that the other compiler infrastructure can deal with.
Starting point is 00:30:45 So, actually, here is my own story from my time there. I got the idea going in that Lua was the simplest real programming language. So, as I was learning their stuff, I decided to build a front end for Lua for them. And actually, that is not the case at all. Loo is super dynamic. And its lexer is non-context, is non-regular. It's actually non-context free. Just determining where a comment starts and ends requires the ability to match the number of consecutive equal signs in their syntax. So you told me a lot of other stories about other languages which are crazy. So just the problem of raw decoding infid dreams is actually kind of tricky.
Starting point is 00:31:41 So in Python, one of the first two lines must declare the character encoding of the file. So, somehow, you have to guess the character encoding long enough to read the string that tells you the character encoding in order to read the rest of the file. They did a project with a Japanese multinational company. And part of the reason they got the job is that they dealt with the Japanese version coding, which is called ShiftJIS. And the people were just so impressed, they dealt with ShiftJIS. That's part of why they got the job.
Starting point is 00:32:21 I think there's some case in Ruby where... So they have their lexer. The lexer is the thing that turns the raw source text into a stream of tokens. So it goes from here's an I, here's an F, to here's an if token. They have different lexer modes, which is a pretty good idea that other lexer generators I've seen do not have, where it can see a character and say, all right, we're switching to a different lexer now. And they have a stack of these modes.
Starting point is 00:32:56 And they found some cases in Ruby where they actually needed to dispatch on the current lexer stack. So people will talk about lexing being a solved problem, but dealing with all the the 80s sequences of real languages is absolutely crazy. You have languages where keywords, there are things that are keywords in some contexts but variable names in others. You have some languages where whitespace, in every language calls itself whitespace insensitive, but there are languages that are more whitespace insensitive.
Starting point is 00:33:35 You can put whitespace in the middle of a keyword and it's nothing, or having a space in a variable name. All this makes me want a checklist. I guess you were from Aira. Aira's list for things to not include in the programming language to make it bad. Because it feels like... Or maybe it's easier than that. How can programming language designers not make these mistakes? How can they make a syntax that's easy to parse? Yeah. That's a pretty good question. And that there are a lot of these things which anyone in program analysis would be super obvious that makes things difficult. So, one example is in the IEC 6113 state standard, which is this international standard for certain
Starting point is 00:34:34 kinds of control systems. There is one part of it, I think it's a lateral logic language, but there are five different languages in the standard, so don't quote me on which one it is. There's one part of it which is basically a long change of if conditions and actions. If this controller is a signal greater than 80, then do this. Very long change of this. So that could be paralyzed. You can try all these conditions at once. Then someone decided to add goto
Starting point is 00:35:07 to this language. If you have a goto, then all of a sudden there are dependencies in the control flow between things that used to be control independent. And therefore they cannot be paralyzed. They must have some kind of sequential order. Got it. So to me, it sounds like we're talking on two different levels. So the go-to is like on the program verification, like semantically. And so all these things kind of fit together as far as decisions you can make in the language design, which makes it harder to analyze, harder to parse, harder to lex. Well, I think harder to analyze is like a higher level than parsing and lexing.
Starting point is 00:35:51 Okay, so just talking about lexing and parsing, a simple, there's an easy thing that if your own parser and lexer in your compiler infrastructure is easy to write, then so will others. And if you restrict yourself to something that could be parsed using Antler or using some kind of CFG generator, then other people can do so too. If you don't rely on parse actions, so if you can parse your program and then interpret it, it has something that runs in the middle and says, if you see the symbol, do this, and that affects whether something later is valid.
Starting point is 00:36:37 So if you don't add any context-sensitive kind of stuff, then it'll be easier to deal with. Got it. Okay, that makes a lot of sense. I feel like if you, it's almost like the answer is as simple as like, make sure it's a context-free grammar. Yes.
Starting point is 00:36:55 I get you like 80% of the way there. Yeah. Got it. But I do, I think, I haven't really thought about that problem too much. My thoughts tend to linger more on where you were going with like, how do you make programming language that don't have bad constructs that decrease your power of casual inference?
Starting point is 00:37:19 Yeah. And so GoTo is the classic example, GoTo considered harmful. But I was kind of going through a lot of the things in programming languages and recently, you know, in my mind, and it occurs to me that almost everything is harmful. Or like there may be more harmful than, there may be more things to get rid of than things to remain. And it depends what your goal is.
Starting point is 00:37:44 There's a very classic tension between flexibility and the ability to reason. And that's the more things that can happen in one place, then the more things you can do, the more things you have to think about. So an example of this is inheritance. Inheritance says I can have one function which can be overridden to mean many different things, and there's dynamic dispatch that determines which one. So that lets you do a lot of things, and people have done some pretty hardcore stuff with this. So, for example, you can take a language like Ruby or JavaScript,
Starting point is 00:38:43 or Julia, and you can override all the basic functions like plus and times in order to return a parse tree instead of actually doing the operation. And you can implement all kinds of advanced tools based on that idea, like symbolic execution. But that also means when you see one x plus one, you don't actually have any idea what's happening. And so there's this very beautiful line from a classic essay by William Cook called On Understanding Data Abstraction Revisited, which I think is one of the best readings of computer science I've ever seen.
Starting point is 00:39:21 Wow, I haven't heard of this one. Can you repeat it one more time? On understanding? On understanding data abstraction, revisited by William Cook. He's a professor at UT Austin. Cool. I'm excited about this. There's also the follow-up, which written by my advisor at CMU, Jonathan Aldrich, which I have old teeny and not acknowledge acknowledgement on, which is called The Power of Interoperability, Why Objects Are Inevitable. Both of these are very good because most industrial programmers
Starting point is 00:39:58 and most academic research as well have a major misunderstanding of what objects in object-to-orchid programming actually are. And theorists have come up with very good answers to this question, which explain very well when objects are the right thing to use, when they're not, when inheritance is a good idea, when it's not. But most people don't know this stuff. The reason I brought this up was a little side comment
Starting point is 00:40:26 in the first essay I mentioned, which is objects have been written designed to be as flexible as possible. It's almost as if they were designed to be as difficult to verify as possible. Yeah, I'm with you. And I think we all feel that tension. You can describe it in a lot of different ways. Like people who like interpreted languages, dynamic languages, versus people who like static languages, compiled languages.
Starting point is 00:40:54 It's like, yeah, you have Ruby and JavaScript and Python on one side and Haskell and Rust on the other side. Yeah. And I want to point out that the generalized version of this tension happens not just in language design, but really every single time you call a function. And that's the caller has a desire for the preconditions of this function to be as broad as possible so that it can apply to the current situation. Whereas the function has a desire to make the preconditions as narrow as possible. So the function is easy to write.
Starting point is 00:41:28 That's interesting, because I think when I'm using a function, when I'm the caller as a programmer, I want the function to... I'm so nervous, I have no idea what it's going to do. I kind of want it to be as narrow as possible. So if the precondition is so narrow that it does not include the current state, then you call it without satisfying the preconditions and its contract says anything
Starting point is 00:42:00 can happen. So you want it to be easy to satisfy the preconditions. Otherwise, I can't even use the function? Yeah. But conversely, the preconditions are too broad, then it becomes very difficult to change the function because it's used in so many different ways. Interesting. Yeah, I think I kind of, maybe'm like very much on the um i like the reasonability is important to me more than than the flexibility so i i feel like it runs in the opposite direction
Starting point is 00:42:35 for me when i'm writing a function i i want like sometimes i'll get uh you know tricked into making it more generalizable than than it needs to be. But when I'm using a function, I really desperately want it to be as dumb simple as possible so I can understand what it's doing. I'd rather just write my own function than use someone else's function that I don't understand. I think those aren't necessarily intention. I'm also not entirely sure I understand your position right now. Okay. Well, we can move on. Well, actually, I want to linger on this divide a little bit more because I think it is fascinating. Because it's a little bit dispiriting, I think, for both sides
Starting point is 00:43:20 to think that there isn't a right answer, it just kind of depends on your situation? Well, any time when two components in software interact, it's a negotiation. And, yeah, there is kind of something fundamental about those sides of negotiation wanting different things. Well, so the perspective of large software projects that we need to maintain, to me it seems like it
Starting point is 00:43:50 seems like in that context, which is most context, large software projects we need to maintain, it seems like reasonability and reasonability and strictness is so much more important than flexibility. Because flexibility makes it easier for you to write things, but makes it so much harder for you to read things.
Starting point is 00:44:08 And so for me, it's pretty clear. Okay, serious. This audio cut out briefly. What makes it easier to write things in order to read things? Oh, so having more flexibility on any line of code, anything can happen. That makes it easier to write things, but it makes it so much harder to read code, even that you've written, but especially code that other people have written. Okay, so... So I imagine for you, who you're interested in the maintainability of large programs, you would be much more
Starting point is 00:44:45 on the verifiability. I'm generally a fan of having pretty restricted interfaces. A line I like to repeat a lot is that the power of a software design is not what it can do, but what it can't do. Your goal as a software designer is to design it in a way where all the things that you need to happen can happen and all the things that you don't want to happen can't happen. And generally, when a function accepts a broader space of inputs, then that goal becomes harder.
Starting point is 00:45:19 And there's a bit of a ratchet effect. You have a function with 10,000 callers that call it in 20 different ways. You must continue supporting all those 20 different ways of calling it unless you go around through and change those 10,000 calls. Obviously, there's a continuum of this ratchet effect from a function which is called once in the same file all the way up to the HTTP standard where someone was spelled the word refer back in the 80s and that's never ever going to be changed. I'm with you. Okay, there's one other question that's semi-related to this sort of stuff that I wanted to ask. Then we can move on to Hubix. So it's very specific to me, but I think it might be common to other people too. So I thought you might have some good thoughts here.
Starting point is 00:46:20 So I was given a job where I was given a a few thousand lines of javascript uh that were written years ago and written by someone who was new to programming and so they're like unmaintainable yep call that cal etc and so they wanted the code to do exactly what it does now uh but just be cleaner and so it and i just had to do it with with my eyes basically i added tests but um it just drove me it drove me a little bit crazy that i didn't have like formal tools to prove that like this on this these code never happened and you know it's more complicated than like their after return statement like you know they're quite there's some reasoning that has to be done in order to prove that they don't happen, but it's very straightforward proof.
Starting point is 00:47:09 I have to do them in my head. There's no formal tools for these kind of things. I was wondering if you had thoughts on... Yeah. And that's going back to what I said earlier, that most tools can be built, just the supply is zero. That's most... all these tool things that we know how to build that could help you with that,
Starting point is 00:47:29 there aren't very many actually around. When I was at Semantic Designs, they have an employee who used to have another company called Blacksbox IT, and they built, they built some program comprehension tools for COBOL. One of the things they did was this thing called program slicing. Program slicing is an idea invented by Dr. Weiser or Dr. Weiss in the 80s where you take a program, you say, pick one variable or one output and say, give me just the parts of
Starting point is 00:48:03 this program that affect that one output and say, give me just the parts of this program that affect that one output. And it will trace back and find that for you. So I was surprised to find that in the COBOL world, there actually are a bunch of tools that do this. Whereas in the rest of the industry, I had never heard of anything actually used commercially that does this. There are lots of academic tools. It's a very old idea, very well known. Nothing that anyone could just download and use.
Starting point is 00:48:31 So I'm actually reminded of a JavaScript task that I had to do during my time at Aptimize, which also involved refactoring some thousands of lines of unmaintainable JavaScript. And a tool that I wish I had at the time is actually a semantic designs tool, one of their few off-the-shelf tools, not these custom migrate your tires and things, but a much smaller thing, where they have one of the world's best clone detectors, meaning that Meaning that it can search through a code base and discover common patterns in the code. There are a couple other tools that do this. There's a company called Pattern Insight, I think it was acquired by VMware, which can also do this at a much greater scale, so like for millions of lines of code,
Starting point is 00:49:25 but it's not as flexible in their pattern matching. So I looked at the outputs of the Hispanic Designs clone detector, and I find some very interesting things. So for discovering common concepts that could refactor, it would have been invaluable. Got it. Okay. You reminded me of one other topic I want to touch on before we move on to the cubics. So there's this whole field, I guess, of program comprehensibility. So I'm fascinated by this field.
Starting point is 00:50:00 So one approach is program slicing. What other approaches are there? I'm not super familiar with this subfield. There is, I'll tell you a couple things I do know. So there's a work from the 90s by Gail C. Murphy and David Notkin, which I like a lot. It's called Reflection Models, Reflection with an X. It's basically about this interactive tool for helping programmers build a map of a code base in their head. So it starts like this.
Starting point is 00:50:33 You look at a code base and you say, okay, I think this part is IO, I think this part is data management. And you just mainly write these ideas down. It's like, this file is I-O. It says, okay. And then based on that, it generates a component connectivity graph where it says, all right, here's everything you said was part of the I-O code, and then it draws lines between them for, I think, basically call graph or data references.
Starting point is 00:51:06 And you see, oh, this function, there is this subcluster within that which is very heavily connected, or this thing, I'd say it was an IO, but it has all these interactions with the data management part. And then from that, you can refine your map. You can break things down to finer components,
Starting point is 00:51:23 move things around, try again. And so they had a case study where a guy at Microsoft, he was trying to do this big Excel refactoring project. He saw the talk, tried it at work, and after four weeks, he said that he had gone deep enough understanding of the Excel code base that he thinks would have taken him two years without the tool. So this is super cool and exciting. Yeah. So they built two different tools that did reflection models, one for C++, one for Java. And you can get neither of them today. This is my go-to example of ways in which tool development
Starting point is 00:52:12 is behind in some ways where we were 20 years ago. Got it. Okay, that makes sense. I guess I just wanted to try one thing one thing out on you and then we'll continue with your story so um the research that i that i'm working on now is on i i think it's in the field of program comprehensibility but i'm taking a very different approach uh my approach is that the languages we have today don't lend themselves well to comprehensibility so like we need to vastly restrict what's allowed to do.
Starting point is 00:52:48 For example, no go-to statements would be something that I'd want to kick out of the language. So anyways. As a little side note, I don't think go-tos are... They're interprocedural go-tos. I don't think they are that important for comprehensibility. And that if it doesn't affect the interface of the function, then it's a local problem. It makes one function harder to understand, but not the system. Yeah, that's fair.
Starting point is 00:53:17 Yeah, but it turns, it effectively turns that local function into a black box. Potentially. Yeah, which is okay if you're okay with it. I'll point out that in the systems programming world, it's pretty widely known that that goto is the best contract in the C language for error handling. So it's still very much used. It's still very much used. Interesting.
Starting point is 00:53:48 Well, I guess my question here is, it seems like you're very much taking this polyglot approach where your thought is that tools are too expensive to build for one language. So if I build approaches that allow tools to be built for any language, then that kind of solves this problem. My inkling or whatever, my predilection in this, my tactic is to just build a language that's just better.
Starting point is 00:54:23 And then somehow build a language that's just better. And then somehow, like build a language that lends itself to tooling better. So that's how I decrease the cost of creating tools. Yeah, I think definitely some people will share that idea. A very extreme example is there is a language called Parasail, which is created by Tucker Taft. I saw a presentation about it many years ago.
Starting point is 00:54:54 It basically was designed to be a very restrictive language. I think it might not even let you do recursion. The idea that it would be so restrictive that it would be very easy to write tools for and very easy to super optimize and parallelize automatically. So that's the relatively extreme approach. Got it. Cool, yeah. So yeah, definitely some tools are easier,
Starting point is 00:55:22 some languages are easier to build tools for than others. That's one of the reasons you see so much academic work focusing on Java. And Java compared to C++ compared to Python is pretty tame. You can do a lot of things just with a bytecode, which is pretty well designed. Okay. And obviously there is a lot of old stuff in existence and it's not going away yeah yeah yeah that makes a lot of sense but particularly from your experience at semantic designs yeah you you you're like intimately familiar with you know massive code bases of
Starting point is 00:56:01 dead languages yep or i guess the other way to put it is that, like, programming languages don't die. Yeah. If you get a pay stub, there is a pretty high chance it was processed by ADP and went through a large 40-year-old COBOL system. Actually, not COBOL, assembly for dead language. Probably a lot of other things will go through COBOL systems.
Starting point is 00:56:25 The company I started, we use ADP, so there you go. Cool, so let's stop talking about it. Let's talk about kubix. Tell me a bit about the idea and what your novel approach is. So kubix is my framework for language parametric transformation. The tagline is one tool, many languages. So, here's a motivating story for why this is important. When I was at Facebook as an intern in 2010, they had a lot of privacy bugs. And it was things like, so in Facebook, you can upload private photos or things
Starting point is 00:57:08 only your friends should see. And you go to someone's photos, they view photos, it would fetch the photos, it would check which ones you can see and show you those ones. And that is error prone because you need to remember to do the same thing any other place we give you the photos One place where they did not do that is in the report profile button So if you went to report someone's someone's profile, it's a this profile is bad because of its photos
Starting point is 00:57:38 It has an illegal photo say okay, which photo do it report and there you can see all the photos. And they had a lot of other things like this. Another thing was for a few hours, there is the button that says, how does Bob see my profile? What does it look like to him? For a few hours, you press that button, you were actually logged in as Bob and see his private messages.
Starting point is 00:58:01 Wow. So they needed to do a whole program refactoring in order to fix this. And their idea was to an architectural change. They would create a viewer context object, which, and instead of having to remember to every time display a photo check whether it should be visible, instead you would move all that to a central location. When you get photos in the database, right there you would pull out all the ones which should not be visible eventually. So they needed to pass through this viewer context parameter through many, many, many tens of thousands of functions.
Starting point is 00:58:39 They took a couple dozen of their best engineers off their other projects. They walked them in a conference room called the candidate room. So this is the candidate team. Basically, they spent every waking moment for several weeks just adding just these parameters to function calls. And so as an intern, I had this piece of the code that no one else was working on. I wake up one day and get a merge conflict. Like who else worked on this? These people did. They added some parameter passing. So basically, a massive amount of effort adding parameters to functions throughout the codebase. In 2014, Dropbox had a different problem with a similar solution. Right now I'm logged to Dropbox on my PC. I actually have two accounts on this computer.
Starting point is 00:59:28 I have my personal Dropbox. I have my MIT work Dropbox. They also needed to add an account parameter to many thousands of functions in order to implement this. They obviously did a lot of other things too, but that was a large part of it. And I'm told that it was the number one project for the year 2014. At the time, they had over 100 engineers. Two companies, massive change, adding parameters to functions. This is the kind of thing you can hire Semantic Designs to build a magic button that does for you. But if both of them
Starting point is 01:00:02 had gone to Semantic Designs or hired some other pruning transformation experts, they would not have gotten the economy of scale from having the same problem twice because Facebook, PHP, Dropbox, Python. So this wouldn't be solved via the
Starting point is 01:00:19 multiple front ends that Semantic Design has? They'd have to build the same thing separately. Maybe they could share some code, but not that much. Got it. But with kubics, you could build the same tool for both languages, and in fact, we did. So in our kubics paper, we built a prototype of a tool that does this.
Starting point is 01:00:42 And in the space of less than a week, we built this prototype and got it running on C, Java, JavaScript, Lua, and Python, which are the five languages that Qubics currently supports, not yet PHP. In one week? Yeah. The prototype is not that sophisticated, but the big thing is that we are still sharing most of the work between languages because we can using the qubits approach. Got it.
Starting point is 01:01:09 Okay, so yeah, so what's the approach? How'd you do it? It's called incremental parametric syntax. And it's basically a recent existing idea, but with a small addition that makes all the difference. It's an extension of some earlier work on modular syntax, particularly something that's well-known in the Haskell community called data type solid cart. Data type solid cart lets you say I'm going to find a programming language in terms of different fragments. Here's my control flow fragment that has while loops and if statements. Here's a fragment that has go tos. Here's a fragment that has functions.
Starting point is 01:01:59 A fragment that has plus and minus. And I can put these together into a language. And I can define a transformation or an analysis that runs on each of these parts separately. And when I put them together, I get the transformation analysis for the whole language. Some people took this, made it better, made it easier to scale. But they still have the problem that if you wanted to do this for C, what you would do is you would basically take every piece of C, the C spec is about 100 pages, which is small for a language spec, and you'd go and implement every single part as a generic fragment. So you'd have a generic function of fragments that handles C, and hopefully some other languages. You'd have generic pointer fragments, every single thing is in C. You'd somehow need a
Starting point is 01:02:55 model generically. And this is very hard because basically if you had generic functions which would be used in C and Java, you would somehow need them to be the same, which they're not. So this approach couldn't really handle mismatches between languages. Whereas, I say, language parametric transformation, sharing code between tools to different languages, it should be possible because languages are similar, but it's hard because languages are also different. Yep. So we made a small addition to this idea called sort injections.
Starting point is 01:03:29 Where basically I can now say things like here is a generic function declaration and it has a list of arguments. But what an argument is differs by language. And I have a way of saying for this language, this is an argument. Similarly, for variable declarations, I can say a variable declaration is a list of left-hand sides, is a list of declaration binders. Each declaration binder potentially has some attributes. And then for each language, I can say what those things are. So in C, a declaration binder could
Starting point is 01:04:16 have a pointer. In Lua, you can declare many variables simultaneously. You can say var x, y, or as a list. You can do that in JavaScript, too. In Java, you can have attributes on each declaration. You can say int x, y brackets. And x is just int. Y is an array. I'm with you. This makes a lot of sense.
Starting point is 01:04:49 Yeah. Whereas in JavaScript, you don't have that. So we have this nice thing where different languages share common parts that you can write against. But you can still capture all the indistinguishable of each language. Cool. Yeah, this makes a lot of sense.
Starting point is 01:05:06 So I just want to backtrack a bit. I have two questions. The first one, so you mentioned this data structure is a la carte thing, which sounds fascinating. I, and I imagine a lot of listeners, are pretty familiar with Haskell. So could you give, can you explain how this is in Haskell? Sure. So, and this actually is a new name for an even older idea from the term rewriting community called Sum of Signatures.
Starting point is 01:05:31 And I think the best way to understand it is to take a step back from it. So, Haskell has algebraic data types. You can say data tree equals leaf of int or binary node of tree, comma, tree. You can take a step back from that and look at the theory of how these are defined. And they actually are defined in three separate phases. So first, each of those things like leaf, node, those are called constructors and they're just tuples. So a leaf has an int, it's a tuple of ints, a one tuple. The interior node is a pair or a triple, say it has two children and another int.
Starting point is 01:06:20 So that's the first step, is getting these constructors. Then you can say a tree is one of the many constructors. That's a sum. It's an or. And at this point, I've said, really I've said these are what my nodes look like, but I don't have the trees yet. So, maybe I say my language has an add node and it's going to add two expressions together. What's an expression? I haven't defined that yet. The point at which you define what the expressions are is when
Starting point is 01:06:57 you do a fixed point. When you add recursion to the data type, you can say, feed this thing back into itself. So when you just have a list of different node types, but you don't know what your children are, this is all very modular. It's only when you add the fixed point or tie the recursive nods, let's say, that becomes very tied to the current state. So what data types a la carte does is it lets you program get signatures rather than term types.
Starting point is 01:07:34 So you basically write things in a way of an add is a plus of two expressions. What is an expression? I'll tell you later. And you leave a type variable for what the children are going to be. And at some point later, you say, so I defined this list of nodes, which is either an add or multiply or an if statement, and they have children. What are those children? Now I'll tell you. It's the thing I just defined. That's the recursive fixed point.
Starting point is 01:08:07 Okay. I have a little more clarity. So to speak it back to you, it sounds like the sum of squares and the data types a la carte are essential to the implementation of algebraic data types? In the actual type theory, an algebraic data type is defined from three basic type theory components. Recursive types, sums, and products.
Starting point is 01:08:36 Got it, okay. And like a tree with two nodes, that's a sum. Yeah. So the product is saying I have a type variable T, T cross T. It's a pair of Ts. What's a T? It's a variable. The sum would be saying int plus T cross T.
Starting point is 01:09:08 So it's either an int or it's two of these t things. I haven't told you what a t is yet. And then the final stage, say mu of t dot int plus t cross t. So there you say, what is a t? It's a one plus a T cross T. That's a recursive type. And when you actually spell that out, it becomes what's a tree? Either it's an int or it's two ints. Or basically, when you actually substitute one plus T cross T and for T recursively, you get this infinite sum which describes every single shape of a binary tree. Got it.
Starting point is 01:09:55 Okay. It's pretty fascinating. There's a great reading on which unfortunately, Could send a I could send a link out because they announced go to web that archive for it's off the internet it's called the algebra of algebraic data types by Chris Taylor multi-part series and Shows you how you use point-o-meal manipulation on these out of break data types and find a lot of cool properties Is it okay Okay, cool. I'll add that to the notes. There's also, there's another article which I think is a lot less good,
Starting point is 01:10:33 but it still exists on the internet without web.archive, which is shorter. It's called the Algebra and Calculus of Algebraic Data Types. It sounds like you're approaching cubics, the parametric. Can you repeat the phrase for me? Incremental parametric syntax. The incremental parametric syntax. It sounds to me like that's very similar to this idea of a universal abstract syntax tree. But I know that that's an idea that you aren't so excited about.
Starting point is 01:11:04 So what's the difference? Yes. The universal AST is something that I love to hate. So the idea of the common representation is that I'm going to create a single syntax tree. And instead of having Y loops in C and in Java, I'm going to have one kind of Y loop. And I'm going to translate all of C in Java and JavaScript into this one syntax tree. I'm going to write things on this one thing. And when I want C or Java back, I just output them.
Starting point is 01:11:45 This is how most program analysis tools work. It works great for program analysis. Architectures like GCC and Clang and LLVM, they'll do this. They run GCC on Java or Pascal or Objective-C or Fortran. You'll get into the AST for C or Fortran, do some stuff there. Then I'll change them into, I think the IR is called Gimple. I'll change them to some common representation, do some more optimizations. And then from this IR, you'll pick a code generator off the shelf and get your x86 to your arm.
Starting point is 01:12:33 But there's two big things wrong with it. So one is that I said before the power design is not what it can do, but what it can't do. And it's very important not just what you can represent, but what you can't represent. So, there are a lot of when you're reading a Java program, you have to read it differently from a C or C++ program. In that, if you see a local if you have a local variable x, it's an int and you call a function with x in Java, you know that x has the same value afterwards. In C++, that function you call could actually take x as a reference and then modify it, and now you have a different x in the calling function afterwards.
Starting point is 01:13:22 So the presence of pointers, and especially especially references makes a lot of programming analysis things difficult. Both computers doing programming analysis, but also just you reading the code. The knowledge that your programming language is not a pointer or not a pointer arithmetic is very powerful. It's just absolutely lost. That's part of the reason why all these different infrastructure, they will do some of their authorizations at the language specific level before going to the IR.
Starting point is 01:13:55 But the other big thing is that when you want to have a perm analysis, it's easy. You set everything in. It's okay if you lose information as long as you have enough to still produce useful bug reports, whatever you're trying to analyze for. But in source-to-source transformation, well, if someone types in 0x10 and they get out 16, they're going to be mad, especially if the prune transformation didn't touch the part of their code.
Starting point is 01:14:22 So you need to keep all this information about language-specific stuff around. It sounds like that's exactly what you're doing with kubics. Yes. Yeah. So in kubics, we don't have a single representation for C and Java or JavaScript. We have a family of representations. Each of them shares common pieces,
Starting point is 01:14:42 but each one specific to that language and able to store it or track everything. So hold on. So to me, it sounds like in Cubix, like if I have an assignment in Cubix, that's a data type that is very general, that can handle all the quirks of every language. Yeah. So we have a general assignment data type in Cubix,
Starting point is 01:15:06 but it has custom pieces per language. So an assignment is general, but a left-hand side is language-specific. But even still, there's some common left-hand side. So every language has a left-hand side that can be a single identifier. Some languages have more, but everyone has an identifier left-hand side that can be a single identifier. Some languages have more, but everyone has an identifier left-hand side. And so I can write a prune transformation that can see
Starting point is 01:15:31 an identifier left-hand side and do something, and know it's something for every single language. Got it. Okay. So to me, it sounds like that is a universal AST. It's just not what people thought it would look like. You can call it that. But the thing is, it's a different kind of type. It's instead of saying, I have a type IR,
Starting point is 01:15:57 I'm going to convert all my representation to that and convert it back to the original representations. I have a parameterized family. So I write my types in a different way. And in the talk I gave on this, you can see a recording of this talk on YouTube that I gave to the Boston Haskell group, as soon as you declare the type signatures, saying I can invert things to common IR and then back to the different representations, you've already lost. And one reason is that when you write down those types, you're basically claiming you can invert any language to any other language, which is too good to be true.
Starting point is 01:16:45 So the catch is you get things like... So there are more than zero frameworks that do try to let you write... They do use common AR and do try to let you write transformations. And all of them will mutilate the code. So one example is the Compass-Royce framework from... I think it's either Lawrence Berkeley or Lawrence Livermore. I think framework from Lawrence Livermore. In their manual, they have an example of a programming transformation written on C. And it converts all the for loops into why loops, even though it should have been able to leave them the same.
Starting point is 01:17:26 Why? Because they use a common IR. And this IR does not have for loops and Y loops separately. It just has Y loops. Got it. Yep, that makes sense. I have a friend, Aiden Knief. I don't know if you know him. Yeah, I had a Skype with him the other month.
Starting point is 01:17:47 Cool. I'd be curious to get your thoughts on his approach. Let's see. For anyone who didn't listen to the episode I did with Aiden, he's building a tool just for one language, but it's code generation. So you would explain to his tool how you want to write backend routes for your express router. And then it could generate, if on the front end you need some data, it could generate the backend route for you automatically or vice versa, that sort of thing. Yeah.
Starting point is 01:18:31 So it actually is from local languages. Well, I don't think it's from one language to another. No, it's not. So the interesting thing about it, I think, is just identifying the problem. He found the problem, which is practical, but also relatively simple to solve with simple technology. I think this has a lot of potential. My big point of skepticism is the flexibility of their matching. Which is they're basically using tree patterns,
Starting point is 01:19:09 which are a pretty easy thing to come up with. And it is very easy to overestimate. To think this is what code for doing this should look like. Very easy to underestimate how much variability you can see in that. So whenever you get into application where it's important that you find every case where something happens, or even 95% of the cases, then pretty soon you need much more sophisticated technology. But I did tell him some of these problems. I told him to look into associated commutative matching as something which is very important,
Starting point is 01:19:52 but it takes some architectural changes upfront. So, and I found him pretty humble and hopefully he'll be able to do some great stuff. Cool, sounds good. Um, be able to do some great stuff. Cool. Sounds good. Okay. Cool. Thank you. Let's talk about the coaching business you run. Sure. So yeah, maybe give a, I'd be curious to know, yeah know how it got started. So a fun story. Back when I was an undergrad, I was deciding whether I wanted to do software engineering programming languages research with Donovan Aldrich
Starting point is 01:20:34 or to do cybersecurity analysis of binaries research with David Bromley. David Bromley has become very famous. You might have heard of the DARPA Cyber Grand Challenge, where basically people program computers to hack into each other and stop each other from hacking into each other. They ran a contest at DEF CON.
Starting point is 01:21:01 His team, for all security, won that contest. So he has some pretty awesome stuff involving binary analysis. So I was choosing which professor to work for. At first I chose Brumley. So I was going to take the elevator back to my room to send the email to announce this. And then I changed my mind to the elevator for a very bad reason. I thought, oh, maybe if I worked for Jonathan Aldrich software engineering research, that will suddenly make me a better software engineer. And then I'll be able to do stuff faster. And of course, that was silly. But the funny thing is that
Starting point is 01:21:40 over the next many years, it actually became true. And that as I got a deeper understanding of software engineering and being able to see the preconditions and post-conditions of functions, I actually discovered I'd become very good very fast. It became very obvious when I joined Aptimize. The person who replaced me at Aptimize, but who said my code was like a poem, like one of those beautiful Haskell Bermuda you see, except that this was Java for Android. That code base has managed to survive very well, easy to make major, done some very major architectures to it in relatively short periods of time, pretty low bug rate. All things are pretty important, especially given that we are under very heavy constraints to make something with few bugs.
Starting point is 01:22:40 Because if something goes wrong, it's an SDK that other developers put in their apps. If something goes wrong, first, our customers have to upgrade their version in their app, and then their customers have to download the new version. So you want to get things right. So I actually stayed on as a contract for Apptimize in grad school. I started making some extra money on the side. Didn't like living like a grad student. And I had one instance with a coworker where she had committed some bad code.
Starting point is 01:23:17 People were criticizing it. She didn't understand what was going on. And I sat down with her and taught her some basic, taught her some of these soft engineering concepts, which are some things that I think some people have intuition for, but are pretty non-obvious. Not many can really explain very well. And that made a huge difference for her. I just realized how satisfying that was and also how impactful that was to make her better. Much more impact than I could have in an hour just doing it myself.
Starting point is 01:23:51 So about two and a half years ago, I started a company doing this professionally. My first client was someone who had just been fired from their job. And a few months later, they were a totally transformed person. And suddenly, we're getting offers left and right from Google and Facebook, and now are quite senior at the company and having like fresh Ivy League grads look up to them. It's a huge transformation for this person. So, yeah. So, over the years, I crystallized a number of different teachings, which are largely inspired by my knowledge of the academic side. Basically, the way I look at it is every time someone writes some kind of program analysis or synthesis tools, there's some insight behind that about how software works.
Starting point is 01:24:49 My goal is to teach this intuition without having someone having to spend years studying type theory. There is a lot of stuff I'm going to talk about in my strange loop talk which is coming up in a couple weeks. One example I like right now is if I have a function called sanitize that escapes all single quotes, and what you're really doing is that you're creating a notion of a sanitize string which is separate from this function. And this idea of a sanitize string can be hidden. Meaning that if I were to write my own code which sanitizes the string exactly the same way, then there's a sense in which it's not legal
Starting point is 01:25:28 to use that because the notion of sanitize is opaque. And this is something which you could write down very clearly in a theorem proving language like quk. But it's something which is almost kind of mystical and ethereal, you just look at normal code, because you're talking about properties and abstract ideas that are not present in the program at all. Yep. And in fact, so much of what makes good software involves working with ideas that are not present in the code directly at all.
Starting point is 01:26:03 Something in the design space which gets lost when it's turned into code. And it's kind of interesting that this is an idea which sounds almost kind of crazy and mystical in programming circles. But in other circles, it's just mentioned offhand, something obvious. So, in a thread that I'm in the other day, there's a discussion, it's like this famous researcher says you should document the module by saying what secrets it hides, what decisions it's made that can change and no one else can care about, can know about. And it's often, oh, but this is much harder to extract in the code if it's just not present. So you mentioned that how in a language like,
Starting point is 01:26:45 I think it was Coq was the language you mentioned? Yeah. You can communicate the high level notion of what you're trying to do? To some extent. And you can write things like, this function must take a sanitized string. This function makes a string sanitized.
Starting point is 01:27:03 And set it up in a way where the only way to create a sanitized string is to call that function. And if you write your own function that sanitizes that string, then it's not sanitized. You might have replace all single quotes, but you don't know what sanitized means.
Starting point is 01:27:19 Oh, well that I understand, but how about a formal definition for sanitized to make sure that the definition of sanitize is awesome? In Coq, you would actually write down a formal definition of sanitize. You can make that a private definition. And you can prove that your sanitize function satisfies the definition. But you can't prove that for any function in another module. Yeah, and so it's two parts.
Starting point is 01:27:47 You describe the ideal. The thing that's ethereal in most programming languages is you can make it explicit in Coq and then you write the implementation code the lower level code and then you prove it. In some order, yeah.
Starting point is 01:28:04 Got it, okay, yeah. You can do it in some order yeah and got okay yeah you could do in either order but but they go hand in hand um yeah and i see the proof as less important from a design point of view but just having just having idea that there's this some kind of concept which is not present in the compiled in normal source code, but is present in this design space is very important. So is the solution that we should all be like, we should have the language, we should bring it to our code. Like we should bring that feature from cock to like every language.
Starting point is 01:28:40 That possibly. And so there already is some variation in this. Like, in Python, it's actually very non-straightforward to define an interface in the Java or C-sharp sense, and saying that these are the functions which other people should be allowed to call. Here's an abstract description of what they do, which is separate from any specific implementation. You can do that in Python, but you almost have to work around the language to do it, whereas it's just very natural in Java or C Sharp.
Starting point is 01:29:17 So there's a lot of things in that spectrum. But in my business, the angle I focus on is more just teaching people to think like this whether even if they are working in python or ruby got it that makes sense i think i think that's a great stop gap uh just in the interest of improving programming at the like the language level i'd be interested because i think a lot of my best insights for improving programming are taking things that I've taught to students very instructionally, like, like the way you're doing, but, and then come up, and then come up with creative ways to embed them into the language themselves
Starting point is 01:29:57 so that they don't even have to be taught because embedded. So with that in mind, I'd be curious to hear your thoughts on like almost like higher level languages where you can retain more of the abstractness of your idea uh so like you're not losing because when you uh like as i've seen you write in other places when you um write an implementation for a high level idea, you necessarily lose a lot of the notion of what you're trying to accomplish. Yeah.
Starting point is 01:30:29 And so, yeah, I feel like you're someone who would know the like state of the art on what a higher level specification language would look like. Because I have no experience with those languages. Yeah. So I've done a medium amount with a number of different specification languages.
Starting point is 01:30:51 I don't have experience using any of them for deployed systems. For that, you might want to talk to my acquaintance, Hila Wayne, who is another blogger and expert in TLA+. Got it. Okay. And I think you mentioned somewhere that you were familiar with Sketch, which it sounds like is related to this idea. Oh, yeah. So my lab built Sketch.
Starting point is 01:31:21 So Sketch is very much not something... Okay, I guess it kind of lets you express your idea at a higher level. So Sketch is a general purpose program synthesizer. And its big thing is the idea of a... A Sketch is a program with holes. So some of the early applications were, you say, things like, here is a very, very dumb implementation of linkless reversal. Which is like, you just remove stuff and add it to a new list. And then you want the more efficient version of linkless reversal. So you say, okay, I know it has something, it's going to involve a while loop and it's going to involve some combination of these assigned operations. Here's a soup of possible things you can do. Here's a reference implementation. Go find some way to put these together into a program that
Starting point is 01:32:14 does the same thing as a reference implementation. And it would. The way it works, it gets super nitty gritty in the implementation. And it actually does some bit blasting, which means it creates a difference. It creates, it basically looks, expands your program out to a static graph, unrolls your loops, looks at all the bits that can be in your program, and does solving techniques on the bit level. Oh, wow. On the implementation side, it's super nitty-gritty, not very abstract at all. But from another perspective, you can use it to raise the level of abstraction and say,
Starting point is 01:32:48 I don't care about the details. I just care that it does the same thing as this reference implementation or it satisfies these properties. And here are some constraints on how it works. Okay. That makes sense. I like to end with an opportunity for you to mention ways, if you're interested in being contacted by people with questions, ways to contact you, places you produce things on the internet, anything you want to get out there or want help with. So, my blog is pathsensitive.com. I mostly blog about advanced ideas related to software design.
Starting point is 01:33:32 You can also check out my papers on Google Scholar or on DBLP, the computer science paper database. My coach business is jamescouplecoaching.com. I offer one-on-one coaching as well as a web course and in-person courses to individuals and companies. The next Advanced Software Design web course
Starting point is 01:33:53 is starting on October 11th. I actually have a special offer for listeners of this podcast. So if you go to jamescouplecoaching.com slash Steve, then you'll get a special offer, a special bonus if you sign up for the course. The course is six weeks. It'll basically take you through a number of big ideas about software engineering, things
Starting point is 01:34:15 that are intent, that can change the way you view code but are not very well known. You can check the testimonials. It's gotten some pretty amazing results. People saying it made them way better, including both junior people and very senior people. It's done in a pretty structured way, where both you'll do pretty low-level drills with small code examples, and then it'll also give you a walkthrough of a large source code base. And I'll show you how this idea affects this real code base. And something else entirely, when I decided projects for way too long, has been the area
Starting point is 01:34:55 of binary modification. My other area of expertise, which I haven't talked about at all, is in how to modify programs without a source code and in reverse engineering. So at so project iron fist is a game mod and for the classic pc game here is a might magic 2 that i've worked on with some international collaborators for a long time yeah you can check it out at iron fist i-r-o-n-f-I dot S-T, and see how we work our magic. And of course, my personal website, which I'll update sometime this year, probably, is jamescouple.com. Cool.
Starting point is 01:35:38 That's awesome. Well, anyway, thanks again for coming on and talking with me. I learned a lot. Yep. It's good to talk to you, Steve.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.