 Hi, Hamel. You're muted. I said now I understand why you're looking up like this. I will move you down to my level. There we go. Alrighty. Hello, everybody. Hi, Wayne. How are you? Doing good. How are you doing? That feeling a little better today? Yeah. The hay fever has gone away. I hardly ever get hay fever anymore because we've filled our house with air purifiers, which do a great job, but something got past them yesterday and I just, ah, so now I feel like a bit flat after a day of feeling bad. You know, the next day you kind of that. You know, APL will cheer me up and the company of you folks. Do you have any recommendations on air purifiers? I know there's like the Dyson Maldehyde ones and molecule and all this kind of stuff, but I haven't seen it in our community. Oh my God. Do I? Of course I do. Pray to tell. I'm all about air quality. So there's basically, if you Google for like, let me try to think. Oh yeah, CADR calculator. That tells you the clean air delivery rate that you'll need. Basically to get a certain number of air changes per hour, which is ACH. And like if you aim for, I don't know, like five to eight air changes per hour is being pretty good. Then you just type in your room size into one of those online CADR calculators, clean air delivery rate calculators, and it'll tell you what CADR you need. So that is just a case of buying an air purifier that has that CADR and a HIPAA filter. It's like it couldn't be less high tech. It's literally like a piece of woven cloth, which with a fan that blows air through it. That's what an air purifier is. So I got this thing called the UHU. It's like a sense that I was interested to know air quality. And I discovered the CO2 was way too high just because closed windows and things. And so definitely that's easy, right? You have to ventilate. There's no solution other than scrubbing. Yeah. So I had, I went through that last year or the year before with the wildfires in California. And we had to close up all the windows and everything. And, you know, the process I was worried about, like, oh, is that going to be bad? And I bought a CO2 monitor and I discovered our CO2 was like 1800. You know, when the maximum recommended 800. Yeah, you get headaches and you feel like an idiot. And so ever since then, I've been pretty careful about CO2. And, you know, that that's separate. Of course, you know, you can have perfectly good CO2, but still bad air quality if there's. One thing that I have is quite high TVOX that are unpredictable. Like, so I don't know if it's the sensor. I'm trying to figure out. Sorry. That's okay. I was just going to say, I don't know if anyone has any experience with that because I haven't been able to figure it out. I've been collecting data for months now and I currently figure out any clear correlation with the TVOX. But they sometimes are quite high and I suspect it affects, you know, sleep and things like that. So I do know there's some sensors on the market. So I just don't know if that's something you already looked into. Yeah. I mean, I've got air purifiers which have gas and particle sensors on them. And so then they have an auto mode where they'll go go harder if there's more stuff. I don't find they seem to correlate with my hay fever though, honestly. So my method of setting the fan level is if I start getting hay fever or turn it up. I don't find the auto seems to work that well for me. Okay. But yeah, that's definitely been a life changer for me is getting clean air in my house. That's basically the first bad hay fever I've had in like 18 months. And it used to, you know, be like the single biggest impact I reckon on my quality of life was feeling crap all the time. Anyhow, that's a bit of a side, interesting aside, nonetheless. Any interesting APL discoveries since yesterday or questions or anything else? That's fine. It's remarkably hard to do simple things. Yeah. Well, I mean, we just started, right? So that's. Yeah. Shockingly hard to load. How's that posted? I posted in the forums a basic kind of genetic algorithm, which was pretty cool, but I saw that. I think I think basic is a is not a fair description. I mean, compared to where at least I'm up to, it looks pretty sophisticated. I feel like there's a lot that can be done to transform it into a more kind of array based solution. Well, that'll be an interesting project for us all to try to help with. I think, yeah, I mean, we're not close to knowing all the glyphs that you're using yet. I think we've got some catching up to do. My goal is to implement Connect4. I've implemented it in so many languages and it seems a good enough problem that is non-trivial. Yeah. So like with an AI that you play against? Yeah. Yeah. Just mini-max kind of implementation. There's a good gaggle competition on that one going on since a while, which is fun. Then we could try slotting in a genetic algorithm to try to optimize it as well. That'd be cool. Yes. But just like the simple, the board and simple. Yeah. How to best represent the array of the board is already hard. Yeah. I'm not even at a point of thinking about doing anything yet. Oh, I just pressed the wrong button. I just had a question from the topic about, oh, sorry. Okay. Oh, I was just going to say, I spent a lot of time the last day trying to figure out how to load images in the APL just to get the pixel values. It was a lot harder. No. No, and I asked on the Discord if there was any kind of beginner friendly ways to load it. And I got a lot of resources that I had no luck deciphering. Was that on the APL Discord? Yeah. I saw a dialogue conference that they're having coming up that this is a hot topic that they're going to discuss. Image processing? Yeah. Awesome. I wanted to ask, we'd be talking a lot about complex numbers, which are super cool. I noticed they're supported in Torch and PyTorch. Is that deep learning uses? Oh, yes. What is that? Absolutely. Yeah. I mean, apart from anything else, there are an input format for audio, for example. We would often represent as magnitude and phase. And we don't normally have to worry about it, but you can optimize convolutions using Fourier transforms and using complex representation. That's kind of handled for us by Cudi and N nowadays. But yeah, inputs and outputs as complex numbers is certainly a thing. And also if you've got layers that represent kind of more like, you know, the activations you hope might kind of represent something from your domain. They might be represented well as complex numbers. You might have loss functions based on that. Cool. Yeah. But the only time I've used them in PyTorch is for audio. But I know other folks use them for other things. I also saw that Adam, who actually works at dialogue, and I think he's the guy in a red cast who said he's like used APL his whole life, answered some of our questions. Okay. So once, okay. So if you use, I'm on Mac, not on Windows. But on Windows, once you've removed some docked Windows, you can click session save. You can right click on the language bar and hide caption. Once you've got boxing on, you can save your session. And yes, I've already started in the forum to get backticks with the in-browser backticks space. So that was good to get Adam to answer some of our questions. And then the other thing I wanted to mention is that Wasim did some really nice notes, which I finally got a note around to reading. And so I actually highly recommend them. So they're linked from the lesson one forum. So thanks for doing that, Wasim. Am I pronouncing your name right? Yep. Cool. Where is that name from? You're in South Africa, right? So funny enough, I'm in Sydney at the moment. No way. My parents, but I'm originally from South Africa. And the name is Arabic. Cool. Welcome to Australia. Better time zone for you. How long before? Until end of next month, actually. It's the most long time. Great. Yeah. If you say hi in the forum, if you want to meet up with any fast AI people, I'm sure there's a bunch of people in Sydney. Yeah, these are great notes. Thank you so much. I love that you've got the juggling notation. Had you come across juggling notation before we discussed it? No, not at all. It's interesting, isn't it? It's like a game changing, apparently. And Aaron Hughes PhD. I don't know how you pronounce this name. Serada, you might know. Do you know how you pronounce this? I guess this is a Chinese name. I mean, I know it's not Pinyin, but it's... No, you don't know. Okay. I thought for APL today... Oh, good. There's a link here. Thank you. By the way, for those of you who hadn't noticed, at least when I remember or when Serada reminds me, I click on the make a wiki, which means that anybody can click edit on these posts. And so thank you for those of you who have been adding stuff to them. I'm thinking like in terms of stuff that's going to help us understand more of the documentation and do more things. I think there's two main things I wanted to cover today, which is left arrow and row. And basically, do they call it left arrow? They do. Okay, cool. So left arrow, which is left square bracket, is used to assign names to variables. So A is three. So obviously in a lot of languages, we would use equals for that. But, you know, a statement like X equals X plus one is not a mathematically same statement. So I'm glad APL does not use equals to mean that. So in other languages, we have to say equals equals to mean that. And I know this is something, you know, the kids I teach found quite confusing when we're doing Python. It's like it's a very strange meaning of equals. So you can absolutely do that. You know, if you've got something called X, you can rebind it to its previous value plus one. I mean, let's try it. A plus one. Okay. And if you add a plus sign before that A, a plus A arrow, A plus one, it'll actually print it out for you as well. Just save your line. I mean, that makes sense, doesn't it, right? Because we learnt that monadic plus is conjugate. Now that won't work for a complex number because it will actually give you the conjugate. But yeah, this is going to return the conjugate of everything to the right. So assignment is returning the assigned value and then taking the conjugate of it or as a result print it out. I think this might be better. Left tack. That's, because that's actually always monadic function same. So if I replace this with that. And I think you can also, when you start nesting these assignments, these assignments can be, you could create a new variable as part of, you can create A is left arrow. B plus one, A plus one. So you can actually nest them. I think if you do left arrow and then the box, I forget what it's called. Assign it in the box. This quad, which is, is that an L there? Yes. So I think if you assign to that. That's what they do with the dogs usually. The mnemonic is you're kind of like saving to the screen. Got it. So that's a special thing to assign to. Yeah. A lot of the IO operations are handled by quad. Uh-huh. Great. Now the other interesting thing, which is happening, is that Isaac has started creating a website for the study group, which is not quite up and running yet. Did you do the settings pages, the GitHub pages, the GitHub pages branch and all that? Yeah. I think we could just probably do that now. So let me, while I remember to get four. And then, yeah, we should be. So for those of you that don't know, GitHub has a very nice feature called GitHub pages, which basically turns a repo into a website. Um, and to use it, you basically go to pages and you say source is this branch. And in theory, I should now be able to click on this. And we may need to, oops. So I can check what's going on by switching to that branch. Okay. So there's definitely something there. I had to do a little after I set the settings and pages. I had to make a small commit to publish the first time. I've noticed that too. Okay. I'll remove one carriage return from here. And I can vaguely hear, how are you talking? I can vaguely hear your ghostly distant voice. Can you hear me now? Oh, there you are. That sounds great. Yeah. The site is up actually. It's ready. Fast AI.Github.io. Great. Something I like to do is when I go here is I copy this and then I go into settings and paste it here. And that way anybody on my page, including me, can jump to the website. I really wish they knew that automatically. Yeah. Look at that. Okay. Thank you, Isaac. This is beautiful. It all is. So, oh, this is cool. I didn't notice this thing here automatically pops open. So this is Quarto, which is what NB Dev2 will be using, which is full of neat tricks. Tags. So fast. Yeah. A lot of Quarto's commands are really well designed. Yeah. It really is. It's from RStudio, JJLA's company, and everything he's done has been great. He's hired a lot of great people as well. And he's been super helpful. I think we need some image of some APO thing. That'd be nice. It's a very cool image though. All right. Well, that was easy. Yeah. All the images are the Quarto default stuff. I see. Well, if anybody wants to do a PR, which uploads an image of, I don't know, a cool formula or picture of Isaac with a little lambda on his head or whatever, you know, it'll all be good. So the way, yeah, so the way this works is, as I say, basically the way I like to do it, and this works pretty easily, is if you have a branch called GHPages, then any HTML, et cetera, in that branch just ends up as your website. So here's index.html and that's the website. And now the way that's being created is there's a thing called GitHub Actions, which is basically something that will automatically run some code for you when you do things on GitHub. They're YAML files, of course, because all the cool kids use YAML files. And so you say, OK, well, when should this run? And oh, it's going to run when you push to master. OK, what happens when you push to master? Well, it's going to run a job called deploy, which will run on Ubuntu. So they've got like every major OS with lots of releases, check out this repo, set up Python, run this script, run this command, and then run this action, which is deployed to GitHub Pages. And I'm guessing, Isaac, you basically borrowed this from NDProcess. It looks similar. Yeah, yeah, I took this from your fast compiler repository and there's some minor changes, but roughly the same. Yeah, so fast Kaggle, I just did NDProcess new. NDProcess is the current name of what will be NDPdev2, hopefully within three weeks or so. And as you might have noticed, one nice thing about this is that we have a, why is this in a separate folder, by the way, Isaac? Was that necessary for some reason? I don't think so. That was the, that was how it, the default create a website Porto function did and I didn't change the structure. Anyway, so we've got a notebook here. And that notebook has been auto converted into a post, which is nice. So once you've got this set up, you can start authoring technical blog posts with notebooks really easily, particularly because if you hit dot, why is it not working? I thought if you hit dot. Yeah, it's meant to be dot, never mind. You can open up the notebook in github.dev, which is basically a slimmed down online version of VS Code. And so I can start editing straight away. I assume that they won't have the APL kernel installed, but I'm not sure. You can't, not sure you can even run Python, can you? But you can certainly edit the markdown and move cells around and stuff. Or you can just put markdown files in there. All right. So let's, in fact, let's go ahead and make this a bit simpler while we're here. Otherwise, I might go a bit crazy. So if we move all that into the parent, then we should be able to remove that. Yes, OK. Well, we can add this to this dot, getignore. So getignore is the file which contains a list of all the things that get will, by default, ignore. So dot, quarter. And if you end with a slash, it means it's a directory. OK. OK, so we should also add dot, i, pi, and v checkpoints to our getignore. And so then let's check. Then underscore, quarter.yaml is where it's kind of defined. So this doesn't need to be dot, slash anymore. Can you think of anything else that might need to change off the top of your head? Isaac. Thank you. Thank you, God, everything. What does freeze do? Is that different to execute false? I'm not sure, to be honest. I think that was a default setting. Check. All right, so get status will tell us how we're doing here. Oh, yeah. And I was going to add dot, i, pi, and v checkpoints. Dot, i, pi, and v checkpoints. OK, so I think that means it's not going to re-render or re-run file unless it's changed. OK, makes sense. All right, so we've renamed some things. We've deleted one thing. We've modified one thing. That sounds good. We haven't got this set up yet. That's fine. So get commit minus am. So a will add everything that's not yet added. And m means I'm going to put a message right here. I thought I'd already done that. Oh, that's right. I added that one carriage return. And so now we should be able to go to bus.ai.github.io slash APL study. And it's still working. How about that? And so something that's useful to know is your GitHub actions when they run, oh, didn't work. They get logged here. And so when it breaks, you get across. OK, quite a render is going to change. So that's just no, that's not going to need anything anymore. So we'll change our, oh, I mean, so, you know, just something else to show you. We don't have to like switch to the terminal. We can just go to GitHub workflows and click on here and click on edit. And just edit it directly if we want to. And that by default uses the current directory, I believe we can just go ahead and commit that. And I don't know why we have architecture here. I think it defaults to X64, doesn't it, Hamel? Yes. Yeah, you don't need that. And then something else you don't need is this pipe is used in YAML to do a multi-line thing. And since we only have one line here, we don't need that either. But your screen has so much vertical space now. But it's split in half, Hamel, so it doesn't really. So I still have reason to complain about vertical space. Besides which, that's an important part of my personality. All right, so that worked. That's good. And so after it updates, then the GitHub pages bot will actually put that up on our website. Okay. So, great. So this is called a raw cell, which Isaac's created for us. And you can create a raw cell by pressing R during this menu. And things that are between three dashes are called YAML front matter. YAML is yet another markup language. And basically, this is much of key value things in YAML. And yeah, this is where we basically put the information we want. The title's actually not needed because it'll pick it up automatically from an H1. Or to put it another way the H1's needed because it'll come automatically from the title. Great. I suppose I should put my name here since I'm writing it at the moment. Something I find really helpful is I use this thing called collapsible headings. And so I just hit control shift left. And as you can see, it closes everything up. And then you can basically press right arrow to jump to the end of a section. Or to open a section. So that's left, right. And if you're already at the start of the section, you press left again, it'll close it up. I find it really helpful for zipping around quickly. As you can see. So we started talking about precedence yesterday. Yeah, I don't think there's too much more to say about precedence. Maybe we'll create a section called like expressions of which part of that is about precedence. And then the other thing we put in here is about functions. Okay. So in Python, or indeed in math, in math, you would write a function like this. You'd say f of x is, you know, whatever, 2x, say. Or in Python, you would say define a function which takes x and it returns 2 times x. Or you could create a lambda in function. f is a function which takes x and returns 2x. So these are all ways you can define functions in math or these two are two ways you can define functions in Python. They all have something in common, which is that you're telling the reader in the case of math and the interpreter in the case of Python, what's the name of the thing that you're passing in? And you could pass in more than one thing. Right? APL is different. APL has decided for you what names you're going to call things. So to create a function in APL, it's just assigning something to a symbol, right? So rather than saying, oh, I've got to turn my APL thingy on, which means I'm going to turn on my bookmark bar, which I thought I needed a shortcut key to, but I don't. Shift, command, E. Let's try that again. Command, shift, B. Oh, there we go. APL. All right, f. So we can assign a scalar or a list or the result of an expression with possibly various other functions in, right, whatever, or we can assign a function. And to create a function in APL, you use curly brackets. So curly brackets means this is a function. And then inside the function, you say what you want to do, and you don't have to name the parameters. They already have names. If you have one parameter, it's going to get called omega, which is w. So here's a times two function. And to pass the one parameter, you just check it on the right. Okay. What if you want to create a function called g, which does something times two plus something else, then a second parameter will always be called alpha. Now, the second parameter goes on the left. So this will be, this becomes omega. So it'll be four times two, which is eight. Plus three is 11. That's not right. Oh, sorry. It's going to be this. Sorry. This happens first. Yep. Yep. Thank you. So it'll be two plus three is five times four is 20. Okay. Great. As you can see, I'm still not thinking APL yet. That's, I think, all there is to know about functions at this stage until we get to operators. Actually, we should do operators first. Maybe. Do we? No, let's not. I think that's enough. So. What happened? We have more than two variable. Good luck. You don't. You can have zero. One or two. I guess like basically, I have a feeling it can do unpacking. It can. You can do some pattern matching. Yeah. So you could pass the list and then unpack it or destructuring as I think some people call it. I guess we should keep that here because that's actually quite interesting. Can you pass in the function above as to the equation function? Can you pass the function above? What do you mean? Can you put the F inside the G function? Oh, yeah. Absolutely. F and G are now like just the same as plus minus whatever. They're just APL functions that you can do whatever with. So yeah. So we could H is equal to two plus F of omega. So that's something that I like, right? Because all the APL glyphs, at least the ones that are functions, are either unary, monadic or binary, dyadic. And they always, you know, if they're monadic, the thing goes on the right. And if they're dyadic, then they're infix. And the functions you create are exactly the same. And you can create unicode function names if you want to. So you can create your own very APL-ish looking functions if you wish. D structuring assignment. Okay. So when we use the word array, we're using it to mean the same thing that NumPy calls arrays and that PyTorch calls tensors. So they're, you know, n-dimensional, regularly shaped bunches of things. And in PyTorch, we call the rank of a tensor the number of dimensions that it has. So a vector would be one-dimensional. The matrix would be two-dimensional. A scalar would be zero-dimensional. So it'd be helpful to know how to create things. So we know how to create scalars. You just type them in. We know how to create vectors. So rank one arrays. You type them with spaces. So something that's going to be helpful in explaining this will actually, first of all, be to learn about iota. You can also, as an earlier step, you might be, if you wanted to teach the row, you could, you can actually use the row to reshape and give it a one or a zero to broadcast it. Yeah. Yeah, absolutely. Okay. Yeah, let's do it that way. Thanks. Oh, we can just type it in. Let's just type it in. So let's just create something. And let's use our trick now that we've learned it. Okay. So display a list we assigned to A. And we're going to have to do this backwards, but that's fine. Diatic first. So let's look it up. Here it is. And we are going to get to learn a song today. That's the good news. In fact, we're starting to see some of the song here. That's cool. I guess we should mention strings, actually, because they do use them in the documentation a lot. I don't know what they call numbers and strings or arrays. What's the term for those things? Things that aren't functions. I got to call them basic objects for now, but if anybody learns what they're actually meant to be called, let me know. In the box, they say it's a language element. Is it supposed to call all these things? Yeah. Yeah, that's right. But I'm trying to talk about things that aren't those. I'm trying to talk about numbers, arrays and strings, which is none of these things. We'll figure it out. So I'm not sure there's much more to say about strings. What does the language reference say if I search for strings? I'm not quite sure what order they think they're showing this in, but it's definitely not the most helpful one. I see. They don't call them strings. Maybe this is considered a list of characters. I suspect it is, actually. Found another blog post that calls them character vectors and scalars. Oh, right. Because I think this is different, right? Okay, so we're about to get a slightly ahead of ourselves, but this tells us the shape. Okay, so that's weird, right? So I don't think we should do strings yet until we do row, because they don't make sense until we can look at shapes. Okay. All right, so we've got a list. So we can turn that into a matrix using dyadic row, which is called reshape. This is just called row. Figure out what I did with my heading levels here. So that's two. Oh, yeah, that's three. Okay, that's four. Great. So that's reshape. And so that is, I think is that the same as what NumPy calls it? Reshape? Yes. Same as NumPy's reshape. So it gives a new shape to an array. So the shape of an array is basically like how many columns and rows and whatever does it have. So if we want to do three rows of two columns, we can reshape our array. As you see. One thing that threw me off. I was just going to say at this point, like, or maybe at the very top of this, we should say boxing style equals max. Did I do that? I'll stop boxing on style equals max. You would style dash max, I think. Dash style. Actually, I can see it in the background there. Okay, great. So there we go. What was it doing? Slow. Okay. Okay. So I think Isaac wrote something on the forum about this. So anywhere you see an arrow, that means this is like a dimension that exists, right? There's no arrow here. So this is considered like infinitely thin. So think of this as a vector, not as a one height, you know, as a matrix with one row. This is a vector. I was talking to my daughter about this yesterday and she found this very confusing because she's like, well, it does have height. So say like, okay, it does on the screen, but this is a representation on the screen of an abstract mathematical object that doesn't have height. And it's just that if I drew it infinitely thin, you know, it's like, Claire, you wouldn't be able to read it and you would think that wasn't very helpful, which she agreed was true. Whereas this thing here has two arrows. This actually has three rows and two columns. And then the sprinkle means that this got numbers in. There's two other options. It could have a mixture of things with some strings and stuff in or it could even have other arrays in. They would get different symbols. So I think perhaps one of the more interesting ones to look at is what happens if we have one row with six. And so now it does not look the same, right? No arrow, arrow. So this is a matrix. So the shape is whatever you would put on the left-hand side to create that thing. I assume it's going to be called shape, but I suppose I should check. Shape of, okay. Shape of. So for example, let's call this matrix, okay. And so if we then get the shape of A, a single dimension of length six, where else the shape of matrix is two rows by three columns. That's the question. Yeah. I may have missed this. What is the writing to the box thing do again? It's just printing it in a more nice way for us. So everything we know what I mean is writing to the box. That prints it out on the screen. And then you would sit on the screen. No, it doesn't. If I remove it because I'm assigning, it doesn't display it. Oh, because you're assigning. Okay. Sorry. Yep. Yep. So you're just kind of changing the assignment to the screen as well. And this box. Is that a self-function? Like. Yeah. That's a, but that's a function called quad, which I think does a lot of things. I think this is squad. Is the same thing as quad? Oh, never mind. It's a good question. I don't know. I didn't think so. No squad is used for indexing. Okay. So maybe quad is like. Not a language element. And then it's some weird special thing. What if I search for it? Here we are. It's a variable. Which communicates between the user's terminal and APL. Depends on whether it's been assigned a reference, but it's assigned. The array is displayed. Okay. So it's a special magic variable. Thanks. I'm thinking on these creating and reshaping. Matrices that. Some. For me. I didn't realize I had a bug. Because you can actually reshape. To any size. So if you have. Four numbers and you reshape it to a three by three. It'll just. Look through it. It'll use the first, your four numbers, plus the first two in the array to make sex. So it can broadcast and kind of weird ways. Sorry. I just wondering. Did we. We've got saying here called functions and assignment, but I don't actually see if we ever. Did normal assignment. Because I don't think we missed. Oh, okay. Well, that would be the right place to talk about quad. That seems like a bit of an oversight. Okay. So let's pop it. So actually. I guess. We can do. A function. An anonymous function. Without assignment. So that's a function. And therefore we can apply it to something. And that's the same as first of presiding it to F and then calling F on the thing. Assignments. Okay. So we can go. Equals three. A. And then this is the same thing. But with printing. And we can assign a list. And that's the same thing. I'm curious to see if the. The box still. Own the value three. I guess I could check here. It said that there was some special thing when you reference it. So no. It doesn't. It's not a normal variable. It's a weird special thing. When you reference it, a prompts displayed and input is requested. And then you can put things after it as well. Like IO and stuff to change the way. All right. So. That means we can do. We've got a. We've got a row of our matrix. We've got a row of a. We could do also things like. Row of three. And that's this is special. This is. This is a scalar. I believe. Although it's printing out. Well, this is a scalar. Oh, no, this is not a scalar. This is just a, this is like the empty set. This is nothing at all. Which I think. There's a symbol for. Might not count as a. As it's one of the last three, I think they call it. Just one moment. Yeah. Sorry. So it's one of the last three. Okay. This is a zero or one of the last three. So. This is the zero. Or something. The old day. Empty vector. Is a numeric constant. Okay. Let's see if that displays the same way. It is. Okay. And the shape of that is zero, I think. How do you enter that. To check the shape. How do you type? I just posted it. Did you find that as a matter of interest? It's kind of far right of your keyboard up at the top. Right. Three from the right. Oh, well found. I see. Empty numeric vector. Great. So interestingly, the rank of Zilday is not Zilday. It's actually an array containing zero. And so this brings us to the song, which is that if I, so given that row of mat is two, three, that means row of row of mat is two, right? Because it's like this is a list of one dimensional array, containing two elements. So this is row of two, three. And so row of that is one. And because row of Zilday is this, row of row of that is one. And row of row of row of that is one. And actually let's go higher dimensional. We can do bigger ones. We can say give me two faces, each with two rows, each with three columns. This is like a kind of a rectangular prism, if you like. And that's how they display it. Oh, A changed somewhere along the lines. Let's run this again. Use A. And you'll see it's created two matrices that kind of you can think of them as stacked on top of each other. This is a rank three tensor. And when it ran out of numbers from A, it just went back to the start. So you can use row as repeat. So for example, if I use the scalar, it's just a matrix of ones. So let's call this C for cube. And so we can get row. On that matrix thing, does the thing on the margin of it mean anything to you? This one here? No, like the one above it. This one here? Yeah. Yeah, so this has got two. There's actually two dimensions happening here. There's this dimension and there's this dimension. So ideally, if we had a 3D display, they would be on top of each other. But we don't. So it just prints them with a space between. And it puts two dimension lines here to tell us this is actually representing two separate axes. Because this is two faces by two rows by three columns. I see. OK, so each arrow is kind of a dimension in that sense. Exactly, exactly. Yeah, so we could do row of row of row of C. And so row of row of row of anything ends up being one. And so that gives us our first and possibly only APL song. APL, row, row, Richard Storman. Here we go. Oh, there is actually a dialogue poetry section. That's important. And here's the one about row, which Claire and I have now learned by heart. Row, row, row of X, always equals one. Row is dimension, row, row, rank. APL is fun. So yeah, row, row, row of anything gives us one. Row of something is the dimension. So it tells us how many rows by columns or whatever. I would call it shape. They call it dimension. Row of row of something tells you the tensor rank. So that's why that poem. One above, it's pretty good, too. Nice. Oh, there you go. There's an MP3 recording of an APL song. So to wrap up, let's do iota, which is a nice easy one. So iota is just the same as range, basically. So iota for, it's the same as range, except it starts at 1 rather than 0 by default. You can change that. I believe you can say quadio0 or something like that to change, like, so it starts at 0 instead of 1. I kind of like just going to leave it in the default because otherwise it's just going to get confusing, I think. If you haven't found it yet, one of the really cool things about iota is you can range in multiple dimensions. So if you do iota 202. Yeah, so it's creating basically all of the coordinates to kind of index into a multidimensional structure, I guess. And so this is like the Cartesian product of the set of 1, 2 with a set 1, 2, 3. And so now we've got arrays and arrays. And so you can see the symbols changed. So to create our matrix, an easier way to create the matrix would have been to just go 2, 3 row of iota 6. So iota 6 is 1, 2, 3, 4, 5, 6. And then 2, 3 of that is the matrix. All right, so let's, oh, did I close that? Oops. I had a question. With iota, you know how in Python we have a start, stop, and step? Is there something similar with iota? No, it's not. But you don't really need it, right? Because let's say I want to step by 2. That's easy enough. Or if I want to start one more than that, that's easy enough. So I think that's why, because we don't really need it. OK. iota, iota, iota. Where is it? Here it is. OK. Monadic iota means index generator. OK, so that's why it's called index generator, because these are the indices of all of the locations in a 2 by 3 array x generator. OK, let's just check the help for index generators to see if we missed anything. OK, so r equals iota y. You pass it a scalar or a vector of non-negative numbers and you get back a numerical array, the set of all possible coordinates, which is exactly what we thought. Oh, so that's interesting. So I think one special thing is iota 0, which is another way of getting that order thing. That's the empty set. OK, so the dyadic version is index of, and this won't make any sense really until we've got strings. So let's do strings first. OK, so strings are basically vector arrays, sorry, character, character, characters, and character vectors. So that's a character vector and that's a character. And so now we should be able to understand their example. So I've noticed the examples when I click on the name of the dyadic version, for example, the examples tend to be more complicated than the one in the overall summary, just to warn you. So I'm going to use the simpler ones. OK, so index of takes this array and tells you the index of each of these things. And so remember, this is a list of three letters. I believe it's identical, is it? Let's see. Actually, here's ACF and here's a list containing AC and F. Yeah, they're the same thing. So that's interesting. Yeah, so that is a single character. This is a list of characters, and this is just a little syntactic shortcut for creating a list of characters. And lists of characters appear with no space between them when it outputs them, but they are still just lists of characters. I believe that you put a character on the right-hand side that's not in the left, like the V. It will give you one more than the total length. Oh, good. That's how that works. So that 11 is there, but it's not actually in the list. Thanks. Got it. So then an interesting example they have is what if you've got a higher-ranked matrix? So here they're saying, oh, let's assume we've already got a matrix with this in it, because they're assuming we don't know how to create one. We might get confused. So now that we do, let's go ahead and create one. So we create a matrix, and they used three rows of two columns of iota 6 of a row. OK. And so then they said, given that, what if we do this? Now, what's that doing? The first occurrence of subarrays in Y, which match major cells of X. Oh, OK. So this is an important concept. I don't know the difference between a subarray and a major cell yet. But the idea is, OK, so Y is the thing on the right. X is the thing on the left. OK, so here's Y. So it's going to try to find this subarray in the major cells of X. So they're going to treat this as a row and try to find which row contains that in it. And the answer is row three. Does it work if you put 1, 3, 5 or something? We'll find it, I guess. So that doesn't work. I'm pretty sure it's not going to, because that's not considered a major cell. Yeah. So the major cells of this, so it's rows. So if you wanted to do this, you'd have to transpose it first. And there is a transpose operator. There is. So we should probably do a, I think, something that's missing in the dialogue docs is the simplest possible versions of things. So let's just say let's find the number three in the list. 1, 3, 6, 5, 4. Now, why is, oh, wrong way around. In the list of this, find the number three. There we go. OK. Are we done? I think so. I think we made good progress. I think so, too. Thanks, gang. Are vectors list and arrays the same term in APL? No. An array is like a NumPy array. So an array can be any shape. So a vector is a rank one array. A matrix is a rank two array. A scalar is a rank zero array. I don't know what we call rank three arrays, but yeah. It's the same as what PyTorch causes tensor. Although one difference is a PyTorch tensor can't contain tensors. But I think a NumPy array can contain arrays. So it's probably more like NumPy than PyTorch. All right. Thanks, everyone. That was cool. Well, you all learned something there, hopefully. Bye. Thank you. Bye. Take care, everybody. See you.