Future of Coding - Max/MSP & Pure Data: Miller Puckette

Episode Date: May 12, 2020

Miller Puckette created "The Patcher" Max (the precursor to Max/MSP), and later Pure Data, two of the most important tools in the history of visual programming and computer music. Max was designed by ...Miller in the mid-1980s as an aid to computer-music composers who wanted to build their own dynamic systems without needing write C code. Max had no facility for sound generation at first, but that would come eventually with the addition of MSP. A decade later, after some academic politics nonsense forced him away from Max, Miller went on to create its successor, the open source Pure Data. Both Max/MSP and Pure Data have become wildly popular, with Max/MSP as a more polished-looking commercial product developed by Cycling '74 (now owned by music behemoth Ableton), and Pure Data as the thriving independent community project of hackers and techno-punks. Node-and-wire visual programming languages are almost a cliche at this point, as the vast majority of them either borrow heavily or at least reference the visual design of Miller Puckette's original Max patcher and its MSP/Pd offspring. Though as you'll hear in the interview, many of them are poorer for not rethinking some of the underling assumptions of their inspiration. I decided to bring Miller on the show after hearing a fabulous interview of him by Darwin Grosse on the Art + Music + Technology podcast. (Tip: subscribe, it's good.) Miller gave a great retelling of the history of Max and Pure Data and the forces at play when he created them, and that episode is a tidy complement the more design-focussed interview here on our show. Miller mentioned in passing that one of the three books he has yet to write would be his thoughts on realtime scheduling, so that was the initial hook for my interview. Looking back on the 30+ years of Max/Pd history, what has he learned about the design of tools? What were the alternative ideas that he didn't pursue? Where is there room for improvement, perhaps by others picking up where he left off? In this interview, Miller said a handful of things that were, well, painful for me to hear as a dogmatic champion of visual programming. So if you come into this thinking it'll be a well-earned hour of congratulation and adoration, sit up and get ready to flip the dang table. This interview was a blast; on a personal level, I was thrilled to have the chance to talk to such an influential figure in the history of my field, and I hope you enjoy it as much as I did. Quote of the Show: "It's not only powerful, but it's also inadequate." The transcript for this episode was sponsored by Repl.it. For the full transcript and links go to https://futureofcoding.org/episodes/047Support us on Patreon: https://www.patreon.com/futureofcodingSee omnystudio.com/listener for privacy information.

Transcript
Discussion (0)
Starting point is 00:00:00 And it's not only powerful, but it's also inadequate. Welcome to the future of coding. I'm Ivan Rees. The interview today is with Miller Puckett, the creator of Max, which later became Max MSP, and Pure Data. I was inspired to do this interview with Miller after hearing him on the very cool Art Music Technology podcast by Darwin Grouse. That episode had kind of bad sound quality, so I only recommend people listen to it if they are extremely interested in visual programming and music and the history of Macs, which is of course extremely cool. So I recommend everybody go and listen to it. Just tough it
Starting point is 00:00:51 through the audio quality. It's super worth it. Really interesting stuff. There'll be a link to that in the show notes, which you can find at futureofcoding.org slash episodes slash 47. Miller only had an hour to record the interview, so this episode came out a little bit shorter than some of our recent ones have, but I actually like the feel of that a fair bit, and I'll probably try to keep future episodes closer to the one-hour mark rather than pushing well past that as some of the recent episodes have. In the interview, Miller and I talk a little bit about the history of Max, but again, to learn more of the historical details have. In the interview, Miller and I talk a little bit about the history of Max, but again, to learn more of the historical details, you'll want to go listen to that other
Starting point is 00:01:30 episode with Darwin Grouse. In that episode, he mentioned specifically that he had a lot of thoughts over the past 30 years about scheduling and some of the lower level implementation-y, design-y kind of stuff behind Max and Pure Data that he seemingly didn't really get the chance to develop to the full richness that he wanted. And so that was the hook for me going into this interview. I wanted to find out now that it's been so long since those projects came to life, how might he have done things differently? How did he have done things differently? How did he arrive at the things that he did? And how has he reflected on that path in the time since? I certainly learned a number of very interesting things that are sort of painful to me to hear in my particular dogmatic worldview as a strong proponent of visual programming. So I guess it just goes to show you
Starting point is 00:02:26 that you have to kill your heroes. I kid. Miller is delightful, and I think you will enjoy this interview as much as I did. It's a beautiful day It's a beautiful day It's a beautiful day It's a beautiful day It's a beautiful day It's a beautiful day It's a beautiful day It's a beautiful day It's a beautiful day
Starting point is 00:02:58 It's a beautiful day It's a beautiful day It's a beautiful day It's a beautiful day It's a beautiful day I found the podcast interview you did with Darwin Gross. Oh, yeah. And enjoyed that a lot. And there were a couple of things that you said in that interview that I just kind of wanted to follow up on because I felt like they would be really interesting to the community that I'm doing this podcast for. What kind of community? Yeah. It's called the future of coding, mostly researchers, mostly people either working
Starting point is 00:03:38 independently or in academia who are interested in not quite HCI, not quite programming language theory, looking at ways to make richer, more dynamic tools. There's a very common thread of people who are interested in building visual environments. Max and Pure Data are two of the quintessential touchstones for the history of visual environments. Something that you said on Darwin Gross's podcast is, of course, that it was 30 years ago that you were first working on this sort of thing and that your recollection about exactly why things came about might be distant memory at this point. Suspect. know distant memory at the suspect yeah yeah so i as much as i would love to go down that rabbit hole and say oh you know why do you have bangs the way they are that sort of thing but i think a good place to start would be getting anything that you do remember about how you went about
Starting point is 00:04:38 designing max and the patcher and then eventually pure data. Right. Okay. Yeah, that works. First off, the thing that always interested me about computer music was the possibility of getting it to work in real time. So the environments that existed when I got started in 1979, I think, were almost exclusively non-real time. There were the beginnings of things that you could use in real time, but they were not programmable in any very general way. And so you had a choice between sort of special-purpose things
Starting point is 00:05:12 of various kinds or a general-purpose language, for instance, Music 11, which was the precursor to C-sound, which was a fully general sound renderer but which would never run in real time. So I was in the lab that was being run by Barry Virko, who was the inventor of C-Sound. And Barry's true interest really wasn't so much in making a software synthesis engine. In fact, those had existed before C-Sound. I think that was a sort of a thing that he did in order to just sort of be of practical help to the community. He never saw that as his main drift. His main focus was on real time. And so I fell in with him and caught onto the idea that, gee, you could try to make a computer music instrument run in real time and that would be a wonderful thing to have happen. So the main things that I were thinking about were first off being able to design sounds in a software kind of a way
Starting point is 00:06:10 and second just how to solve the problems that come up when you change the model from feeding punched cards into a computer into either playing on a keyboard or having other kinds of real-time input coming in. For instance the sound that would come in from a microphone. So a thing that you couldn't do in C-Sound or its predecessors was hook a microphone up to it and play an instrument to the microphone and have something come out with an echo or some distortion or filtering or something like that.
Starting point is 00:06:40 You couldn't make a guitar pedal, for instance. And in fact, I remember one visitor to the MIT Experimental Music Studio, first question they asked when I was showing them what I was doing, yeah, can I plug my guitar into that? And the answer was, no, you can't do that just yet. I'm working on that. So really, the whole thing that I was thinking about
Starting point is 00:07:00 had nothing to do with graphical programming environments. In fact, I wasn't even thinking in terms of graphical programming environments when I got started. I was thinking in terms of real-time structures and ways that systems could react to real-time inputs. So it's another kind of HCI problem, but it's not the problem of arranging things on a screen. It's the problem of making your computer into a musical instrument. And I actually didn't even care at the outset what you had to do to specify what the instrument was going to be.
Starting point is 00:07:29 I just cared about having the thing be instrumental in nature and not batch in nature. And that's pretty much where all the terminology came from. A researcher, another very influential researcher, Max Matthews, who's usually described as the father of computer music, was also concerned about real time, also interested in real time. And one of his ways of thinking about it was that you would trigger things. And triggering, I think, you know, etymologically, I assume trigger really comes from pulling the trigger on a weapon. But in fact, when people talked about triggering things in 1970 anyway, even though the Department of Defense was funding most computer science research at the time.
Starting point is 00:08:18 So there certainly was a militaristic financial background. Well, the zeitgeist was military in the 60s and 70s, as far as computing was concerned. If you wanted to be bored, you would work on banking software. And if you want to do the research, then you were being funded by the military. So, I didn't even think twice about the idea of using terms like trigger. And of course, if you're going to trigger something, the natural, whatever you say, verb or I don't even know what part of speech bang ought to be, exclamation or something. The natural sort of thing that gets triggered is a thing that goes bang. I thought that was kind of funny because, of course, the thing that you do not want to have happen when you plug your amplifier into the wall is have it go bang.
Starting point is 00:09:03 Yeah, like a loud pop or something. Yeah, yeah. So there was actually sort of a built-in, what's the right word, built-in warding off of bad luck by giving something the worst outcome as a name. As opposed to like click or something like that. Yeah, click would be a minor problem, but an explosion would be a major problem. That would be enough perhaps to get the audience to leave the concert hall. And so I started naming things bang just as a
Starting point is 00:09:32 way of saying, yeah, this isn't going to work but let's write it anyway. It really should have been a single dot. Like a period character kind of thing? Yeah, like a single period. You can't parse it as a number. And I actually proposed to the PD mailing list, why don't I change bang to just period because it's completely neutral. It doesn't say anything about what is going to happen. It's a nice reference to the Hitchhiker's Guide to the Galaxy because the message that
Starting point is 00:10:00 gets carried across the galaxy by some automaton turns out to be a single dot. It means greetings. And anyway, and you wouldn't want to use exclamation point because that's usually pronounced bang. So why don't you just use a period? And the answer I got back was, oh, we love bang. Let's just use bang. Let's just stick with bang. It's totally part of the identity of Max and PD
Starting point is 00:10:24 and the derivative languages that have come since then, for sure. It's true. And I didn't really quite invent it because, of course, the notion of it being a trigger predates that. But the idea of calling the trigger bang was, I think, that originated pretty much with me. So going back to that early period where you started, before you developed the patcher interface and when you were working on the, is it fair to call it real-time scheduling at that point?
Starting point is 00:10:51 I think so, yeah. I think, say I am a colossal fan of visual programming and of using graphical metaphors to represent things that are happening inside the execution of a program. And I think there's a lot of really, really interesting ideas there that have yet to sort of have their moment. But what I mainly actually wanted to talk to you about today was that whole scheduling matter, specifically because in the podcast interview with Darwin Gross, you said that one of the three books that you still have in you is a book on scheduling and that you may someday write that book. And so that makes me think that whatever thoughts you had about it at the time that you were first working on that project, you're still having more and more thoughts about it to this day. And I'm sort of curious, how did you approach the problem back then?
Starting point is 00:11:55 And how has your perspective on the problem changed in the time since? Okay. Well, first off, being at MIT, I had access to people who thought about real-time programming. And I didn't find that their research actually was answering the questions that I was asking. So, the way people thought, or at least the way the people I talked to thought about real-time programming and scheduling back in the day was, you have a bunch of inputs and you have a bunch of outputs and you want the outputs to be some function of the inputs regardless of time. And you simply want to do the computations that compute the outputs from the inputs as fast as possible or perhaps by some hard deadline. So, for instance, the thing that you can't do is make a metronome because a metronome isn't a function.
Starting point is 00:12:45 It's a thing that has its own state. So I didn't get anything out of the real-time community, at least the bit of it that I talked to. There also were people in other places who were writing real-time operating systems. And that was all about interrupt handling and getting, again, getting things into tight deadlines, usually being deadlines under a millisecond, like in the microseconds. Like what you'd use for landing the Apollo lander or doing some sort of fly-by-wire system for a fighter jet or something like that. Something where you need a result, no matter the quality
Starting point is 00:13:23 of the result can be sacrificed, but the result has to arrive in time actually yeah i don't i'm not sure how people would talk about quality versus versus timeliness kinds of trade-offs but um but a a better a better problem space to think about was robotics where where you would have an arm and if you reached too far with the arm you wanted to pull the gain back so the arm would come back in. But if you did that too late, then the arm would come back in a little too far, and then you'd push it back out, and it'd go out a little too far, and so on. And pretty soon you'd punch yourself in the face. Yeah, or you'd get that sort of hunting behavior where it oscillates back and forth. Right, exactly.
Starting point is 00:13:57 So most of the people, I think, who were doing sub-millisecond scheduling really were worried about robotics applications or other kinds of servo control kinds of things. And that wasn't what I was trying to do either. It's hard to explain what I was trying to do. But one of my examples was, gee, someone walks up to the thing and plays a C major chord, and you just want to hear the thing come out the speaker. And that, well, how would you do that? Well, the other example I had, besides those two kinds of examples, the sort of flow-based real-time model and the interrupt-based real-time model, the third thing I knew about was Max Matthews' work. He had done a thing called RT-Sched, which stood for RT-Scheduler, real-time scheduler. And that was a thing which modeled whose model or whose programming model
Starting point is 00:14:43 was a bunch of parallel processes, each of which was waiting for a specific kind of trigger to set it off. So, for instance, you would model a piano. I'll get this approximately right, but not exactly. You would model a piano as 91 processes, each of which has a dedicated key that's going to go down, one of the 88 keys or three pedals, and then there's going to be some kind of action that will take place when it gets set off. And then after
Starting point is 00:15:11 whatever the process is takes care of the action that is associated with its trigger, then it specifies what the next trigger is that it will wait for. So for instance, if you want to be conducted and if you were only playing things on beats, you would wait until the conductor conducted beat one and you would say, all right, I'll play note number one and I'll wait for the conductor to hit beat two. That'll be my next wait condition. And then when beat two comes in, I'll play the next thing and so on like that. So I thought about this and I had two reactions to this. One was that, in general, there might be several different things.
Starting point is 00:15:50 There might be a disjunction of things that you would want to wait for, and you might want to have different actions based on the various things that might happen. So, for instance, this is a bad example, but the piano key, if you hit the soft pedal, the action moves over. And if you hit the key, the action goes bang, right? So you need actually to wait for two things and whichever of those things happens, you need to make the appropriate response. And you don't know in advance what order they're going to happen in. That would be the piano telling you what score you were going to play before you went in and played it.
Starting point is 00:16:26 And just to illustrate that for the listener, that the action moving over is something that takes a certain amount of time to happen. And then pressing the key, you know, if you pressed it right at the same time you're pressing the soft pedal, the soft pedal won't necessarily have moved over far enough yet if you're doing it, you know, incredibly quickly. Right. Actually, that's an interesting, that's an interesting comment because that's precisely where the metaphor falls apart. Because in fact, the, probably the hammer is flying through the air at the same time as the action is sliding over. And you don't know where the hammer is going to hit the string until the hammer actually hits it. and that's when it matters where the action actually happens to have been shifted over to. So really to model this correctly, you would need to do something continuous in time and
Starting point is 00:17:13 solve some differential equations. But I didn't take any of that stuff into account. I was thinking, well, look, it's a computer. We don't have to deal with physical limitations. We can have things happen instantaneously, and that might make it easier to think about and easier to design the instrument, even though the instrument might not have quite as interesting a character as it would if you really built one. So yes, you would idealize the thing as being the shift, sorry, the shift key, the soft pedal is a sort of shift key, and it matters which order you hit the shift key and the key key right okay fine um
Starting point is 00:17:49 so that was uh that was critique number one so then i started thinking about rather than having the so-called process as max was calling them rather than have the process specify what it was waiting for it would specify simply that it was waiting and have the thing that triggered it know which processes had to be triggered when it went off. So you're moving some of the knowledge into the message that's doing the triggering? Exactly. Or actually over to the sender. Right. In other words, it's not the receiver that says where I want to get the message from. It's the sender that says where I'm going to send the message. That was idea number one. Idea number two was rather than have all the data in the in the world be global variables why don't you actually have the data be encapsulated in the message that is the trigger
Starting point is 00:18:32 right and that I think uh I don't think people had done that before um at least not in music systems and that's really what made the max paradigm what it is, is the fact that you send things messages and the message isn't just a trigger. It's the trigger plus all the information that the trigger needs to specify all the things about it that you might care about. Again, which is determined by the sender, not by the receiver. Interestingly enough, what that meant was that a thing that received a message then didn't have to go out and read data. It could maintain data encapsulated in itself, and it could receive data as part of these messages. And therefore, you would have a very high degree of data encapsulation by using this model. And that's a plus and a minus. It's a plus because it means
Starting point is 00:19:27 that your programs will grow more robustly. Because as you start adding stuff in, you don't have these interdependencies between things that get out of control. You don't have to worry about global state changing some local behavior in a way you didn't expect. Exactly. But the downside is that, of course, some things really want to be global, like the sample rate. And so you don't want to have to send the sample rate along with every message. And so what ended up happening was a sort of a compromise between globality and locality, where most everything that is happening that is interesting in real time is local.
Starting point is 00:19:59 But certain things that you really just want to have around, such as stored sounds, which are large arrays, or globals such as sample rate, those are indeed global. And things in Max entities, which are called objects, can go find them and do things with them. And when you're doing this work, are you aware of things happening with Smalltalk? It's this 85-ish, we're thinking? Well, I started doing this in about 82. Oh, okay. I became aware of Smalltalk, I can't remember exactly when, but somewhere along in there. Somewhere between 1980 and 85, two influential object-oriented systems arrived, More than two, but one of them was Smalltalk, Smalltalk 80 as it was called. And one was so-called Class C by one Bjorn
Starting point is 00:20:53 Stroustrup, which later became C++. So, at MIT, even in 82, we had a precursor of C++ that essentially was C with message passing. It didn't have all the polymorphism and other kinds of things like that, but what it did have was the notion of a data structure that you would hide from the outside world, and you would pass messages which were selectors that at that time had to be resolved at compile time. Yeah, static messages rather than... Right, exactly. But of course you could see immediately how to generalize that.
Starting point is 00:21:28 And we also knew that small talk was completely dynamic in that respect, so the static versus dynamic thing was a choice to be made. I think it was very much in the air in programmer circles between 80 and 85 that this was going to be a good way to do things because basically of the data hiding aspect of it. And Max and PD borrowed that very, very directly. Max and PD did not borrow notions like inheritance, polymorphism,
Starting point is 00:21:59 all the other stuff that goes into object-oriented stuff these days. Lazy evaluation, forget it. Yeah, all the things they added to small talk on the way to self and on the way to future derivatives to try and make it scale up to larger programs and give more different ways of forming abstractions. Right, exactly.
Starting point is 00:22:19 And as far as I was concerned in the design of Max and Pedia, I wasn't concerned about that because I was only concerned about things that were as large as a piece of music. Yeah. However large that would be. And I found out that the size of a piece of music can get up to about 1,000 sub windows. Oh, yes. Yeah. But, of course, probably not 1,000 different sub windows.
Starting point is 00:22:43 Probably that would include copies of things. And so probably you would talk about hundreds of unique sub windows in a patch though though then of course there are there are people like myself um who upon discovering an environment like max or pure data say okay can i meta program this and and generate programmatically a thousand different sub windows oh yes oh yes i've Oh, yes. I've done that. Oh, yeah. Yeah. But at that point, you're not caring about what those thousand subwindows are. You're caring about the program that generates them. That's exactly right.
Starting point is 00:23:15 Yeah. And yes, in fact, one person at Earcom where I was working did exactly that, wrote a list program that generated these million line cue lists that would essentially sequence the passing of audio data from one static location to another in a max patch. And actually got pieces of music to stage based on this system. Oh, wow. I laughed at it, but it actually turned out to work.
Starting point is 00:23:42 Yeah. I was curious to hear whether they were doing it legitimately or if they were doing it to just see if they could bring down your environment. No, it was in an ear comm studio with a concert date, so it was legit. It was like, let's make this work. All right. And what year was that about, do you think? I'm guessing that was 92 or 93.
Starting point is 00:24:04 Okay, so by then, then you know the environment has had a lot of use and i'm sure the robustness was a lot higher than it might have been when you first started working on it right i think that was pushing it but i think at that point yeah things were pretty much settled in yeah so backing up a little bit to the to the very very early days of the patcher and the and the scheduler behind it. When you were working on the scheduler, you mentioned three different kinds of scheduling. And there was one that I didn't quite understand the relationship to the others. There's Maxis scheduler, which is that sort of independent processes that communicate with messages.
Starting point is 00:24:41 Right. that communicate with messages. There's real-time a la real-time operating systems and sort of that hard real-time kind of scheduling where you care about hitting specific millisecond targets. And then you also said flow-based scheduling. And I want to know what that is. Okay, so the, I've forgotten the name, but there was actually a PhD thesis out of MIT under Michael Dertousos,
Starting point is 00:25:06 who was the prof that I was aware of at the time. This was a real-time scheduler that looked like an acyclic graph. So it actually, you could make graphical representations of it if you wanted to. And the idea was that you had inputs and outputs that were essentially voltages, and you wanted the output voltage A to be the logarithm of input voltage B, say, and you wanted that to settle by a fixed deadline. In other words, if the input changes, which it would do at discrete moments in time, you had then a certain amount of time to get the outputs to be a function of the inputs, which was described in an acyclic graph.
Starting point is 00:25:48 And I don't know what the name of that kind of scheduling paradigm is, but it's a somewhat different thing from the interrupt-driven kind of thing, because you don't talk in terms of tasks. You only talk in terms of having the outputs reflect the inputs functionally within a deadline. And so the execution model would be something like each one of the nodes in this acyclic graph would get a certain number of opportunities to recompute its result or something like that? That's correct. And what you would do is you, on a computer, you would actually pre-schedule the whole thing. So you would simply run the nodes of the graph in a fixed loop of any length that you wanted to. And the loop would have to be designed in such a way that you could guarantee that when an input changed,
Starting point is 00:26:34 that would trickle down to all of the outputs that it affected by each of their individual deadlines. And I don't know, that might be kind of a minority approach to real time programming but it was something that I was aware of at the time that sounds vaguely similar to how some game engines work in my experience, but I might be misunderstanding it it could be there are certain sorts of things that you would want to code that way I'm trying to think of a good example right now
Starting point is 00:27:05 and kind of failing. So, any other thoughts on scheduling before we get to the next phase of the evolution of the patcher? One thing that turned out to be very important was to have messages actually have ASCII equivalents so that you could type them and see them, print them out, and they would print out their entirety when you printed them, right? So, that precluded the idea of having any kind of data structure because that would require formatting. I suppose you could. You could have messages with parentheses in them or something like that, but I quickly decided that since I wanted the message to be human-readable, the best way of doing that that I could see was to simply have there be only atoms that were things that you could type, which were symbols and numbers.
Starting point is 00:27:56 And then to have the message simply consist of a string of those atoms, or not a string, but a collection of those atoms, an array of those atoms of various types. Right. And so did that prevent you from doing things like having a higher order message where a message contained like a function or something like that? Right. You couldn't send, you could not send a function around, although you could send its name around. So there, yeah, that was quite a strict limitation in what the code would do. And I did that partly because I wanted things to run very quickly. And I wanted to be clear to the user how long it was going to take a thing to happen.
Starting point is 00:28:35 Okay. And a good measure of that was going to be simply how many messages got passed. Whereas if the message itself could contain, you know, could be some polymorphic thing, then it could be arbitrarily large and complicated. And then just the fact of passing a message from one thing to another could take a certain amount of CPU time that you'd want to care about. Yeah. Right. Yeah, you lose the sort of the uniformity of how long it takes to process each message and your utility of using that as a measurement goes out the window.
Starting point is 00:29:01 Right. And the other thing is all names are global. And that confused a lot of people because, of course, that works directly against being able to make scalable programs. And again, that was for the reason that when I saw composers trying to use computers, they would write something like A that they'd define somewhere and not get it. So actually, scoping was a middle hurdle to get over for people as opposed to a source of power, which it would be in the hands of a programmer.
Starting point is 00:29:32 And to the best of my memory, it's still that case today in Max and Pure Data, is it not? There's no namespacing or anything like that? As far as I know, I mean, I haven't used Max in a while, but as far as I know, Max doesn't have it, and I'm pretty sure PD doesn't. What you can do in PD is name mangle. So you can make names that are generated in such a way that they look local, but you can still see what they are and you can still get them from anywhere you an escape hatch if you need it, if you're doing something very complex, something where you're generating code or generating structures of your flow graph in PD. Right.
Starting point is 00:30:12 Actually, you need it right away because as soon as you want to make a thing which is a delay, you need to have a delay line that you will name. And that name should be local to the abstraction the abstraction that defines the delay right or else if you use two of them they'll share they'll fight yeah right yeah and so you need it right away and yet i make people actually name munch in order to to get that to happen as opposed to have that have a local variable kind of facility that that reminds me a little bit of the debate around hygienic macros does that feel similar to you or is that sort of a a little bit of the debate around hygienic macros.
Starting point is 00:30:45 Does that feel similar to you or is that sort of a different sort of thing? Gosh. Like in the Lisp community where you have a macro preprocessor and if you have hygienic macros, you can use names without fear that the macro expansion will cause sort of naming conflicts. Right. In other words, making sure the name stays within the macro. Right. And I suppose, yeah, if you can't scope a thing within a macro, then again, you're going to have to name munch to get the thing to work. So that probably is about the same thing. Or in the early days of C++, when you wanted to make generic functions like an array add that didn't know the type of arrays it was adding, then you would have to write this horrible macro that didn't know what type it
Starting point is 00:31:29 was operating on and then invoke the macro and all the types that you were going to want to ever define the thing for, right? And we're still, to this day, trying to find better and better ways of dealing with generics. Yeah, right, exactly. So on that topic, when you're working on the early versions of Max and then later PureData, what sort of thoughts about types are you having? Well, I wanted the type system to be as stupid as possible, and where stupid is intended as a compliment. And in the days of Max,
Starting point is 00:32:09 there was one consideration that was just practical, which was that I was writing for a 68,000 processor, and there was no floating point unit. So floating point operations were roughly, I believe they were roughly 300 times as expensive as fixed point ones. And so you needed an integer type as well as a float type. And then, of course, you needed a thing for naming, which I called a symbol. And those were the three types.
Starting point is 00:32:33 That was it. So were messages not a type then? Or would the message be the type of the contents of the message? Yeah, messages were not a type. Okay. That's right. Messages were just messages. I don't know how to say that, but, but the type system really had three types. Yeah. Yeah. So does that, does that then mean that those three types are there? They're a kind of data that the system is aware of and operating in terms of, does that then mean messages are not considered part of the data model?
Starting point is 00:33:06 Are they part of the execution model or something else? Oh, let's see. I don't know how to answer that. It might be a very bad question. I'm still, it's been about a decade since I did a deep look at the internals of how Max and PD execute. So, yeah, but I'm actually even thinking just externally. So internally in the implementation, a message is simply an array of typed atoms.
Starting point is 00:33:38 Yeah. And an atom is just a type and then a thing of that type. And so there are types like that in the.h file that everyone reads that wants to write a PD object. Right. But the user never sees those types. The user meaning the PD programmer. Yes.
Starting point is 00:33:55 Yeah. Yeah. And so there's, let's forget this types question because that's a rabbit hole. When you're building this environment, how are you distinguishing between, you know, you, the programmer working on the underlying system and the scheduler and eventually the interface versus the end user who's going to be writing, you know, compositions within this environment? Are you, and then is there a third category, which is these are people who might be making plugins or extensions or that sort of thing? How are you dividing up the different roles of people who are going to be all touching the software that you're building?
Starting point is 00:34:35 Right. I think the answer is that it's a direct map of the culture at IRCOM in the 1980s. Specifically, there were composers who uh who wrote music and who would never be much more than a pd user or max user in other words they would learn how to how to make things out of max but they wouldn't actually learn how to make max or make additions to max then there were the and then there were people called researchers i was one of them and we researchers would actually write software that hopefully the composers would be able to use. And then there was a layer of people in between who are now called realizers, but who at the time were called musical assistants.
Starting point is 00:35:17 And these people were people who were not only power users of Macs at the time, but were also people who knew enough about the internals that they could write their own Macs objects, which were essentially plug-ins. And so I was thinking in terms of those three populations as I was writing along. Lots of people were able to write small, were able to write application programs in C that would go up to 100 lines and would
Starting point is 00:35:46 do a specific thing like interpolate between two rhythms. There were people like that around and I was interested in having them be able to use their work inside an environment. But then there were people like me around who could make the environment work. And then there were people who simply would use the rhythm interpolator in a piece of music and they would just want to be able to call it and feed it the two rhythms, make a patch that fed it the two rhythms and enjoy the interpolations afterward. And those would be the composers. And at this point, none of the composers were doing something that I see more of nowadays, specifically with Max, now that Cycling 74 is owned by ableton uh if i remember correctly yeah i think
Starting point is 00:36:25 that's right um where with their tool max for live you can build a max patch that has a certain user interface skin for it and then use that within ableton live so you have this new category of people who are end users of max at the same level as the composers at Earcom, but they're actually making yet another piece of software that is used by another less programmatical, more musical person down the road. That's an interesting comment. That indeed has happened, and I'm working with an Ableton musician right now who uses plug uses plugins that are
Starting point is 00:37:07 written in Mac sometimes, but he would never actually dare try to use Macs himself. He doesn't have time to learn it. So that is a thing that's happened. And that's kind of funny because Macs itself can have C plugins. So you have at least two layers of plug-in-edness going on there. And did you ever feel like back in the early days of working on these projects, did you ever feel that sort of multiplication of the number of different layers of people interacting with this system? Because that's, in my own work on visual programming languages, which are used by people to make software, which are used by people to make software, it gets really hard to conceptualize for me. And I'm wondering if that's something you also had to struggle with. Gosh, I don't know the answer to that question, because if I did struggle, it was a struggle that was spread out thinly over 30 years of messing around. So I don't think I was ever actually aware of that as a thing.
Starting point is 00:38:07 What I would be aware of is people were trying to do things in Pure Data or in Max, and they were coming up with gothic weird solutions because of design flaws in PD and Max, because I hadn't anticipated certain usage patterns. And then I would see those, and then I would try to abstract a solution to it that I would then add to max or to PD. But that was, but I was unable to, I didn't, I never actually thought about someone who was doing something that I wouldn't be doing myself. And you'd sort of, like, I'm sure that eventually came up, somebody would come to you and say, here's something I want to do, and you'd go,
Starting point is 00:38:49 oh, I'd never thought about doing it that way. Let me go back to the whiteboard and see what I need to change about the core design. Yeah, that would happen. You know, the core design is pretty much frozen these days because there's 30 years of back compatibility to worry about. But that was definitely true in the early days that people would try to do stuff and it would be hard. And then I would just have to react by making something.
Starting point is 00:39:16 For instance, the whole idea of in Max, there's a thing called the table, which is a thing where you get to just draw a graph of a sampled function, and then it can just apply that function to anything. Like, it can use it as a table of probabilities, or it can use it as a sort of transfer function to get from some control change to some level change that might be nonlinear. And it's just mapping input numbers to output numbers according to this curve that you've drawn. That you draw, right. So it's nothing but a response curve. Well, that came up because a composer I was working with wanted to be able to do that. And the first version of the thing that I was calling Max at the time didn't have that facility.
Starting point is 00:39:59 And so I just added it. It was like, okay, that seems like a very general thing that other people are going going to want to be able to do let's just add a thing called table that does that and i'm still angry that that it seems every new visual programming environment that comes out these days doesn't have that because to me that's in hindsight that is such a such a powerful thing it's such an essential thing when you're working in a visual paradigm. It is. And it's not only powerful, but it's also inadequate. And in fact, one of the things that I've been struggling with for, I don't know, but not all 30 years, but anyway, 20 of them is a more flexible way of being able to visualize data. And this is something I've written about, but just to sort of say it in 50 words or less,
Starting point is 00:40:48 what Max and Petey are very good at is describing real-time processes. And what they're very bad at is describing heaps of data that you might actually want to just refer to in your process. A good example being a musical score, right? It's a heap of data. It's not a functionality at all. And there's a problem in Max and Pure Data, which is that you're writing these things in terms of how they act. You're making an instrument, but someone wants to store a score in the thing and do things that refer to objects in the score. And at least so far, there's no good design,
Starting point is 00:41:23 or at least I haven't seen a good design, that actually marries these two ideas in a single environment that works. So what have you seen and what have you thought about for attacking that problem? Because you're absolutely right. That's a huge, huge issue. Well, there's an attempt in pure data, which is a sort of a part of pure data that most people don't look at. It's called data structures, which is, in fact,
Starting point is 00:41:51 it's what pure data was named for because right when I started pure data in about 96 was when I was thinking most seriously about this question. And my idea was to have a sort of a draw program where you could draw shapes like triangles and whatnot, and the colors and the locations of the vertices would be data that you would then integrate into the real-time programming environment. So that, for instance, the shape of a triangle could be turned into the timbral controls for a note of music. And then you would make a score that would be a bunch of triangles on the screen to just make a stupid example and then you would you you could tell the thing to play and you could you could sort of see the triangles and imagine what they
Starting point is 00:42:32 would sound like and then you could actually get the numbers out and make those sounds and and vice versa you ought to be able to analyze the sound and turn it into a whole bunch of triangles that would that together would reproduce that sound in some way right and then when you think about what that actually would entail uh it's it it gets very very difficult and complicated very very fast i know in my personal experience of playing with that feature of pure data i did find it to be unexpected i wasn't like as a newcomer to it i wasn't sure what to make of it um knowing now that it's designed to solve that problem that that data visibility problem uh gives me an interesting perspective on it uh as and i'm assuming this was this was your idea your i don't want to say responsible for it but you're you have authority over it. Are you able to say, uh, how you think it worked,
Starting point is 00:43:27 where it fell down, what you might do differently? Um, sort of. Yeah. Um, so first off, just, uh, just for fun, I should say, uh, PD didn't even start out as a max clone. I, I threw all the max like stuff in, in it a year after I started PD, uh, because there was a music production. I needed to be able to make some sound. Right. And so it's sort of, let's just go with what we know. And it's, let's make a really, let's make a simple, stupid strip down Mac so that we can at least get something happening out of the speakers. But in fact, the first thing I ever did with Pure Data was make a graph for a paper that I was writing with Judy Brown, a physicist on phase vocoders. And I wanted to make a graph. And the thing I was graphing went
Starting point is 00:44:06 up to about 5.1. And I did not want the graph to go all the way up to six as any graphing program would do. So I wanted to make a graph where the line just went outside of the rectangle of the graph. And so I did it. And that was my sort of founding example of what I wanted pure data to be able to do. So to go back to the question of, like, is it working or why is it not working? What doesn't work is very easy to find. It's that if you want to actually make a patch that goes through the data structure, it is misery. There's an object in Pure Data called pointer, and you have to get a pointer to get itself latched on to one of the objects on the screen.
Starting point is 00:44:47 And there's no graphical way to do that. You have to do that programmatically, which means you have to make a patch that goes and looks at the objects in the screen and figures out which one the pointer should be pointing at. And the only way to do that right now is to actually go linearly through all the objects in that screen until you find one that obeys whatever criteria you're looking for.
Starting point is 00:45:04 And that's just horrible. And then you can have objects that have other objects inside them. So there is actually an encapsulable data structure thing going on here. And would that be like a B-patcher? Is that one of them? No, no.
Starting point is 00:45:20 It's like if you wanted to have your triangle have a curve stuck on it, what would you do? Well, you would say, well, the curve is actually going to be an array, and that array is going to be of objects. And those objects could just be numbers, but they could also be any other pure data type, data type in the data sense of the thing, the data structure. So you could make the curve actually consist of little triangles, say. Oh, but then to get the data out of those triangles, at the patch level is misery, because you have to make a patch that scoots forward until it finds the thing that owns the curve,
Starting point is 00:45:53 and then you have to make another thing that scoots along the curve until it finds the object that you're looking at, and then the items in that have names that you have to utter in order to get the stupid data back out. So it feels very imperative to me. Yes, it is very imperative, and yet it's sort of turned inside out in a weird way because, well, because you're making a patch that's doing this. And anything imperative in a patch is going to be kind of either sideways or inside out
Starting point is 00:46:19 or something, right? Because you've got these two conflicting notions of when something's going to happen. Right. You have execution time and you have time time. And those coexist rather difficultly in pure data. And that comes to a fore when you're doing something like, you know, let's write a pure data program to search for prime numbers just using the stupid algorithm. I've done it just for hilarity's sake. And you come up with something that's just purely unreadable.
Starting point is 00:46:45 You have two nested until loops, and you have to use triggers to get the inner loop to actually completely execute before the outer loop ticks forward. And by the time you're done, something that would have been three lines of C is, I don't know, 20 objects or so. Yeah. And furthermore, you cannot read it. You can look at it and laugh,
Starting point is 00:47:04 but you would never actually put yourself through programming that for any actual task. So, yeah, so that's another thing. PD really needs a text language of some kind. You feel that. You feel like it's worth dropping down to text to do this kind of thing rather than trying to find a different visual representation that might work visually but still fit the problem you're trying to solve? I think so. I think that text languages are so good at describing, going through a collection of things and picking out the one that matches a criterion.
Starting point is 00:47:40 And, well, that's an, okay, so that's imperative programming, as you call it. That's to say, that's the thing where you just sort of say what it is that you want to have happen, as opposed to, you know, finding some sort of functional way of saying, well, yeah, where's the object that obeys this function? You know, let's map this function to everything and just give me the set of all things that return true, check that it has one element, and so on like that. Like a query or something like that. Right. But, well, first off, it Like a query or something like that. Right.
Starting point is 00:48:05 But, well, first off, it's hard to make things like that work in hard real time. And second, you know, I'm learning Julia right now, which is a language that has very powerful mapping capabilities. In fact, they seem to get more powerful every time Julia gets a minor upgrade. And it's a wonderful feeling of power, but at the same time, it took me an hour to figure out how to sum the rows of a matrix. Because I mean, I found it eventually, but in MATLAB, you just say it. And in Julia, you have to, you know, the descriptions of how you do it that I found on the web pages that I first ran into basically meant that you had to do some kind of map reduce on add.
Starting point is 00:48:57 And it was like, man, am I going to use map reduce just to do a row sum of an array? All I want to do is have the rows have mean zero. I just wanted to add them up, divide by n, subtract those. And I can write that in two lines of MATLAB. And in fact, I can write it in one line. And I can write it in one lab of Julia now that I figured it out. It turns out there is a function that does it. But if you wanted to build that function.
Starting point is 00:49:17 Yeah, if you wanted to build that function, which of course is the ethos of Julia, then you have to do MapReduce, I think. And gosh, MapReduce, really? Okay, fine. And by the way, it might matter whether you sum it from left to right or right to left, because of numerical precision issues.
Starting point is 00:49:36 Yeah. And so actually MapReduce would have to have a little bit of description about how you would like it to MapReduce in order to be able to specify that. And by the time you've done all that, I think you might have been happier just writing the damn loop.
Starting point is 00:49:50 Yeah, it's that problem of the, where you're pushing programming so far in the direction of mathematics that you start running into the limits on what computers as we build them are capable of doing you know before the the abstraction starts leaking before the machinery of it starts to infect the pure mathematics that you want to preserve oh i like that metaphor of a leaky abstraction i'm gonna use that
Starting point is 00:50:17 but yes exactly and also simply the the mental load of understanding what the thing is doing might actually outweigh the increase in elegance. Well, it's a trade-off of power versus understandability, I guess. I know there'll be some people screaming at their car stereo right now. If somebody was born into an alternate world where imperative programming wasn't the norm and the sort of functional or declarative style was more normal, the familiarity would help them. And so, it might not be as foreign feeling, but we have our culture. So, we have C as the underpinning of most modern languages that people learn first.
Starting point is 00:50:56 Or JavaScript now. Yeah, exactly. So, even if it's just a matter of familiarity rather than something purer, that's still a a factor that needs to be considered yeah and and for me you know i go back to i'm writing this for musicians uh they're they're not going to want to understand map car or map reduce right uh and so you know i'm living within the world that i'm in but i have to admit that um i feel a lot more comfortable thinking of the computer as a thing that executes things sequentially and i don't mind the idea of just writing down that sequence and so when you look at max or pure data um you know back in your your history of working on them and working with
Starting point is 00:51:36 them do you feel like they're capturing uh computation as process and as machinery more than computation as like the evaluation of a mathematical structure or is it somewhere in between or where would you how do you feel about that um well it does abstract the machine away completely so what i'm what i'm saying about how i like to think it might be different from how a composer would like to think which is more more uh more in terms of a reactive well more in terms of a musical instrument design. Yeah, like a guitar pedal or something. Yeah, it's not a modeling language, but it acts somewhat like a modeling language in that you sort of say, well, I want a thing that when you push it here, it does this. And that's different from a sequentially written program.
Starting point is 00:52:21 For me, that's the right way to design a musical instrument. But if you are going to do something that will traverse a score, which is a heap of data, then from my standpoint, the most natural way I would think about that would be procedurally or sequentially. Yeah, where you care about something like this imaginary notion of the instruction pointer, where it is at any given moment, that sort of thing. Exactly, yes. And so, at least my comfort zone would be, yeah, having the things that traverse these data structures basically be some kind of language, sorry, some kind of text language, but a procedural one, an instruction-based one, an imperative one is the correct word, right? Yeah, yeah. Well, it's one of the options.
Starting point is 00:53:05 Yeah. The transcript for this episode is brought to you by Replit. That's R-E-P-L dot I-T. That's their URL. You can go there to check them out. Folks, the world is in the grip of an unprecedented use of the word unprecedented. Everyone is at home, which means the close collaboration we normally enjoy with our peers, mentors, and students has been shaken up. Before, I could just run downstairs and pull
Starting point is 00:53:38 up a chair next to one of my co-workers so we could quickly pair program our way through a problem. Now, they've been reduced to throwing folders of source code at me over the proverbial wall. Not good. Repl.it, of course, have a great solution to this. Collaborative editing, which they delightfully call multiplayer. Send out invites by username, email, or with a unique link, and boom, you and your coworkers, students, friends, and family, if you have a cool family, can seamlessly work together email or with a unique link and boom you and your co-workers students friends and family if you have a cool family can seamlessly work together on the same
Starting point is 00:54:10 project live and in real time you see their cursor they see yours you each type where you want to type and it all syncs up like magic if you've used Google Docs or other collaborative tools you know the idea but wait till you try it with code. I can even see myself using this when pair programming in person. It's so nice to be able to zero in on a specific character, to fix a typo without derailing my partner, to add comments while they add code. Here are some of my favorite little details Replit includes.
Starting point is 00:54:42 Each person can have their own keybindingsings so you, a high-level Emacs sorceress, can peacefully coexist with a vim robot from the future. You can fill your REPL with emojis, and they work cross-platform, which is an important form of emotional expression in this dark time. There's a chat widget in the lower right, so while it's awfully fun to have text battles in the main REPL, yeah, I totally got sucked into doing that the first time I played with it, you can communicate in a safe side channel. For a limited time, you can have up to 50 people in one multiplayer REPL at a time on Replit's free plan.
Starting point is 00:55:20 So for your next pair session, spin up the world's coolest online REPL, invite your besties, and build something together with multiplayer. Thanks to Replit, that's R-E-P-L dot I-T, for sponsoring our transcript and helping to bring us the future of coding. I think I'd be remiss if I didn't ask a little bit about how the original patcher came about, and especially how you decided on what things to expose to composers and what things to hide from them. What can you recall about that time and how you approached that problem? The whole process was a process of carrying things over from you have to code this into C into you can do this yourself without having to code into C. And in fact, the way I thought about it originally was reusability.
Starting point is 00:56:12 So the idea that if you had a sequencer that you could reuse it from one application to another, which would be from one piece to another. And so what I was thinking about originally was taking pieces of, was ways of writing little pieces of code in C so that you could assemble a bunch of them together, perhaps with some new stuff and make a piece of music out of it. But then the next piece, you'd be able to pull, say, half of it out and reuse, right? So I was still thinking in terms of the piece would be a C program, but the modules of the C program would be largely reusable. And then at some point, I was showing what I was doing to the scientific director of IRCOM at the time, Jean-Francois Aloise, and I was showing him, yeah, okay, so here's a little bit of C code and put that together and
Starting point is 00:57:06 it makes this nice oscillator with an amplitude control and he looked at the piece of C code which is pretty elegantly put together and he said you think a composer is going to want to do that and the answer was kind of maybe not and that was what made me think, well, yeah, okay, maybe I'm just going to make a graphical editor to allow you to put these modules together. Because the way the modules, the code modules were fitting together were beginning to look like things that you could connect graphically, even though the functionality itself was pretty much fatally in C. Like, I couldn't imagine writing a sequencer graphically, but I could imagine adding two oscillators graphically. Yeah, like a modular synthesizer with patch cords. Exactly that. And in fact, I knew all about modular synthesizers, so I had that sort of model to go on. And I knew that that was a very good way to talk about signal flow. But most of what was going on, we were using a 68,000 processor, so we weren't actually directly coding signals at that point.
Starting point is 00:58:07 So really the question was processes that were about control. Actually, I was doing both. I was trying to write oscillators anyway, but I knew I wasn't going to be able to really use them. But I was also writing things like sequencers, which are control objects which you could run on a 1 MHz processor. And it got to be more and more like you're going to have this sort of repository of of code that each of which makes some kind of module
Starting point is 00:58:29 which eventually got called an object and what i want to do is make a way for you to be able to put these things together and the way that you put them together should also reflect the message passing scheduling ideas that i was working on and And so the obvious thing to do was, okay, have the message passing, you know, be sent along paths that you describe graphically. And also to have the things that you connect not be pictures of oscillators, but actually command lines that instantiate things. Explain that a little more. I didn't quite catch that.
Starting point is 00:59:00 Oh, well, if you're programming Unix programs for instance um you you write a c program and the way you invoke it is you is you type something to a shell which is a bunch of arguments that that the shell takes apart and feeds to the c program right and so i was thinking all right so the thing that you type in a box is not going to be well you're not going to make an icon of an oscillator you're going to make an empty box and type a command to create an object. And that command, to me, the best way of doing that was going to be to allow you to just type a command line. Yeah, so it's your object name in the first position and then a couple of arguments to that command invocation. Right, and the object would have its own code that would parse those arguments and decide what to do with them. Right.
Starting point is 00:59:46 And at this point, you've already got one or more input ports on the top and output ports on the bottom? Or did that come later? Yeah, you had to have the input and output ports because of being able to pass messages back and forth between these objects. Yeah, so that things get executed at all. Right. So I had already thought about the idea of having these objects that were instantiated with command lines and then defining interconnections between them. The thing that finally occurred to me
Starting point is 01:00:15 was that you could actually make the connections, the interconnectedness be graphical. Interesting. So before the interconnections were graphical, did you have another solution you were playing with or were you just not sure quite how to do that yet? Oh, well, I actually had a solution, which was you made a text file that gave everything a name. And everything could only have one output at that time. And then you would simply give it as part of its arguments, usually the last arguments would be all the objects that you would connect it to named.
Starting point is 01:00:50 Right. So you sort of specify your signal graph that way? Right. And so everything only had one inlet and one outlet, and then the connections were all by name. Well, first off, it became useful to have the idea of different inlet ports that would have different functions so that the messages themselves didn't have to say what they were. You could just make the message do what it did by connecting to the appropriate input. And the other thing that went along with that was being able to have more than one different output so that, for instance, something could say, give out numbers, but then could have another output that would say, no, I don't have an answer for you. Better do something different or something like that. I know you say that there is no notion of polymorphism in max and pure data,
Starting point is 01:01:27 but that's sort of a hinting in that direction where you can have like a sum type in a language like Haskell, where you say, you know, it's going to be a number or it's going to be an empty value. Oh, right. So you have your one output is numbers are going to come out of this output,
Starting point is 01:01:44 but if there's no response, rather than putting it over that same output, we'll put a different output port. And that's where the empty result is going to come out. Yeah, that's interesting. I hadn't thought of it that way at all, but that's an interesting way to think about it. That's my whole approach. And I think a popular approach in this future of programming community
Starting point is 01:02:03 is learn a little bit about everything and then try and see connections between things where they don't exist try to make a language that can allow you to describe them yeah yeah so and this one's going to be deeply dissatisfying to the community and and maybe you as well but i'm i'm just going to ask for my own personal curiosity um In the time since you made the original patcher and then Max grew up out of it and then eventually that got spun out and then you made Pure Data and at some point Cycling 74 came into existence
Starting point is 01:02:37 and Pure Data kept growing as an open source project and Max kept growing as a commercial project. Max's user interface was seemingly refined and refined and refined and refined by the folks at Cycling74. Pure Data's user interface also refined and refined over the years. It looks and feels a lot nicer now
Starting point is 01:02:59 than it did back when I first played with it, like, oh, maybe 20 years ago. Ooh, yeah. How much of the direction of the user interface improvements in those projects came from you and how much of it came from other people? Do you sort of feel like the interface to Macs now and to Pure Data now fits how you imagined it would progress or did it fall short or did it exceed what you expected how did the history of the interface development fit with how you felt it should have
Starting point is 01:03:32 gone maybe huh um well i would say in the case of pure data maybe about half of the evolution was my work and half of it was the work of frustrated users who just wanted to be able to select two objects and hit command k to connect them right as opposed to having to drag that stupid line i was patient enough to just drag the stupid line but on the other hand i noticed that after an hour or two or three of using pure data i would have my shoulders would ache because of the you know tedium of actuallyium of actually getting the mouse to be within five pixels of some stupid place on the screen. So I'm actually glad that there are people who think a little bit more broadly about the user experience than I am able to.
Starting point is 01:04:21 At the same time, a lot of the improvements actually were me, just getting tired of having to do a thing and finding a faster way to be able to do it. For instance, duplicate. That's an important thing. And there are other things like that that I came up with over time to try to just sort of make life less miserable for people who had to use the program. So a little bit of both. But PD also is, there are two things going on. One is just the ease of manipulating objects, and the other is the visual thing that you get on the screen.
Starting point is 01:04:58 And one thing that I've been very reactionary about is keeping that as nearly monochrome and as pixel light as possible. Partly as a matter of aesthetics because I think it's...
Starting point is 01:05:19 I don't know if I should not subject other people to things that I find irritating, but I find decorations of all sorts irritating. Interesting. You know, I like straight lines and I like them better if they're horizontal and vertical. And I like, you know, I like simple type. I do not, you know, I do not do dingbat type and that kind of stuff. Other people, you know, sort of get off on decorating their programs or their windows in general.
Starting point is 01:05:48 And you can, you know, you can find things in PD that will allow you to decorate stuff. But I simply don't and avoid having PD actually present itself that way. Because I, and this is an aesthetic thing, I don't think it's healthy to be creating music by making pretty pictures on a screen. It seems like it's a distraction. eye candy for themselves as laptop performers say. It doesn't quite infuriate me, but it does disappoint me because I think they should be focusing all that energy on the sound and not on simply what they see on their screens. You see a strong distinction between something that might have an ergonomic benefit versus something that is there just for you know giving somebody the warm fuzzies or something like that that's right and so ergonomy i really care about but
Starting point is 01:06:50 but the but uh having the you know having beveled boxes i do not care about yeah yeah yeah i can't stand that kind of stuff and do you do you feel like it's in keeping with say the aesthetic of like electrical schematics or something like that for pure data? Or is there some other sort of thing you can point to and say, this is the root of the aesthetic that I'd like to stick with? Actually, it's my mathematics training. You don't put in details that aren't essential to the argument. Yeah. Yep.
Starting point is 01:07:21 And so, yeah, so it tries to cut everything down. So it's deliberately an attempt to cut everything down to the bare essentials and to leave all distraction out. Neat. And just the second half of that question was sort of in how it's evolved, do you think it fits what you imagined it would have been when you started? Or is it different? It's actually surprisingly close, I think. Well, PD hasn't really evolved a whole lot in any fundamental ways. And the evolution that I've seen is, you know, a growth in the kinds of objects that people can use and also a growth in the sorts of media that you can apply it to. And that was something that I actually was thinking about from the outset,
Starting point is 01:08:06 that it should be, insofar as reasonable, it should be medium, what do you call it, agnostic. It's not quite, because the scheduler, time moves because sound moves in and out. But except for that little detail, it's media agnostic. Neat. Well, Miller Puckett, thank you very much for coming on our program and for sharing this bit of history of visual programming with us. Right. Well, thanks for inviting me. This was a fascinating conversation for me
Starting point is 01:08:36 because it gives me a point of view on pure data myself that I don't often get a chance to explore. So that's it for our show today. that I don't often get a chance to explore....girls... So that's it for our show today. I want to thank Miller again for coming on, and thank you for listening, and thank Repl.it for sponsoring the transcript. Go to repl.it and try out their multiplayer feature.
Starting point is 01:09:02 The next episode is actually going to be one that Steve recorded. He left me with a handful of interviews that he'd recorded but not yet released, and so I'm going to start peppering them out over the next while to get those really cool interviews he did into the feed. I won't say who the guest is yet, but given Steve's impeccable taste so far, I think you'll enjoy it. I have a few surprises planned coming up, so if you are listening to this and this is your first time with us, you know, be sure to thumbs up, like, fave up, fovea, ground pound, flip fry, subdub, destroy that toggle button. That's it for this time. Thanks for listening, and I'll see you in the future.

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