Conor

Welcome to episode one hundred and twenty-three of Arraycast. I am your host, Connor, and today with us we have our only panelists, therefore promoted to co-host Adam. Introduce yourself briefly, Adam. I'm Adam Dlotzewski.

Adam

I have a long history with APL. I currently work as head of language design and also doing a bunch of other stuff at Look Limited.

Conor

And as mentioned before, my name's Connor, host of ArrayCast, massive fan of all the array languages. Excited for today's episode. And we do have, I think, two announcements from Adam. But before we get to that, I realized we should mention that we had a regularly scheduled array cast, this ArrayCast episode 123, that was going to be with Henry Rich. And I'm going to mispronounce uh his name. I believe it's Marcin. I'm going to avoid the last name because I one don't have it in front of me, and two, I'm going to butcher it. And they were going to be talking about the upcoming release of J9.7. And then typically in these episodes, the annual J release episodes, we talk about the beta, which would have been 9.8. That episode, if you are an astute viewer of the channel, you will have seen has been postponed until tentatively May 4th. So we've titled that Arraycast Episode 125. It was because I believe they wanted to put together some demos now that we have the live stream on YouTube. And so we were originally going to do it today, and it wasn't because they don't want to come on. They definitely still want to come on. They're just in preparation mode. So expect tentatively a month from now, we'll have both Henry on and Marcin on to talk about J9.7. So if you were looking forward to that episode, just put that hope on pause and we will do that interview in a month's time. So we're going to do a different episode today, which we, I guess, kind of chatted about last episode in Arraycast 122. But before we get to that, we've got two announcements, so we'll throw it over to Adam and we can do those first.

Adam

Right. So there are two uh get togethers, real life, coming up. First, there is the APL Germany spring meeting in Mainz, sort of southwestern Germany. It is on the 20th to the 21st of April, so it's just coming up very soon. And immediately after that, the week after, is Dinah 26, so Dinah's dialogue's North American get together in New York City on the 27th. And the registration for that dialoges on the 17th. So if you're here during this live, then uh that's in 10 days.

Conor

Awesome. And if you watch it anytime in the next 10 days, you'll still have time to figure out if you can make it, if you're local to New York, or if not, you're able to travel there. Links we'll try and put in the description slash show notes. And I don't think I have any announcements. I mean, technically, I'm working on a YouTube video. I tell you, with AI these days, my YouTube videos take way longer because I can realize I realize I can do way more. And there's been some interesting interactions between Elias, author of CAP online, and also Dima, implementer of CBQN. So, I mean, there's a GitHub repo. I'll find it and put it in the link of the the discussion. If people want to take a look, it's on the maximum odd binary, so M-O-B. And it's solvable very simply in three characters. A one rotate reverse sort. If you have the reverse sort primitive, that is. And anyways, there's gonna be it's almost gonna be like a YouTube talk, because it's gonna be such a long video. I'm thinking about even doing it live, but that's probably too much work. Anyways, if you follow me on the Blue Skies, Macedons or Twitters or any of those, you might have seen some of that interaction. But yeah, we'll uh look forward to that video coming out on this not this channel, this is the Arraycast channel, which I don't know, pop the uh the champagne and little confetis. We've we've crossed the 200 subscriber mark. We're a fifth of our way to the goal. I I see on the statistics we get about 800 within the first like month, 800 downloads. So we do have at least close to a thousand. So hopefully we can translate that into a thousand YouTube subscribers. Anyways, we're looking at on the screen what I'm calling the APL dojo. And this was we did talk about this in the last episode, right? It wasn't like a month ago, it was ArrayCast episode 122, I think, where there was this idea of concepts, primitives, expressions that exist in array languages, not specifically APL. I'm calling it APL dojo, but as you can see in the the bottom right here, I guess it's this is confusing. So I'm screen sharing on one monitor, but then I've also got the thing that I'm screen sharing on a different monitor. So I've got to look at this monitor, even though you know the screen share's here. And so you can see down here we've got six languages. I do feel really bad that I haven't added K to ArrayBox. The reason that K is not here is that anytime I build one of these AI scaffolded websites, I just have git submodule, the ArrayBox site. So it has all the syntax highlighting, the logos, the input methods. So it's actually pretty easy to spin up these little websites now. And the idea is that we are going to, if you've ever seen the tier lists on YouTube, usually it's S tier, then A, B, C, D, etc. And they'll do, like, you know, the tiered list of Pokemons, the tiered list. I just watched one the other day of all the different Harry Potter games in existence from the Lego Harry Potter to Hogwarts Legacy. And so usually they use like a rainbow of colors. I personally prefer the karate, like dojo black belt, white belt system. If you saw the last episode on YouTube, you will notice that we are missing a bunch of colors. I've omitted the yellow belt, the orange belt, a couple other belts. Mostly because one, we don't need that level of granularity. We don't need like 18 levels of, you know, levels or grades. And so I just pick my favorite colors. Obviously, white is beginner, black is expert, and then green, blue, and purple are the intermediate levels in between. And so now we just get to have fun for the next 90 minutes or two hours or however long this goes, and we can come back to this. You might think, oh, you didn't cover all the primitives, all the expressions. Of course not. We can't do that in 90 minutes, folks. But you know, we're calling this the APL dojo. Maybe we'll have the J Dojo where we're still gonna have the existing board, but then we can add primitives that are specific to certain languages. And hopefully at some point when I add NGNK6, um, we can come back and add those. Anyway, so thoughts from Adam first before we start throwing up primitives and expressions, questions, thoughts, or can we just hop into this? What do you what do you what do you think?

Adam

Well, I mean, this looks promising. I don't know exactly how it works. I haven't seen that yet. I like the colors. They should be safe for people who have uh colorblindness or color vision deficiencies.

Conor

So that's the way it's well we also have the text. I was I was that was I was thinking that we should they asked me, do you want to keep the text? And I was like, yes, yes, yes, because you know, just in case we've got colorblind. I don't know the full spectrum, but uh definitely you should hopefully be able to make all the black, purple, blue, green, white. And I guess, yeah, we should try to keep this audio friendly as much as possible. So the the way it works is we've got APL input. So we can start with IOTA. Well, actually, is this the website? I might have not prepared correctly, folks. We got an F11 out of this. This is the website we need to launch. Uh actually, I think it already is launched. So if we go into local website. So can can anybody go to that website and yes, anybody can go to this, but it's not gonna like save your stuff to the official website. And so the idea is this is the locally hosted one. And you can see actually, so let's get rid of this because we're gonna do this from scratch. Is that if we want to make changes on the fly, I have a cursor instance open and we can just say, like, I haven't I've tested this minimally, but you know, if we get to the point where we have, you know, a whole row's worth of blue cards or chips as the app likes to call it, is it gonna wrap and create like a second line? Probably not. My guess is that it's gonna create a horizontal scroll bar. I don't want a horizontal scroll bar, so we could quickly ask and say, hey, make this wrap onto a second line. We may or may not get there, but the point being is that this is local, so we can uh potentially you know make changes on the fly. Madeline in the chat is saying this is gonna be the most rage-inducing array cast episode ever. Well, I'm not sure if you mean because we're gonna be arguing over what category things go in, or because the audio listener is gonna have absolutely no idea what we're doing right now. But, anyways, if we want to add iota, we can you know type back tick i, we can name this because you pointed out Adam, it might be nice to have uh the name of this. You can choose the rank.

Adam

So currently it's only probably called range, right? A range generator or index generator because iota is just a symbol name. Ah, well, so here's the thing.

Conor

I'll put range in parentheses. I I have a soft place in my heart for IOTA, and it's you know, if we have a little bit of editorial control here, iOTA shall rename remain named IOTA as far as this app is concerned. But I do agree, range is the better name for this from like a non-emotional point of view.

Adam

So we'll put range in parentheses, and we will actually uh Rubin Reg or Medelin has already sort of given names to all the primitives across all the various APL like languages in the omnibar. So shout out to that, and there's something we could pull on as well.

Conor

Oh yeah, should we open up omnibar here? I think so. And then I can just tab through uh we go omnibar. I was just on it the other day. And so I can't.

Adam

So if we search IOTA, or is it gonna is it gonna be Yeah, it's it found it. It found it, right? But it says it calls it index generator or range, right? Which is fine.

Conor

Although, so how do you get it to Okay, so clearly I don't use this enough. So, like you know how in Google Translate you can search by the name and then click and it'll show you everything else with the same definition but a different name? Yeah, it doesn't do that. It doesn't do that here? Or am I just not showing BQN, show one hidden language? Yeah, there we go. That's what I was expecting. Oh, that's what he meant, okay. Is that I wanted to see the alternative glyphs. So a better example for this, if we go table, you know, this is one of the the most what's the word disagreeing. Yeah, yeah, like disagreeing, bifurcating, non-uniformly not so much named. Most languages either call this table or outer product, but in terms of the symbol, it's got uh bajillion symbols, which is uh it's nice from a kind of historical, you know, anthropological or archaeological point of view, but from a learnability point of view, it's it's kind of sad. I love this little table thing. And so, like, well, let's do that. Let's do iota and table as our our first two. And so if we go back to our little thing here, we'll just, you know, Adam mentioned that I should add rank because technically, you know, we've got different behaviors across ranks. So we just want our rank zero iota. This is a primitive, it's a monadic function, so we go create, and then we get this little thing, and then oh, except I messed it up. We want to go all because even though they've got different symbols, the the the Unicode character is not supposed to be representative of what the language chooses as a symbol. It's just uh look, there's a little bug there, but that should be fixed once we drop it. And so I would say that this is a beginner level primitive or concept. Then the question is is do you agree?

Adam

Well, it depends a little bit on what kind of scale we are, because you could probably say that plus is even simpler in a way, but you could also say plus is more complicated depending on what kind of arguments you give it. And so do we do we even look at things like basic mathematics or do we just ignore that?

Conor

Okay, well now we have to redo this because uh we've I mean, like I said, I minimally tested this, but now Iota, all, create. Okay, so there are the little language logos at the bottom. And then I should be yeah, when you click on it, it should give you an update. For some reason, it just didn't do that. So repeat what you just said, because I was a little bit concerned that this whole thing was gonna fall apart. You said are we defining this just for arithmetic?

Adam

Like no, are we defining are we defining this for just for, should we say, interesting functions, right? That do sort of array manipulation generation things. Otherwise, there are certain structural functions or mathematical functions that are super, super simple, right? That are even simpler than this. So I agree that when I teach APL to somebody, then uh the index generator function comes in very early on, generally. But that doesn't mean that there aren't any other functions that are even simpler. For example, you could argue that the write tech, the right identity function, is the simplest function that is even theoretically possible. It takes an argument, returns it. Nothing done. There's nothing to understand. A lot of people have problems understanding it because it's too simple. They think it's gotta do something, but it doesn't.

Conor

So yeah, I guess that's a good point to clarify. There's no uh or at least the design of this when I designed it, there's not supposed to be any kind of ordering of simplicity here. It's not like we're we're reaching for the simplest idea. We can do that if we want, but the order that these show up, and I'm not even actually sure. So I mean if you want to, you're calling this what is it, right tack? And what do we call this?

Adam

Identity? Well, is monetic dadic? So monetic, yeah, monetic identity function or it's officially called same. I want to change that, but that's that's irrelevant. And like every everything is languages that have this. Well, maybe maybe not wewa, because maybe it might not make sense in Weewa, right?

Conor

Uh I mean Wewa does have a monadic identity. Well, like they don't have a they don't have ambivalence, but they definitely do have identity in the the jot. So like I said, it it uses a different thing. So if we go create for this, we can drag it. And so, I mean, can we rearrange them? I mean, I it doesn't look like it. I mean, technically we could do this, right? Oh actually, what's going on here? Is it possible to get the tack on the left? There we go. What? Nope. It doesn't like it. It doesn't like it. So I don't know what what sorting is using here, but the point being is it's supposed to just be like the level of we would not have it, yeah.

Adam

Or at least the concept of a density. So so that's the thing. What which one is simpler? A monetic identity function or a range generator, where you have to think about like inclusive start, exclusive start, and end, and index origin. There's a lot more to understand and know with a range generator than there is for an identity function, right?

Conor

I would agree. But to be honest, like that's the thing, is your brain is always operating in like the most complex, fully formed version of like every primitive, which is something I've realized, right? Like if we if we go to uh array box, and you know, I I was just mentioning the the one rotate reverse sort. So if we go, I actually don't know how to type uh rotate now that I think about it, and then I think it's four or yeah, there we go. And that, and then we do this. Uh and so what was I about to show here? Oh, right, is that if if you click on this, you know, so it shows you do you want the monadic or dyadic definition of the function, and then it has the same concept of rank. And what I've realized too is that when you go to dyadic, you've got two arguments, so you have to consider the rank of two different arguments. And like I, to be honest, I just like I have never in my what's 2019, seven years-ish of array programming ever thought about like the rank of arguments when using a dyadic function. Like a lot of the dyadic functions are pervasive or scalar, so you don't need to think about it, unless if like you've got a vector and a matrix, and then you know what are you doing? But honestly, that's that's typically you've got a scalar and then some arbitrarily ranked array.

Adam

Let's say, for example, something similar to what you've been doing lately, let's say you have a matrix of text lines and you want to center them or write justify them, something like that. So you want to do a separate rotate on every line. Now, in in or in languages that are leading axis originally, like J and BQN, there you would have to use the rank operator to do that. But APL traditionally is not like that. So therefore it defines vector left argument with matrix right argument on a last axis rotate to automatically pair up a rank zero, one. So every element on the left argument will rotate one row of the right argument. And similarly, you can use the first axis. It's not really first axis then, it's really column-wise, right? So then if if you do a the the circle horizontal bar rotate with a vector left argument and a matrix right argument, then it rotates the columns individually, which would be complicated to do in the other languages that are strictly first axis. You would have to transpose first and then do a a uh rotate rank zero, one, and then transpose back again.

Conor

So there's a lot more nuance to this than I mean, how do let's take a little mini tangent in our we've we've barely even got two primitives up on the board, folks, and we're already in tangent land. I mean, what is your cause what is your thought on the complex because I've realized that like dyadic functions are so complicated, you know, in a certain sense, if you start to think about them in like the rank of both arguments, because like a lot of times when I'm working with these languages, I I like I say, I am thinking in rank one land or like rank zero land. Like when I think of the without glyph, I've never thought about a without on anything other than a rank one left and right argument. It's just like that's and maybe maybe uh without if you've got a rank zero, like just a scalar, yeah. Um like that that makes sense. But like I've never thought about it in matrix land or like you know, rank three plus land.

Adam

It it it dial like it doesn't, but it should, and you know, you know, everything it does go by major cells. So that's another thing. That's the that's the that leading axis orientation thing where everything that applies to the individual elements of a vector really also apply to the major cells of any rank array. And then for the dyadic ones, then they have to have some ad hoc rules that sort of say, okay, we have to decide on on the rank of the major cells combined of the right and left argument. So, for example, for a lookup, you want to treat a higher rank array as in the lookup table, and then a lower one lower rank array under on what you're looking for, you would treat that as a single major cell of the higher rank ones. For example, you can look for a vector in a matrix, means you're looking for a row. If you're looking for a matrix in a matrix, you're looking for individual rows. But they are you can't just generalize it like that, and there are some complicated things. So J makes it very explicit in this documentation what the function rank is, and that means it defines a behavior on the smallest possible rank, and then if you uh and then if you give it arguments that have a higher rank than that, then it just runs a loop basically. It just applies to cells of that rank that the array can handle. So as an example of this is matrix division, matrix inversion operates on matrices, obviously. If you give it higher rank arrays, then we'll just go to the individual rank two cells. I see. So that's what function rank means in J.

Conor

I've like I've it's come up a couple times, and I think I've every time I've either been confused silently or I vocally said, I've never really understood function rank in J. Function rank in Just is a is a primitive being assigned basically like and that's actually that's what I've done here a little bit, is that like you can see in the top right, I'm defining like what is the most common, you know, defined by me half the time when it was done explicitly, and then you know, Claude 4.6 Opus when it are the primitives I didn't look at. You know, so if you s if you add to this list IOTA, I don't I I think this is for, yeah. Oh, look at that. It calls it index generator. Like I said, the AI was responsible for getting all this stuff. But I made sure that it gave index generator like its most I don't know what you call it, the default rank or the function rank, but it's the one that you most commonly use in my experience. And and then if if you add like in in one of the ones when it was the I think mix and split, you know, mix is typically on a nested list, yeah, and then split is typically on a matrix. Like in my experience, I'm not saying that these are you know representative of all array language programmers everywhere, but when I'm building this tool for you know myself and then other people that want to use it, you end up with this kind of like, oh yeah, you know, some operations you know you use across ranks, but others you're typically reaching for a single rank, and I guess so that is what Jay has tried to do. They choose a rank and then they loop.

Adam

Well, they I think I think at the time of definition of the primitive, they would have looked for the highest rank that they could have some kind of unique behavior and then set the rank there, and that's actually in a way sad because that prevents further extension in the future. So uh for example, with a matrix division, right? So dialogue APL, or I think all APLs supposedly, they don't have the rank two set for matrix inversion. If you try to invert something higher rank than that, it will just error. Maybe one day somebody will come up with some ingenious insight that will be the multidimensional or many many-dimensional equivalent of inversion, right? What something that is to a to a hyper matrix, right? A cube or higher, what inversion is to a matrix. And that that day that that happens, APL will just go, okay, well, we'll add that algorithm and the primitive is extended and all good. And J will go add another dot to the primitive, right? To make a new primitive, because the matrix division, matrix uh inversion primitive, is already defined to loop over rank two subarrays. And there's nothing you can do. You cannot use any sort of inverse rank operator to tell it to no, no, no, I don't want to look at rank two. Broaden your scope, look higher. You can't. So it's it's a gunner. It's it's fully defined. You can never again extend it. Yeah, interesting trade offs. So it saves you some rank operators that you don't have to explicitly loop over things. That might also make it a more obscure what's actually happening. That's the cost, of course. But then again, you can say that about arithmetic. Functions being scalar in nature, right? That not having a loop like you do in most languages makes it maybe more obscure what's happening. But on the other hand, you're able to extend things. So you could say like yeah, as an example of something that could happen, but obviously it didn't historically. You could mul you could define multiplication on scalars, and like nobody could think of what they would do on vectors, so we just define it as rank zero. And then somebody comes up with the idea of a vector multiply, right? The inner product thing. And and then you want to extend it, you can't, because you already overloaded it to all higher rank arrays by automatic looping. Uh, we don't want to do that. We experience has shown that that for for array programmers, that's not what we want. But that's the that's kind of concept that it could happen. Right, right.

Conor

Okay, well, I mean yeah.

Adam

There are cases where where this is where things are weird if you if you try to just extend them with rank. For example, you if let's say we now we're doing with the range generator, right? There are different ways you could extend the range generator to a long right argument. So the way dialogue does it, and I think most APLs do it, is that they say, okay, it generates the indices of an array of a certain shape. So if you say two by three, then you get a nested two by three array where every element has a vector, uh two-element vector, that is the enumeration of the indices of all those elements. Right, like exactly like what you're showing now, IOTA 2.3. J defines it differently. It defines it as filling a two by three array with the range of the product of the right argument. There is a there's a third definition you could have done, and then you could say, oh, range. I imagine if they had back in flat APL land when there was no nested arrays, if they had thought, hmm, there it doesn't make any sense to do the range of more than one number, so we'll just define it as rank zero. That would mean that if you do the range of two, three, you'd get uh a a uh rank two array. The first uh row is uh the range of two and the second one range of three, but that means it has to pad it. Yeah, so if you do if you uh range rank zero here, no not each, it has to be rank zero. So just uh citation zero and you have to put a right square bracket to separate the strand. So then you would get this result where the first row of so this is range rank zero on the array two three is zero, one, zero in the first row and then zero one two, right? And they might have said, okay, you know, it's maybe not the most useful, maybe sometimes you want this, and it's fine, and just pad with zeros. Maybe it's good for like making triangles and things. This would allow you, for example, if you now write instead of two three, if you write iota five or i. Maybe that would be useful. And then somebody comes and says, Hey, no, we could we could do this instead. We could make it fill a two by three array with the numbers from zero to six or two five, or in the APL land, you say, Oh, we could make it nested because now we invented nested arrays, it's too bad ship is shelled. Anyway, that's there's a tangent a bit. You're absolutely right that when we can't just make a list of perimeters because the pairing of left and right rank, or even left and right nesting level, and and in monetic form as well, and nesting level and rank and so on. Sometimes even type, like in K, you get in Q land you have like type overloads as well.

Conor

Yeah, yeah. This is what we were I was just talking uh with Madeline, who's also in the chat right now, on the last tacit talk, is this realization that we you know we always hear about rank polymorphism in array languages, but you never explicitly hear about ad hoc polymorphism. And on top of that, like there's multiple kinds. You're overloading on the rank of your argument.

Adam

Type polymorphism, type polymorphism, even value polymorphism, I would say. So if you go to to say dialogue APL and you do question mark five, you get a uh a random number from between one and five. But if you change and and any any positive integer there will give you that same sort of result. But if you change the to a zero instead, it's actually a different function. It's actually it doesn't generate a and value in the range from of the first zero natural numbers, rather it gives you a float between zero and one, which is actually something completely different. So that's type overloading, right? There's no rank polymorphism here that's different between those two cases. There's no depth polymorphism that's different. An example of the depth making a difference is I believe in the in the from or select or whatever it's called function in j, then you you for every dimension you can give it a list of the uh the indices along that dimension that you want to to pick out. But if you enclose that one of those elements, it means all the those enumerations along that dimension except these. So the depth, you just adding an enclose, changing the functionality completely. So to being instead of select these, it means deselect these. So what do you call that? That's depth of it.

Conor

Definitely it's a type of ad hoc polymorphism, but yeah, it's sure. But then you could call anything ad hoc polymorphism. I mean that's that's the thing is ad hoc polymorphism is is ad hoc, right? It's it's when you define separate behaviors based on different things, number of arguments, type of the arguments, depth of the arguments. That's I mean, that's why it's called ad hoc, because it's just kind of like ah, like we could we could inject different behavior in here based on something, right?

Adam

And if you go with with uh an APL2, then the slash is either replicate or reduce, and it's always an operator. And the type of the operand, it's a monetic operator, the type of the operand determines the functionality. What what is that then? Type overloading, two different primitives, is the same primitive? And and you really have that as well in in some dialogue operators, right? The the the power operator, the the asterisk with two dots on top, if you give it a function right operand, then it means until, until that function returns true when evaluated with the arguments of the previous and the current iteration. If you give it a value and an array, which has to be a type scalar number, then it repeats, right? So it's repeat and until which are related concepts but definitely not the same. Repeat is is a is a fixed bound, and until is could run forever, we don't know. So here again, it's the it's the type of the upper end. So if you go back to the dojo, things are things will go get a lot more complicated if you don't have nearly enough selectors on the right. Because what what what if you want to do something like reduce? So let's try.

Conor

First of all, so which one this is not so this is uh a one monitor.

Adam

Okay. So we lose our ranks, which is Yeah, but but hold on. So which which derived function in in APL, dialogue APL at least, the diadic derived function is windowed reduce, but the monetic derived function is just normal reduce. But you if you try to select monetic dyadic function up here, then you lose the selection of the one modifier. Those are not exclusive. Well, if I do it's not an expression either, it's a derived function. So you need to use the.

Conor

I mean, but you can technically if we call it an expression, I can choose you know this to have just the reduced meaning. We choose it as APL, and we choose all of this, and when we create this, this will basically it'll syntax highlight it as I mean, so technically this is you know, so I guess actually what we should what the real thing to do is if we get rid of this, we we want a primitive and we want to be able to select one modifier, but when you select one or two modifiers, it should give you the option to say what you want function. Uh yeah, yeah, the area.

Adam

Or ambivalent, because sometimes it's nice to treat them together. For example, we for the dojo here, we might want like functions derived from key or anything derived from key, right? That might be you want to want to treat that separately, but sometimes you would you would want to treat both the monetic and daddy form, things like constructs with ad or something, where it doesn't really matter if it's monetic daddy, the the the power operator and so on. There it's not important, so you should be able to leave that out. But what you could do here is some actually internally in dialogue and in APL2 as well, I think the other APLs, if you ask the system for the attributes of a of an entity you have, then it will tell you the valence. So, and that's also something that's missing over here. You you have you have subtype, you've written monadic function, daddy function, but there's also in principle niladic, right? So, for example, zilda, right? That's a sort of a niladic function, returns a constant value if you want, or you could see it as an actual array, that's up to you. So so we we use numbers, and you can query these numbers for any given name, and say what is the function valence, and that could be zero, one, or two, and it can be ambivalent, which is designated minus two, but it's just some number that you can refer to. And then there is the what is the operator valence, and that's also zero, one, or two, where zero means not an operator. One means you're right, one modifier, two means a two modifier, or monetic that it could operate. So those two numbers, the function valence and the operator valence, those completely describe the the syntactic role of any given thing.

Conor

Are you saying, well, I got a little bit confused. Are you saying that because uh one modifiers don't have the ability to accept different airity or in your parlance valence functions, right? Like a reduction change.

Adam

True, but that's not the that's not the point. It's the the the the function valence of an of some of a construct using in an operator would be referring to the derived function. So for example, plus slash.

Conor

Oh, I see. What you meant there was not the argument, it was the derived function. Yeah, okay.

Adam

Yeah, the derived function. I mean, definitely we should add that.

Conor

So let's let's go which one of my cursor implementations. Okay, so if we say for the one modifier and two modifier, you just need to split that, right?

Adam

So the subtype that we have here, there should just be three options for each row, and there should be not one radio button group, should be two groups.

Conor

Oh, you're saying don't have a new section that is enabled by click because I was thinking if you click either one modifier or two modifier, it'll pop up a news section that says like derived airity.

Adam

I mean, you're saying just have like a reason for that. Yeah, just instead of a stop type, you have one that's called function valence, that which and and then a new section called operator valence, right? And then the first option in operator valence is not an operator, right? On an A or whatever you want to call it.

Conor

And the first the first option under function valence is a idea better because the having to click uh not applicable is anyway.

Adam

So that can be the default, right? It will just be zero.

Conor

Add a section called what do we want to call it? Derived function.

Adam

Yeah, derived valence or derived function.

Conor

Should I switch to valence? I mean, I I like erity, even though I prefer monadic and dyadic, and I know erity goes with unary and binary, and valence goes with dyadic and monadic, but I I don't know. I guess if you if you're if you're listening to episode 123 of a ray cast, you probably are able to interchange between the and valence.

Adam

I think Marshall had a very good point in like keep simple language. Just you call it a one modifier, two modifier. Why not instead of subtype monadic function, diadic function, you just say one arc, one argument, two argument, right? And then one modifier two modifier. That's all it means. And then zero argument zero argument means it doesn't, it's something that's like zilda or hash or those things, null or just numbers.

Conor

Why use monadic and diet? I guess because one argument and two argument to my ear sounds like the this is the incorrect word, but the the word that popped into my head was like Neanderthal is like it is you're describing it to understand. Yeah, you're describing something in simpler vocabulary, but something that has a specific a word that was specifically designed for it, and it's it's kind of like Trumpy, you know, like Trump says we've got big, beautiful books, you know, and it's he says one-syllable words to make it understandable to more people. But it's like, well, there is a word for that that we have called unary binary monadic dyadic.

Adam

Um but I guess why I started doing this in the in the appeal challenge that we have going, where I've started simplifying the way we describe things, both the la the names for things. Like we use we experts like using long, complicated sounding words to make them sound more intelligent or or more educated than the masses, even though it's just simple concepts.

Conor

Yeah, that's true. I mean there's pros and cons, right? One argument, like I definitely when I'm giving talks, and ever I whenever I first say the words unary and binary or monadic and dyadic, I always add a little explainer like FYI, and sometimes I'll even show the Wikipedia table of the Greek words and the Latin words for unary, binary, ternary, quaternary, and monadic, dyadic, tetradic, and quadratic. And then people probably go, oh, okay, yeah, that makes sense. Because I definitely remember being confused the first time I heard the word binary and didn't realize they were talking about aridity or valence. But anyways, let's uh we'll put the maybe maybe I'll rename this stuff, but let's uh I'm I'm still halfway writing the prompts. Add a border with the color for the modifiers similar to uh expression. I didn't really explain this well, so I mean if the AI understands what I want, that'll be very impressive. It will understand something. Uh well that's I I mean it'll understand something, but it will it understand what I wanted? Maybe maybe not. So what I'm hoping is that there'll be a new section called derived function erity, and then it only shows up if one or two modifiers selected. And then so if you currently, if you add a slash and we call this reduce. And so technically we're we're talking about the monadic derived case here, which I believe all the languages have. The dyadic derived differs, but if we do this, it should create me a yellow. And and note here at the bottom, I haven't mentioned this. So I'm using the Weewa syntax highlighting, which is differentiates between monadic and dyadic functions, which we can do in wiwa because we have no ambivalence. We've got fixed area.

Adam

That's good, that's good for this purpose here. Yeah, I do that in AppleCard as well, differentiating entirely between monadic daddy functions.

Conor

I do give the option though underneath, because people are gonna get confused if they start seeing, because technically a one modifier in most of the array languages is syntax highlighted green. So if you want, you can switch and then make all the functions blue, actually, just so people don't get confused. And what should this be? A green? Blue?

Adam

Reduce? I mean, again, it depends. The in the basic form where the where the where the upper end is a scalar function, then it's yeah, green is fine. But if the if the upper end is not a scalar function, then it's interesting. And I would even say you could even go further. What kind of reduce? Plus reduce, times reduce, sure. Those are very simple. Everybody gets those. Maybe those are even white, even if they have a bit of special syntax. But unequal reduce, which is an which is an XR checksum. Maybe not. What about left tag and right tag reduce that selects the first and the last elements? Are they as simple? And then you have things like custom function reduce. I do that sometimes. We want to run the same function on the original data and then with varying left arguments. So you take all the left arguments, concatenate them to the enclosed of the original data, and then apply reduce with some giant custom function. That's a whole different technique.

Conor

Alright, let's let's pause you there because this is fantastic. This is f this is what I'm talking about, folks. This is what the APL dojo is all about. Well, first of all, we're gonna hit F5, see if the AI did what we wanted. We're gonna hit this. It doesn't seem to Well, what if we uh Did you reload it? I did reload it. I don't want to hit control F5 because that could potentially relate my memory release.

Adam

But if we Th there's another thing that's missing here, I think, is the type. You've got primitive expression concept, and I would also add technique as another one. That's neither really an expression nor is the concept. But but as we'll get to eventually on the black belt is is dual-wielding uh rank operator with with two different ranks for the left and right argument. Uh that's a technique, it's not an expression, it's not a primitive, it's not a concept. Alright, we'll add the technique for next time.

Conor

So the the AI, I think we can start a new podcast, the APL Dojo podcast. This is all we do.

Adam

This is all we do.

Conor

Well, so actually, while we're waiting for the AI to fix what it failed to do, let's add the not equal to because I actually had this as one of the expressions when I was sending you screenshots. So this is an expression. It is a monetic It's not an expression. It's I mean you could I guess you could call it an expression.

Adam

Yeah, okay. Yeah, it's an expression.

Conor

Anything that's more than a primitive but less than something that needs to be described by words, and then we can highlight it as APL. Do all of the I think all the languages have it. So we go create, and so this one you can see has a gray background. And what is this? Is this blue? Purple? I don't think it's black belt, but it's no, not more than blue, I would say.

Adam

All right, it's not that hard to understand. And so you can see also the the scan equivalent, right?

Conor

That one's more interesting. Actually, that's the one that I was thinking about. That's what I was thinking about. So let's add that one as well. And actually, wait, we the AI sets it's done. Let's hit F5 and see what happens. So now we go here. What is going on here? It says I mean it's so sad, you know, you spend so much time working with these tools and it does everything perfectly.

Adam

I think we might be running out of belts very soon. Because I think we'll be able to identify things that are definitely easier than one of them but harder than another one, and fits in between. Madeline wrote in the chat that she thinks a reasonable split is associative scalar or scalar or other on and then on vector or higher rank. And that's probably especially like reduced first would be higher difficult than different than higher rank. So so yeah, think about it. Where would you put plus slash like monetic plus slash, the sum? On on green, right?

Conor

Yeah, I mean I would say, I would say, and that's the that's the tricky part, is when you were breaking down all the different reduces, is that there are more complicated reduces like the not equal to reduce and you know the left tack, right tack, and the custom ones, and the non-scalar ones. But like when I when I see just the reduce, in my mind it kind of categorizes it as like the simplest version. So like plus reduce fits in here, multiplication reduce fits in here, you know.

Adam

But it stops there, right? Because as soon as you go to minus reduce, things get real fun, right? Because that's an alternating sum. And division.

Conor

It depends on your implementation, only APL has alternating, and then other ones do not, right? BK.

Adam

So so the so the so the plus slash in in APL is different from the plus, well, the tiny little and that's and that's why we've got the languages.

Conor

So when what as soon as it's different, you start tagging them. But like uh honestly, like that's that's the problem, is that in my mind you do all right, let's hit F5 again. I sent them a screenshot.

Adam

So what happened? I mean, what's going on here? It's not different.

Conor

Should I risk hitting control F5?

Adam

You're gonna lose all your data. Well, it didn't lose. How does it go? There we go.

Conor

It was it was uh it was a hard refresh problem. So now this is monadic, and if I update it, now it shows that this. And so technically, nice if we want, we can do what you were talking about earlier. And so for this, which so BQN doesn't have so I'm thinking about the n-wise reduction. So J but see there's a difference as well. Uh here's a value difference. There's always a difference, man. That's the problem, is you're operating up here, and I'm just like, let's just add this, and you're like, no, no, no, there's six different things.

Adam

Connor, if you do a two-wise unequal reduce, that is a very simple concept. That's just comparing adjacent elements to see where do we have edges, right? Where do we switch from one value to another? But anything more than a two as left argument, that means you're actually doing XOR reduces over Windows, which is right.

Conor

Well, I mean, so in my mind, it was just gonna be this. It was gonna be, once again, this is uh one modifier, but dyadic derived airity, primitive. We can even call this n wise. BQN doesn't have it because they uh use the left argument as an initial value. I actually doesn't have it either, right? J doesn't have it. Wewah has folds and reduces, and I I definitely don't think wewa doesn't build it in here. Cap, I know, has it, and I think Tiny Apple has it as well. So we create this, now you get one with the green border. I would add this.

Adam

Not the prettiest thing.

Conor

Yeah, it's a little bit hard, but you know, it's it's something, it's something. Um and also, too, it's a little bit I should add like a black.

Adam

I would say that's a big difference between the two wise reduce and n wise reduce. Two wise reduced is something so simple that even K has it as an as a standalone operator, right? Yeah, it's prior, right? Prior, exactly. Okay. By the way, Badland says Tiny Apple doesn't have that reduces his intlai value. Well then be gone, Tiny Apple. Yeah. So so I think there's a big difference there. Between what do you like if we go to C land, right? Adjacent differences is called and and doing windowed things. Yeah, adjacent difference.

Conor

Adjacent difference in C 98 is just that, but the generic adjacent transform that showed up in C23, that takes a static argument, a template argument that can be anything. So it's it's like the n-wise reduction. So I mean, but like how do we so if you want to delineate these, technically the way to do it would be, you know, it's technically well. I don't actually know. So how does that work by the way?

Adam

When you click the addict function there, you know what we should have?

Conor

We should have like the cross, you know, like the uh we should get the symbol, you know, the you know, the two different crosses, one's like Henry's and one's I don't know, some other guy's names. And we should like that's not a symbol in any of the array languages, so that should just be for a generic binary operator, so that we can put like how is that not not a multiplication symbol? Well, because multiplication is actually uh a thing, right?

Adam

Yeah, but that's the other cross you're talking about, right?

Conor

Yeah, anyways, but I'm just saying we need one of those symbols, like in in at in mathematical like academic papers, they use that for they usually use a blob, a blob or something. Yeah, yeah. Well, we need something because op looks bad. You know, all of these are taken, and you know, question mark, it means something. But you want the solid blob. Well, uh we can just go get that. Yeah, where let me uh I need another uh let's Google Google generic binary operator cross unicus.

Adam

Actually, what do you think? What I've seen in mathematical papers are two different things. One is a star, and then there's the those that use just a filled black circle, a blob. So I'm on shape catcher right now on a different monitor. That's that's a bad thing for filled out things. It'll be you have to fill it by hand. Man, I just got a bunch of clocks.

Conor

What the hell?

Adam

Here, actually, people might be. Yeah, because you're trying to fill it. That's the problem. I can give you the Unicode value if you want. Uh you have the U U plus 25C F.

Conor

What?

Adam

Yeah, never mind that. Just go just right. Get U plus 25 C F. U plus 25C F, yeah. That's not the one I want. No, sir, I don't know what you want.

Conor

I want the I want the cross one. Which cross? The dagger symbol? I don't know. There's two, there's two.

Adam

There's Henry's cross. Oh, you want them the circled ones?

Conor

Yeah, yeah.

Adam

Oh, that's one around. I mean, even that's sort of. Come on, what's going on here? Is this this? No, that's a that's a weird letter. I can also old italic letter the? I mean, this is pretty close, but that's not what you want. You want the one with a I know now I understand what it is. What is your after? Here, there are a couple of different ones. It's NRE circled operators called or circle plus, if you want.

Conor

Circle. I mean, actually, I should have been able to guess that. Circle plus. It is uh it's u plus two two nine five. U plus two two nine five, he says. Yeah. There we go. Now we're gonna You should have just told me what it was you wanted.

Adam

Well, you know. Or you could have a S an LLM, who knows? That's true.

Conor

You could there we go the whole thing. All right, I'll keep that in my copy buffer and make sure not to.

Adam

Roger Huey and I suggested giving that meaning in APL, but yeah. And I believe it's actually an a function in tiny appl? So now we create this, and you're saying this is simple?

Conor

This should be here?

Adam

I don't know. Yeah, no, that should be on yeah, I don't know, I guess.

Conor

And then you're just saying like N.

Adam

And this is Yeah, so just know that in Tiny APL, this is a a function that Roger Huey and I proposed.

Conor

So does that mean we get rid of the nwise reduce here? Like, what's a better way, like yeah?

Adam

I think that's much clearer. Now you can see what it means. Otherwise, I can't tell the difference other than by color, the difference between that nwise reduced and the normal reduced on there.

Conor

So get rid of this one, the one that I'm the the colored yellow one, and then just keep the expressions is what you're saying. Yeah, I think so.

Adam

It's much clearer at a glance what it means. I mean, what I would do in in say AppleCard is I put an F. An F for the N or an F for the symbol? For the for the generic function, because it's not necessarily a primitive. This sort of indicates there's a primitive, it could be any function.

Conor

Well, it's supposed to just mean binary operation, yeah, is what it's supposed to mean. So I mean for the audio listener that hasn't switched over to YouTube, big mistake. We're we're we have been trying to figure out how to separate the variations or variance of the nwise reduced. So, Adam, I'm sure you understood earlier with saying that a twowise reduction is much simpler than an nwise, where n is greater than two. And I guess, yeah, that's actually not technically n could be two here, but hopefully the fact that both of them are on the screen, people can deduce that.

Adam

Yeah, that that that's fine. Otherwise, it'll be too complicated. But see, what I would do here, you have another problem, right? Which is the rank that's not steady that you're going to put in the little circle in the corner. That that also makes a difference. So here this is last if you're doing APL, this is last access reduced, but the first access reduced would probably move up one level because then you have to understand how it works along the columns. So you're just saying just the first access reduction? And we can well, first no, that's first access and reduce first access, all of the first X reduces are like one level up, sort of from from their equivalent last access reduces. It's easier to understand the last access reduces.

Conor

Oh man, it's so confusing.

Adam

Yeah, but that means we have so many. So so what I do, instead of all these colors and the settings and things you have to do, what I do in in say Apple card and and the other Apple card-inspired things do the same thing, I believe. That is to use codes, right? So so here on if you go down to like the IOTA one, right? That says IOTA with rank zero, then I would I would write that as an expression. I would write IOTA M uppercase M lowercase s. That means so M means a write argument that is numeric. And oh sorry, sorry, uh N. So uh uppercase n lowercase s that means oh and numeric scalar. And then if you want a vector, you write nv, numeric vector, and then at a glance you can see what it what it means, and that's so so too with a function. So you could you could also introduce things like fs for scalar function or fm for mixed function, things like that. There, so I use I use text codes that don't rely on coloring, don't rely on like little icons and things, those different stuff, anyway. This is hard, right?

Conor

It is because now it's ruining the fun of APL Dojo, there's too much nuance.

Adam

Yeah, so now we are up to the purple belt on N-WISE uh reduce, right? On a on a primitive, but would you not say that there are concepts and primitives and so on that are like leagues above that? Yeah, so you're saying we need more colors, maybe, or we need to revise our strategy here because this is that's what I'm saying. This is hard.

Conor

What do you mean it's it's uh that's something the AI is not gonna mess up? We can add back a couple colors, although it's gonna have to choose a red because I gave it an image and it chose the colors perfectly based off that image, but now that it's just gonna have to make up a red, which may or may not choose a red I like or a brown I like.

Adam

I'm not sure it's a good idea because at what point does it not become useful, right? Well, we could also do a sort order, like an absolute ordering, or like a total ordering of primitives and concepts, and everything is like what is harder than what, and then you can choose your cutoffs arbitrarily and then you get your belts. Medalin saying in the in the chat that first axis reduced is is simpler than last axis reduce because if you explain uh if you explain leading access concepts early, but that's not true. That is true in a proper leading access language, but in traditional APL, leading access reduce is not actually a full leading access primitive dealing with higher rank cells, instead, it does some uh sort of interesting thing along the columns or along the it's it splits up the array into slices along the first coordinate and then applies things. Well, is it well it says APL dojo, Madeleine's protesting it's a general array language dojo, and I don't know. I think this I think it would be incredibly difficult to do all of this and also have all the different nuances across languages in mind.

Conor

There's already so much nuance just for one language, and I guess here's the question Is it possible to do on to do this nuance less? Modulo nuance? Like, is it is it possible to just kind of discard the because like in general, you know, we don't need to split two wise reduction and n-wise reduction. Like, and that's I guess that's the problem, is depending on how you learn these languages, what your background is, how you're coming at it, you know. I I technically when when I discovered n-wise reductions, I I had seen the two, comma slash, and I just thought that that was an idiom. I didn't realize you could replace the comma with like any operation. And the day I realized that, I was like, holy smokes, that's amazing. And so really, like when commas your operation, a two, a three, a four, it doesn't really make a difference. And so then when you realize you can place it with a binary operation or, you know, and then it just does a reduction equivalent basically on it, it's uh to me, they're the same thing. So it's like people are gonna, you know, if if Madeline thinks that reduce first is simpler, you know, because of her path, and I think you know, ny's and two y's go together. The question is, is like, are we able like, you know, dyadic transpose? That's what we mentioned at one point. This is a dyadic function, and we're just gonna put, I believe that's that. We call this dyadic transpose. And how many languages have dyadic transpose? I don't know, because I never use it. APL?

Adam

I suppose all of them have, but they don't they're not defined the same way. That's all right. That's what I mean. Nuance. Yeah. So you can you can is it easy enough to just do that? And like, or or do we have to say that we're all What are we trying to achieve? What's the goal of this?

Conor

I don't know. I think the goal of this is to at a high level put primitives, idioms in the form of expressions and high-level concepts in these different categories so that if you are in general at like the blue belt level, you can look at what is above your level of knowledge and find the missing you know tools and concepts and ideas and be like, oh, okay, like, and you know, double rank. You know, is that a concept? No, it's a technique. It's a technique? All right, well, we don't have technique for now. So we'll just call, and I I guess can I oh I look at that. I can the the uh the input method still uh still works here. And so is double rank, is that a thing for all the languages as well? This is something that I never do as well, so like I'm out of my depth here.

Adam

And any of any rank any language that has the rank operator can do double rank. Double rank is not a built-in thing, it just means you took a you took a function that's derived from the rank operator and you applied it with the rank operator.

Conor

Does we will have rank?

Adam

Uh has planets, right?

Conor

We'll keep we'll leave a weewa. So if I do this and then I just put double rank up here, you know, that works.

Adam

And so if that is where hold on, if that's black belt, where do you put single usage of rank? Yeah, that's a good question. That's what we're here for. That's what the APL dojo is about. Yeah, but if the if single usage of rank is purple, then surely dyadic transpose would go down to purple as well. They sort of belong together in my mind.

Conor

Right, say that again. If single usage of transpose.

Adam

If single usage of rank of single usage of rank goes down to purple, then I would put dyadic transpose down to purple as well.

Conor

You think dyadic transpose and rank are at the same level? Yeah, I think so. No, no. I've never used dyadic transpose once in the seven years. But that's what I mean. It's different for everybody. I've never used it once, and I don't even know what you use it for. I've heard you and Marshall have the most crazy tennis match of like primitive high-level black belts going back and forth of like, oh, it's a one rotate on the left argument, it's like, oh, it's just a reverse of blah blah blah. I still remember, I don't remember what episode that was, but the rest of the array cast panelists and uh me were were just like baffled. I use rank all the time. I mean, if I need to do something on a real-wise basis or a column-wise basis or something, and especially in J, you know, rank zero in J is a very common thing. Yeah, and Adam, what is that? What is the chat? I mean, we've got we've got Max, Madeline, and I guess Adam is a third person right now in the chat. What do what do Max and Madeline think? Where does rank Madeline's saying that the transpose has nuance, right?

Adam

That's that dyadic transpose has nuance because there's some languages where you can give like a short left argument to transpose. And she says it's simpler to explain how just bringing one axis to the front rather than reordering or reordering all the axes. Whereas a different way of coming at it is saying dyadic transpose exists in a simpler version that is less powerful, and a more complicated version that's more powerful. And by more complicated meaning those that can take short left arguments, like a single left scalar left argument that Madeline was saying was a simpler thing, I would say that makes the whole primitive more complicated. I'm not saying we shouldn't do it, I think it's a good idea. But I but but there's a there's so much nuance here. I don't know how to do this. That is the problem. We're drowning in nuance. So so so what I have done really, like for real, something that already exists is that I always sort the data table in Apple card by a a very simplistic sort. It doesn't even distinguish between any of these nuances at all. Of course, this is only for APL. The only thing it distinguishes between is the character involved. Okay, and I have made some sort of according to my head arbitrary ordering of primitives of symbols in APL. And I can show you that or you can pull it up yourself if you want. We're going to Apple card? Well, no, don't go to AppleCard, go to AppleCard source, right? On GitHub. I can see it. Yeah, you can you can go through and click click the GitHub thing. Yeah. And then you go to a file called cars. Okay. Cars.apila. Is it in the top? Yeah, it's in the root. Yeah. I like to keep my thing simple. It's right there in the middle of your screen. It was before you scrolled. Oh, it's not in alphabetical order. Oh, it's yeah. Okay, so this is a bit small, I might want to make it bigger. Yeah. So this is my attempt at a rough ordering from simplest on the left to most complicated on the right, where I remove all the nuance, right? There's no consideration of ranks or depths of arguments, no consideration of even the monetic or the form of the primitive. Right? But this is so that I'm saying there was I think it was a space on the left, right? Space is the simplest thing. And then and then right tag is the simplest function, and left tag is this next simplest function. It has the slight complication that when you give it a right argument only, it still gives you the right argument. So it makes it more complicated than the right tag, which is pretty obvious. Then plus removing the nuance that plus deals with complex numbers, right? Comple conjugate, and it is just passed through for none numbers and so on. So that forgetting that nuance, minus times should be pretty simple, right? And then or and and removing the nuance of the number theoretical things, right? Because in the most common case, it's just logical or and and those are easy to understand. Then round up and maximum and round down and minimum, reverse last, reverse first. Notice I do the last axis before the first axis. I think it's easier to understand for most people. Then division, right? Why didn't division go plus minus times division? Because you know, division is a bit more interesting that you have to learn the with the with the typical sort of yeah. So I mean we had minus there, then modulus and absolute value, then we go the the factorial and then and choose k. And then we get our our the random number function, which yeah, it's again in combinatoric, so it's sort of that area. Then we get all the all the comparisons. I didn't order them by simplicity, right? There's no way I can say that less than is simpler than greater than. So I just put them in the standard order they appear in. And then and those are scalar comparison functions, so slightly more complicated in the scalar comparison function are the the full array comparison functions, and then some structural things, and of course, I would say mix and split are maybe more complicated to deal with than drop and take. But being that they share symbols, I've got to put them in an order, so that's where they go, and then reshape, because reshape is sort of similar to to take, you know, and then and then we do more advanced math. So all the advanced math comes comes over here. That's the power, exponential, logarithm, and and uh and the circle fun all the circular functions. And tilde comes here, you could say it's a simple Boolean function, but it deals with sets also. So I guess I put it here. Then the compositional operators, first the monetic compositional operator, then the binding, so on, and then the the more iterative ones, and then reductions and and replicate there, right? And and we keep we keep going, like we can see scrolling, then the naned nores tend to be a bit harder for people to wrap their hand heads around than some of the structural thong things that deal with combining arrays and opening it up and splitting them up and selecting from arrays and lookups and all the kind of lookups and set functions, power operators, not that complicated. Grade, pretty complicated. But again, if we had nuance, monetic grade, not so bad on numbers, monetic grade on characters, yeah, sure, not so bad if you know about Unicode, things like that.

Conor

I can't believe scan. Scan is so far.

Adam

Well, yeah, well, uh but think about what does grade mean on on a on a not not simple array, right? On a vector of multidimensional arrays, right? What comes first? A two by three array or a three by two array of the otherwise containing the same things? That's not that's pretty complicated. That the total array ordering. And then dyadic grade is again has nuance to it, right? The left argument that is scale, that is a vector, and a left argument that's multidimensional. That's like the multidimensional left argument. That's something Roger Hugh would test us to test people if they really know what they're talking about. Then the brackets, and again, I can't say that left or right bracket is becomes one before another, but they actually do a bunch of different things. So that's there's a lot of stuff to learn. Transpose, key, right? It's it gets harder and harder to sort of know see exactly what things should be. Then then the then we've got inner product, but that's also duding into things, so there's a whole bunch of complication there of the stencil. In code decode, it's all simple when you've got a single number you work on and a single base you're working on. But when you like mixed base multi-number conversions, it's right up there in in some pretty advanced stuff mathematically, especially like in code. So at that point, also more mathematics of of Domino, right? Matrix division inversion. Then you've got all kinds of systemy stuff, right? That comes over here. Things that are not even like core language things, but I still have glyphs, execute, format, spawn a thread, system calls to the IBM, the variant thing that changes the behavior of things, input, output assignments that which behave in the assignments, not just assignments, like that's like the simplest concept you can have in a in a programming language. But think about APL assignments. You've got modified assignments, multiple assignments, function assignments, operator assignments, localizing assignments in in defense, which you can override depending on what's on the left. Pass-through values, multi-name left side with a function that has implied each. There's so much stuff to know about assignment. A diamond now fulfills multiple roles, guards in defense, and control structures and stuff like that, and and what is and the and function definitions and uh and other things you do in in a treadfin and a defen, and hash is for namespace references, and then comes arrays. Now, here's not for for complication reasons, right? So I put all arrays and identifiers and so on at the end. That's not because they're more complicated, it's because I wanted that sort order in in for C decreasions in in Apple Cards. The primitives come before name things. But this is like this was my sort of take on a rough without any nuance ordering of the dialect primitives. And of course, you'll disagree with it. I can disagree with it. It's sort of rough like that. But if you now want to give them belts, you have got how got to put some arbitrary cutoffs between them. Yeah, go for it. No nuance. That's what it is. This is what happens if you get no nuance. Well we And this is just for APL, dialogue APL specifically. Now you add splitting monetic dietic, splitting all kinds of overloads, splitting up with argument ranks and depth and values, and multiple array languages, you've got so much nuance. It's like Well, I mean we before we move on from uh uh Madeline pointed out that uh the exclamation mark and the oh I tried to zoom in and uh it's a very minor thing, but yes, the distance between the the dot and the rest of the symbol in the exclamation point and and question mark are different. Also the height of the symbols is a bit different. It's a bit funny. I would say that the the actual problem here is the exclamation point. No, the question marks are sort of loopy part is. Too too low, it should just be higher up in general. Potato, this is minor. This is very much a tangent.

Conor

Yeah, I mean I'm torn because I really do think that there it's possible to have a thing like this and a thing like that, this being the APL dojo where you've got a nice little tiered ranking. You know, a linear list of this doesn't. I mean, maybe I guess if you want to learn, you can start just by going primitive by primitive by primitive.

Adam

But I don't think it's a good idea either. Because because I I like to put my students in APL in a position of being able to do something fun really quickly. So I want to teach them sure range duration on it. That that's fine. Then I want to teach them maybe some uh some reductions and some arithmetic, and all of a sudden they can now compute things like Pascal Triangle type things and and and uh the number of sugar cubes in a pyramid of of sugar cubes and things like that. So there's also like what should you be learning next? And I think I I I have taken very, very little art martial arts. I started going to an Aikido course uh long time ago when I was in high school, and I hurt my shoulder and I didn't want to continue. And there's just a couple of lessons, I think. And then I I I took like a uh a month long, but it wasn't full time, it was like 10 hours a week or something. Course on Balinese martial arts, I don't remember what it was called. So there was nothing about belts, not even getting to any any belts or anything. But even there, I would imagine that you you would take some more difficult concepts and put together with some some simpler moves so that you can actually do something. If you do all the simplest things, it's just the wiggle one finger, wiggle the wiggle the next finger, it gets very boring very quickly. But what this might be able to we might be able to do is to say if somebody's struggling, right? There's they're self-studying APL, and then they're they're they're dealing with dyadic transpose, and they think, why m is my brain not catching this? Getting the reassurance that yeah, this is hard. We know this is hard. It might help.

Conor

Yeah, like I said, that's I mean fits with the thing of like saying I'm at this level, what are the concepts or things above that I should uh learn? Like the goal of this is isn't like I I want to have a certain amount of, like I said, granularity so that you're able to represent.

Adam

Yeah, but I don't know, maybe maybe the rank is Are you uh are you aware of the AppleCart quiz? You ever seen that? No. So try if you go to AppleCart for a moment. So it does a link at the bottom center where you can write click on quiz. And there are these three different types of quizzes you that you can do, right? It doesn't check your answer or anything, it just lets you in your head try to, or paper, whatever, solve something, and then you can check it with your see the see the result and then continue. But notice the first one of these, which is always writing a function of a given task, it says how difficult it is. It solves the following medium difficulty task. And that so there you have a sort of granularity of how difficult is the task as a whole. How did I do that? It's I if I remember right, it's been a long time. It looks at the it does a weighted sum, right? So we we it looks at the primitives necessary to solve this because it's just using the Apple card table, and then it looks at the position of the symbols in that list that you saw before of the primitives, difficulty, and sums them up. That means more primitives, more difficult. More primitives that peer further to the right in the in that list, more difficult. So the simplest thing is to have something on the uh on the far left, a single thing from the far left, and then it just grades it into those three different levels easy, medium, and hard. So I did some arbitrary cutoff, probably like the one-third and two-third cutoffs between the easiest and the hardest, something like that. So there is I think I agree with you that is a way that it's possible to say that something is harder than something else, but I'm not sure how much value there is in saying that this is Jake, this is the level you're at, these are the primitives you should study. Sorry, sorry, Fanny. No, no, we're getting we're getting down, yeah.

Conor

We're getting lost in the like, well, first of all, this is just I mean, it's gray. There's a reason why a rake a rake box, if we uh oh that's not correct, delete, and we zoom out here. I mean, if we hit F5, you know, I got this nice little animation now. You click this, people under, or I don't know, everyone's different one. Maybe some people like gray websites, but people I really value logos, color, and the aesthetic of things, you know? It brings me so much joy to hit control K and then to go control down and to toggle through all these keyboards. And and like color is color is so important, it at least for me. Like when I was doing the Wait, so are you are you commenting now on the colors in that book card rather than that everything is gray? I'm gonna learn something or deal with something. Like I go to a ray box all the time now. I want it to I want it to be a pleasant like visual and like all all all above. The the quiz, it hurts my soul. It looks like it looks like something died. You know? It looks like uh the you know, or at least something inside me died. Whereas even if this is less, we got a little color, we got some logos, we gotta have logos. That's why K, you know, K would already be included if K had a logo. And that's the problem, is I gotta come up with my own logo. I don't want to come up with a logo. And uh logo for APL then. And uh and I there was a bug in J that this was not being syntax highlighted correctly. And I realized because this was like blue and this was orange, and I was like, wait, what's going on anyway? So and then I went and got and fixed it.

Adam

You have to tokenize it.

Conor

And but that's the thing, is it it's a lot easier to read J when you've got syntax highlighting of you know the operators and the functions, and anyway, so you could have multiple multiple things of the same.

Adam

We're we're way off topic from what we discussed before, but in even in J, you can have multiple tokens of the same type adjacent to each other, and you can't see the borders. For me, the big problem with J is the tokenization, it just blurs in my mind. Maybe maybe a uh a clever ligature font could fix it to like sort of move the things together so you get a little space, or it's much easier for me to read J that has spaces between the primitives, between the tokens in APL. I don't like that. Yeah, yeah, that's fair enough. I know I don't understand why, but like when people write verbose proper light languages like C and Python, JavaScript, and so on, they put spaces everywhere, and I don't get it. It's already so verbose, so little information on the screen. Why do you add more spacing? But but maybe also because those languages have multi-character tokens, right? So the spaces help you sort of tokenize, whereas in array languages that use fancy glyphs and and in K, you you barely need that. There are very, very few multi-character tokens in those array languages. Yeah, yeah, I mean that's a separate issue. Um the syntax colouring, it might it might be more useful if every other token had a different color. I but and I guess if you're not so used to the language, the the syntactic role of any given token is not so obvious to you, but once you're used to that, it doesn't really add much. I know Martin Kronberg says syntax coloring doesn't really do much for him.

Conor

I mean there are some things.

Adam

Everybody's different, but like you can't for some there's some utility things that I that I agree on. Like I would I would I mean I do have that. Uh in when you're dealing with trade difference in the APL, then there's a big difference whether your your names are localized or not. And having a different color or some indication of whether something's local or global, that is genuinely useful. Maybe the syntactic type of of user-defined names would be useful for me. But the primitives, whatever. Anyway, we can add color to AppleCart if you want, or I'll do a lot of things.

Conor

That's the website again. The the goal here, I mean, we're we're so we're so lost in the sauce here. I mean, this is this is uh uh not a failure, but you know, we we shot for the stars and we landed in a dumpster. Like the the the the goal is that, or at least for me, like I had this vision of like a board that you know it's not it's it's not that oh this is the go-to place for people to learn languages or you know, the I I want to get into array languages, you know, you start at white and then you work your way up. It's more of just like I'm hoping that you know you and others that are more expert can put things here that like I can target as like you know, for for instance, you know, I don't know if this is a concept or an expression or a technique, I guess it would be a technique, but it's like you know, a dyadic reduce. You know, you want to apply a dyadic function on two arguments, but you know, it's in the form of a list. So you you you know, it's like it's like the idea of outer product, you know. Yeah, yeah, but for rank.

Adam

So so so I think I think that one of the reasons why we end up in the dumpster shooting for the stars here is is exactly that shooting for the stars. Like try to reach the moon first. What I mean by that is we're trying to do all the array languages at the same time. We're trying to look at all the different possibilities of these primitives. One thing I sort of liked, sort of don't like, about the Weewa's website or documentation is it seems to sort of say that the highest rank is two. I know it's not the case, but if you pretend that the highest rank is two, then then instead of you first axis, last axis, this kind of thing, then it's just you know the rows and columns, it's easy. So I think if you remove nuance in a different way here, firstly, I would recommend starting with one language, you can always add it later because things get really complicated when there are new differences between the languages. And then maybe start with going through just the primitives, maybe start even with the primitive functions, just have a starting ground for like how difficult things are. And when you start with the functions, okay, split them in monadic, dyadic, that's fine. But assume that the arguments are of the smallest rank and depth that is reasonably meaningful for that primitive. So for example, dyadic transpose doesn't make sense on a vector write argument, but dadic and dyadic transpose doesn't make sense on a matrix right argument either. It only makes sense on rank three and more, right? Because, well, except if you're having duplicate left argument uh elements for the left argument, so you're already some some new answer. But assuming that the simplest application of dyadic transpose is when the left argument is a permutation without duplicates, right? So then it's much easier to speak about things. Then we know dyadic transpose is talking about vector left argument in in APL's case where there's it has to be a vector, so vector left argument, rank three right argument, and then it's way up there in the black belt, right? For for plus, even just one plus one, right? That's that's meaningful. Is that probably the most common case use of plus is just adding a scalar to another scalar that goes down in white. Yes, there's a lot more nuance to plus because there's scale extension, there is the uh array application, there is pervasiveness, right? There's and for some languages you got the leading axis, conformity, and bracket axis, and there's lots of stuff. But in the simplest case, one plus one is very simple, it goes in the white belt. Yeah, then build it up from there. Then we can always add more new ones, but start small, start with a minimal variable product where you say these are the primitives and their simplest forms. This is how you grade them, and then maybe maybe you even have like function black belt, right? Primitive function black belt on symbols form, and maybe there's like advanced function application where you later where you say, like, okay, these primitives actually can do a lot more, and then you get like separate build for that, or then you can start adjusting, like move everything down to just green and white, or something like that. Then you can do the nuance later. But I think if you start with that, you actually have a chance of getting somewhere that's that has some meaningful information to the reader. Uh I know you want to do everything, right?

Conor

But it's not that I want to give everything, but just like starting with one plus one is boring.

Adam

You don't have to start with one plus one. That's boring, yeah. So, but starting with IOTA on just an a scalar right argument, that's right. That's what we did start with. It was right here. Yes, yeah, yeah, sure. But it's but you're trying to fill out all the like to cover everything. You have the little badger in the corner saying it's a good one.

Conor

I'm just trying to cover everything.

Adam

I'm trying to create so so so if for so now we can go in and if you want to look at operators, I would recommend staying with functions just to get to get used to the process of assigning belts to the functions. So now we go through the language bar, whatever list of primitives, and just do the functions and just look at each one, what are their simple applications? That's what I would recommend, just as a starting point. So, sure, you can skip the arithmetic, but where would you put, for example, monadic circle, right? Monetic circle, I would say, is very simple. In its simplest form, it takes a scalar, right, argument number, and it just multiplies by pi, right? So pi is a bit of an interesting number, but it it's not a complicated concept, right? That is just multiplies by a constant. So I would probably put that on white or maybe one level up from white, but definitely not more than that. The fact that it's a scalar function that it can do all these stuff, right? Uh forget that for the moment. And then you can do the domino, monetic domino, right? So that's it's not a difficult thing from an APL perspective, as in like it takes a matrix and it returns a matrix, sort of similar to transpose. However, it does something that's mathematically difficult. So now this by by limiting our scope like this to something quite simple, now we get to actual questions that we need to ask ourselves. Do we look at things that are the difficulty of things from an array programming perspective or even from a concept perspective? Like N choose K, right? It's a scalar function APL that makes it very simple. But mathematically, it's sort of a more advanced thing, you don't really learn in in basic school. So do you want to grade that as well? Is it the APL part? Is it everything? Those are the questions you want to ask instead of getting into nitty-gritty nuance details, in my opinion.

Conor

I mean, I've used this once in seven years, and I've never used the circle function ever.

Adam

Yeah, but that depends what you're doing. If you're doing graphics, like somebody's writing basically a a Minecraft clone in APL, you want to use the circle function, right? You want to you have to determine what is the how far are things in in two dimensions or three dimensions from you. You need you have an angle and you need to know you need to know how many blocks this way and that way is it? How far can you throw in that direction? You need the circle function. And if you are trying to solve constraints or doing like a nicely ragged adjustment of text on each line in monospace at least or something, then or even not, then you need you need the domino function. Yeah, I guess this is there should be it very much depends on your on your domain.

Conor

Well, I guess we're just doing APL now.

Adam

That's that's also what I recommend is that like limiting the scope I think will get you a long way. I mean that that depends depends on the other question, right? But that's a fairly easily to resolve question. Do we take concept non-APL conceptual complexity into the picture or not? Like are you only interested in the difficulty of understanding array programming, or are you also interested in the actual concept involved? I don't know. I don't know. That's that's that's that's just a design choice. Is this this is this the the beltness of APL ness or is this the belt level of the everything in the in the primitive? So if it's just in the in the APL nest, then all scalar functions go down in the simple this on the same level. There should be no difference between n choose k and plus or minus, because they're but just scalar functions. There should be no difference between LCM and G C D and multiplication, even though there is a huge difference in the actual knowledge and the standing here to to uh to employ them.

Conor

Okay, updated APL dojo with my death skulls.

Adam

It has failed. It's not it's not dead. You just have there's some choices that need to be made. What is it and if you don't write user story first, what is it you want to to who's your target audience? What did you want to achieve for that target audience? The target audience was me. So okay, that's fine. That's valid. So if your target is you, right, that means you're already very familiar with programming concepts. That means that reduce is a pretty easy thing for you to understand, right? Or map, right, and each. But for somebody who is not familiar with that kind of thing, or if they are not familiar with higher order functions because they only program in C or something, then then that's more complicated. But if you're the target audience, that's much easier.

Conor

Yeah, I don't know. I think if you convince me though that it just doesn't work. No, I don't want you to think.

Adam

So so Loki is is suggesting something completely different. That it's more of a course indicator, saying, well, white build means learn this stuff first. Basically, you have to decide on a lesson plan. And that's something I've done. I don't know if you've looked at lately at the APL challenge. APL challenge I've tried to make really pedagogical, where we start you start with no knowledge necessary other than basic school mathematics, plus plus minus times, basically, is all I required to know, and the and the alphabet. So and then we build up from there. In that case, you say, okay, if I'm teaching somebody, and again, there's a question of who's the technologist. So obviously it doesn't make sense to say if I'm teaching Connor today APL, because you already know. But if I was teaching Connor seven years ago APL, what would be the first things he should learn? And they would put that on the white level. Then what would I teach him next on the green level? What would I teach him next on the blue level? That's a whole different thing. That's not a question of how difficult they are, but just of a pedagogically worked out lesson plan. But that probably corresponds more to the belts of martial arts, right? They don't say, oh, if a black belt means you're doing something more complicated. That just means more experience, you've learned more. It's like complexity. This is really the crux of it, I would say. Who's the target audience and what are you trying to do for that target audience? And then it's not dead, then you then you can do it.

Conor

Yeah, Max. I mean, that's the problem, is that everybody there's a billion ways you can look at a thing like this. People mentioning teaching basics, Max is mentioning frequency of glyph usage and existing coding problems.

Adam

But that doesn't mean that they're simple. That's just that's a different thing. Then it's color-coded frequency analysis. That's that's something else. It's also interesting to know how often primitives are used.

Conor

But I yeah, I don't think Max, I think I'm more in line with what Max is thinking, though. It's that like, you know, I have you know, we can what what was the last one we we were trying to add here? Is like matrix inversion. It's like I said, like I've used this once. And yeah, that's my personal experience, but like this rarely comes to the case.

Adam

So that's like build, right?

Conor

You can basically remove it from APL and nobody would cry. Nobody would uh if you remove this versus like reduce, like obviously reduce is a bread and butter thing versus matrix inversion. And I mean, how many APLs actually have like BQN doesn't have it?

Adam

What matrix inversion? Yeah, I don't ever every proper APL will have it because it's it's standard, it's been there since almost day one. It was I mean BQN's an APL and it doesn't have it. Okay, but that's the question of the definition of APL. Anything that I would say has the label APL, has the name APL, will have it essentially, because it's part of the standard. There's an APL standard, the ISO standard. And if you if you even if you like adhere somewhat to that standard, you'll have it because this is breaking news.

Conor

Adam declares BQN not an APL. No, no, I'm not saying that. But you just did say that.

Adam

You said every APL that no APL that has the APL label, right? BQN doesn't say that that it is just an an APL dialect, right? It's an A it's an APL, yeah, it does say it's an APL for a flying saucer. What's gonna say? Doesn't it say it's like a modern APL? Yeah, it's like but it's there's some pretty radical differences too. So it's it's an it's another we can do a whole episode on what is an APL, and we've had the question of what is an IVS and Yan language, so on. So I tend to go by by something like APL wiki's definition, which which is basically that it's recognizably something like APL 360 superset or something like that. At least the basic glyphs are the same as in as in good old APL and and the RAI model and so on. As soon as you depart that would make make J not an APL, right? Others would argue APJ is an APL, it's just a matter of spelling. And of course, if you took APL as is and replaced every glyph with some keyword, then is it still APL? Are you according to the APL wiki definition? No, it's not an APL. Madeleine's saying that APL wiki has an APL dialect category. Yeah. And DQN is not in that list. It has the it does there's a there's some text in in the APL wiki on what is APL. It's an interesting question, but it's a whole different question, right? So that's why like it's amazing this uh vibe coding, don't get me wrong, you can do beautiful looking things in short time, but you still have to have the human asking themselves, okay, what is what am I actually trying to do here? And I'm not shooting this down, I don't mean to kill this. I think it's a cool idea. This has nothing to do with vibe coding versus humans. I mean, uh humans. No, no, no, but no, the vibe coding makes it very easy to go from zero to something in no time, but you need to you still need to to take a step back and think, okay, what am what am I actually doing here? Is the ABL dojo? We're gonna grade the primitives and the expressions and the concepts and the other thing. But I really push back on that.

Conor

I think the problem here is that we've just decided to drown in nuance and like at a certain point.

Adam

What kind of nuance are we do you want to get rid of? I'm all for removing the nuance, otherwise you can't put things into five categories, right? But what kind of nuance are you getting do you want to get rid of? Or and what kind of grading or what is weird grading? What does it mean, difficulty? Is it difficulty again? Uh LCM, right? And GCD, they are not syntactically difficult. From an APL perspective, they are just uh scalar functions. They're even simple in the sense that for for most APLs that they only exist in daddy form, so there's not even the monadic daddy duality there. Very simple functions. Do you actually understand L LCM and G C D like mathematically? It requires a whole lot of number theory and prime numbers and stuff like that. So does that make the primitives more complicated? From an APL perspective, and how I usually teach APL is they're not complicated. Because what I will do is I'll teach people some representative functions for very and for operators and so on from the various categories, syntactic categories, and then I tell them, okay, now you basically know all of APL. You just need to expand your vocabulary. It's like learning a new language. So learning the pronunciation and learning the the writing system and learning the grammar and so on, those are those are hard things. But learning another word, even if it's a long, complicated word, that's fairly simple. Even if the word stands for something that's incredibly difficult to understand, acquiring that one more word in the language isn't really hard. Just understanding the concept is hard, but syntactically you can use it. So you can use quantum physics correctly in a sentence. But do you actually understand quantum physics? So if you were to grade English compound nouns in a list of dip by difficulty, why where do you grade quantum physics? It's not a it's not hard to spell, it's not no complicated pronunciations or anything, it's a fairly simple phrase of two words. But understanding what it stands for is much harder. Same thing here. The and symbol. Syntactically, it's straightforward. The symbol is not hard. And the how it behaves with data, very simple. What it does, that's complicated. What is it that we're grading here? That's all I'm asking. I'm just trying to shoot this down. We have some fun stuff going on in the chat here.

Conor

Yeah, I mean, I agree with Madeline earlier in the chat when she said that teaching is all about nuance. I mean, I completely agree. There's a reason why I'm trying to build the whatever bells and whistles in the panel, and the same thing with the comparison mode and array box. But like it's like when I was talking with Ben Dean on ADSP about how you know teaching is just a series of lying to you less, you know, you omit stuff. Because right now, like, you know, and that's the thing is you're saying, what are we trying to do here? I have a very clear understanding of what I want to do. It's that other people have different ideas of is this a pedagogical teaching tool? Is this for beginners? Is this for someone that knows whatever?

Adam

But like I don't disagree with you, Connor. I'm just trying to pull the information out of you. What is that thing you have in your head? Because it's not clear to me what you're trying to achieve. I asked you before.

Conor

And it was very clear.

Adam

You said it multiple times.

Conor

It's that I want this to be a thing where people can look at and say, I'm roughly at this level. Here are some concepts that are like currently I have not like learned or put in my tool belt. Because in general, like my experience in learning the array languages is that some things are just obvious. And yes, that is informed by your experience and what are the programming languages you've learned. It's going to be different for every single person. I understand all that. I'm not trying to ignore that someone learned Python or someone doesn't know any programming or someone is good at math or isn't good at math. Everybody's experience is different. But in general, you pick up certain primitives, certain tools, certain concepts. Like I said, for me, I learned two, comma slash. I didn't realize that could generalize. And like having like N-wise reduction as a thing that like you could look at in a tool, and like there's a ton of these, and they are they exist in different array languages. But it seems like, you know, when we have this discussion, it's very quickly just like, oh, well, if you talk about IOTA, we got to talk about you know the 17 different flavors of IOTA. There's rank zero, there's rank one, it's different between jades, and it's just like, okay, well, then the tool can't exist because there's just too much nuance. And like, yes, we can drown in nuance, but like in general, depending on the tasks that you're doing, and that's the thing, is I have to say, depending on the task, because the tasks that I'm doing are different than the tasks that the graphics programming are doing, like, there in general are a set of primitives and techniques that you reach for on average more than others. And like the goal is to try and like put those on a kind of star map or a tier list that can expose them to people sooner rather than later. The fact that, you know, prefixes is available in Wiwa in the tuples primitive, like if you have a prefix concept and then you can, you know, hover over it and it shows that you know it's spellable a certain different ways. Anyways, it like, but I I I just feels like this kind of thing and it honestly it makes if yeah, I don't know. If this is the way that the conversation happens when you try to build a tool like this, that you have to either evaporate all nuance and just get a linear list of primitives, or it's too complicated. Like it's it's unsurprising that so many people bounce off of these languages because it's just like there is an easy path where you like over time learn things and you pick up a new thing, but it's just it feels like in trying to do this, it's just like, oh well.

Adam

I think I I think that's there isn't one path. I think there are many paths, and then it's more like what Loka was saying, like, okay, so this is a course material, but then you have to choose your way, your path in. And I think that depends a lot on the person. It doesn't happen so much anymore, maybe because I'm not around so much. But usually when I see a new face, new avatar in the APL orchard, then I ask them, hey, interest in APL. And then sometimes it's somebody that doesn't know about APL, only heard about it, something, and sometimes I offer them like an intro course or even a full course in APL in the chat. And I usually my my the first thing I do is I I ask them if politely if they will tell a little bit about themselves because their background, whether they have programming background and which language is their programming language uh experience with, if any, their their knowledge and interest makes a huge difference to how I would approach them. So somebody who is like a mathematician and all and and into like theoretical things, so I have a very different approach to somebody who is a programmer. If somebody is a child that doesn't know a little whole lot of mathematics, then they'll try to avoid the mathematical things and and so on. So I it I think it depends a lot on the audience, and it's fair enough to say, okay, we imagine Connor, or maybe imagine Connor seven years ago, what would have been the best thing for you? And that's fine, just like Stefan Kruger wrote his book saying that this is the book that he wished would have been there for himself when he started learning. And there will be other people who are in a similar position to him, and it'll be useful for them. And I don't think it's a bad thing to have the Connor's APL dojo, and and for people who are sort of similar to where you were seven years ago, they would come in and see, okay, she learned these things and these things, and then it becomes sort of a course, and you get the belt, and when she's up to the black belt, and you can do a whole bunch of stuff. I think that's fine. I don't have a problem with that. As long as it's clear what we're trying to grade to grade, and then we can say, okay, Connor seven years ago, the war you're familiar with matrix inverses, right? No, yes, was it complicated? Could you pick it up? And then we grade it according to that. If you want to include all the concepts that APL includes. Because APL, as opposed to many programming languages, comes with a lot of it's not really the batteries includes included, but it's got a lot of, especially J has, and a lot of like mathematical things that that are included in the core language that you don't usually see including. There are no other real-world production series languages that have matrix inversion as a single glyph. That doesn't exist. There are those that have inner product as a as a single glyph. Yeah, so but that I think that's fine. I think it's perfectly valid to do this. Don't get me wrong. And if this is clear, yeah, let's go for it. But then the answer to every question as to how complex this is is asking you. Think about seven years ago, how difficult do you think this would have been for you? And think about this, how difficult would that be for you? And then you can put in the various concepts, you can leave out some things, you know, oh yeah, inwise reduced, two wise reduced. Yeah. Have you I never really got an answer to that. Have you looked at uh at the APL challenge lately? Yeah, I always do it. Okay. So so you there you have uh again, I don't have a talking audience uh that's a specific person, but I have in mind like kids, maybe like early teens or something like that, and trying to phrase it in such a way and build up level by level. And so there I don't teach all of APL, obviously. I teach so it's just some basics, and I try to make the tenth problem out of the 10 be a problem that is at least moderately interesting to do, where you do something that sort of looks nice or has a nice idea, concept. So for example, the the current one we build up to to determining whether a a square is a magic square. Sort of a cute thing to do. So you just learn learn just enough to be able to do that, but we get to dyadic transpose. Okay, so this is a from nothing course, a 10-step course that where where we end with dyadic transpose. So what happened? That black belt? No. You know by the end of this course, you know a fraction of APL. Tiny fraction. But you do know something about dyadic transpose, at least for a matrix.

Conor

Yeah, I mean there's a a bunch of different paths, tools, and stuff.

Adam

Yeah. I think they're all valid, and unless we can make some really clever AI that somebody is suggesting in the chat here as well, that can adapt to people automatically, maybe analyzing all the times that I've taught people APL in chat. I don't think it will actually work, but maybe because the problem is the AIs don't actually understand APL or any other programming language, so I'll venture to say.

Conor

That's actually not true anymore. I mean, it successfully wrote profiling for every single one of the six languages that I wrote that I that I have on these sites. Like it knows quad underscore measure is tiny APLs thing, it knows the system timed thing from BQN.

Adam

It's not it doesn't okay. Anyway, that's another discussion. There are lots of videos on YouTube, people discussing whether AI systems, LMS and so on, know anything, understand anything. That's not we don't have to take that discussion here. I doubt that it can be done well, but hey, maybe, maybe one day. So yeah, we can do this. Let's get let's get going. Let's start. We're 20 minutes past the hour and a half mark. That means we're almost okay, okay. Almost at the two-hour mark, then is how it's put it. Yeah, but I think this is potentially useful, right? We hashed out some of the issues that are involved in making something like this. We've narrowed down the scope of what is you're trying to do with it and and the and the goals and what we're not trying to do, right? You can't be comprehensive, we can't do everything. Yeah, I think it would be useful to not. I mean, I I know you like the color, but I think that itself is a barrier to have all this colour-coded and information. If I come to this as a complete new B, it's hard for me to put myself into the shoes of somebody completely new to APL, but I do tend to do it a lot because I teach people, right? This would be very overwhelming. Even what I'm seeing just here is already like, whoa, what are all these things? I think just some some much more neutral things that even with just the name that I can read, because I don't even know how to pronounce any of this. I can't refer to the to the right tech, because I don't know how to say right tech.

Conor

So, so I think But like well, like I said, this is not designed for begin it's designed for me, you know?

Adam

Yeah, yeah, I understand. So that's that that's the thing. But even for you, you didn't know all the glyphs either. Even though you had now I've heard you in the various parts of the city.

Conor

You keep referring to the seven-year version of me. Like it's not designed for seven-year version of me. It hopefully is useful to that, but it's designed for me, like me now. The guy now, but you okay.

Adam

Like, but but right now you're pretty high up in your belts, right? No, I think I'm blue.

Conor

I think I'm blue.

Adam

Yeah, that's it.

Conor

I'm like, there's a bunch of stuff up here that I don't know, and the goal was to kind of fill this stuff out, and it's like, what is okay useful for someone here or someone here? Like, yes, I didn't know NWE reductions at one point, and so I was green at one point, and I was white. It's supposed to be useful for a bunch of people, but like honestly, selfishly, the same reason that I I built a Ray Box, if we can iterate over here, the reason I bought this built this was for me. Yes, other people can find it useful, hopefully. But like I wanted a nicer tiny Apple cap REPL, and like the main thing is when I make YouTube videos and things and I'm switch, I'm always switching, and it's such a pain. And like the docs are all over the place. Like for some languages, they you know, it's easy accessible, other ones. So I've always got like 20 different tabs open. I've got four different repls, and I I can't remember all the ways to type the glyphs. And so now I have a super easy way that I can you know flip through these. It's got a certain amount of like primitive translation. If I forget something, I can look at the keyboard. If I know the name, I can just like control space. Like it's a tool I built for myself. A ton of people would probably argue it's hard to use. Where's the help? You know what? If you hit F5 for 10 seconds, it shows you how to get the keyboard, how to get the help. You know what? It's not designed for like a hundred percent of everyone that hits this is gonna get it find it the most useful. It's for me, and I want it to be beautiful, and like it, it's it's also like primarily keyboard driven. It's not designed to be used with the most. If you if you bring the keyboard up, you can't really click. And I think that was a thing that like you asked for at one point. I designed this for me, and hopefully other people find it useful, and it's open for PRs. Like, there was someone who, you know, they contributed. I think it's I know I know it's been merged, but I think it'll work if we do this. If you hover over this, you know, someone contributed this. They were just like, oh, you know, this is kind of like BQN. I'm happy to accept contributions as long as it doesn't like ruin my design. But the point being is this is a thing that I'm designing for myself and then putting out into the world that hopefully other people will find useful. But if no one else finds it useful, it's still a win for me because this is how I primarily use stuff. That's the same goal for APL Dojo. I'm not thinking about the beginner, I'm not thinking about you know a hundred other flavors.

Adam

I'm not actually We're sort of I don't know if we're running out of time. I've got time, but it's but at some point we want to draw a line. Yeah, yeah. Let me throw out just as an ex some examples, because because if this is really for Connor, to know like if you want to get better at these languages, what are you likely missing? Right? You've been going on APL for seven years, which means you have picked up some advanced stuff and some things you've probably completely neglected, often because the type of things you do, if you excuse the phrase, toy problems, you don't touch so much on certain more everyday business type things, or maybe you don't do so much advanced math, so you don't touch on those things. So it's sort of hard for me to know, of course, which things you have not you have not seen. But let me throw some things out at you that you might not have done.

Conor

I mean, that was supposed to be the goal of the APL Tojo is that like you don't know what you don't know, and then every once exactly you run into like an N-Wise reduction, and you're like, it is for a lot of people, or at least it was for me, when I discovered the NWISE reduction, it was the first time I encountered like windowing algorithms in any programming language, and it blew my mind. Same thing with outer product, like outer product, first time I encountered it was in APL. Yes, Haskell has an outer product function in some library, but like a ton of the algorithm like ideas and techniques I discovered in APL, that is essentially what it's for. It's not for exhaustively listing out the primitives. Like the reason that IOTA's here is because it's like, I don't know, a bread and butter amazing. Like again, ideally, this is fleshed out with like the most coolest, you know, like unkeep from Weewa, which is like run length and code and a bunch of those things that like people can at a glance hover their thing and be like, oh, that's cool. And also for me, you know, I'd like to be a black belt, but you know, uh this is supposed to be like a hack. And it would work better if we had the full panel of you know a bunch of different people from languages contributing the best techniques. But anyways, go ahead and throw out I can probably go for like 10 more.

Adam

Okay, I'll throw a couple of a couple of things at you just think off my head. Sometimes you want to normalize an array so that it's not a scalar. Are you familiar with one slash in APL?

Conor

One slash? No, but also too, I was kind of catching up on the chat, so I missed the first little something with a scalar.

Adam

Okay, so yeah, so sometimes you have you you want to normalize. You want if it's a high rank array, keep it the way it is. If it's a vector, keep it the way it is. If it's a scalar, you want to ravel it. You want to make it a one-element vector, so you have an axis to work on, right? So, how do you normalize an array to always be at least rank one? You can do that in the APL with one slash. That's a cool technique. You might not have realized. It's just a just an example of I definitely didn't know this. So okay, so this doesn't it's a no-up for every array except a scalar. For a scalar, it does a revel on it. So it's like revel if scalar. Yeah, okay. So we need to so what is this? It's a monadic function expression. It's it's not a function at all. It's a snippet. You can you could wrap it to become a function, but it's yeah, it's because expression, yeah. I mean it's a manadic. Oh, then that's there's a there's a bug here in the dojo. But it only primitives can be have that subtype, right? Expressions and concepts don't have subtypes.

Conor

No, I added this so that it would you you were the one that pointed this out when I sent you. It's that like, oh, these have derived erity, right? This is a manadic function.

Adam

Yeah, but this one does this one doesn't. It's not a monadic function at all. It's just a snippet. It doesn't have you can't assign in the in dialogue APL, you cannot assign this a name. It's not a valid syntactic construct, it's just a snippet. It's a technique if you want, or an expression. It doesn't have a value. If you enter this into the REPL, it will error. But you're applying this monadically, correct? No. Yeah. The point is specifically replicate with a scalar one as left argument, right? So the way I write it in Apple card, I would write one jot slash, but you don't actually want to ever write the jot.

Conor

So but I'm I'm confused though. But we did not just apply this.

Adam

It's a technique, right? No, this is dyadic slash. One slash is not a thing, it's dyadic slash slash is a function. It's applied with one as left argument and IOTA six as right argument. But it's a technique, it's a it's a tool in your toolbox to write. Oh, I need to normalize this so it's always has at least one axis, one slash.

Conor

I mean, this is what I mean. This is what I mean by drowning in nuance. So like the point that you're making, your point that you're making is that like this is a valid expression.

Adam

Yeah, sure. This is a valid function, right? A divided function, one jot slash. But that doesn't matter. I wasn't even trying to argue with the with the denimization in in in the APL Georgia. I was actually trying to give you a useful tool in your toolbox that you might not have known about. It doesn't matter how you ever you categorize it, it's up to you. In uh tiny APL and in some other in K and so on, it would it would be considered a monadic function, the monadic derived function, I guess. That doesn't categorize it as you want. Okay. It's a useful thing. Are you sometimes you yeah, sure, put it like that. That's but that's not yeah, okay. It just doesn't describe what it does. It's just a symbol, but yeah, that's fine. Yeah, you have to grade it. Okay. Good. Are you familiar with how to count if you have a Boolean vector to count the number of trailing ones? Like the tail end, how many ones are there at the tail? You ever seen that? I've seen you do it once, like I could solve it. Yeah, up up tech commute up self if you want. Oh yeah, this one. Yeah, and then you like one zero, yeah, whatever, it doesn't matter. Yeah, so this gives four. This is a nice tool in your toolbox. It doesn't have a name as such. And special maybe. And you you're you're you're aware of dadic transpose with all one all the index origin left argument, right? Gives you the diagonal. It's completely nothing to do with this one. I'm just giving another another one that's like something that that to put in your a tool in your belt. So sorry, I'm just going too fast. So this is a monetic function. It's not a primitive, but it is monetic function.

Conor

Yeah.

Adam

So so for for a matrix especially, one one jot transpose. This one you're familiar with? You should be if you've done the APL challenge. So it on a so one one jot transpose on you don't actually need the jot normally, but if you want to make it a function, then yes. On a m on a matrix, it gives you the diagonal. Yeah, I definitely didn't know that. Okay. You didn't know that's nice, that's the diagonal of a matrix. That's how you do it. Okay, here's another one. If you got a positive number, you want to split it into the integral part and the fractional part, you can write one zero jot encode. You ever seen that?

Conor

One zero jot.

Adam

You don't actually again you don't need the jot, but yeah, just to make it a function. Yeah, so you write one two three one two three point four five six. You split it. Sorry, this was wrong. Did I say it wrong? Zero zero one. I'm sorry. Zero one in yeah. So it splits it into the integer part and the fractional part. That's sort of a nice thing to do.

Conor

Is this just like a custom it it's not special, right?

Adam

It follows from the definition of encode, but it's a technique, it's a tool to have any tool belt. Like if you know this one, you're like, oh, I need to split this number into the whole part and the fractional part. Yeah, that's that's how you do it. Otherwise, you start with like, oh, the floor coordinated with, and then you know it's like the original number minus the floor. Yeah, but this is much easier to do it. And here's another one. Let's say you have a matrix and you want to rotate it 180 degrees, not flip it upside down. That's just a first axis reverse. You want to actually rotate it. So that's that's you do a rotate first, rotate last.

Conor

Yeah, I think that one I've seen. But that one just kind of makes sense, right?

Adam

Yeah, sure. But what about rotating 90 degrees left and right? Yeah, so this doesn't rotate, right? Up sorry, upside down. But if you want to rotate 90 degrees, you've got, for example, last axis reverse, transpose, that rotates clockwise, and clockwise and transpose, last axis reversed rotates counterclockwise. You could also spell them with in the opposite order with first axis reverse, that doesn't matter. But that's so the two different spellings of each one. So now you've got all the rotations of a matrix 90, 180, 270.

Conor

Yeah, that was covered in a challenge, wasn't it?

Adam

Maybe. Yeah, that kind of thing, right? So you've got all the rotations. So those are those are things I would say, those are good techniques to know.

Conor

Yeah, how do we classify those though?

Adam

I mean, they you get they are just they're just two trains, right? So you could just take them and put them in. Exactly. So that's that's so so there's rotations, right? The rotations of a matrix. Rotations and and yeah. Call it a concept. Yeah, matrix rotations, sure. Another thing, here's another different thing that like is good to know. Like basically all the entries in the in Apple card you could take. Like, what about an identity matrix? What's the best or fast way or whatever to make an identity matrix? That's a thing that's you should learn. So you don't sit there and try to piece it together.

Conor

Yeah, I guess that would be depends on where outer product would go.

Adam

And where the combination is. But that's not a good way to make it really, it's not a good way to make a an identity matrix because it using an outer product selfie of an IOTA range, right, makes a giant number, right? It's the n squared number of come of comparisons for no use whatsoever when you already know what values are gonna go in there. So what's better is to to do a one followed by n zeros and then reshape that into n by n, right? So like right, four, four, reshape zero, comma, four reshape one four, four reshape one, comma, four, reshape zero. Right? This is the better way to do it. Because here we're not computing anything, we're just reshaping. That's the fastest, you're just doing memory copying operations. There's nothing else the computer can do faster than this. And especially since we're using bit Boolean, it's gonna be right. It's literally just writing bits out in memory. That's that's the thing you should know if you didn't already. Yeah, exactly, like that. And there's an entry in Apple Card that looks something like that, right? Of course. It's comma comma selfie reshape one, comma, reshape jot zero if you want, but whatever. What is it tacitly? Yes, comma selfie, right? That that makes the omega omega. Reshape one, comma, uh reshape jot zero. It's a train. I like that. Switching the wrong tabs. There are other ways you can write it as well, but whatever. You could instead of the one comma and the V shape, you could do a and overtake, but whatever. There are different ways to do it. It doesn't really matter so much. But something like that, right? Is good to know. Okay, so these are all these are all things that I would say you should learn as an APL or you should just reach for immediately without really having to think about it. Um and then you can you can use those to build up, right? It really is like like Lego bricks. So an APL that had has a higher level built, they don't have to think for writing certain things. Like, for example, the average, right? If you give in the task as a new APL to write average, then you might need to sit sit and think about it. But you can you can do it in your sleep, right? You can wake you up in the middle of the night and say, How do you do average an APL, right? You're right. Plus slash bar divided by tally, done. But that's something that that is something you sort of have to know, right?

Conor

Yeah, maybe maybe the better way to do this than is just with idioms, basically, because this is what they are.

Adam

That's what I but we can go through something completely different, right? This was just some examples of some techniques, right? That that I would say you have to learn in order to become a black belt APLR. There's many, many are basically you have to know Apple cart, right? By heart to to uh to be a black belt APLR. But there are also also other things that you should know about. For example, how to use namespaces effectively. You ever use namespaces in APL?

Conor

Nope. I mean I've seen them used and I know what they are. And I've saw when we had TASA talk episode 30, you demoed a bunch of stuff, but uh right.

Adam

So now with version 20, and like there's a whole bunch of stuff that you should know. That is some that's essential. Being able to decide on on you how you structure your things. How about error trapping? I would say if you're writing a production system in APL, you better be able to trap any errors and deal with them and write and report that you send by email to your to yourself so that so you can go do something about it, right? And that don't have this the user system crash. So collecting information, pertinent information from from the system when it when it crashed and and and catching that and dealing with that. Have you ever used traditional functions in APL? I think I've written like one or two, but I forgot. So all the can I understand, but sometimes you need control structures to write something sanely, I would say. I know DQN shirts away from that, but you know, with the type of programming I do, I very often have like giant switch statements with loads of different things that I need to do or for loops and so on. So um that's something I would I would say you should you should know about. The even object-oriented programming in APL that occasionally is useful to use. Um if you've never never used that. For example, right, if you're writing some kind of some object that that represents some things, connection to some database or something, and the user can set all kinds of options, and you need to like normalize the settings that the user uses or check that they are valid. So they might be exposed as as as fields, but then you don't have a chance to check them until runtime. If you expose them as properties, then you have a getter and setter, as a setter that checks when the user assigns to them that the value they're trying to assign is actually valid. All those kinds of things. That's stuff you need. That's bread and butter for the applications programmer, but not for toy problems from lead code, of course. So there's a bunch of stuff there to learn. How to effectively use regex in APL. I don't know if you've ever used regex in APL at all. So so Max is saying in the in the chat that air trapping and transference are beyond Connor's use cases. But if the the question is, how does Connor become a black belt APL er, right? Then what does it mean black belt APL? In my mind, it means you could work as an APL consultant, right? One of those companies that use APL, they can say, hey, we have some code that needs to be worked on. Can you come in, have a look? It's running slow, can you make it faster? Or we need to implement some new functionality, and Connor is able to do that. That's I would say is a black belt. That's not my definition. Definitely not. So how do you define it?

Conor

I'm more interested in like the algorithmic ideas. Like all of these things, I mean, some of them are more idiomish than algorithmic, but like you know, like this is a great example of like every single time I ever spell an identity matrix, I use the outer product selfie iota.

Adam

It's just fine, it's easy to understand and explain, but you but you understand why this is better.

Conor

Yeah, this is this is really good to know, and I feel like I probably should have known by now. And also, too, uh, you know, going back and forth with Zima on Twitter over the weekend, he was talking about you know optimizations of bit arrays and and how the problem I was working on was a string of ones and zeros, and he immediately, his idea was to convert it to a bit array of integer ones and zeros. And that's not really something I think about because I'm not typically thinking about like performance-oriented APL programming or BQM programming or whatever array language. But then as soon as I start to profile things, you know, I I I am looking for that kind of stuff. And then, you know, Zyma, I think, is thinking that way like 100% of the time. He's always thinking, what's the way that I can make this run faster? And so, anyways, Max is absolutely correct that error trapping and trad funds and like going to trad funds and to to need control structures is like a limitation of dialogue, it's not necessary from a language point of view, right? And also, too, just like trad funds in my mind are much more difficult. Like the barrier to writing a trad fund is a lot higher than like a D fund because of the fact that you need like, what is it, a minimum of a couple lines to get the the deltas?

Adam

And uh I like I don't even know the syntax of the syntax of the that's just the syntactic thing. Okay, so so here's here's another thing you might like. You sometimes you want to do it like Lisp style, I guess, to take the first element and then all the remaining elements. And and that you can do with one one jot what is it called? Uh partition enclose or something.

Conor

One one jot partition enclosed.

Adam

Yeah. So if you were one one enclose or whatever, left shoe. No, no, no, that no, just a plain one, yeah. And then write like quote A B C D E or something like that. Alright, so it takes the first element as a vector, one element vector, and then the rest of the elements. I think that's pretty neat. Nice technique to have.

Conor

So that's interesting because like as soon as you mention this, um, my thought is that in cap um, and I guess you need pair.

Adam

Yeah. I guess this is one one drop and one, yeah, sure. But you this also this is not pair. You need you need comma wing club or something. Yeah. Does it have pair? Oh, it has pair, yeah. Oh, so yeah, so is that similar? It's not exactly the same, but yeah, it's similar enough, yeah. Sure. It's a technique, it depends on the language. It's a fairly recent extension we did to allow you to do this, but I found that useful on occasion. Here's another thing that's really useful that I've had to tell a customer about multiple times, and that is you these days uh you spell it comma square bracket iota 2 go square bracket.

Conor

Oh, that's comma square bracket iota 2.

Adam

Yeah. Well, you can't do it on a on a vector. You have to so the way you have to do it on a on a like a 345 reshape quad A or something. Yeah. So this merges the first two X's. So so if you don't have the have what I anything in front of the three, four, five, you get like a three three layers that are each four by five. And this merges all the layer bunches together all the layers into a single to a single matrix. You can't actually you can't see because of the boxing here, so it's hard to tell. But it doesn't if you turn on full boxing or something, you can I don't know if you have that. But if you if you do it on oh, I think you I think your output is missing spaces. Try try to stick a there's something there's something funny. Yeah, you can't do that. Try to stick a format in front of this. I'm not sure there's something wrong with the output. This is not okay. The it looks like your array box doesn't render empty lines in the output, which is a mistake.

Conor

Yeah, I think yeah there might be a bug because I stripped those at one point.

Adam

Yeah, that's about if you go to try APL you can see what's happening, or or just a open APL and one.

Conor

Oh OBS is that works slowing down the system.

Adam

Yeah, okay. So now if you write this, this is not gonna fit on the screen, yeah. Okay, okay. See now, so this has got three layers. Each one of the layers is three by a is four by five. And then if you do the the comma square bracket and iota two, close square bracket, then it will merge those two, the merge the leading two axes, and you can merge any number of x's by changing the two to to a higher number. So if you merge if you write IOTA three inside, you will merge all three axes, then it's just a normal rebel. So it's basically like a leading revel. That's a very useful thing to do. Another useful thing to do is so you so Max is saying you can spell what we just did with a rank, and I will challenge you to do so, at least without using transpose. So go for it, Max. You are here's another thing. If you got let's say you've got three matrices of the same shape, or no, or so even more common, you can try this. So write like open paren and like three, four, reshape quad A, for example, and then close the paren. And then open paren and two four reshape, say quad C quad A, just if you can see the difference, and then yeah, you can add one more just for good measure. So you can add open and then like uh four, four reshape quad D or something, so you can see the difference. Okay, so now so now we want to stack these. So you can see these are rows, right? These are collections of rows, and we want to merge them all into a single matrix. So, how would you do that? So the way you do it is disclose comma bar slash. Which is not the same thing as a mix. If you do a mix, then you end up with a three-dimensional array with padding, which and then you can't fix that. That's the split. And you need the the parentheses. See, that's not useful. And you can't even do anything to merge. Now you have to remove the rows, but you don't know which rows were inserted, so that's that's not what you need. Right? So that's the technique. Disclose, comma bar slash. Very useful tool to have in your toolbox. Join matrices.

Conor

Alright, last one. We've now set the record for the longest uh longest episode.

Adam

I mean, there's a ton more we can do, right? Well, but this is the one. No, no, no, it was good. It was necessary. I don't think it was necessary.

Conor

I don't think it was necessary. Even even the jot, you know, like this jot is like a beginner, you know, like, and technically in certain cases, it's necessary. Like I can't remember if it was you or someone made the comment that when I was building the comparison tables on a ray box. Uh what was this for? It was for a first, and you know, when I was doing this, and if you switch these to nested and nested, you know, initially I didn't have these at, which like I I understand that they're not valid expressions, but like, do we need to explain that?

Adam

I think I think they should be. I I'm in favor of making the well, I don't like the two trains being hooks in J, but I'm in favor of making what we call AF trains valid. So you can just but that's that's the difference.

Conor

Yeah, I don't I don't know. And like honestly, like this is what makes me really like cap's two-train model because there's no difference. Like I think it's such a such such a wart, or and maybe warts not the wrong word, such a I don't know the exact word, like deficiency is too strong, but like it is it is so nice in the cap two-train model that two juxtaposed functions are the same, uh parsed the same, you know, whether it's tacit or there is a argument on the right. And like the reason that I ended up adding these at is because I've set up a unit testing system in the background that like tests every single one of these expressions on input and expected output, so that like if I want, I can go and mess around with these to change them and then check, does it still give the correct result? And in order for that to work, you do need the way that I set it up, you do need these to actually be correct tacit expressions. But like I could you could argue that like you don't actually need these because you know, are people going to expect what?

Adam

Yeah, what are you saying is it would be a snippet.

Conor

It's a prefix of a non-tacit expression. Yeah, and that's like the the same thing here when we're talking about like, oh, this isn't a monadic function. You know, yes, I understand that like technically what you're saying is correct, but I don't think that like the jot not being there is detrimental to the understandability because like a lot of people that are beginners that don't understand that it doesn't parse as like a function are just gonna copy and paste this into whatever REPL they're using and then put another.

Adam

If they put it into an expression, that's fine. But if they try to give it a name to save it for next time, it will fail. And that's one of the reasons why I think we should allow saving that. I think you should allow, for example, like diagonal gets one one transpose and not have a jot. I think that would make that that makes it so much nicer. And we often speak about it, we often speak about some some function with a fixed left argument because the left argument is usually the control argument. So then so the the pairing of a left argument with a with a function often has its own meaning. And having to insert a jot there, I think is just unnecessary, especially since syntactically it's unnecessary. And there are a lot of entries in Apple cart that are of the form argument jot function. I think it's a pity that I have to do that. I think it would be much nicer if I didn't. But that's that be that as it may, however your notation for it is, that is that is there are we can stop here. There are a ton more of these like short snippets and things. Bunch of them are in AppleCart, of things that I think one should know as a black belt algorithmic APL er, even if you're not writing applications. I think there's so many things that you should be aware of. Some of it to do with quirks and language, some of it is just using primitives in ways you might not think. I'll give you I'll give you one more. Sorry, Connor, I'll give you one more. Let let's say if you uh if you go over to like array box or something, so you can play with this. So let's say we have we have some some phrase and so like a a a uh in text phrase, just easy sounds, like your name or something like that. I mean a dog, yeah, that's fine. Yeah, that's fine. Okay, should probably put single, yeah, single quotes like that. Okay, so you know how you can how you can remove all the vowels, right? So without and then a list of vowels. But it's the way around, but yeah, you need to do without. You can do a commute on it if you want. Yeah. And if you put uh if you put instead an intersection, then it finds all the vowels. Yeah. Right? So this now that is basically just a primitive. You put in commute, but you could just have reverse the arguments, of course. It would be the same thing. It's just a primitive, but I think a lot of people think of intersection as being just for sets, and in and this can actually be used for data extraction. So sometimes you have in in some kind of problem where they have some digits and they've got some letters in between, and you want to extract just the digits. So then you would write that. So if you if you remove everything to the left of the cursor right now, right, and you write one dog, so change a to a digit one, example. A to a digit one. And the second A, I changed A cat, change that to like three and cats. So let's say you have some some parsing problem with this, and you want to extract the digits that are in there. So at the end of the line of the expression, you just write intersection quad D. Now you could do whatever execute each or something like that to get the numbers, right? That's a that's a technique that I would say you should you should be familiar with. It might not be so obvious. Maybe it is obvious, it's just a primitive. There's nothing nothing special going on here. But these kind of things. And how do you write this?

Conor

This is I mean, there's the more complicated like one where you need to deal with juxtaposed digits. And yeah, Marshall has a thing in BQN just called ints or nats that is used for ads.

Adam

So we we can try that. If you if you write so if you get rid of the each here and the uh and after the quad D, yeah. After quad D, uh you can write commas quote space quote, for example. It's one way to do it. There are many ways to do it. Yeah, and now you can just do an execute on the whole thing. That presumes the digits are followed by spaces. No, it presumes that there's at least one space between all numbers. They can be anywhere. So even if you remove the space between one and dog and between chased and three and cats it will still work as long as there's at least one so no need each just execute if you want to get the numbers and you can we can do even better because you could actually you could take you could you could do there are things like quad v fi there are system functions you can use for this if you want maybe you call that not pure anymore but there are lots of like this also shows there's a whole area that you should know as a black belt AP other even if you're just doing algorithms there's a whole area of knowledge of of how do you extract easily the parts of the data that you want. So I'm not saying this is the right way to do it in a production system. Of course if there's no space between dog and chase this will fail but there are other ways you can do you can do this and that would that works nicely.

Conor

Right.

Adam

So if if you write qua yeah quad c open brand quad c quad a close brand quad v fi omega that will that will work no matter what's in between them that basically means sp split and convert it does the execute for you numbers separated by any numbers any letters want me to spell it out again no no no we'll stick we'll stick with this one we're now we're now past the two and a half hour mark we gotta yeah yeah we gotta go so so we're saying there are right there are there are things that are techniques like this this is what I so even if we say right you just want to be an algorithmic expert you gotta know these right you can't sit and spend time thinking about how to do this kind of thing that you just gotta know and there's so many more right we could do a whole episode just of these but but essentially I've put as many as I could into into apple cart that's one of the points of apple cart you gotta know Apple cart.

Conor

But aren't there like thousands of entries in Apple card?

Adam

Yeah there are almost four thousand but many of them are are not techniques like this.

Conor

Many of them are just primitives is there a way to filter by these like idioms that's the thing is I don't think as I don't think of AppleCart or BQN crate as like idiom repositories. I think of them as like just a very exhaustive or you know not exhaustive but a very long list of expressions that you can find useful so if you need to know how to do something that you're struggling with you pipe it into BQN crate or Apple cart and it's likely to show up.

Adam

Yeah there's no information in the table in AppleCart that tells you like a flag saying this is in Connor wants to be in a it's not just me. I guarantee you there's other folks out there that want to like like there's no you're right there's nothing in the Apple card table that tells you this one you have to know in order to be a black belt algorithm person. That's that's true. Yeah that'd be useful. Although that'd be going through 4000 entries and flag oh I've I've gone through those 4000 entries so many times so I'm not sure if that would be a lot of work but then but but it's sort of an arbitrary criteria right what about things you have to know in order to deal with text manipulation right or things you have to know if in order to do math in APL right those that another flag so yeah we could do we could do a lot of Boolean columns that say that so that you can say like these are these are mathematically necessary things to do for like this level of mathematics these things you need to do for text processing these are things you need to do for accounting these are things you need to do for etc etc we could do that but that like what what there's no limit there's no end to the number of of c of subjects and and and fields of study that exist and and for every field of study and every interest group there is marking for every every entry in AbleCard whether it's relevant for that it seems a bit much maybe. So instead you read through it you doesn't have you can you could filter out all the primitives all the system functions or the user commands and so on and then you could go you go through them. If you I mean if you take 10 a day you get through it in the course of of a year right yeah that's true.

Conor

I mean Max in the chat's just saying so APL dojo could be belt based rankings from Apple card in the midst of Madeline author of the Apple and Elias author of Cap discussing uh implementation of primitives. But anyways this is this has uh been an interesting episode we did end up kind of where we were where I was aiming to go with a lot of new nuance along the way and it may has me you know if anything has come out of this it's got me convinced that well it would it be the ideal but I was talking to Madeline on the last Tacit talk that she has empty syntactic space for non banana bracketed primitives. So the trains need the banana brackets but then it's empty syntactic space when they're not there. And I said well you could technically have like a hybrid tacit model and borrow you wouldn't even need to borrow everything necessarily from a cap just like the two trains in the form of the you know monadic function composition and left bound functions. You wouldn't even I wouldn't even really miss the uh the B1 combinator that much but even if you just had juxtaposition of left bound so aka an argument on the left and the monadic functions that would like be so nice. And like it would avoid the problem that we have with the the jot in dialog APL and the at in j of that those just parse correctly it it is it is available syntactic space in dialogue as well right we can make array function be a valid construct in a in dialogue APL.

Adam

It's not the that's the ship hasn't sailed I and which it doesn't make it the same thing conceptually as the left bound functions if that's what you call them but it but effectively that's what it gives you right because in a train that would mean you can put so we could we could do how far ever we want right you still have to do a a jot when it's in the middle of a train.

Conor

But wait what are you saying that is uh and also wait to answer the in the in the chat ellias is asking is banana brackets the official term Madeline says I call them moons at one point I was calling them moon brackets but then I read a 1987 or 89 paper called the introduction to the theory of lists by Richard Byrd who is the algebra of programming and he was calling them banana brackets back then and uses them for like list notation. And so since then I've been calling them banana brackets but it's it's not like the official term brought to you by Madeline. It's a term that I read in a paper from like what is that 40 years ago and and then I started using so what is the and what is this the all right and honestly last thing we're gonna hit like three hours now and I guess alias was the one that messaged in at one point that he said he wanted three or four hour episodes. What's the thing that there's still because you definitely can't have monadic functions in a row because that that space is taken.

Adam

No but but essentially right if you write in in APL one plus two times divide right it looks like you have left bound functions.

Conor

One plus two one plus two times divide? Yeah okay yeah so AGH fork and then an AGH fork.

Adam

Yeah this is fine right the one thing you're missing is that if you want to do to do one plus two times ten divide that's not valid. Right because you mean the tack then you've got a you have an extra divide division symbol in there. Right and that tack or you can put a jot if you want right a jot between the 10 and on the left of the right and that could just be removed the that requirement you could just say if the second carriage so to say of the train counting from the right is an array then it has an implied jot or right tech or whatever.

Conor

Oh I see so you're saying this is empty syntactic space.

Adam

Exactly.

Conor

So you could add left bound functions you could add a part of the cap model.

Adam

So you couldn't add the two trains no but but the inside that inside a a longer train it already works right you you have the effectively you have the left bound functions because you have AGH trains. So that's not a problem. It's only to the far right that there's a problem. You're saying AGH trains essentially are already this yeah just if you go back to what you had read before the one plus two times divide right or and then put that in parentheses right it looks like it's a one plus applied to the two times applied to the reciprocal so it looks like you got left right this this is works identically in cap and in dialogue right and in k. Even though two of the languages cap and k have left bound functions and dialogue doesn't but effectively works the same because there's no notational difference between left bound functions used in this matter. Does it you have to give an argument yeah well I mean this is just an expression now put parentheses around every about two times the reciprocal and then one plus that so that's a different thing that you would get right how is it reciprocal of 10 is 0.1 times two zero point two one plus that one plus one to plus one point two or six fifths. The fact that this is an AGH fork doesn't actually it doesn't matter that's what I'm saying. So so notationality there's no difference between left bound functions and AGH trains when it comes to to this the difference is on the far right and of course the ability to to stack monetic functions that are not left bound. The way that that's solved in in BQN for example is by having the nothing right so then effectively you have AGH trains where the A, the array on the left is a nothing and then everything just works out. So you have if you had a by convention and a left argument that signals to the function that don't use me. Just pretend I'm not here and just run your monetic function definition.

Conor

So food for thought I'd love it in dialogue APL I'd love it in Tiny Apple. Or I'd love it in some new array language that doesn't exist.

Adam

I I I think I think I'm not sure I would add nothing. I don't think so I don't think it it it it adds anything no pun intended but I think I would add the AF train if you want to call it that or left bound whatever you want to call it.

Conor

Yeah. Alright well we gotta call we're at two hours and 46 minutes at this point.

Adam

Yes my my food has been served my dinner has been served and is now getting cold on the table. I sent a photo but from my wife of my food getting cold on the table and it looks delicious.

Conor

My wife just popped in and was looked very confused as what are you still doing podcasting? Anyway So are we are we launching the APL Dojo podcast I mean what's we're not launching a separate podcast that's for sure will we revisit this topic maybe maybe not I will push these whatever changes to the live site and link it for folks that are interested in they can play around but I think we've talked enough about the APL Dojo for at least a few episodes if you do have comments thoughts questions you can either leave them in the YouTube description or reach us at here we go contact at arraycast.com first time since the relaunch of a cast 2.0 era that we got that right and yeah thanks for everyone in the chat we've got people we've got people asking for a 24 hour charity stream a raycast episode um no I don't think we could do a 24 hour conference but uh yeah Adam in the chat saying I do it yeah I don't know we'll we'll uh we'll see I've I've thought about doing like a an online conference a Raycon kind of thing uh which could could go 24 hours but you need multiple people uh hosting anyways thanks for everybody in the chat yeah leave comments in the description or you can reach us at that email address and with that we will say happy array programming nailed it nailed it thanks everyone by