Transcript

Transcript prepared by

Adám Brudzewsky, Bob Therriault, and Sanjay Cherian

Show Notes

Transcript

00:00:00 [John Earnest]

It is an unfortunate consequence that quite a few people look at Decker and, based on their initial impression, assume that it's not very powerful, that it's sort of a slavish clone of old software. But I promise you that if you dig a little bit deeper, there is a lot to play with there.

00:00:28 [Conor Hoekstra]

Welcome to episode 109 of ArrayCast. I'm your host, Connor. And today with us, we have a returning guest who we will get to briefly introducing. You're probably familiar with him already if you're a regular listener. But before we do that, we're going to go around and do brief introductions. We'll start with Bob, go to Stephen, then to Adám and finish with Marshall.

00:00:47 [Bob Therriault]

I'm Bob. And as we record this, it's Canada Day. [01] So wave the flag, Canada Day. And I'm a J enthusiast.

00:00:54 [Stephen Taylor]

Yay, I'm Stephen Taylor. I'm a Canada enthusiast, and I also play with APL and q.

00:01:00 [Adám Brudzewsky]

I'm Adám Brudzewsky. I like both Canada and APL.

00:01:03 [Marshall Lochbaum]

I'm Marshall Lockbaum. I have fairly positive feelings about Canada. No comment on APL. I'm the creator of BQN.

00:01:10 [CH]

Fairly positive. What the heck? But I'm Conor, as mentioned previously. I live in Canada, just like Bob, two Canadians. And just, I mean, some of the biggest array language folks, they reign from Canada. I mean, Iverson himself, Whitney. Anyways, so I like Canada. It's a very nice place. Happy Canada Day. And I also like all the array languages. And I think we have a few announcements. We will start with Marshall, and then I think Adám's got a couple after that.

00:01:41 [ML]

My announcement is a recurring event that we've done one of, and so we will do the next of soon. What happened was an article from the Quote Quad came up in our array forum, the Apple Farm, and we had some interesting discussion about that. So I decided, what if we did that on a schedule every week? And so this last Sunday, we voted on an article from a 1978 issue of Quote Quad, and we discussed it. It was about, it was like a survey of error messages in APL, and specifically they looked into what sorts of errors students ran into. And so that was neat, and we'll do it again this next Sunday. So that's July 6th. This is in the main channel of the Apple Farm so you can access that through Matrix or Discord. And you want to search for the quote squad. So the squad that discusses the quote quad. And that will lead you to the last discussion which you can of course read and even comment on if you want. And that will also have the specific time for the next one and which article we voted on that we'll be discussing. Check that out if you want to.

00:02:52 [CH]

Awesome. Link will be in the description. And over to Adám for, I believe, your three announcements.

00:02:57 [AB]

Yeah, but I never cease to be amazed by the names people come up with for various events and products and so on. This is just amazing. Well, okay, so we at Dyalog are putting our final touches on version 20, which, in my opinion, is going to be awesome. There's so many good things there, but I'm not going to bother you with that now. I'm sure we'll return to that once it's actually released. If you want to play around a little bit with the more languagey parts of that, including, I'm sure your recurring listeners have noticed that there's a new combinator or compositional operator, then you can now do so on tryAPL.org. So head over there. And, well, if you find something really bad there, you might want to report it to us so we can fix it before actual release. And then for all Array programmers, the British APL Association, their next meeting, which is on July 10th, is going to be their annual general meeting. And that's where they both decide their finances, whether they work or what they're going to do with the money. Which means if you want some influence on how they will spend their resources and what kind of events they're going to do, then you can show up for that and make yourself be heard. And finally, there's the APL challenge with three weeks, three and a half weeks to go when this is released. And which is this introductory, both course and competition where you have a chance to win cash.

00:04:28 [CH]

Awesome. Links for all of that stuff in the description, as always. And very exciting about TryAPL 20.0. That means, I'm guessing, the release of Dyalog 20.0 is around the corner, folks. So very exciting. We'll probably have an episode on that in the future. And with all of those announcements out of the way, we are back here with John Earnest, who is now our number two most frequent guest, was previously tied for number two with Nick Psaris at five appearances, four as a guest, once as a panelist. but now you're in the outright standalone. You've left Nick behind in the dust. And if you are not familiar with John, I mean, we will link to episodes 41, 43, 53, 95, and 96. Those are the five that he was on. Most recently, episode 96, I believe, was back in January. We were talking about Decker, and that's kind of why we're having you back today. There's been some evolutions or changes, I guess, with both Lil and Decker. And I think we're also, it's kind of good timing. I think, if I recall in the email, there is another kind of, I don't, what's the name? Is it the July Fun Camp or Decker Fantasy Camp? I was actually trying to look it up and Bob sent the email to my other email. And anyway, so what is the actual name of the jam that is starting now?

00:05:51 [JE]

The jam is called Decker Fantasy Camp.

00:05:54 [CH]

Okay, Decker Fantasy Camp.

[JE]

Arguably, it could be considered a game jam, but it's really even more broad than that. You don't necessarily have to make games. We've had people make zines with poetry in them, occasionally useful tools or toys. It's really just make anything interactive in Decker and share it with people. And kind of an interesting consequence of last year's fantasy camp, I wrote a little animated drawing tool in Decker that was reasonably well received. And then about two weeks ago, it went viral in China. And I've had about 5 million plays of it.

00:06:38 [CH]

What?

00:06:40 [JE]

So it's by far the most successful project made in Decker so far. And the fun thing about it is that, you know, it's just this drawing program. But all of the tools of Decker itself are available. you can just sort of break out of that container and modify the tool itself seamlessly. And so that means that there are 5 million people who have had an array language at their fingertips should they choose to dive into it.

00:07:13 [BT]

And I probably should say at this point that Decker is based on HyperCard, which was produced by Bill Atkinson, who passed away recently.

00:07:21 [JE]

Yes.

00:07:26 [BT]

And the thing about HyperCard was it was really easy for people who are not computer programmers to go in and make alterations to what were called stacks. And I've heard people say that part of the reason the web is the way it is now is because of HyperCard, because HyperCard introduced links that you could jump between these different pages. And so it's an interesting concept, but it's very flexible, and there's a lot of things you can do with it. And I'll let John talk more about it because he's, yeah.

00:07:50 [JE]

I mean, for those who aren't familiar with his body of work, it cannot be understated how much of an influence on modern computing Bill Atkinson had over the course of his career. He was the lead author of Quickdraw, which was like the graphic subsystem of early Mac OS. And then he designed and implemented Mac Paint, which was a drawing program that was highly influential. Mac Paint and Photoshop and countless other tools. have UI conventions that were established by this. Bill invented, you know, tear-off menus, the concept of like the marching ants outline when you make a selection on things. Just a huge amount of the visual vocabulary of macOS comes to this. And so HyperCard can be seen as a much fancier, more powerful version of Mac Paint. What's interesting about it, if you compare it to other programming environments is that it's a rare instance of one that is first and foremost a drawing program. You have this virtual stack of cards, and you can draw or write text on them, and then you can add interactive elements to them and link them together. There are a lot of other hypertext systems that preceded HyperCard in one way or another, but HyperCard was one that made the concept of hypertext extremely accessible to people. because part of the licensing deal for HyperCard involved getting Apple to agree to ship a copy of it for free with every Mac. And so there's just an immense cottage industry of software that was developed by users using this tool. And we've kind of lost any modern equivalent of the amount of plasticity that a HyperCard stack had. Like even as a non-programmer, you could sort of dive in. You could make a little personal database. You could take an existing stack that someone else had made, pop the hood, make changes or additions, resize things, scribble on the background of cards. It was just very open and plastic by nature. And so Decker is a modern iteration of this kind of idea with a lot of new ideas as well. And one of the things that I changed the most in creating Decker from the HyperCard model is using a scripting language that was in the array family, which is why I'm talking about it here. And so Lil, which is the scripting language of Decker, is largely influenced by q [02] and k because professionally I'm a k programmer And that's my favorite family of array languages. So you have this high-level, accessible visual environment. And then directly underneath it, you have the concision and expressive power of an array language. I think that it's one of the design decisions that I made with Lil that I think makes it a little bit less exciting and appealing to a lot of array programmers is that I decided to go with a keyword-oriented design rather than having an APL-style symbolic notation. And that was a compromise. I'm a fan of symbolic notation, and I see the value in it. But in terms of accessibility, I decided that the best approach for the audience I had in mind for Decker was to start with something that looked like a more familiar keyword-oriented programming language. It visually resembles Lua quite a bit, which is a popular embedded scripting language. But the semantics are heavily based on q. I have the same kind of general operators, collective operations, the array way of thinking about things with a queue-like, you know, rich set of container data types like dictionaries and tables as a first class entity.

00:12:23 [BT]

Well, and that compromise, I think also, I mean, that existed with the original HyperTalk, which I think was an attempt to take a procedural computer language and make it more English-like. So you could refer to things like this and stuff like that, that you'd recently done.

00:12:39 [JE]

There were even connective words that you could just kind of sprinkle in in order to make sentences read more like English. From the perspective of allowing people to understand what a pre-existing piece of code did, it was pretty effective. But the downside was that it made authoring nice hypertalk very difficult and extremely verbose for lots of things. I took a different approach because I like q better than HyperTalk.

00:13:14 [CH]

So wait, to roll back things a little bit, you might not know the answer to this question, but going viral in China, do you have any idea how that happened? And did you post something on Reddit or something got traction? Obviously, no one really knows how things go viral, but do you know the genesis of what led to what and then it just kind of caught fire?

00:13:36 [JE]

Not exactly. the the tool uh that I made is called wiggly paint and it is based on there's this animation technique called squiggle vision where you sort of um like if you draw the same drawing uh several times with slight variations so you get kind of a line boil effect uh and cycle through them it It's a really pleasant effect of just making things stand out visually. And Wigglypaint is a tool specifically for achieving that effect really, really easily. And it's designed in such a way that you can export an animated GIF that you drew. By virtue of being implemented in Decker, it works on mobile devices and phones, tablets, iPads. just as a natural consequence of being on this platform. And so I think people just liked it. And then they saw people sharing things that they made with it and like, ooh, how did you make that animated GIF? And then one thing leads to another and it becomes kind of a trend.

00:14:50 [CH]

And so you said that you initially implemented this tool as a part of like last year's one of the jams. And then it took off in like the last...

00:14:58 [JE]

Yeah, I spent a total of about maybe six hours building the whole thing.

00:15:00 [CH]

Oh, wow.

00:15:10 [JE]

And then published it and people liked it. And then it just kind of has cruised along. And then out of pure coincidence, about a year later, it just took off and became very popular.

00:15:18 [CH]

Did you notice because it's just like metric tracking on this website? Or are you hosting something and like something fell over and you had to like spin up some?

00:15:26 [JE]

Fortunately, nothing fell over. The tool, like the Game Jam, is hosted on an online platform called Itch.io, which is sort of a marketplace for indie video games, and it also has a lot of features for allowing creators to host Game Jams. So there's a lot of, it's an audience that is very receptive to like short form, you know, here's my little five minute adventure game, or here's a short zine that I wrote. And so I have metrics through that. And I just saw my my little visits chart go from maybe 50 visits a day to 20,000 and then 100,000.

00:16:15 [CH]

And I guess they have geo tracking like similar to YouTube. You can look at like where the visits are from by country or whatever.

00:16:22 [JE]

Well, a big hint is when all of the people who are posting comments are doing it in Chinese. I guess.

00:16:31 [CH]

That also is probably a giveaway, yes.

00:16:34 [JE]

I'm actually working with a friend to see about properly localizing Wigglypaint in Chinese, but there are already countless video tutorials that people have made to just explain what every button does in Korean and Chinese and Japanese. because, you know, there's only a handful of buttons and it's pretty easy to explain.

00:16:54 [CH]

And so is a part of the virality not just that people are visiting it and using the tool, but then they're also posting it and like some of these. So like, are there, were there like a top five of these posts that like contributed to, you know, it was very compelling to see the one gif of like some Mandarin character.

00:17:15 [JE]

I don't think that I could possibly identify like a patient zero for this type of thing. One of the aspects of it that I think made it popular is that I included the ability to do like a mask layer for animated GIFs. So you can make something that has like a partially transparent background. And that works really well for making like stickers and instant messaging applications. So people make a bunch of little emoticons for themselves and they're sharing it with their friends. And then their friends, of course, want to know how that was made and make their own. Just the fact that the output of the tool has a very distinctive look, and it's a very, very quick and easy to use. There's a lot of design decisions in the tool that encourage just don't worry about the details, just make something. And that appeals to people.

00:18:11 [CH]

So I found this, we'll put a link in the chat, internet-janitor.itch.io slash wigglypaint. And there are, what is 40 times 2,044 is like 81,000 or something. That's crazy. So there's 2,044 pages, all containing 40 comments. Is this how people primarily post and share this stuff?

00:18:36 [JE]

This is just a tiny fraction of the things that people are making with this. If you search for like Wigglypaint on just about any social media site, you can find tons of people sharing stuff that they've drawn with that.

00:18:47 [CH]

I see. I see. and I mean I used to live in China so I can read a bit of Chinese and uh I mean and we're not really talking about technical stuff here but this is very fascinating is there um I don't know I want to I want to see some like uh there probably is not but like uh you know like on many social sites including the orange ones you can upvote and stuff is there any place because it looks like these are are just uh chronologically you know the most recent ones are at the top and like is there a way to switch by the one that has like a thousand upvotes or something or

00:19:20 [JE]

The comments in itch.io don't support um like a hierarchical ranking uh so you know it's just it's just a a constant stream of doodles the people have done in uh in wildly varying levels of of complexity uh but some really remarkable artwork that people managed to make for that.

00:19:40 [CH]

All right well I'll tell you what I'll tell you what I'm gonna do I'm gonna take a couple seconds and someone can ask a question while I'm doing it. And I'll send Claude Ford to write me a Python script to scrape this and figure out what the most updated one is. And we'll see if we can get to the bottom of this by the end of the episode. We'll just let the robots do our work for us. But this is, it's very cool that, I mean, it must've been very gratifying, you know, to have, even if it's only six hours of work, it's built on top of an immense amount of work in both Lil and Decker. And then to see this kind of take off and people do, you know, heartwarming, you know, graphic sharing or whatever is, uh, it's very cool.

00:20:15 [JE]

I mean, like I'm, I'm thrilled that people are expressing themselves creatively with this tool in particular. Um, but I also see it as very gratifying that it's sort of a... it's a social proof that you can make stuff in Decker that people appreciate, not just at, on the basis of being, well, that's a nice thing in Decker. It's just a useful, fun application in its own right. And it was built taking advantage of the rapid prototyping capabilities of the Decker platform.

00:20:46 [BT]

Well, and speaking a little bit about the Decker platform, you've made some changes to LIL. Yeah. It's sort of talking about nothing really, isn't it?

00:20:54 [JE]

Yes. So the language level change that I made the most recently to LIL, which is sort of impactful, all has to do with the concept of indexing out of bounds, or as we sometimes say, outdexing. And the treatment of a null value [03] in the language. So k has kind of an interesting approach to null values, which is a little unique. In most languages, you'd have a null type that is like the absence of a useful value. And perhaps you have the not a number of IEEE 754 floats. But k sort of generalizes this concept. It gives all of the vectorizable atomic types a distinct null value. So you can have a integer null. You can have a floating point null. You can have the null symbol, the empty symbol. And you can have the null character, which in most dialects of k is a space. It might seem a little bit odd because the space is not an ASCII null character. But from the perspective of like padding data, it's an appropriate choice for that. So there have been some like classical k dialects like your K2, 3, and 4 treat indexing out of bounds as an index error. You'll just stop dead. You've done something wrong. In newer dialects of the language, I think starting with K5, there is this different approach that instead gives you an appropriate null type based on the thing that you're indexing out of bound. If you have a list and you ask for the negative third element of that thing, then if it was an integer vector to begin with, then you get an integer null. And when you think about applications like implementing a cellular automaton or a board game or pathfinding on a grid or something like that, there are lots of instances where you might want to be looking at a stencil on a vector. And APL has a first class construct for stenciling, at least Dyalog does. But when you have a stencil operator, you need to think about how you deal with the edge cases, literally. And depending on the way that you peel that particular apple, you end up with a lot of different consequences for how you would write programs. I think that being able to index out of bounds and then get a value that indicates missing data is really convenient because then if you have an operator like the K5 fill, which takes an arbitrary value on the left and then a recursive structure on the right and replaces all of the null values with the replacement, then you get to say things like, on my game of life board, the out of bounds cells should all map to dead cells. Or in my pathfinding algorithm, everything that's off the map should be solid, and so on. So having control over this, being able to like observe that outdexing is the thing that has occurred is pretty useful. And if you don't have the ability to just, you know, get a failure value and then clean that up afterwards. You instead have to sort of contort algorithms. You have to shave your edges before you do your selections. You might need to do a balance checking that's comparatively inconvenient or, or heavyweight on like a byte code level, depending on the particular implementation strategy of a language. And I see it as kind of like a counterpoint to the classical problem of, you know, if you access a file on your file system, it is either there or it isn't. You could check for the presence of the file, you know, stat it before you try to read the file, but that doesn't actually make this problem any simpler because the file could be disappeared or locked or something in between the test and the read. So the most robust way to handle a missing file is just try to read it and then look at what you got back, either nothing or a successful read. In LIL, I did a lot of experiments to try to keep the language as conceptually simple as possible. And one of the ideas that I did was to try to design the language with no null value. And for functional programming enthusiasts, I don't mean that like there's maybes or anything like that. I just mean that there isn't a distinct null type. So basically, outdexing or accessing an uninitialized variable or anything like that, you would get the number zero. For mathematical cases, this works out just fine most of the time because zero is an acceptable identity value. But the more complicated things that I wrote, the more ungainly edge cases I ran into with that set of semantics. because if you're indexing into something and expecting a string value and you get this zero masquerading as as emptiness zero is not a good uh identity value there because it's a you know it's a one length string if you were to to cast it over so ultimately after a lot of stewing on this I revisited the design decision and instead introduced a null type with the semantics that that a null will coerce to an appropriate identity value based on the way that it's being used. So a nil can become a zero in a mathematical context. It can become the empty string in a string context. It can become an empty list in an array processing context and so on. And it was a remarkable amount of work to revisit basically every primitive in the language and make little changes to it to account for this. But when all was said and done, the vast majority of programs run unchanged and a bunch of nasty little edge cases that you could trip over are gone.

00:27:46 [BT]

And I think you've also given the programmer the flexibility by using, I'm trying to think of the term you use, but essentially when you have a null, you can then replace the null with something else. So you can actually make it any value that you like in the process.

00:27:59 [JE]

Yeah. So there's fill is, it works just the way that the primitive did in k, although, you know, it's the word fill instead of dyadic caret. So you can do a recursive replacement, which is particularly useful when you're like filling in default values for a column in tabular data. Another example of the rat hole that this all goes into is rewriting the CSV parser so that I can preserve the information that cells are missing from a table so that you can then post-process them and fill in replacements. or the parsing primitives have the ability to, instead of inferring a type-appropriate zero value, you produce a nil, and then in bulk you can replace it as is appropriate.

00:28:55 [BT]

And you don't have the separate, like you were mentioning in some versions of k, you would have a different null for every other type. You don't have that null.

00:29:06 [JE]

Yeah, the k approach has the advantage that you can do things like express type information with an empty vector. Sometimes this is called a prototype. It's particularly useful in the context of having tables in k. You know, if you do the zero take of the empty symbol, that is a vector. It is a symbol vector, but it contains no elements. And so a table can contain a set of columns that represent a type assertion for all the data without having any data in it. And this is something that LIL does not currently represent because it just has a singular null. It's a complexity tradeoff. Part of the reason that I didn't pursue that design in LIL is because I don't semantically distinguish between true vectors and general lists. Like k and q, LIL is one of these nested list languages rather than a nice rectangular language like APL. It's just something that you kind of give up.

00:30:21 [BT]

Yeah, I think in J, I've heard people talk about it's an empty warehouse is what it is. You've just got an empty space ready to put stuff into. And I think similarly in J, once you've declared it of that rank or zero, zero, there's nothing there. Again, I don't think there's any restriction on the next assignment. You could put anything into it. But then you've lost that ability to know what would have originally been in.

00:30:46 [JE]

Yeah, I mean, you can join in any k or q dialect. You can join non-vectorizable elements together and they fall into being a general list, which semantically is fine. All of the same operations work on them. But performance-wise, it's kind of bad because you've taken something that's nice and neat and uniform in memory and turned it into a bunch of indirect pointers to things. So in the context of, you know, making a tick database or something like that, you do actually want to be certain that all of the columns in your tables are vectorizable.

00:31:25 [BT]

Yeah. So you're you're kind of exchanging the flexibility for well you as soon as you go off the grid, as soon as you're flexible, it's very hard for things to be optimized for you to.

00:31:36 [BT]

Yeah, so you're kind of exchanging the flexibility for, well, as soon as you go off the grid, as soon as you're flexible, it's very hard for things to be optimized for you to work at speed.

00:31:38 [JE]

Yeah. And, you know, Lil is a language that can be used for data handling, but so far, no high-frequency trading desks have reached out to me about applications for that. It would certainly be an interesting conversation.

00:31:53 [CH]

It's probably their secret sauce, you know, they're just not letting you know that they're using it.

00:31:56 [JE]

Yeah, they don't have to tell me that they're using it. They could just be quietly behind closed doors. There are a lot of quants that have talked about how they desperately miss the GUI rapid prototyping capabilities of K2 that were lopped off for K3. You know, Decker has a WYSIWY GUI builder right there. The earliest versions of Decker were designed to be very sandboxed because I thought portability and archivability was the most essential thing. and I still do like those properties how you know like every deck it has any fonts it uses bundled in it all of the sounds it's it's a self-contained single file unit but over the course of the last two years I've had a lot of examples of people who are interested in using it more like a conventional IDE or doing you know home automation stuff or you know just general purpose programming and so there's now a way that you can opt into dangerous decker which gives you it basically just unlocks apis for doing things like shelling out to posix commands or raw access to the file system instead of you know mediated through uh through disclosed access it's stuff that I can't match in the browser version although that has its own escape hatch for doing uh embedded JavaScript and little JavaScript [04] interoperation. But if you're willing to give up portability, then you can use Decker and little as a fully general purpose programming environment.

00:33:42 [BT]

So danger Decker is the action hero of the...

00:33:47 [JE]

Yeah. I basically like all of, all of the things that potentially have like side effects and consequences and aren't portable are packaged inside of a, an interface called danger. So you have to say like danger.read, danger.write, so that it's impossible for a user to not be aware of the fact that what they're doing has potential consequences for portability and general safety.

00:34:10 [ST]

John, as an erstwhile HyperCard developer, I get a huge nostalgia hit from seeing the faithful recreation of the 1980s user interface. And I'm wondering, is that purely a homage to Bill Atkinson's work? Or is it a clue to what you'd like Decker to become or to be used for?

00:34:38 [JE]

Well, there are a lot of reasons that it looks that way. You know, it is modeled closely after the System 6 Macintosh UI because I like that. But in addition to that, it has a lot of nice side properties. Like one of the things that in order to behave the same on every platform where Decker can run, whether it's as a web application or a native application, I need a consistent UI toolkit. And so I needed to build something from scratch. And I want Decker to be simple and clean and, you know, high contrast and all of that. And so taking the design cues from this old design allows me to make something that is functional and has a fairly small code base, fairly modest resource requirements. And when you think about Decker as sort of a drawing tool first that has the ability to be enhanced with interactive elements, I think it's also very valuable that Decker has UI elements that you could easily draw. You can make things with a pencil tool, with a few rectangles that fit in with the aesthetic of the rest of the software. it would not have been tremendously difficult to allow people to take uh you know 24 million color images uh that they prepared in photoshop or something and pull them into decker but then you would have this like this gulf between or or likewise if I made the the buttons look like windows xp you know jellybean things like there would be this gulf between things that a user can quickly do by hand and the way that the environment looks. It's a really nice workflow to make games and tools and anything that has a mixture of behavior and visual components in Decker, because you're working seamlessly in a single tool. You can, even when you're like preparing graphics for something, you can make little prototypes and interactive things. Like, you know, sometimes my users are like making animations for a game and they'll just build in the card with a few lines of code, a preview tool. And they're just doodling on the background of the card and then live, you know, there's, there's a little box playing the animation cycling through and it's all in one seamless environment. So I think that having simple, clear visuals invites tinkering in a way that something that was really slick might not. And so it is an unfortunate consequence that quite a few people look at Decker and based on their initial impression, assume that it's not very powerful, that it's sort of a slavish clone of old software. But I promise you that if you dig a little bit deeper, there is a lot to play with there. and it's sort of you know it's just this layered environment you have apparent simplicity and a huge amount of depth available the more ambitious you want to get with it you can make useful tools and toys and applications without writing any code at all and because we have this this array language sitting underneath it, you can do a lot with very little additional code. You have this expressiveness.

00:38:25 [ST]

Can I get outside the UI? Because HyperCode development left me with one index finger shorter than the other from all the pointing and clicking. And I'm wondering if I'm going to produce an application in Decker, can I write something like a make file to construct it?

00:38:45 [JE]

Well, you could. So there's kind of several different directions that you can look at that from. One thing is that Decker uses a plain text file format instead of like a proprietary binary format for stacks like HyperCard did. And it's designed to diff pretty nicely. So if you have one of these decks in source control and you're making simple localized changes, they will generally be simple localized changes, you know, on just like one line of the file. And you could certainly generate decks just in that format procedurally. But I can do you one better, which is that Decker has a companion application, which is called Lilt, which is just a headless terminal interpreter for Lil. And one of the things that it can do is it has the entire object model that Decker normally has. You can open a deck from inside of Lilt at the command line and use Lilt scripts to modify it. You can even do things like simulate clicking a button in a deck and then observe the results by programmatically looking at widgets. I use it for automated testing, but you can use it to procedurally build decks. You can use it to merge decks together. I've heard of several Decker users that have done like a large collaborative project where they've sort of just given a template to multiple people and they all do their work in individual decks. And then you can write a Lilt script that just sews it all together into a single deck. Or say if you were serving a deck on your website and you wanted to have some dynamic information in it, you could use Lilt as a CGI engine and generate on the fly the WebDecker build, which is a single HTML file that has the JavaScript version of Decker with all of its tools, but also the data of the deck. And much like TiddlyWiki, [05] if any of you've ever played with that, WebDecker is self-replicating. So you have a deck combined with a runtime with all of the editing tools, the little interpreter and the command line and everything. You can open in your web browser and interact with the deck. Then you could start making changes to the deck. And then you could save the deck as a new HTML file that's sitting on your computer. And if you open that HTML file in a web browser, it's still Decker. You could email it to somebody or you could copy it to a floppy disk and mail it halfway around the world. And it's a self-contained portable executable, taking advantage of the fact that web browsers are virtually omnipresent.

00:41:37 [BT]

Do you think the group in China has figured that out yet?

00:41:39 [JE]

Quite a few have. I have seen evidence of this, although I only have mediated access to these discussions. Who knows what is going on in languages I don't understand in chat rooms that I don't have access to.

00:41:54 [BT]

And when you say it was self-contained stack, what's the size of that?

00:41:58 [JE]

So the baseline for WebDecker with an empty document is a little under half a megabyte. So that includes several built-in fonts, the entire Lil interpreter [and] all the editing tools. And then the content of your deck is basically just added to that. So I think Wigglypaint itself is something like 650 kilobytes.

00:42:26 [BT]

Yeah, so it's something that you could move around. And the other thing I was going to mention (it sort of brings back around to the Fantasy Camp), is when you're looking at something somebody's produced, you can open those up and see exactly how they've done things. That's one of the things I think is really neat.

00:42:41 [JE]

You can even borrow parts very easily. Resources are like blobs of data that are part of a deck, like fonts [and] sounds. You can package reusable sections of Lil code as modules, which you can just sort of suck them from one deck into another. If you just select a couple of widgets or a card in Decker and copy it to the system clipboard, all of those things have a JSON representation that you can then paste into another instance of Decker somewhere else. Another collaboration mode that works surprisingly well is if somebody asks me a question about how to do something in Decker, like on Discord or in email, I can give them a blob of code that they paste into Decker on their own computer with a full example that they can start playing with. And Decker has a facility for something called a "contraption". There's a certain set of primitive interactive widgets like buttons and checkboxes and fields. And you can design your own more complicated widgets made out of those. So a contraption is an accumulation of those pieces. If you just copy and paste a contraption from one instance of Decker to another, it travels with its definitions and even travels with any fonts that it references. So there's a huge amount of just ad hoc sharing capability that just naturally falls out of the way that the thing is designed. And if an application takes off virally, nothing on WebDecker really relies on any backend web components at all: it's just one file. It's cheap for me to serve on my own web host. If you're offline [and] if you have the HTML file, you have Decker. Of course, I should also note that there's also native Decker, which is an application written in C that's fully compatible, that doesn't rely on any web browser functionality. A _very_ old machine might not be able to run it but a fairly old machine or a machine with no Internet access or a machine that you just don't care to install a web browser on, it can still work.

00:45:11 [BT]

I haven't heard too many other languages moving in this direction where things are easy [and] the collaboration becomes the key thing. There's got to be a cost for that. I guess, is it proprietary information that people don't want to make that too easy to do?

00:45:28 [JE]

I think there's a lot of interest these days in software as a service (SaaS) models where you have something that's running on your web server and you can make it very convenient for remote users to interact with that and do real time collaboration, facilitated by a web backend. Google Docs is kind of the canonical example of a tool that works like that. And that is a model of sharing that I can't match with WebDecker because I don't have a web backend. But the flip side is that quite a few of these tools and services don't share their backend at all. It's not open source. You can't self-host it on your own servers. So people get locked into a subscription model.If the company goes under or something like that, then everything that they built in this tool goes poof! There have been a number of HyperCard-like things over the years that have taken this kind of approach, which I find very disappointing. I think that an important aspect of user empowerment is that their creations can't just be sort of yanked away from them in the future. And so there's technical compromises that have to be made in order to make WebDecker as compatible as possible with the behaviors that you get in native Decker and vice versa. There are certain pieces of functionality that I choose not to expose because I can't do them in a consistent way across these platforms. And, there are escape hatches like the danger interface when you don't care about that consistency [chuckles]. I think that being able to share and to build things and run software locally and just sort of spiral off and do your own thing, is very important if the goal of this piece of software is to empower individual users. That's just my opinion.

00:47:35 [CH]

I have the results. I have the results.

00:47:36 [JE]

OK.

00:47:37 [CH]

Unfortunately, the listener will not be able to partake in this visual experience, but I will post this, (whatever, .html), and you can go look. At first, Claude 4, he was a little confused, and the AI only looked at the first page like 51 times over. Also, it's become clear, the AI had ... [sentence left incomplete]. I said, "please go search all 80,000 images," and it said: "listen, Connor, it says 1 to 40 of 2044; there's not 80,000." There's no math you need to do. It's just 2044. So I misspoke earlier. The AI set me straight. And anyways, it only scraped the first page. And I said: "no, no, no, just scrape them all." Anyways, it figured it out. It was 2977 total posts. Not all of them have images; some of them are just comments. Across the 2044 posts (I guess the top level posts don't include maybe the responses) there [are] just under 1800 images. These are the top 10. The number one is by Squid with 27 upvotes and one downvote, which curiously is not using any WigglyPaint [laughs].

00:48:56 [JE]

Well, it's a screenshot of the WigglyPaint user interface itself.

00:49:00 [CH]

Oh, I see. That's what this is. And then the rest of the nine are all (I can maybe zoom in a bit) using ... [sentence left incomplete].

00:49:09 [JE]

We've got some Hatsuni Miku, some Spider-Man.

00:49:12 [CH]

Some Hatsuni what?

00:49:14 [JE]

You know, the Vocaloid.

00:49:15 [ML]

Over on the bottom right there.

00:49:18 [JE]

It's an Internet thing. Don't worry about it too much.

00:49:21 [ML]

With the blue twin tails, is the signature thing.

00:49:24 [CH]

The yellow, blue, and pink one? But it is very ... [sentence left incomplete]. You can see why something like this might go viral, you know?

00:49:30 [JE]

It just has a nice set of, sort of, creative constraints that I think people enjoy a lot. You get five colors with a variety of palettes that are built in. The certain canvas size, and a handful of different drawing tools that all have their own effects.

00:49:50 [CH]

Wait, what do you mean? So you choose a palette and then you're constrained to only five colors within that palette? Is that the way that works?

00:49:57 [JE]

Yeah, you get a foreground color, a background color, and then three colored markers. So the line art is sort of drawn on top, and then the markers fill in color underneath. It makes it really easy to [chuckles] do things that normally would require, like layers and more tools. It just sort of constrains the set of possibilities and the workflow that you use with the tool and allows people to be really spontaneous and quick.

00:50:31 [BT]

And you tend to get a pretty high contrast in those images too. You make those choices, but you can get some real pop out of them.

00:50:37 [JE]

Yeah. I used a variety of five-color palettes that I found on a pixel art website called lospec.com [06] that has a huge gallery of different types of palettes that have been designed by users. In the options menu of WigglyPaint, there are a whole bunch of those by name.

00:50:58 [CH]

Very cool. These are very, kind of mesmerizing, to be honest.

00:51:02 [JE]

It's remarkable how much a little bit of line boil can add to a drawing.

00:51:07 [CH]

Yeah. Anyways, back to our scheduled conversation [chuckles]. I will stop sharing my screen. And as mentioned, we will make sure ... [sentence left incomplete]. I guess you don't need to host an HTML. You just need to post it somewhere and people click on it, correct?

00:51:22 [JE]

I mean, you can host it or you can email it to people or you can put it on a floppy disk.

00:51:27 [ML]

How often do you do this floppy disk thing?

00:51:30 [CH]

A floppy disk. [laughter].

00:51:32 [JE]

One of my friends who has been making zines in Decker since not that long after it was created, is a real fan of floppy disks and has put every issue of her zine on a physical disk. And if anybody asks, she'll mail one to you.

00:51:51 [ML]

Have you asked?

00:51:52 [JE]

Yeah i have a couple of issues.

00:51:54 [ML]

So you do have it

00:51:55 [JE]

And I have a USB floppy drive so I can read it.

00:51:59 [CH]

I was gonna say ... do you even have hardware to use a floppy disk?

00:52:03 [JE]

Like I mean it's, you know, it's just a three and a half inch floppy drive. It's nothing too obscure really. You could mail somebody a USB stick but then, in our in our modern age you'd have to worry about whether or not they have any USB-A ports. The humble thumb drive is becoming a legacy format.

00:52:22 [CH]

I wonder how many of our listeners don't actually know what a floppy disk [is]. I imagine there's got to be at least a single digit percentage of them that don't know what it is.

00:52:34 [AB]

And even those that think they know what it is, they're actually mistaken. Those are not floppy disks. Those are diskettes.

00:52:39 [JE]

Wait?

00:52:40 [BT]

Five and a quarter. 5 1/4.

00:52:42 [AB]

Yeah, the three and a half inch ones are not floppy disks. Those are diskettes. You have to go to 5.25 to actually be floppy, where you can hold them on one side and then flick this other side and they will flop.

00:52:56 [ML]

That's a better medium for WigglyPaint.

00:52:58 [CH]

Oh, my bad. Yeah, I actually I never knew what a floppy disk was then.

00:53:01 [AB]

Exactly. You really should be on a real floppy disk. But John, do you have [chuckles] a 5.25 inch drive?

00:53:09 [JE]

Not handy at the moment, but one could be acquired.

00:53:13 [CH]

Do they have extensions where you can feed that in as well?

00:53:16 [JE]

I mean, there exists USB interfaces for that sort of thing, but probably it would start going through a procession of retro machines, networked to slightly newer machines, and so on.

00:53:29 [BT]

The medium itself, if you're dealing with a 5.25 disk, an old one, they are just basically rust on mylar [John agrees]. So in time, they degrade. So the last 5.25 I actually saw was back in the 80s. [Laughs] the old 1980s. You'd slide it into the disk. And so something that is that old has probably degraded.

00:53:52 [AB]

But they make three and a half inch ones, right? So it's necessary for missile defense systems, public transit systems, hospital journals.

00:54:02 [JE]

And a lot of systems are still using seven or eight inch [chuckles] for certain metropolitan ... [sentence left incomplete].

00:54:09 [AB]

Eight inch disks? Wow.

00:54:11 [JE]

Here's a question. If you put a file on a 5.25 inch disk and set it in a reasonable environment in your closet, and then you put the same file in your favorite cloud-hosted solution [Adám laughs] and come back in 10 years [laughter], what are the odds that you can recover each of those media?

00:54:32 [AB]

Did you pay for the cloud solution? Did your pay card manage to survive? Did your bank survive? Did your country survive?

00:54:39 [JE]

It's pretty easy to just put a floppy disk inside of a Faraday cage.

00:54:44 [AB]

The actual weather environment might be problematic.

00:54:47 [BT]

Temperature is a big deal.

00:54:49 [AB]

Humidity is going to occur.

00:54:51 [JE]

Yeah, heat.

00:54:52 [AB]

We're slightly off topic maybe, but I had some time for things in the back of my head, to stew a bit. And the thing you did about prototypes and the null type, it seems very appealing to me. Because I often complain when people have systems that don't have a prototype, that it loses information. A classic gripe is in the list-based thing that if you transpose a matrix twice, you should get back the same matrix. But if the matrix is empty, you get a list back in many systems. There is really a structural type more than it's the actual content type. But by deferring the decision as to what type is this until later when you try to use it (where, of course, it's very lenient, then it will just be whatever type you expect it to be), that does solve some problems that do bug me [John agrees]. For example, we all know there's a difference between a bag of potatoes and, say, a jar of coins that was empty. But still, if you concatenate a list of one type to a list of another type and they're both empty then it will be hard pressed to fit both types in there but if you only have a single empty type then that probably just goes away.

00:56:16 [JE]

Right. And I am a little bit constrained in the set of of solutions to this problem that I have available because one of the weird design decisions I tried with Lil is that it has no runtime errors. If you have a syntactically well-formed little expression, it has well defined behavior which may or may not be surprising depending on what you intended when [chuckles] you wrote it. But it means that you know everything is total. If you do something that might seem nonsense, I have to pick the most reasonable behavior to fill in there. So if you're doing out-dexing, I don't have the option of saying: "wait, stop the universe index error." I have to return a value.

00:57:02 [ML]

Yeah, and it is really interesting how [with] the first approach with zeros and stuff, all the casting that you do (because if somebody expects a string and gives you a number, you have to do something), that was the liability with the first approach because like you said, zero becomes a length one string. Well, that's no good [John agrees]. And then in the second approach, it's actually huge strength because you can pass null into anything and it's likely to do what the user wants.

00:57:28 [JE]

Yeah, the way that I've described it to a few people is that in most languages, a null or nil is a value that you can't do anything to [chuckles]. And in Lil, a nil is a value that you can do anything to. It's always suitable.

00:57:44 [AB]

Yeah, that's neat. I do think during development, it's nice for me to get an actual error. And the error message can tell me more than just a value, right? If I give an error, I get an error value back. Well, I suppose a nil can be a value that I actually use for something.

00:58:00 [ML]

I mean, but that's kind of the point, isn't it? There aren't any developers here.

00:58:06 [AB]

No, but I'm imagining actually writing larger systems using a language like this. Then I make lots of mistakes. Maybe you guys don't. But when I make a mistake, I appreciate the system telling me what kind of mistake I made rather than just, say, giving me some praised result. if I try to add together two vectors of two lists of different lengths, I appreciate getting a length error rather than a rank error or a workspace full or whatever it might be. If I would just get some placeholder value back, then I have to go investigate.

00:58:42 [JE]

Well, yeah, you have to decide. Depending on what you're trying to do and your personality and your general mood, you might appreciate having things stop you earlier. In Lil, if you try to do something that would be conforming together lists of varying length, the rule is that it keeps the length of the left argument. I have a blog post where I talk about some of the reasoning behind this, [07] but in a nutshell, it allows you to get the behavior of a couple of k adverbs for free at the cost of: if you genuinely do make a mistake and you have things that aren't intended to match, then you might not notice it. I mean whenever I build up complicated programs in Lil I definitely emphasize building them up in small pieces but a lot of, verifying as you go in a REPL session just like I would if I was writing something complicated in k. But the key thing about this decision is that Lil is designed primarily around programming in the small. Most of the pieces of code that people write in Lil are short: maybe a few lines. And in that context, I find that the concision is more valuable than the bumper bowling.

01:00:08 [ML]

Yeah. Well, there's probably also a big difference in the behavior that the developer directly sees and what sorts of behaviors they need to handle. If you're writing a serious enterprise program, you need to be able to handle users who need this program to guide them in how they do their work. So they need to be able to click on something random that doesn't make sense and get a correctly handled message and all. Whereas with Decker, somebody has something particular they want to do. They're going to write it. They're going to see whether it does that. And then, somebody else can hopefully do the same thing with it.

01:00:49 [JE]

[Agrees] And in Decker, the user can be interactively, continuously revising the thing as they're building it, which is a very different experience from a prepackaged, sealed, verified piece of software that's being delivered on high to an end user. [Marshall agrees] You know, this is a sketchbook rather than, I don't know, a Dolby film.

01:01:13 [BT]

I was thinking that when you were talking about Lilt (that rapid prototyping environment), your errors are going to show up to you almost in real time. And in that way, if you can spot them, and Adám makes a good point, if they're not becoming apparent to you, you're going to miss them. But if they show up on your interface, you're going to know right away.

01:01:35 [JE]

Yeah. And I will never claim that Lil's approach to error handling or not error handling is the correct solution in all situations, for all languages. But it was an idea that I wanted to try in terms of improving the useful semantic density of this language. Usually when you add runtime errors or type assertions or things like that, what you're doing is sparsifying the space of valid programs. So inherently there is a degree of verbosity and a degree of disfluency to that type of a system. When you get to a very large scale code base, those disfluencies and that redundancy is worth it because it is no longer a program that can fit in one person's head. It is no longer a program that is being necessarily maintained by one person. But the experiment in Lil and Decker is make a system that is human scale, that is strongly intended to be, usually, used by one person at a time and tinkered with; tried interactively. You make little changes. It's tailorable rather than the result of an industrial pipeline.

01:03:02 [BT]

And I think it also expresses a thing that is often talked about in array languages, where you work harder to take something out. [John enthusiastially agrees]. You remove code as opposed to adding code all the time.

01:03:13 [JE]

There are lots of situations in which Lil's error handling concept simplifies things a lot. There's the example of reading the file and the race condition thing. There are counterpoints to that in all kinds of UI programming, where I say things like: "I write a script that is designed to keep track of whether or not a user has visited certain cards in the deck." I can write that in a way that just says, reach into every card, find the invisible checkbox that remembers whether or not you visited the thing. If it's missing, the code is harmless because, grabbing a widget that doesn't exist just gives you nil and then call it asking for a property of nil gives you nil again. And so, from one perspective, it's like silent failure: "oh, no!" But from a different perspective, it's an opportunity to make things very loosely coupled. You can make changes in the system and you can modify contracts in the system. And if you've designed things in the right way, you don't necessarily need to go off and change the other half of the contract.

01:04:25 [BT]

And talking about removing code, I'm just going to jump back to a Bill Atkinson story that I've recently heard. I think I heard it a long time ago, but it bears repeating.

01:04:35 [JE]

[Laughs] I know what story you're going to reference.

01:04:37 [BT]

You know the story [chuckles]. And that is, I think it was QuickDraw that he was writing, and the managers at Apple decided it would be a good idea to grade people on the lines of code they'd produced in a week. And he was obviously a brilliant programmer; brilliant developer. And he didn't like [it]. He thought this was ridiculous; lines of code, that's ridiculous. And what he found is, one week he went in and eliminated a whole section that had been used and was slower. He changed the algorithm. And at the end of the week, they asked him [chuckles] how many lines of code he wrote. And he wrote in minus 2000! And after that, they stopped asking him [laughs] to write how many lines of code he'd produced because this was working so much better and so much quicker. And he'd actually put a large negative value. We'd taken a whole chunk of the program right out.

01:05:33 [JE]

Add lightness.

01:05:35 [BT]

Add lightness, yeah.

01:05:36 [AB]

Do code colf.

01:05:37 [BT]

Yeah, I guess, but it's code golf with a functional purpose.

01:05:43 [ML]

Yeah. The reason code is costly is not the characters in it.

01:05:47 [AB]

No, I'm joking. But yes, removing stuff, obviously, is good.

01:05:50 [ML]

Not unless you're putting it up on a very giant screen display or something.

01:05:55 [AB]

Usually not. Usually not. My father did tell me about that. Or because it has to fit in a very small computer.

01:06:03 [JE]

Or if you have to store your program on a small removable medium.

01:06:08 [ML]

And haven't heard of compression.

01:06:09 [BT]

Do you know whether Bill Atkinson ever did any programming in the array languages, John? I don't know of anything.

01:06:16 [JE]

I don't know. I haven't read of any anecdotes about that particular crossover.

01:06:23 [BT]

Yeah, there's not a history of the array languages in Apple the way some of the IBM systems had it.

01:06:28 [JE]

Yeah, I mean, at the time at Apple, pretty much everything was done in a mixture of Pascal as the high-level systems language and then 68000 assembly language, which was most of the stuff [chuckles] that Bill was writing. And then, over time, C and to some degree, I think some Lispy stuff worked its way in there. But I can't speak to what he did; what languages he played with outside of his career at Apple.

01:07:00 [AB]

As an anecdote against the thing about just silently failing. Well, sort of as an anecdote. Maybe it actually becomes an anecdote for that. I know somebody who actually makes money writing APL code. And you'll know that in procedural APL code, you write "if" statements with ":If", and there are also other cases like that. And you have to have a boolean value and at Dyalog, we allow any singleton (so any dimensional one or zero) is fine as a boolean. But not, say, a vector of ones and zeros or anything else that would fail. So I know this person who spells "if", rather than spelling ":If" like the rest of us, spells it ":If first" . And I personally frown on that. I keep telling him to not do that. I mean, the only reason he does the "first", of course, is because it has happened enough time to him that he didn't have a single scalar or some other singleton. And he thought: "eh, just need that first value anyway".

01:08:08 [JE]

I've definitely seen code like that in industrial k codebases all over the place.

01:08:14 [AB]

But imagine that you were checking whether the password matches. Obviously, that's not normally how you check a password but let's just say. And by mistake, you write "equal" instead of "match". So now it tests every character separately and just tests whether the first character is the correct one rather than all of them. This is pretty disastrous to do silently. And the same thing I could think here. If you silently not fail (you silently succeed), then things really should fail because they have the wrong length or something. It's almost like you could construe an example where somebody puts in an empty (nothing) into the password field and you compare it with the actual password. And since it has the wrong length, then yeah, we just silently fail and it all comes out to: "yeah, your password is good; all the characters that were there, they matched and it's all good; continue." I understand: small systems, single user, no security considerations really: it's fine.

01:09:12 [BT]

My understanding, though, is with Lil, the nil, when you apply any function to it, it returns a nil, right?

01:09:20 [JE]

Well, if you apply functions to a nil, then they do whatever the function does. Most of the primitives, where it makes sense, will treat nil as an appropriate identity. It's a primitive by primitive case, because if you enlist a nil, then of course you get a length one list containing a nil, and so on.

01:09:41 [ML]

But like multiplying would give the other argument, right?

01:09:44 [JE]

Well, so multiplying currently would coerce to a numeric equivalent of the nil, and so you get zero.

01:09:55 [ML]

It would give you zero.

01:09:56 [JE]

Yeah. And that's a questionable case. There's definitely stuff around the edges that I'm still open to considering. k5 and k6 [08] had a lot of interesting corner cases to the way that they conformed things because as I understand it, Arthur [Whitney] was trying to make it so that the conforming semantics of dictionaries would allow the dictionaries to behave algebraically correctly as if they were sparse vectors and so that is the case where the conforming behavior of multiplication and addition would be slightly different.

01:10:38 [ML]

Yeah, I mean, that's a pretty tricky one. In BQN, I was thinking the natural identity element for an array's shape is one. Like, if you want to extend the shape in the negative direction, you should add ones to it because that keeps the total number of elements the same. It's also the identity: usually you want to multiply links together to get the total number of elements. So it's the identity of multiplication and so on. But I was like, if I introduce a kind of array that has an identity of one into the language, that could potentially be really confusing. So you write a method that depends on the identity being zero because it almost always is; and then somebody passes you a shape and you get this really weird result all of a sudden. I mean, that could be a big problem.

01:11:25 [JE]

Yeah, I mean, that's a case [for which] I haven't tried to come up with a really clever solution to, so far. For the most part, I've tried to make it so that the casts of nil follow as uniform a rule as possible. But as you point out, there are certainly cases where it might be more useful in practice to substitute a different type of identity.

01:11:51 [ML]

Yeah. Like, the instinct of every developer now is to say: "if there's any possibility of confusion, immediately error." But, I mean, in a lot of cases, what that does is take the space of inputs that you can do, and it chops off part of it. And, I mean, in some cases, it's actually pretty dangerous, because you can write a program that in testing doesn't run into these cases, and in usage does [John agrees].

01:12:20 [JE]

Well, another way to think about it, of course, is that if you're doing any kind of conditional check, you've increased the branching complexity of the graph that represents that program [Marshall agrees]. And that program is slightly more complicated to test. If you eliminate edge cases or you make it so that the edge cases are handled by primitive operators in a nice, appropriate way, as we typically try to do in vector languages, you can reduce programs to a straight pipeline, as much as possible. When you do that, the code is testable. As long as code is executing in a straight line with no edge case branches or anything [Marshall agrees], trying it out interactively in a REPL is actually a reasonably thorough examination of the behavior of the program. Now, obviously, there are cases where that's not true, but in many cases it is.

01:13:22 [ML]

If you branch, you really want to branch on something that's usually going to be the same, something like type or the rank of an array and so on. I mean, [in] almost all programs, a particular variable has a particular rank. So if there's an error with the rank, it'll show up in testing. If you branch on the length, I mean, that's really bad.

01:13:43 [JE]

Yeah, completely agree.

01:13:44 [ST]

I'm remembering here my philosophy professor, David Armstrong, who liked to say that the best style for a philosopher to write in was one which revealed to him his errors before his colleagues did.

01:13:57 [JE]

Certainly something to aspire to in our programs.

01:13:59 [CH]

So I think maybe as a wind down question, what is the future of Decker and Lil in terms of your next, virality? What's the next WigglyPaint [where] you're going to do six hours of work and then it's going to blow up? Or is there no way of knowing?

01:14:18 [JE]

I don't think that there's any way of knowing what will just click with people and be a huge success. It could well be that WigglyPaint is the most successful individual thing to ever come out of Decker. But the Decker community continues to grow. The tools continue to be more refined. I improve usability and stability [and] performance all the time. And I've even been making some effort to sort of push Decker backwards in time: if I improve performance, I can make it be usable on older computers. [Conor agrees]. I did a whole bunch of work ... [sentence left incomplete]. So Decker uses an IO library called SDL as its sort of graphical abstraction and I did some work to add a shim so that when SDL2 isn't available, it can use SDL1, which means that it's technically possible to build Decker to run on Windows 98 machines if you want to. It's a little bit RAM-hungry by the standards of those machines, but that too can be improved over time. And I'm hoping that the ceiling and floor of the Decker ecosystem continue to expand as the community continues to try to do more ambitious and interesting things with it. And that's what Fantasy Camp is all about: seeing exciting new things; new firsts.

01:15:53 [CH]

Which is a perfect way to segue into the final plug. Did it start today? Or is it ongoing? What are the start and end time for this Fantasy Camp? [09]

01:16:03 [JE]

So we're recording this on July 1st, which is the first day. The Fantasy Camp runs for the entirety of the month of July. So by the time listeners hear this we'll be a little bit in, but don't worry, because the reason we make it a whole month is not necessarily because you need to spend every waking moment of that entire month working on a project. You can make something small in an afternoon and still have quite a bit of fun and meet a community of people who will be excited to try your thing.

01:16:35 [CH]

Yeah, I mean, I feel like I should be going and WigglyPaint thing for myself. I've just, uh, seen a bunch. I'm not much of an artist. It was actually one of my worst grades in high school. If I'm being totally open and honest, I didn't do well in that class. And I think that's BS because, it's art, you know? Like who are they to say that my art wasn't that good?

01:17:00 [JE]

It's never too late to pick up a new skill. And just in terms of broader philosophy of outreach for array languages, there have been many episodes in this that talk about how array language has managed to successfully appeal to people in a finance background or a physics background. Decker is largely directed at people who are coming from a visual arts or a writing background. And it's another funnel to get a new set of voices playing with these types of languages.

01:17:39 [CH]

Well, maybe what we should do is we should get all the panelists, including myself, to take part. And then we can let the listeners vote. Because obviously we've got to vote. Not us, the listeners. And then we can figure out, you know? I've grown since my high school days.

01:17:57 [ML]

So like on the one side, you're saying it's art and it shouldn't be graded. And on the other side, you're saying people got to vote on it [laughter]. What's happening?

01:18:05 [CH]

[laughs] I need the external validation, Marshall, you know? Except clearly, I feel like I'm going to lose and it's just going to reinforce that I'm not an artist. But it's not the point, folks. It's the making of the art ... I lost it! You know, I was supposed to say something meaningful, but I don't know. Help me out, Stephen. You're the poet here.

01:18:26 [BT]

You may find that your perspective changes if you go through and do the Fantasy Camp. And honestly, I am really strongly considering going in just trying to play around with something. To me every summer here where i live they have a sandcastle competition and they have people travel all around North America and do these incredible sand sculptures (and they're sculptures; they're not just sandcastles but it's a sculpture of various things) and they fence it off so nobody can go in and wreck them or anything and then you could you give a loony to a local charity you walk around and you can look at all the things that done. The fantasy camp is like, then you can go and you can build your own sandcastle based on what you've seen [John agrees]. So you may find that some of the most interesting ones aren't really involving visual arts at all. They may be using different things.

01:19:23 [JE]

Sure. I mean, like really, anybody can approach this with whatever kind of creative approach that they want to manifest in the world. It's open-ended.

01:19:35 [BT]

So build your sandcastle [laughter].

01:19:37 [CH]

All right. If listeners or non-listeners have questions, thoughts, comments, either for us or for John, they can reach out at ...

01:19:50 [BT]

I was going to say non-listeners, we probably can't reach. Except there's a lot of people who read the transcripts. And the way to get in touch with us is contact@arraycast.com. And mentioning transcripts, thank you to Sanjay, who helps out with the transcripts, as well as Adám, who bulks out the transcripts for us and gives us timeframes and all that kind of stuff for people who do interact with us that way. I prefer people listen to us, just because I think there's a lot of things that are lost in the transcript. But if you read the transcript, I'm not going to complain.

01:20:21 [ML]

If somebody just guesses the email but clearly has never even heard of the podcast, what's our protocol?

01:20:28 [BT]

Oh, [laughs] so do you mean if they just guess them?

01:20:31 [ML]

I guess it depends on whether what they say is relevant to the podcast [laughs]. They have to guess the email and happen to guess what the content was.

01:20:39 [BT]

Yeah, No, that's exactly right.

01:20:42 [JE]

If you manage to email ArrayCast without being aware of this challenge, you will receive a prize. But be aware that if you make any indication that you're aware that a prize could be offered, null and void.

01:20:57 [ML]

I think just by doing this, you've kind of invalidated it.

01:21:00 [AB]

Hold on. Don't you have to claim your prize?

01:21:02 [ML]

Somewhere on this earth, there will be a prize [laughs]. If you find it, it's yours.

01:21:07 [JE]

But we won't tell you where it is.

01:21:09 [BT]

We won't tell you where it is. And we won't tell you what the prize is, so whatever you find, that's your prize [laughs].

01:21:15 [CH]

This might be one of the roughest landings on ArrayCast yet [laughs].

01:21:20 [BT]

We're bouncing along the runway now.

01:21:22 [CH]

I'm not even sure if we bounced or we just crashed into a tree and anyways we still have our landing gear [chuckles] so with that we will say Happy Array Programming!

01:21:32 [Everyone]

Happy Array Programming!

[Music]