Future of Coding - Max/MSP & Pure Data: Miller Puckette
Episode Date: May 12, 2020Miller 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)
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
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
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
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
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
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
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
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
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.
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
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.
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.
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.
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
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
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
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?
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?
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.
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
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.
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
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
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.
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.
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
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
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
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
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.
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
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.
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,
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.
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.
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.
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.
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.
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.
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,
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.
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,
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
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.
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.
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.
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.
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.
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.
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
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,
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.
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?
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.
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.
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?
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.
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
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
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
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.
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,
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.
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.
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,
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,
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,
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
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,
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
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.
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.
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.
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,
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
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.
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,
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.
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.
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.
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.
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.
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.
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
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.
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
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.
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.
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
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
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.
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.
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.
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
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.
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
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.
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.
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
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.
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,
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,
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
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
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
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
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.
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.
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...
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.
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
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.
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,
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
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.
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.