 Hello. Hi. How you doing? Good, how are you? Very good. Always look forward to APL time. Hi, Wasim. Hi, Serada. Hello. I want to say hi to Joao, but I don't know how to pronounce his name. That's good enough. It's Joao. What country is that name from? It's Portuguese. I'm Brazilian. Okay. Great. Yeah, I came here because of a request. Though, I mean, if I had known that you're having these meetings open, I would have come anyway. Welcome. Thanks for joining. Hi, Radek. How are you? I don't hear you. Let's start. Anybody got anything they wanted to mention or talk about? Hopefully Radek doesn't because his microphone is not working. You can use sign language or chat or something, I suppose. I was really worried that I may be a Mr. Lester or something, but apparently there wasn't any. No. I was talking to J.J. We were doing 2 and a quarter were coming out in like a week's time. So I decided to do a two-way ask-me-anything with him. I scheduled it for like two hours before our time and then we ended up going on for such a long time that I didn't really. Yeah, I was late enough that I then thought, okay, I may as well cancel it. Otherwise, people might have come and gone and then they miss out. You still don't hear me. Yes, we do hear you. Hello. You can hear me. What magic button did you press, Redick? I don't know. It just started to work. The technology continues to surprise me, but I just wanted to second what the Danish said. I was also worried I missed a session because I couldn't come here on Friday and I kept looking on the forums, but what a fabulous surprise. So not only did I not miss a study session, but there will be also a, you know, an interview with you or like to look forward to. That is what a way to start the Tuesday. I said Hamel, you know, a preview of the interview and he said he really enjoyed it, so hopefully people like it. Cool. All right, I will share my screen. So a couple of things on the forum. Adam, who has been apparently writing APL since pretty much as long as he could read or talk or something, pointed out that the way I'm doing operators is not quite right, which I was kind of aware of, but I was hand-waving over, which I agree I should not be. So let me show you what I mean. So operators, the issue is that operators themselves can be monadic or dyadic. So a monadic operator means that you just have a function on the left of it, whereas a dyadic operator would have a function on the left and the right. Well, not necessarily, it could be a function or an array on the left and the right and would return a function. The functions that these operators return, regardless of their monadic or dyadic operators, can themselves be monadic or dyadic functions. I guess I should also say it could be, I don't know if people would say ambivalent or ambivalent. Ambivalent sounds like they don't care to me, but anyway, ambivalent meaning two valences that could be dyadic or monadic. So if we look at the help, for example, they do point this out in the documentation. So operator slash, okay, so this is operator slash. So this is the function being returned, which is monadic. And then I know Serata asked about this, NYS reduces. Is this the dyadic version or something? No, it's not. This is something else. Slash is a monadic operator with a dyadic operand. Oh, okay. So the thing that it takes is dyadic and it returns. Okay, so this one only returns a monadic function. Serata, what is NYS reduced? How is this different to... Oh, no, this is dyadic. This is the dyadic function version. Okay. We don't hear you, Serata, even though I can see. I hear you now. No, just the documentation is very intimate day and I can't distinguish what is the difference between reduced and reduced NYS. Okay. Well, in that case, this is a perfect example because I don't know either, but I can see from here that it's a monadic versus a dyadic function. So what we could do is we could go all the way down to a fifth level heading here and say monadic function. And then we could have dyadic function. Okay, the monadic function is called reduce. Okay, which means we can't put the name up here anymore. Well, maybe I should put both reduce slash reduce NYS. But have they read it? NYS reduced. Okay. Copy that. Monadic function. NYS reduce. Okay, and so then all right. Okay, so I4, we know what that is. That's fine. All right, what's this doing? So this is three. If we have some more examples, let me know if anybody figures out what this is doing. Window sum, it seems. One, two, three, two, three, four. Window size of three. So this is a yeah, so it's kind of chunking it and then adding it. Okay, that makes sense. So you've got. Oh, no, it's not chunking it. I see. So we've got the numbers one to four. So it's adding the first. Oh, so it's doing, it's kind of like a moving average, right? So if I did. Window sum, I guess. Window sum. Window sum, yes, exactly. So if I did three divided into on my APL keyboard, divided into, what's the swap thing again? Yes. So that would be like, yeah, that's like a moving average now, right? The average of one, two, three, the average of two, three, four. There's probably a better way to write that, but it's and then lamp is moving average windowed sum four. Why don't we put it here? Put it above. Windowed sum with the average of two. What does this do if you pass in an array as the alpha argument like three, four or something? Your microphone is so loud it's kind of like distorting. I don't know if there's a way to move it away from your mouth or change it's volume or something. Just FYI. So that was two, that was three. That is better. That's actually almost too quiet, but that's quite so crazy yet again. Oh, I was wondering what this does if you pass an array as the alpha argument like three, four into it. That's a good question. Let's find out. They don't like it. The docs say X must be a simple scalar of one item in teacher array. Okay. What's the distinction between a simple scalar and an item in teacher array? I mean, one thing I did want to do today or soon is something that Adam suggested, which is to look at the rank operator, which would allow us to deal with this nicely. But for now, let's put that aside. Okay. Yeah. So this one just is doing a sum of single things, which is not very useful. Okay. Identity element. This is kind of interesting actually more of a mathematical or computer science idea, but I think we should keep it because that's part of what we're learning about is the idea of the identity element for an operation. So basically this is like if you want to start with a number and then add things to it, then starting with zero is the number you would want to start at to get the right answer. Zero plus a bunch of things gives you the addition of a bunch of things. But for multiply, that's not true. For multiply, you have to start with the number one. And so, yeah, so APL seems to know what the identity element, at least for these operations is. That's interesting. So is that flipping the window when the scalar is negative? Sorry, where's the scalar negative? Oh, the last one? Yeah. Okay, you're getting ahead of where I'm up to a little bit. Okay, so this is just showing the example with comma where comma means concatenate. That's easy enough. And all right, so then yeah, so it's just flipping it around. Okay, seems reasonable. I'm not sure we need both of those. Have we done comma before? Does anybody remember? I don't remember doing it. I don't think we did. Oh, okay. Well, that's important. Not the best though. All right, button. I do have a difficult thing to search for. Let's just do it. No, we haven't. Okay, fine. So let's do comma. I get a bit confused because I also do similar classes with my daughter and her friends. So I get confused about what I've done with whom, even though I'm trying to make them somewhat aligned. Okay, so here's comma. Presumably they call comma. Yes, they do. My native comma is called revel, which I saw came up on the forum. The nice thing is that as we do more stuff, we can increasingly use examples directly from the docs, which is nice. Okay. So best. Right, so cube is going to be 2 by 2 by 2. I guess we could print that out. Row in there as well. Oh, thank you. 8 by 2 by 2 row 8. Oh, no, it's just 2 by 2. Oh, I see that extra axis is to show us that there's a second face. Cool. Okay, so comma just would be what we'd call flatten I guess in PyTorch. I think it will not flatten nested arrays out though. Right. Which I don't think PyTorch would do either. PyTorch doesn't have them. And I look into the documentation. They are actually different from the epsilon. Very subtle difference. I don't think we've done epsilon yet, have we? Do you think we should do it now? Okay, well we can do it now if it's something worth looking at. Yeah, so if we revel that it doesn't really do anything because it's yeah, because it's not a it's not a it's not a higher rank tensor, it's a array of arrays. I guess that's worth including. Yeah, I think epsilon does flatten that out. I see. Let's do a simple one. Okay. Diadic comma Oh. Have we talked about axes yet? Does that ring a bell to anybody? Yes. Oh, we've got them here but we haven't talked about them. Maybe let's create a section for axes then. And so let's move these because this is important. Okay, let's move axis to here. Okay, so comma three four Oh, I think the problem is my little sample one's a bit broken. That's why that's broken. Okay. This is kind of an axis. This is probably kind of an operator but never mind. So axes are things you put in square brackets after a function and it lets you apply that function over a particular axis axes. Yeah, I think we started talking about these briefly perhaps. Okay, it does not follow the normal syntax of an operator. So I'm not going to just call it a normal operator. That's why we're giving it its own spot and it can be applied to any dyadic primitive scalar function. This looks like a good example. Okay, so so this is a function that's going to apply equals to columns I guess let's see one four five one four five and so the way it describes it does it say what it is? I've found that kind of one of the way that helped me kind of understand what it's doing is with plus slash and then you use the bracket axes to have a matrix and some over rows I'm hoping to do this before we do operators though which is why I was wanting to do a dyadic version I'm just trying to find anywhere in the help to actually say what it does. I'm having trouble seeing that here. I don't think it actually says what R is does it? That's weird. Maybe this is a description. The axis operator can take a scalar dyadic, nope that doesn't really tell us either. I think the APL Wiki has a better information about the render function axis if I remember right. It's got better search to bracket axis. It doesn't exactly say what it is. It seems like different functions have different ways that axis affects them. Is that what it is? Is that the problem? It's hard to say exactly what it is because it varies. Okay. I guess this is what we're actually doing is we've got an axis with a scalar dyadic function. Plus as well equals a scalar dyadic function. It's an infix thing which can have a scalar on the left and the right. Normally it would apply element-wise over the scalars. In this case we've got an axis so it stretches the lower rank array. The one on the left is lower rank. This is rank one to fit the higher rank. The elements of the lower rank array are replicated. So we want to apply this column-wise. So these are treated as columns. That makes sense. You get 145 equals 135 and then 145 equals 246. That's cool. I think you're right, Tanishka. I think that's the issue. That does make life a little confusing. Let's use this example. Matt is two rows of three columns of that. Okay. Plus will be applied to columns. This is the lower rank. This will become a bunch of columns of one and two. So you get one and two added to this, one and two added to this, which is exactly correct. Okay. I think that makes sense. Now what we're about to discover is that, for example, Ravel has its own special behavior with an axis. Here we are. Ravel with axes. K is the axis. It could be a fraction or an integer or a vector or empty. Well, okay. If it's a fraction, oh, yeah, you see the difference? We've got this. That's a bit subtle because you can't see it in the documentation, right? Because they don't actually print the boxing. So I'm glad we've got boxing on. So this is inserted a new axis between the 0th axis and the 1th axis. And I think we could use anything between 0 and 1. It would do the same thing. For some pie, that would be the equivalent of indexing something with none or NP dot new axis. I think the documentation tried to show it by doing row of that to show that it's... Oh, okay. Yeah, yeah, okay, got it. You're right. Maybe we should do that as also just in case people don't notice the arrow of axes. All right. If it's an integer, then it only ravels along those axes. Okay. No worries. So we're going to create something called M. Okay. Is that what they had? Yes, it is. So what's happening here? Okay, so then we're ravelling over axes 1 and 2, which are these two? No, we index from 1, I guess. Or do we index from 0 for axes? Hopefully we index from 1 because that's what we normally do. So that would suggest we're indexing over... ravelling over these. We're left with 6, 4. Oh, okay. Wait, no, I'm slightly confused. This is the opposite of what I expected. So this is left the trailing axis on its own and the first two axes have been combined. Oh, so that's what this is saying to combine these two axes. Yes, it is. You can see here. It's combining those two axes. Does that make sense? Does anybody have any questions about that so far? I came in a bit late. Is ravell the opposite of unravel? Uh, I haven't done unravel. So I have no idea. Is that a thing? I remember reading about it. I came across it with NumPy before and I think NumPy has some kind of like a ravell method and I was like confused. I'm not sure if that's the opposite of unravel. Oh, you mean just in English? Yeah, I've never actually seen that word just by itself like that. Oh, I've not seen it in normal... Yeah, it's always just unraveled something. Oh, there's ravell, the composer. Uh... Oh, here we go. Apparently it exists. To disentangle or unravel. Oh, that's confusing. To become unwoven. It sounds like the same as... Sounds the same as unravel. Um... Inflammable means flammable. Uh, this is one of those things. Well, thank you for checking the dictionary for me. Somebody said hello in the chat. Hello, Miguel. Are you able to speak or are you just on text chat today? Miguel said... All right. Yeah, tell us what you said in the chat. Well, I do think it means the opposite of unravel. Yes. I mean, tell us what you said earlier in the chat. Uh, you had something about BQN? Yeah, I joined a while ago. I'm also a fan of rave programming languages and memorization techniques. So I caught up with earlier sessions and I made an Anki deck for the BQN glyphs. And is that in here somewhere? Oh, here we are. Miguel Reza's Anki deck. Yeah. Excellent. Okay, so let me just go back a bit. So probably not everybody here knows what BQN is. So do you want to tell us about BQN? So BQN is a another offshoot of APL. It's free and open source. And if you go to the community page there, that's the online rebel too. So you can just try it out in your browser. And there's now my Anki deck link there so that you can also learn the glyphs on the community page. Where's the, sorry, you said there was an online rebel here somewhere? Yeah. Click back. Oh, you mean on here? Yeah. Um, that's Oh, you can actually, this is I see. That's nifty. So BQN, all I know about it really is from listening to the ArrayCast episode with the creator of it, Marshall Lockburn, who used to work at BQN and from listening to the ArrayCast chat with the CTO of dialogue, he described Marshall as basically wanting to go too fast. So Marshall left dialogue and rather than trying to turn APL into the thing he really wanted it to be, he decided to start from scratch and create a new Array language to be all the stuff that he wished dialogue APL was, I guess, or wished APL was based on, you know, all the things we've learned about Array programming since. It uses its own character set, which some things look familiar to me, like down style and up style, and these ones look the same, but there's also some symbols that aren't in APL. Yeah, there's also something interesting where they use stranding for the limiting lists, so that reduces ambiguity in the language grammar. That's this one here, right? Yeah, so stranding means, apparently this was a huge area of contention some decades ago, being able to basically do this to create an array of arrays is called stranding. In BQN, can you create a list like this, or even this list would require that stranding character? You need the stranding character. Yeah, okay, so you can't just write one, space two, space three, instead you have to use this thing, so one, three. What just happened? Oh, that array must do something different to what I thought it did. Do I have to press enter instead? No? What button do I press to Oh, shift enter. I do shift enter. There we go, okay. Yeah. So I think it took some of the ideas from J, some ideas from APL, some ideas that aren't in APL yet. So definitely something I'm keen to check out at some point. What are your thoughts so far, Miguel, about BQN as a language for learning array programming or sand or doing data analysis and or having fun? There's less literature than APL, which has decades. So translating a lot of the materials into BQN is interesting. I enjoy it. I found it way easier to get started with because I couldn't work out how to download the APL thing and get it working on my computer. So I just started with BQN. And JL's just I think put a little joke in the chat, which I think I understand. He said it's the less healthy version of APL. Assume where APL we read as Apple and BQN we read as Bacon. Is that the idea? Okay, I got it. And according to the documentation for BQN, you're not meant to call it Bacon unless you're making a joke. So you are allowed to call it Bacon in this situation. All right. Nice. We are not as yet unravelled. I don't think so. I guess we should do this one now. They added comma. All right. So this one looks pretty straightforward. Oh, well, not quite straightforward actually. So we need our cube back again. All right, so this is just concatenate, which as books on the chat have pointed out, well, hang on, there's some contention here in concatenate. Miguel concatenate is the opposite of concatenate, but I think actually no, as JL's right, concatenate is the same as concatenate. And so I think we are here, we are concatenating 4, 5, 6 to 1, 2, 3. And here we are taking our 2 by 2 by 2 cube and concatenating 99 to the kind of innermost axis, I guess, which presumably the documentation will explain to us. Oh, and then there's a different version, which is comma bar, I guess you would call that. Which we should probably therefore also mention. I guess that's concatenate first, is it? Yes, it is. So is there anything else to know about comma bar? Oh, that means something else entirely, does it? Is this transpose? What a rabbit hole. Oh, that's weird. It's not quite transpose. Curious. All right, so concatenation with an integer or implied axis specification. They're joined along the required axis. What does that mean, the required axis? Why does this appear at the bottom? Because you can denote the axis you want to concatenate along with the index? Oh, it's because this is comma bar, that's why. That's why. The required axis, I guess is implied to be specified. The last axis is implied. Okay, so comma bar and comma are the same thing, but comma bar implies the first axis and comma implies the last axis. To be right, comma bar is. greater than sign, yes. On the APL card, it explains it a little like maybe exactly almost what you said, Jeremy. Okay, cool. Great. I've found comma bar to be helpful if I have a I'm learning with tabular data. If I have an almost data frame shape or matrix, I can use comma bar to with a vector of strings to print out a header row so I could see what all the columns are. That makes sense. Secret standing. Too lazy to stand. Okay, cool. And then there's I think at this point we don't necessarily need to explain how to use every kind of axis in every case because it might get a bit boring. Not surprisingly, if you've got a fractional axis, it kind of works the same way. They're joined along a new axis. Well, unless it's useful for seeing an example. No, that probably is useful, right? This is kind of like another way of doing what Isaac was just describing. Because here you had to already have two rows. But here you only have a vector and you want to make it into a matrix by adding the row. So this is the equivalent of stack in pytorch versus cat in pytorch. So, yeah, that's probably worth mentioning. Alright, so shift comma which presumably is called comma oops, which probably called comma bar and the monadic form of that is table. Okay. Which I'm pretty confused about what it's for. Maybe we should look up APL Wiki just in case it knows what it's for. Table. Apply to each major cell. So I think that's like the the biggest sub arrays. For arrays of rank one or higher it's identical to applying rebel to major cells. So rebel will flatten, so it'll flatten each major cell. I don't understand what this is doing. It's quad A. Is that like something they define or is that part of the language? Quad A is A2 set. Oh. Okay. Well, let's put that in our string section, shall we? Alright. So this is the so five row on something that's 26 long is just going to give you the first five characters. And so that's ABCDE. And then now what's going on? This is a function. Oh, okay. It applies. This is just composition. So it applies this function and then it applies this function. So first of all, it applies the function rebel and then this applies this function which prints out the original argument and the shape of that argument. That's kind of nifty. So it's showing us that the result of this table or ravel items is ABCDE and that the shape of it is five one. And then here it's showing us that comma under bar hasn't done anything as far as I can tell. Okay. So that's done nothing at all. But here's yeah. So here it's applying ravel to major cells. So the major cells here are lists of four. The major cells here are vectors of four. The major cells here are matrices of three, four. So it's raveling those major cells. The two major cells that we have. So let's use that example then. Okay. So I'm going to add ravel items here because I think that's easier for me to understand what that means. For an item, I guess they mean a major cell. So this contains two major cells each of size three by four. And so therefore this is turning them into two length 12 major cells. It's a raveling the items. Scalar arguments converted to a one by one matrix. So this is basically like transpose but it's kind of adding the axis. So we should put that first. Actually maybe first we should put the scalar version. Okay, so that's that's that. Does anybody know what this is for? It's equivalent to this operation which we haven't done yet. So we should do that soon. And we haven't done that yet. It's annoying. So be it. So we should come back probably to this idea I guess. So then we could do dyadic catnake first. Presumably this will be the same. Yes it is. But this will be different. And presumably once we add an access specification it will make no difference because the only difference between them is the assumed access specification. Correct. Okay, cool. All right. We happy with that? So maybe we should do axes with operators then it'll be fine those. Okay, so dyadic mixed functions. Oh, these are not in an operator. So the plus slash Isaac was suggesting plus slash with access. How would that work because that's not a dyadic function. Yeah, I guess it can be a function derived from slash. Okay. So you can do plus slash bracket one and then plus slash bracket two and you'll see a row wise sum versus a column wise sum. I see. I don't see it quite defined here but I guess minimum maximum works with it too. Jeremy you have a typo in the AC. Yes, where's my typo? Go up the AC go up. Yeah. That's not a typo. That's what I want axes. That's the plural of axis. Maybe I should say axis rather than axes I guess. I suppose so. All right. Well, yeah. Okay, so I guess we want to we want to make tricks then is that the idea. And then we would say plus slash over one is that how we do it? Yep. Okay. And if you did a bracket two that's kind of the same thing as the default which would be you know, get you the same 615. Just a moment my daughter wants me actually maybe that's a good time to go. All right, cool. Thanks gang. See you next time. Have a good one. Bye. Bye.