 Welcome everyone to the session why APL is a language worth knowing by Rodrigo and we are glad that he could join us today. Without further delay handing it over to you, Rodrigo. Hello everyone. Good morning or good afternoon or good evening. I guess it depends on where you are at right now. It's a pleasure to be here with you today at Functional Conference 2022. And today I want to tell you why I think that APL is a language worth knowing. So before we jump straight into it, I just want to tell you a little bit about myself. My name is Rodrigo Girons-Ran, but you can just call me Rodrigo because I guess it's easier for most of you. And my formal education is in mathematics. And today we're going to talk about code and in particular Python and APL. And I have, I've been writing Python code for around nine years now and APL for two. And my main occupation, we can say is training a teaching APL for a company called Dialog Limited, and I also do some teaching of Python and mathematics for my own personal project at MathsPP.com. Now, why is APL a language worth knowing? So why am I making a talk out of this? Well, I really want to tell you a little bit about my personal experience and I want to go a little bit deeper than just saying that APL is a language worth knowing because learning is good. I want to go deeper than that. And I want to start with a quote by Ellen Perlis, which was a computer scientist and the first recipient of the Turing Award. And the Turing Award, for those of you who don't know, is often described as the Nobel Prize of Computer Science. And Ellen Perlis wrote that a language that doesn't affect the way you think about programming is not worth knowing. And what I want to do is I want to take that statement and think about its inverse that says that a language that affects the way you think is worth knowing. And so the thing here, the core idea here is that as per usual with anything in life, when you're looking at something, when you're studying something, when you're trying to understand something, when you have different angles and different perspectives on something, it's easier to understand it. And in particular, I want to tell you how APL changed my perspective on programming, how it taught me different things or about different subjects and different topics. And well, I just want to tell you how or try to show you how that influenced my Python code. Now, there's an obvious disclaimer that I should make. And that is, I'm talking about my personal experiences. And so I'm not trying to make any universal statements about Python or about APL or about anything really. I'm just telling you about my personal experience with Python and the way APL and the way learning APL changed the way I write Python code. So without with that out of the way, I'm assuming most of you heard of Python because it's a very popular language. But the fact is that APL is not so popular. And so what is APL? Well, APL is a programming language that started out as a, like an alternative mathematical notation. But it then evolved to a programming language because it was so precise and so objective that it just turned into a notation that a computer could interpret, which is a programming language. And APL, the main paradigm in APL is being array-oriented. So we work mostly with arrays. And the thing is, when you work mostly with arrays, this also pairs up really nicely with functional programming. And it's a very concise notation. So it's a very concise language, which means you can express many ideas in a short amount of code. And APL is also very well known for its quirky symbols. So we are typically we are used to having languages use English words to represent functions and et cetera. Well, in APL, we tend to use symbols like the ones you can see on screen. So when I present APL code, it's always going to look like this. So we're going to have expressions on the right and the results on the left, expression on the right, result on the left. And the quirky symbols I talked to you about, they are the built-in functions that APL has. So this Greek letter right here, this iota, this is the index generator function. And so what it does is iota six is going to give you six consecutive integers. So akin to the function range in Python. And now APL is array oriented, like I said, and what that means is that we have built-in support or native support for arrays of multiple dimensions. And in this talk, I don't want to go too deep into that. It's very interesting and very useful, but it's I want to keep this as simple as possible. So we're going to focus on scalars, simple scalars like the 15 here, or the 16. So these are just numbers. They're simple scalars. And when you have scalars in succession, what you get is a vector. Like over here, we have six scalars in succession. So we have a vector with six items. And now there's just one final thing I want to tell you about APL. And that has to do with this expression. So right here we have an expression that reads 10 minus five minus two. So what is the result of this expression in APL? Well, if we were to, and I see people in the chat trying to guess, and your guess makes a lot of sense, right? If we were to parenthesize this from the left, we have 10 minus five is five, five minus two is three. And this is the way traditional mathematics would go about solving this. However, this APL expression results in a seven. And why is that? Now, I'm not going to be very precise, but it's intuitive enough for the purposes of this talk. That's because APL, well, parenthesizes from the right, five minus two gives three, and 10 minus three gives seven. That's why people typically say that APL evaluates from the right to the left. It's not exactly true, but it's good enough for the purposes of this talk. So having said this, let's start talking about why I think APL really changed the way I work with Python. And the first thing I want to tell you about is the way APL influenced my list comprehensions. My list comprehensions are a syntetical construct that many languages have. And in order to understand why I think my list comprehensions changed and why I'm more comfortable with them now, I need to tell you about scalar functions, because scalar functions really, really are something ends. If this was not obvious from the beginning, my background is mostly with imperative languages. So this that I'm about to show you really changed my perspective on programming. So we've seen Iowa, which is the index generator function, it generates a sequence of integers. Now what I want to show you is that with APL, it's really, really easy to take this and just increment every number by one. Because arrays are made up of scalars and scalar functions like the plus so addition here, scalar functions in an intuitive sense, they just want to get down to the scalars and apply the function to the scalars. So in a way, it says if we were ignoring the structure of the array, just to go deep into the scalars and that's why the one plus really doesn't care about the fact that these are six different numbers it's just going to do one plus each one of those. Similarly, multiplication is a scalar function. So I can easily double each number. So very quick recap. I said that scalars make up all arrays. And I said that in some sense scalar functions do their best to act on scalars. And what falls out from this is that scalar functions are great for processing all of your data at once you just have to arrange all of your data in an array. And if you use scalar functions, you get to process all of that at the same time. So we've seen that scalar functions are fine with having a vector on the right. But you can also have a vector on the left. Why not. If it makes sense for your function, fine. And the addition is commutative so really 10 plus all these numbers are all these numbers plus 10. It really is the same thing. And as long as it makes sense as long as the shapes are compatible you can even have vectors on both sides. That's also perfectly fine. So we can use three numbers on the left, three numbers on the right so we can just pair them up 100 times to use 200 zero times three and one times for scalar functions are fine with all of this. And in APL, there are plenty of scalar functions we've seen plus and or additional multiplication, but you can also have the power function. So you want to three square, which is 149, or maybe you just want to compute I don't know the first powers of two. So you do two to the power of your iota six. So power, the asterisk is also a scalar function and so is the residue function. And the residue function you typically see it as the so the percent sign in some languages or the mod function in some other languages. So it computes the remainder of the division so if you have 123 and you divide it by 10, you get 12 and the remainder is three. So that's why you have a three right there gives you the remainder of the integer division. For example, to residue something is going to give you a zero for even numbers and the one for odd numbers. And that's why you have a number of scalar functions. And what I claim is that using them and becoming comfortable with them influenced my list comprehensions. And so what I want to show you is how or why. List comprehensions. Like I said, there are these syntactical constructs that lets you build new lists out of existing lists. And one has list comprehensions. And I think list comprehensions are great. And I just want to show you how I became more comfortable with them because I knew list comprehensions were great. I knew you were kind of supposed to learn them when you know Python, but I, well, I just struggled with them in the beginning. So as an example, let's say that we have square integers. Sorry, you don't have square integers. Let's say you want to square the integers from zero to nine. What's your typical Python solution. Well, you just create this empty list where we're going to store all of the squares. Now you're going to iterate over the integers from zero to nine. And then after you square the number you put it inside the list of squares. This is your typical Python approach. And then you just check that you got everything right. And then if you look at this structure, these three lines of code. This is a very simple recipe, because the first step is to create an empty result list. The second step is to go over your existing lists or similar construct. And the third step is to take the modified value and add it to the result. And this is such a generic, such a generic algorithm, such a generic construct that's the Python people and in many other languages, they understood that it made sense to make this simpler. And if you reject things, you get a list comprehension. And now I think that's from the Python perspective, it's really important to understand that this really is just changing the place of things. So you have the for loop here and the squaring. And you just change the order of things. Now you have the squaring here and the for loop there. And this is the Python list comprehension. Now, what's the relationship between this and the way APL would solve this problem. So how will APL square the integers from zero to nine? How would they do it well? Simple enough. You just generate the integers from zero to nine. And then you square them. That's all there is to it. And why is this interesting? Despite being very, very convenient, the interesting thing here or one of the interesting things here is that APL puts a lot of emphasis on the data transformation that you care about. In this case, I want to square numbers. And there's a lot of emphasis there. Or maybe it's easier to look at it the other way. Notice how APL does not spend a thought on telling you that you have to go over your list of numbers. It just does it. And that's this key idea here of just doing what you need. That's going to really, or that really helped me take the next step with these comprehensions. And to help drive my point home, let's just look at another example. So imagine that you have a number and you want to compute its units digits. The standard way to do that is by doing the integer division with 10. Yeah, with 10 and checking the remainder. So in Python, that would be the percent operator, which is the module. Now, this is for one specific number. How would you do that for, say, a bunch of numbers? You have a list of numbers? How can you compute the units digits of all these numbers? Sorry, that was my phone ringing, which is not cool during a presentation. So sorry for that. So if you have a bunch of numbers, how do you take this and make it work for all of those numbers? Well, you use a list comprehension. And the thing is you take your transformation and you just wrap it around. Python syntax for that. And to me, and in hindsight, this is all very obvious and you'll have to bear with me because I'm going to say a lot of obvious things. But the truth of the fact is that I only reached these obvious conclusions after hours of reflection and after having written plenty of APL code and plenty of Python code and realized that there are connections here. And the connection here was just you take the expression and you just have to wrap it around some syntax. And I find this very, very interesting because now if you take a look at how APL does it, APL does it this way for a single number. You have a number and you the 10 residue of that number. But if you have a bunch of numbers, you just do the same thing for all of them. And like I said, this is very convenient because you're dealing with large amounts of data all at once. And it almost feels like working with one number, or five numbers, or 100 numbers, or however many, it's the same thing. You write the same code. So quantity doesn't really matter what really the only thing that seems to matter is what you want to do. In this in those being very liberating because there's one less thing for you to worry about. And when you get used to this way of coding and to these concepts and principles, you start looking for ways to apply them in other places, even in Python. And so if I just make like this very basic diagram with these four expressions, there's it just, it's just right in front of you. So on the left we have the expressions for a single transformation and on the rights, we have the expressions for multiple numbers. And so what we really see is that the least comprehension is Python's best way or best attempt so far at letting you work with plenty of data at the same time it's the most convenient way you can do it in Python. And in APL, the expressions are the same really up to the name of your variable and in Python, you take your expression the expression that matters. And you just rapids with some syntax. And so what does this mean it maybe it looks like I'm just trying to say that least comprehension set because I have to put the syntax here that's not what I'm trying to say what I'm trying to say is that. And now when I have least comprehensions, when I'm going to write them, I just focus on the transformation that I want the core thing the core idea. And I write it down, because that's easy I know what I want to do it with each element. So I just do it. And then I just have to do this almost automatic thing of pattern matching the rest of the list comprehension I just have to write down whatever syntax is left to right. And now it's, it's almost automatic because I already know that's a big portion of the least comprehension is just syntax for Python to understand what I mean. And so it's simpler for me conceptually simpler because I know what's what it is that I care about. But why should I bother with all of this why would I care about least comprehensions how would I convince someone that least comprehensions are interesting. How can I convince them to learn them. Well, the diagram with the four arrows, it's made me realize that a key argument in favor of least comprehensions is that your data transformation is now highlighted. It's emphasized, because it's right there in front of you instead of being inside a for loop inside of all of that clutter when we have the traditional approach. And again, this is, this is almost a trivial statement. It's obvious that the transformation is highlighted it's the very first thing in the least comprehension. However, you can believe me or not, but it's it's true the truth is, I've been involved in many discussions about why least comprehensions are interesting or not and whether you should teach them to people learning Python and whether to use them when to use them. And no one has ever told me that this is what I think the key argument in favor of least comprehensions. And I was only able to get here to understand this when I realized the diagram that I showed you that the key transformation is really what you write first. Maybe I'm just being sitting down and across the zoom maybe it's it's difficult to put across like the, how excited I feel about this because this really was an enlightening moments for me when I really understood this. Now the thing is least comprehensions they can get more complex, and there's some variants with some filtering and interesting things and I want to get there. I want to talk to you a little bit about Boolean values and the way APL handles them and the neat things you can do with them. Now the Boolean values are just these, typically the two values that the language uses to represent that the truthiness and the falseness of logical statements and languages like Python and Haskell and others use the words to enforce with the first letter in uppercase, other languages use the same two words but with all lower case and language other languages maybe use them in all uppercase. Fine. Truth is APL uses neither of these. Because in APL, when you have a condition that evaluates to true, you get a one. When you have a condition that evaluates to false, you get a zero. And depending on your prior experience with programming, this may look weird at first. But it's actually very convenient, and I think I can convince you of that. And in order to, we'll see obviously we'll see examples but just from a philosophical point of view. Why can this be convenient or how would I justify this? And if you think about it, if you think about how if statements work, they typically have a condition. And if the condition is true, you just run whatever is inside the statement. And if the condition is false, then you don't run. Fine, that's how if statements usually work. But what we've seen with APL is that you try to have arrays of values because you want to work with everything at the same time. However, if statements, these conditions are atomic things. It's just one condition. And so if statements, they would only be good to determine whether or not to do one thing wholesale to the whole array. You have arrays of values and you want to work with them, but maybe do slightly different things with them if you want to do some computations or if you want to do some computations. But if you want to tweak them slightly to change some parameters, that's hard to do with an if statement because you want to have fine grained control. Or rather, if you want to have fine grained control, you can't use if statements. You need to use mathematics. You need to use some computations. You end up with what some people call data-driven conditionals. And data-driven conditionals, they're just, I think they're more easily understood if I oppose them to if statements. So if statements, they tend to ask, should I do X? Should I do something? Whereas the, so the data-driven conditionals, they instead ask, how should I do X? And it's a very subtle difference. In here, we ask whether or not we are about to do something. And for data-driven conditionals, you kind of assume that you are going to do X. So you're going to do that action. The only thing, the freedom you have is in tweaking the action a little bit. You can always do whatever it is that you need to do, but you just try to adapt it the best you can. And let's take a car rental as an example. Let's say that renting a car costs $40 a day as the base price. And then you have some extra fees, and the fees depend on your age. So if you're 25 or older, you just pay $200, but if you're 24 or younger, you're going to pay $500 as extra fees. So how would you write an expression that computes the total price of the car rental or of renting that car as a function of the number of days you're going to rent and your age? So how would you do it? The typical Python approach, let's write a function. The price is going to be the $40 times the number of days. And then we are going to check the age of the driver, and we are going to add the extra fees accordingly, and then we just return the price. Fine. This is one fairly straightforward Python approach. Maybe someone a little bit more fluent would actually rewrite this with maybe a conditional expression. So we have the base price. Then we have the fees, and the fees are $200 if the age is 25 or more, otherwise they're $500. And this is very readable, fairly elegant, and it's the Python way to do it. And if you take these two solutions, so this one and the previous one, you can even see that this animation is nice because of that you can see that if there it's going to slide across the line. So there's still an if you still have branching going on. So algorithmically speaking, these two solutions, they're pretty much the same. Now what's nice or what's worth thinking about is the contrast between this solution and one possible APL solution. So if you were to do the same thing in APL, you would, you are likely to find an expression like this. And I'll just show you how it works really quickly because this can look very weird at first when you're not used to it. It's easier to explain how it works through examples. So let's suppose that the age is 56. Now is the age less than or equal to 24? No, it's not. So it's a zero. And you all know that 300 times zero is zero. And you all know that 200 plus zero is 200. So when the age is 25 or more, the expression simplifies to this. And on the other hand, when the age is 24 or less, what we see here is that this inequality is true. So it evaluates to one and 300 times one is well 300 and 200 plus 300 is 500. So when the age is 24 or less, the expression simplifies to this, which is pretty much what the statement said, the problem statement said. So this expression. Well, how did I get here? In the first place, I can give you the very annoying answer of, well, it's just when you're experienced enough with APL and mind you, this is not advanced APL. It's, it's actually fairly straightforward, quote unquote, but you just you learn APL and things like this, you just learn them, you get used to writing them. And so deduce this expression through some mathematical manipulations. Or, I think, more interestingly, another way to get here is by taking the problem statements which said that the base price was $40 per day. And then you had some extra fees, and you can actually refactor the problem statements. To refactor the problem statement, you can rewrite it as such. There's $40 per day as base price. There's $200 in extra fees. And then there's a $300 surcharge, surcharge when you're 24 or younger. And this is another thing I really like about the PL is that when you have a statement, if you want to write with the PL code to tackle that problem. You really have to think about the problem and find the perspective on the problem that's amenable to the techniques that APL really wants you to use. So this is the code we wrote. Now, let's take a strategic break for me to take a sip of water. Very important. This is the code that computes the price of the rental for one driver and one rental for a certain amount of days. Now, if you want to handle multiple drivers, multiple rentals, you don't need to do anything. You just add the data to the vectors and your expressions still work. And maybe the next thing you might ask is, well, how do I compute the, I don't know, the total amount of money that I get? How much would I net from all these rentals? You just send them. And let's take this, this plush, gosh, this plus slash bar, let's just read it as the sum. Okay, just to make our lives easy enough. So the plus slash bar of the prices, this vector right here just sums it. That's great. Fairly simple, fairly straightforward. So how would we do this in Python? Well, it's the same recipe. You start out with your data. You define an empty list. You go through the lists of the ages and the days together. You compute your base price and the fees. And you just add the prices. You just keep track of all of the prices and in the end you can sum. For example, this is not the best Python approach. It's just one way to do it, right? But now what APL shows is that I can be as crazy. Not as crazy. I can be maybe crazier in the eyes of a Python programmer and I could actually write something like this. I could just write this expression, the money, the total amount of money I net. So the thing, all of the money I get, it's just a sum of this expression across the two lists. And again, notice how this expression right here. It really is similar to the APL expression. The only difference is that APL works on whole vectors at once and Python doesn't. So in a list comprehension, you need something else. You need just a little bit of syntax to get everything to work together. But the core idea, the core transformation, well, it's there. Right, so now we know how Boolean vectors work. And now we can talk about list comprehensions with filters. Because so far the list comprehensions we've seen, they act on the whole existing list. For example, I have a list of integers, let's square all of them. But in Python and in many other languages, you can take list comprehensions that filter the data. So for example, if you only want to square the even integers, you can add a filter over here on the right. You can add an if statement there. Well, it's not the full if statement, but you can add an if something. So now what this says is, let's take a number and square it. For all the numbers I can find in this list, but only if the number when divided by two gives a remainder equal to zero, which can be said in a shorter way as square all the even integers. The thing is, when you start writing list comprehensions like this, even more people start to argue with you saying that list comprehensions are complicated and difficult to read. And at first I also struggled with these list comprehensions they were. I found them too confusing or difficult to write. So how did I get to grips with these things because to me now this feels much more natural. So what did I do what what do I think to make this easier for me to understand. Well, the thing is I learned about another function in APL. So APL is this has this forward slash here. And in this case, what is it doing it's the compressed function. And it has this vector on the right. And when it has a vector on the right you can give it a Boolean vector on the left so you can give it a vector of zeros and ones. And now these zeros and ones, you can think of them as switches that are either on or off. And the ones these are switches that are on and this means that we want the corresponding values so for example the last switch is on. So it means that we want to keep the 10 and the 10 is in the final results. The first switch is on. And so we want to keep the first number the 42. And that's why the 42 is over here. But this switch, this is off. And so the 73 which is the corresponding number. We do not want it. And that's why the 73 is missing from here. So this is what the compressed function is doing in this case. So how do we do how do we take this n square even integers in a in a vector. So we have a vector of numbers. Here you do the two residue, and you check you compare that with zero. So the zero equals two of the residue or zero equals the two residue that's that's checking whether the numbers are even or not. So ones mean even numbers. Now, if you take that and you compress the original vector, you get the even numbers, or you filter the odd numbers out. And so if you want to square all your even numbers, the only thing you need to do is you need to take that. And you square it. This makes sense right if you want to square your even integers you take the even integers, and you square them. So after seeing this connection between the expressions in APL and the least comprehensions I just started thinking of least comprehensions with filters as a two step process. Just like APL does it you filter. And then you transform the data. And that's not really how Python does it because the two things they're not done in in separate in separate steps. They happen, more or less at the same time but in writing the least comprehension. It's again easier for me to focus on one thing at a time. Because I know that in a way, they're kind of independent things to focus on. I like the filter, which is one thing, and the transformation which is another thing. And that's really made it easier for me to write these comprehensions with filters. Now this whole thing, and this whole talk and all of these tiny enlightening moments I had these all were triggered by me, writing a piece of Python code that's when I look that it's, I actually surprised myself for having written it. So it's kind of weird but I wrote a line of Python code, more or less automatically and then when I look that it's, I was actually surprised by having written it so let's, let's see what it was because that was the line of code that's made me realize that APL really was changing the way I think. And that was when I was counting the number of values that satisfy a predicates. So a predicate here that's just going to be like a condition a function that returns true or false. I just want to check what values in a vector or in a list satisfy some restriction. For example, we can have a vector of numbers. How many fives are in here. So the predicate here would be comparison with five like five equality so in APL you just take the five and you compare it with all of the numbers. And because bullion, gosh, because bullions are zeros and ones to count the number of fives. You just need to sum this bullion vector so it's the plus slash bar of the five equals. And this is how you would count the fives in this vector. So what does this have to do with Python. I'll show you I have a list of values. And I wanted to check how many fives there were. And again, the, the most straightforward Python answer is to initialize a counter to go over the numbers to check if the number is a five and to increment the counter when it is. That's maybe the most straightforward answer. And now if you've been paying attention and if I was eloquent enough you should be able to modify this for example, to have instead of an if statements that only increments the counter sometimes. Maybe you can already rewrite this as a loop that always changes the counter. It's just that it changes the counter by a different amount each time. And in fact, it changes the counter by one, when these match or by zero when these don't match. But the fact was that I didn't write this code. The code I wrote was this one. And this code. Consider how similar it is to the APL code. It's just the sum of the numbers that match five or that are equal to five. And I don't think this is very complex Python code. I just mean to say that before learning APL I would have never written something like this. And now that I know APL, I do things like this. I just find it interesting that learning a seemingly completely unrelated language led me to this Python idiom where whenever I need to count how many values satisfy your predicates in Python, I know I can just do this. I can just do the sum of the predicament of value for all of the values. So I just need to use the sum on a list comprehension. I just find it interesting. That's why I decided to do a whole talk on this. So as a recap or as a high-level recap of what we've gone through, we've taken a look at scalar functions and how I think they really influenced my list comprehensions and my understanding of list comprehensions. And we've looked at how APL tries to use mathematics instead of branching for these data-driven conditionals and for these operations that really need to be different on different scalars. And we've taken just a little look at how this can help you write flatter codes in languages like Python. We've also looked at how APL uses the compress function and how I leverage that to be more comfortable with list comprehensions that have filters. And we've even seen how that led me to coming up with or inventing quote-unquote this counting idiom. Now, this whole talk, I wrote it down when I was preparing the talk. So there's an article with this talk and it has more examples. So you can go check it out. Of course, you don't need to write down this link because I'm going to share the slides on GitHub and on the conference page. So you can go to this repo and I'll upload the slides soon. And you can always, and I invite you to reach out to me at hudriguetdialogue.com. Just send me your feedback, send any questions I will be glad to connect with you. And I just hope you learned something. Thank you for your attention. Okay, we are having few questions in the chat section itself, but they are being answered by the other attendees. So if you want to have a look at the chat, there is some interactive chat going on. The questions that are being answered that itself. Yeah, so I see. You also have a question by Joe fish. By who sorry, are you in the Q&A. So I'll read the question a lot for people watching maybe the recording. So the question says, APL seems very esoteric with special operators such as slash bar, such as the slash bar operator. So only if you know the esoteric operators it will make any sense. And any unfamiliar symbol makes it instantaneously unreadable. So if we're branching in APL, we need to run in our heads to see how the zeros and ones play out. Are there any real world use cases to use APL compared to other languages. So I guess I'll just break this down. And so there's plenty of things to address here in this question in my opinion, and different people have different opinions but one thing said was, if you are so any unfamiliar symbol makes it instantaneously unreadable. So it doesn't make it instantaneously unreadable. It's just that you even identify a symbol, so a function view that you don't know yet. But that's fine because if you're reading code from someone else, say Python code, and they are using some specific libraries to achieve a specific purpose. So likely that you don't know all of the functions of that of that library, right, and you have to go check what they do. And then you can say, well, yeah, but the functions in those libraries they, they probably use English names and I might guess what it's in there as opposed to APL symbols because it's harder to guess. Yes, you are right. It's harder to guess what the APL symbols do. On the other hand, the APL symbols, I think there are around 70 symbols. Is it a lot? Yeah, maybe it's a lot. But Python has around 70 built-in functions. Whereas most people don't know all of the all 70 Python built-in functions. It is very, it's much easier to get comfortable with the 70 symbols from APL because the symbols they were carefully chosen to make it easier for you to remember what they do. And so it's much easier to learn the 70 symbols from APL than the 1770 built-ins from Python, plus all of the methods on all of the types, plus all of the libraries, plus all of the functions in those libraries. So, yeah, the unfamiliar symbols they are something easy to tackle just open documentation page. And in a couple of minutes you'll be good to go. Again, we mentioned branching in APL. We need to run in our heads to see how the zeros and ones play out. Also true, but it's only two cases. In an if statement you also have to check what the true case does and what the false case does. So I don't think this is much harder or much complicated. It's just that you're probably not used to doing it. But when you first learn programming, you are also not used to checking the true, sorry, the two branches of an if statement or the multiple branches of a switch case or something like that. And then finally, the real-world use cases. There are real-world use cases. There are companies out there that use APL for real-world things. And it's mostly related with what we've seen, which is when you need to handle a lot of data at the same time. APL really makes it easy and convenient to work with big arrays of data. So yeah, I don't know how specific I can get into the specifics of those companies, but I definitely can say this. If you have large amounts of data and you want to work on it all at the same time, APL is great for that. There's another question in the Q&A. Do we have time for? Yes, we do. We can take this one. Okay, great. So yeah, in the Q&A it's written, are there any other programming languages that treat scalar functions the way APL does? And then inside parentheses, applying them over vectors transparently. And the easy answer is yes, there are because APL is unique in the sense that it's very different from Python and the other languages I knew. But there are other languages in the family of APL. So there are languages like Q&K and BQN and J that have this way of handling scalars. And then in the chat, Aaron posted a couple of links that mention real-world customers of APL. So real-world companies using APL right now. So thanks for the link, Aaron. Yeah, I see no other questions in Q&A, and there's yet another link in the chat now. So if you're interested in, can I read those out? Yeah, so just go to dialogue.com slash reference dash customers slash index. Htm, yeah. You can see some customers there. So Brandon asks, dialogue APL and new APL are the first implementations that come to mind? Are there others? And are they significantly different in terms of APL? Yes, there are other APL implementations. You have APL too, which I think is now discontinued or was recently discontinued. You have NARS 2000 or something like that. You have NGN APL, you have XIMA APL. Those come to mind. Some of them are significantly, I don't know what you mean by significantly it's subjective, like the essence is still the same, the built-in functions are pretty much the same. Some of them restrict some features or some of them have given you more freedom in certain aspects. But yeah, there are definitely different implementations and there are differences across implementations. So I think you're Rodrigo for sharing your experience with us today.