 So should we go ahead and get started? So I'm Aaron Sue and this talk will be an order of magnitude less code than Roger's talk. We're focusing on something slightly different. So the early disclaimer this is an educated hyper drawing statements and a little bit of fun a religious sermon are purely imaginary and of a suspicious mind so with that out of the way don't be fanatical. Enjoy your computing and put some fun back in the coding that you're doing. So we have to talk about the elephant in the room APL Morton likes to describe it as in specific language languages for problems that problems that we can solve or think about using arrays, which is basically everything. So it's a rather infamous language or is it a wonderful language and the answer to that is really going to depend on are you a computer scientist or are you normal folk and if you're normal folk it's a wonderful magical useful language and if you're a computer scientist, unfortunately the experience is slightly different. This is kind of tragic but not all computer scientists are like this. Not everybody has this experience. Alan Perlis found a lot of interesting things to say about APL. He brings out particularly terseness, flexibility, composability and I want to emphasize these last two bolded sections natural language pros and artistic possibilities. So Noresh failed to include a very important group in his group discussion or group exercise, which is the computer artist, the artist in computing. We need to remember that. So the computer scientists that like APL, unfortunately, they often end up here. We've moved past the baby stage, but well we're almost there, right? Just a little bit more we'll get over the fence. So really this talk is about answering this question. What are we going to do? How do you actually learn APL? How do you, as a computer scientist, actually make some progress in understanding what makes this language unique and special and get the value out of it that you want and everybody begins with the game of life. Right? Jon Scholes' game of life demo on YouTube. It's wonderful. It shows the magic. Everybody goes, wow, yay, cool. But then they get stuck and unfortunately they go to write their own code and again, we're back to what am I doing? None of this makes sense and I've been asking myself why for a while and I've come to the conclusion that we have this emotional attachment to engineering concepts in computer science and in computing and this has come a lot from the software engineering movements and things like that. We've sort of claimed that we're not part of that anymore, but we still are. We've been very informed by this experience. In fact, what we have is a cult of best practices. In fact, pretty much everybody now worships at this cult of best practices and where did we get these best practices? Well, through the ages of developing and working with our software, problems have shown up, driven by the machine and we've invented our own spaces, our worlds, our programming languages, allows us to live in these worlds, but the ideas that are driving these programming languages are driven by the machine. We're living in a world designed by the machine and we follow these best practices so that we can live in this world and it makes sense. Sound like something else, you know? The matrix. So, what if I told you that APL is easy to read? All you have to do is free your mind. Free your mind from the matrix. And to do this, we have to go back to the origins and the design principles that Ken Iverson talked about in his Turing Award lecture, he framed them all in terms of these two quotes. He set the stage with these two quotes and these quotes are about the power of notation to affect the human's capacity, mental capacity, to engage with problems and with complexity. And to reify this or put some some meat on this, he developed a set of principles that he says a good notation should have. APL is a notation. Notice I'm really focusing on human here. Keep that in mind. So with APL, what we're aiming for is ease of solution expression. That means the degree to which problems find a suitable and easy expression in our language natively. Suggestivity is a really one of my favorites. It's the degree to which when you write some piece of code, that code inspires you. Suggests alternatives, patterns, ways of looking at things. It's not just about seeing what's there, but seeing how that thing that you're looking at, that piece of code could apply elsewhere. Maybe it suggests that you look at a different type of code or a different approach or you see connections and patterns. It's about recognizing the bigger picture. And to do that, we need to subordinate detail, but not abstraction. Abstraction is hiding away detail and pretending it doesn't exist. This is letting ourselves know the detail exists, but subordinating it so it does not introduce an increased mental cognitive load. Economy is an important element because economy is how much it takes to actually get to the solution. So it's not how neat does your little solution look once you've built up all of your frameworks and your libraries and everything else. It's how much, how big is your vocabulary to solve so many problems. As the more problems you solve, does your library get bigger? Or can you solve a whole lot of problems with a very small vocabulary and a very small set of without needing to build up a lot of libraries and frameworks and other things. An economical language will get you further with less than a language that requires you to build a lot of extra abstractions. And then finally, we saw the amenability to formal proofs. I don't think there's any necessary need to belabor that point because Roger demonstrated that fairly convincingly. You AP was great for pushing symbols around for thinking algebraically about your code as a whiteboard language, right? You want that kind of thing. So how do we get from there to how do I actually program with this? Well, basically you're doing it wrong. And what I've developed is a set of patterns and anti patterns. The problem is, as computer scientists, we have embedded these ideas, these best practices in our heads and how that we need to how we need to approach problems. And those are now anti patterns and APL good APL tends to exhibit design principles that are diametrically opposed to the way you've been told how to write good code. And this is a problem because every time you go to write good code, you're making decisions implicitly that you might not even realize based on those patterns. And so to write good APL code, I suggest sticking with a new set of patterns. And I've got eight of them here. Now, these aren't rules. These are principles that are going to drive your thought process. And they'll each be manifested for a given type of problem in a different way. So these aren't rules. These are spectrums of possibility that open up because of the notation we have. And in addition to this, it's interesting to wonder, well, is this intuitive? Is this natural? So I'm going to be referencing Miller 1981 and pain 2001, which are two studies that were conducted with non programmers in an attempt to see when given a programming task, natural language like English, and no programming background, how did they describe the process of programming to other people? What is the the normal human way, the natural programming model that humans work with before they've been trained in computer science? Principles brevity brevity over verbosity. And I think most people think that short code is good, but they don't really actually like short code. They tend to associate short code with cleverness. And that is a bad thing. You want your code to be stupid. But brevity is really about finding simple, natural, easy short expressions that we can work with. So let's consider a nice simple basic example, your average function. So this is an expression in APL. It's a definition for a function that computes the average of a vector, say. So now, if you're in a functional programming language, you probably do something similar to this, maybe a fold reduction with plus over the list divided by the count. That's basically what this is doing. All right, seems pretty good. But now, I want to do this with an arbitrary number of samples that I've taken. So I've done sampling multiple times. And I want to get the average of each of that group of samples. Now, how do you have to adapt your program? What do you have to do? Well, you probably need to figure out whether you're going to do a zip or a map, another map or another thing. In APL, well, no, we don't do that. We just leave it as is because it already works for that as well. And so we've kept things short. And the reason we keep things short, the method behind the madness, is our code is bigger on the inside than on the outside. And this allows us to do a lot of interesting things. One of the biggest things is that it keeps our code malleable. It's easier to work with. It's easier to tweak and play with. We can really move it around like clay. And one of the reasons we can do this is because we have more confidence in our code because the code can fit in our heads. And this is something that's important. You want your code to fit in your brain. And APL is one of the few languages where your average APL or you go to him and ask, what's your favorite program? He'll write his favorite program down from memory. He's got programs in his memory. How many of you could, without looking at your computer, sit down and write without bugs in it, your program, favorite program, an actual program, a real whole thing that does a real useful piece of work? You just don't do that in other programming languages. It's an advantage of brevity that people overlook. So what do the studies say? Well, the studies found that universally, people were annoyed if they felt like they had to be too verbose in the descriptions. They always wanted to try to create shortcuts and create shorter and shorter descriptions. And that's just a natural human tendency because it's a type of optimization that we want to do when we're engaging with process. So let's look at the next macro over micro. I think we can clearly think about this by looking at some pictures. So here's some beautiful bark, excellent picture, wonderful design, micro view, right? We can really see what's going on in this picture. We've got control, right? I mean, if I need to deal with these pieces of bark, I've got it. The problem is we've missed the fricking mountain that's about to come crashing down on us or that we have to deal with. And so the APL are, yeah, maybe we don't see the bark, but we get to see that mountain. We can plan for it. We can deal with it. We can make decisions at a macro level. And that's what you need to try to do when you're code, when you're working with APL. You want to try to look at that global view, that whole thing. I want to think of everything and encompass everything rather than going element by element or item or item. Look at your problem and your architecture and the way the big picture fits together and make optimizations there so that you don't need to make premature optimizations inside the micro level of your code. So as an example of this, we have this partitioning function or using a hash function to do a partition and compute over the elements partitioned by some categorizer. So we've got alpha here. That's our hash function or our hashing function. It'll partition everything that we want to work with. And to an APL-er, it's immediately obvious what the big picture is here. It's that giant square. And it informs everything that we're doing. We can see that big picture. Notice that we haven't cluttered this up with micro equations about iterations, loops, anything like that. We've used a nice easy to identify symbol that clearly defines our access patterns and gives us the big picture. And then we've sort of, we let the rest of it happen and we don't worry about some of these micro-view questions. So what do the studies say? Well, I think it's pretty self-explanatory. When people program and they don't know how to program, they tend to vastly prefer to talk about big picture things using giant sets of things. They almost never use the singular. They always talk the plural about groups of things, sets of things. And they use aggregate operations. Sound like the language we're talking about? So our next pattern is transparency over abstraction. And this isn't a unique idea in APL. We just take it a little bit further. And the problem is we over-abstract today. And we know that we've been abstracting for years because a famous MIT textbook, Structure and Interpretation of Computer Programs, has this in the forward. It says Pascal's for Building Paramids. Insert your favorite statically typed ADT- focused programming language here. And Lisp, Insert APL, is for building organisms, right? So most people are really concerned with building pyramids, rigorous, well-defined programs that are going to stand the test of time. Another way of approaching it is make it so that you can change and adapt. And I would argue that really code must be thought of as an organism and it's best to make sure that your code can evolve because pyramids perish really quickly in the ecosystem of the programming world. So how can we sum this up? Abstraction considered harmful. We need to start thinking about abstraction the same way we think about the go-to. Sometimes we need to use it, but it better be an act of desperation. It should not be our first thing. And you guys think that you could do this in your other languages, but I guarantee you when you think about a problem and you put it down, the first thing you're thinking about is an abstraction, an extra layer on top of things. Am I using a hash map? Am I using a new tree? What libraries can I call? All of this. You've immediately gone to extra abstraction layers. Instead, when you're thinking about problems, especially in APL, focus on directness of solution. Focus on just say the answer. Don't build a new abstraction to explain the answer. You just want the answer. Just do the answer. Just do it. And so what do the studies say? Well, as it turns out, this has been an understood concept in human computer interaction and usability design for a long time. The more mental engagement steps between the original thing with which you started and the solution path that you want to go to, the more mental involvement there is and the more difficult it is to engage in your problems. So don't do that. So how do we be more direct? Well, we've got another pattern. Idioms over libraries. So to explain this one, I'm going to call upon, you guys may know him, Donald Knuth. He's done a couple of things in computer science. And he's a vocal opponent to black box library extractions. Instead, he wants you to have reeditable code. Code that you can take and reuse, yes. But not code you take and reuse carte blanche without ever being able to change anything you need to adapt to your unique situation. So APLers have their own take on this. And we do like our re-usable code. It's great. But don't tell us that we can't change it. We need to be able to reach into that library and change anything we want, whenever we want. Now, that doesn't mean we're going to do it. But the code needs to be accessible enough that we can do it if we need to. So for a really tiny, tiny micro example of this, here is an operation. It's sort of idiomatic. It's a well-known combination of the inner product and dot equals. And it allows you to take, say, a string and a set of other strings and compare that string against the other strings and find out where that string occurs in the vector of the matrix of strings or something like this. It's maybe not the most high-performance way of doing that. But it does express the desire pretty well. And you can imagine you probably have a library function to do this in your favorite programming language. Or maybe you use a map or something like this. You've got equality. Maybe you have to implement compares to for your string object. And then, you know, we're not going to talk about that. But can you then just say, oh, well, I actually want to just do equality over the prefix? So the APL are, oh, we just put that in there. All right. Maybe you've got your library. Maybe it's been genericized, genericated. I don't know. It's been made more generics. And so you can probably maybe replace the equals. Can you replace the and? Can you change that pattern? Can you maybe make it an outer product instead of an inner product pretty easily? Can you change the traversal pattern fairly easily? Can you still see the relationship of that function to the original function? What if I wanted to now instead of working over strings, what if I wanted to find subtrees inside of my AST of my compiler based on their parent-child relationships? Well, I didn't tell you, but this is actually what you can do. No change is necessary. But with a black box library abstraction, it might be extremely difficult to do something like that. So when you're working with your APL code, directness using idiomatic style tends to work. So now we have data over control flow. This is one that's, I think, a big favorite in the APL community. And the computer scientists generally see it like this. Why won't you, APL is just to use a stinking if statement. Where if statement could be anything. It could be pattern matching, branching, recursion, all that kind of stuff. And the problem is that control flow is unnatural and it's unnecessary. So let's look at an APL sentence. Now this looks scary, but let's read it. This is a compiler pass in my compiler. And we can read it as, from the AST, drop the nodes that appear at the top level or drop all the nodes whose top level parent appears in the top level and is not a binding node and is either an operator or a function. It's fairly straightforward description. In fact, that description is probably something like you might put in your documentation. So it reads much like a sentence. But if you introduced a bunch of control flow and recursive patterns and depth first searches and everything like that, would you still read it as naturally? Would it still match the structure of your natural language as well? And moreover, this fits on a single line and I don't have to use any explicit looping or anything to do that. Instead, what I've done is I've encoded that logic that you would normally think of as a control flow as a Boolean expression using data. And you'll also notice that our macro versus micro question, it's really obvious what the core thing, at least if you know how to read APL, it's very obvious what the core operation is that we're doing. It might not be so obvious with your loops that what you're doing is eliminating nodes from the AST. So what did the studies say? People don't like to use control structures unless they're forced to. Now, another study or Galati convinced people to use control structures, but you know how they did it? They said it was a Martian. They're utterly stupid and they can't follow directions. Well, then they started putting in more control structures. But if they're talking to another human, that's not the natural way to do it. So actually for normal folks and normal studies, control structures in normal programming languages are almost by definition alien. So might I suggest perhaps that it's time for some common sense in our program? So let's look at the next pattern, structure over names. Now what does this actually mean? One way to say it, the APL function is its own name. And what do I mean by this? Well, we know the best practice. You've got to choose good variable names, right? Okay, what does a good variable name look like? Maybe this one's pretty good. I think this is a pretty universally accepted good variable name, right? In fact, I found this one while searching the problem on Stack Overflow. This was a recommended variable name by a well respected person on Stack Overflow. It came with a paragraph of Java docs and some other stuff, but I just extracted this piece out because we only need the minimal thing here. And you guys can kind of guess from this name what's happening, but do you know what algorithm they're doing? Do you know what the algorithmic complexity is? Do you know what your ranges are? Are they inclusive? Are they exclusive? I don't know. Well, we could just implement prime number generation in APL. Do the same thing. And this is the implementation. It's a well known ideal. Some people don't like it. It's quadratic, so we can see that obviously here. So maybe we want something more efficient, but this one is pretty clear. And if you're counting characters, this is one character less than the name that was suggested for the other programming language. But the APL will say, ah, this is a little too verbose. Why don't we just simplify it a little bit? And then, of course, we could implement a prime C that we want. That's a little more complicated, but we see what's happening and we can recognize that. And this is about using idiomatic style and structure to accomplish what we're after. And what that gives us is the ability to create better names that operate at the right level of abstraction. So rather than wasting names on things like temporary variables and places where it really doesn't help and where studies have shown it's cognitively problematic, we can put the names where they really matter, get better names, and that even allows us to get better structure. So we have this giant cycle of improvement where we get better names which give us better structure and it just keeps going. So what's in a name? Hopefully and potentially literally everything. And the studies bear this out because people don't tend to use variable names when they describe problems. They use something called contextual referencing where they use pronouns and other things to refer back or they use control flow through a linear control flow, so a data flow model in their language to allow ideas to percolate down in the instructions. And variables are a known problem for the beginner to deal with. And so you want instead to leverage good structure in your code in order to achieve a, what's the right term, achieve a regularity and a uniformity in your code that will allow you to see patterns without the need for variable names and keep your code closer together so that the distance between definition and call site are closer so that you can see what's happening more quickly and more readily. So let's look at our next principle, implicit over explicit. Now you'll notice that there's in all of the examples I've shown before there's a lot of implicit behavior. We've tried to avoid making certain things unnecessarily explicit. And to an APL we often leave things a little fuzzy. What this means is that we don't over specify the programs. And if you over specify that means you've constrained what can happen with that program. And normally that's a good thing, right? No, you're only allowed to use this in the correct way that we want you to use it. That way it's defensive programming and you're not going to get it accidentally used in some crazy way. But to the APL that misses the whole point. Suggestive generality means that we can take it and we don't over specify it. We might find that it works somewhere else. We might find that that is useful as an idea in another domain that we didn't realize. It allows us to make connections and see patterns. And I call this serendipitous transfer. And what it means is that we can use our programming source code to lead us to new knowledge and new information and new ways of looking at the problem. Whereas if we say we're restricting our ability to see how that code might apply somewhere else. Yes. Right. This is not intentional generality. This is not, oh, I'm going to start with a type class in Haskell. No, no. This is, I've written some code specifically to solve my problem but I'm not going to worry about forcing it to only work on my problem. I'm just going to let that all be more or less, I'm not bothering with it. I'm just going to let the generality fall out naturally. Yes. Yes. Yes. So what can happen is we can write this stuff and we can then take it and recognize that this is a special case of a more general pattern. And then we can continue to generalize it using, for example, the principle of suggestivity. That one more specific solution might suggest a more general pattern. Yeah. And I want to draw. Ah, here we go. So for example, we could have a plus slash over some variable with some function that we're applying to each on a vector. So this is a special solution that we might have come up with. And this works over vectors. But this, we would recognize this as a pattern in APL that we could have just written as V plus FV or something like this, right? And now that's automatically generalized to higher ranks of arrays in a reliable way. And so this suggestivity lets us sort of see that. And it's a form of using suggestivity to get to a general solution. And this general solution can then be really useful in other places. So plus dot times as matrix multiply can be really useful elsewhere. But then recognizing that maybe an or dot and plus will give us a lot of benefit. And so syntax over semantics is the last pattern here. And syntax over semantics ties it all together. Because APL is meant to be human centered. We're meant to be talking to people, explaining ideas to people. And yes, it's executable. But that should, that executability should come to the aid of the human rather than drive it. So we don't want to be reliant on the machine. We want to leverage the machine. But we want our notation to work to empower our mental capacity rather than offloading our mental capacity and expecting the machine to do the thinking for us. It's about putting things in their proper place. And part of this notationally is about focusing on how the code looks. So Roger gave me this example. This is what we call large precision, arbitrary precision multiplication. So big num multiplication or something like this. And inside of that, we have an FFT that we're doing. It uses butterfly. And Roger pointed out that this is a really beautiful kind of piece of code. Because we've got a recursive definition. You remember, we've got a recursive definition. But we don't have a base case that's taking up space. There's no explicit base case line that you would, you know, that's what you're taught in functional programming. The very first thing you learn is always put your base case in. But that clutters things up. And there's the beauty here is that there's a sort of syntactic regularity to this code. It's a uniform code. And I think Roger, you said there's something about it that's just like deeply satisfying or something like this, right? There's just something deeply satisfying about this kind of code. And part of that I would claim is that this doesn't have a base case. It doesn't need a base case even though it's recursive. And we achieve that using our operators and other things. And maybe you could call it a trick, but it's a trick that works a lot. And it allows us to achieve this sort of uniform visual representation and the way we can see the code has now changed. Our engagement with the code can shift. And that means aesthetics matter. And I really, I harp on this a lot. Because one way to do programming is to pound your specifications into the code and cover all your bases and everything like this. The other approach is to design something beautiful and let the beauty drive a solution. Or let the beauty encourage your mind to engage with the problem in a richer way. I actually would say when you're programming I prefer beauty over rigor. Because the beautiful code is more likely to last longer. People that see beautiful code are more likely to engage with it. And they're more likely to see it, think about it, ponder it, make changes, keep it maintained. It reduces your technical debt in the long term. Whereas if you're overly rigorous, now I'm not harping on rigor. Rigor is nice. But if you're rigorous in the sense of basically being too over detailed, constantly trying to build up these horrible, just get it to work kind of pieces of code that does everything to meet the spec. But you've ignored beauty and you've ignored anything else. You've just made sure it's stiff and rigid and it'll work. Rigidity comes back and haunts you in the form of technical debt. And then that technical debt accumulates and accumulates and then before you know it, you can't maintain your software anymore. And you don't want to maintain your software because it's so ugly that it gives you a headache every time you look at it. We don't want that. Instead we should design our processes, design everything we do the way we engage with them. And then we can go to demand simplicity. That could be directness, could be anything. For me, I like to do the aesthetical programming, which means I make my tools intentionally limited so that I'm not tempted to use machines to allow me to hide complexity. Instead, the complexity gets too much from my mind and then I'm forced to find a simpler way of solving the problem so that I can deal with it. Rather than hiding behind, say, a BDE with auto-complete. Hint. So, that means eliminate the need for your language features. Right? Find ways of making your language obsolete. Find ways of not needing to use multi-type dispatch. Finding ways of not needing to use a whole bunch of libraries. Find a way to not need to use genericity in the same way that you used to or not need the type system. That's a big one. If your code is so simple that you don't need a type system, great. Right? Because the type system only exists because you can't reason about your code. And one of the ways to do that is to optimize for rewrite. What does this mean? It means when you're thinking about designing your code, design it to be deleted. Design it so that you're not afraid at all to just scrap the whole thing. And you can only do that when you've understood the problem and designed the problem in such that you're not afraid to rewrite the whole thing. That means you need to have a simple architecture. It means you need to constantly be working to find ways of making sure that you're never afraid to delete a piece of code. And every time you have a piece of code that you don't understand that's critical, mission critical, is plugged into the rest of the system and you can't see somewhere. Suddenly now you've got code you're terrified to delete. And that increases your technical debt. It makes it all worse. And that leads us to this myth of readability. Because readability for most people is about comfort. It's about, can I feel comfortable about the code? It has nothing to do with reality, though. It has nothing to do with do you understand the semantics of your language and what's actually going on in your code? Can you really make a change? It's just, I feel like I know what's happening right here. That's not readability. I would suggest that we need to focus on comprehension. Not comfort. And for that, I have a way that I like to describe it and I call it my readability bet. So I say readability should be defined as the amount of money you're willing to bet that a change you make to the code, particularly large scale architectural changes will work the first time without fail, without fault, without error, without using any mechanical checking tools. No testing, no type system, no nothing. You're only allowed to read the code, suggest and make the change. You're not allowed to use your documentation. You're not allowed to use any of that. And see how confident you are in making that change. If you've designed your system right, you'll be a lot more confident than not. So how many people want to go look into a Java source package without your Java docs and no ID, no compiler, no nothing, and make a change to that Java object hierarchy? I didn't think so. But they break the code, right? And that's the point. And if you told them your year's salary is on the line, do you think they do that or do you think they might even potentially suggest they rewrite the code in something else? Yeah. So readability is about human engagement with your code, not mechanical engagement with your code. So let's do a quick review. Here are our patterns. And remember the take home here is that if you're going to do good APL, if you're going to learn how to think like an APL or make use of APL and make it really work where you can write those beautiful one-liners or you can really use it to be productive, you've got to forget everything you've been told and work on appreciating a new possibility. That means that you're never going to do something like this. There are times and places where this is important, right? These best practices exist for a reason. But because of what APL gives you as a notation, the value in it is that you've opened up possibilities now to make your life simpler and to solve problems more directly. So your abstraction, for instance, you know, sticking with your base layer abstraction, APL abstracting at your domain level where the problem actually is and not having to have a whole set of vocabulary, libraries, frameworks in between that to get the job done. And this goes back to our keynote talk today, right? Because if you are hiding behind a bunch of abstractions, you can't see the performance model of your code, you don't understand the complexity, you don't understand your code at all. But if you can directly express your solution in a thing, in a model that allows you to actually understand that you're both closer to the problem and closer to the machine, and you better are able to solve the problem efficiently and work with it better. So finally I say, you can do this, actually. There is a path forward and you can really leverage this way of thinking in your work, you can use APL to good effect, but you have to recognize that to get the value out of APL you need to be ready to think about your problems differently. This is not just yet another way to do the same type of programming you've always been doing, and if you try to do that way, you'll write Python code in APL, that'll be, but it's not going to be satisfying. So you can find some links to my own research and work, a more verbose slide show that covers most of this, and you can try APL as well. Any questions? Right. So I'll go back to the syntax over semantics pattern. You can do math, and you can have the ideas in your head and think about the problems of math, but without the notation, it's really hard. So what you want to do is you want to get that way of thinking, but you want to use the notational power of APL to make that thinking possible. Because if you don't have that, if I took algebra away from you and then asked you to prove something about the commutativity of plus or proportionality on functions or something like that, if you only have English there, it's extremely difficult, but if you have the notation, it's a trivial middle school or high schooler problem, right? And you're thinking about it, it's the same concepts, it's the same thoughts, but you need both the right way of thinking about it and the notational mechanism to enable that way of thinking and encourage that way of thinking. That's one of the difficulties with trying to take APL and use it in another language, because it's not just the semantic ideas that make APL powerful. That's not how APLers get to where they go. It's a combination of the ideas and the fact that they have a notation which is optimized for the human mental process to interact with those ideas. So you have to have both to maximize that. Now that doesn't mean that people haven't had really good success with bringing, say, the data flow concept into other places. They do, but more and more, the more experience people get with those, the closer and closer those systems begin to resemble APL, if that makes any sense. Yeah, yes. Yes, it was you. Yes. It's a different position and a different place in the hierarchy of importance. Yeah, or another way of thinking is maybe we just shouldn't be loving ice cream. Maybe words that are important or mean something should be reserved for actually important concepts and not be wasted on the trivial ideas that can be better expressed some other way. So to translate that to some of the interesting issues, we have a tendency, there's a limited number of names that we can reasonably use. The increase in vocabulary becomes impossible to work with. That's why we have long variable names because we can't remember what they were. We have to try to read a sentence to describe what the idea was and we're just using the variable name to do that. And instead we waste so many variables with variable names. If we describe the problem in a concise way in English, we might use a pronoun, we might use a data flow model to track things to do this. If we used variable names in English the same way we use them in computer science, we'd never say anything. Right? And so we do use names. Proper names are really useful but proper names are useful because of their sparsity. There's so many things. If I started giving every third group of chairs in here a unique proper pronoun or proper name, we'd start to run into trouble. But we do in fact do that kind of thing in computer science all the time. And part of that is because our notations encourage it. Yes. I would say the nature of the language in the community has a strong social bias to encourage people to try to write a different type of code. The culture and the language will encourage, have a tendency to encourage a different style of programming. That doesn't mean you won't write bad code. It does mean that over time it will have that tendency will more likely feel bad to you. That would be my kind of... But it's... I don't think it's just the language, right? There's not this mechanical fix. What I'm suggesting is not a mechanical fix. It's to get back to the process that we are as humans and leverage the sort of humanity in programming. Not just try to turn ourselves into machines that are following a set of rules and then design our cages so that the machines never rebel, right? Interesting. So I like to say that I... There are two programming languages I like to use. Scheme and APL. I've been a schemer for like... I started scheming for like 10 years before I got into APL. Then I learned APL. I couldn't do APL and scheme. I could do any other language in scheme but not APL. So I started doing APL and using it for a bunch of problems and I'm ready to use scheme for any of the problems that APL doesn't seem to fit really well with. And I thought I had one and then it turned into my thesis where I demonstrated it wasn't actually true and APL was a great language for doing it. I'm wearing it. So the last bastion of other types of languages I... I figured out how to do really nicely so I haven't really been doing other languages since then because I haven't encountered a problem that doesn't just call out to be used for APL but that could just be my own psychosis. So any other questions? Yes. Yes. So good question. I began to get really tired when I had to write a scheme function. My muscles had atrophied I wasn't nearly so used to typing all the parentheses but to answer a little more clearly I became a lot more eager to leverage points free data flow oriented programming than I would have been before and I became very careful in my use of macros. So there's a problem in the scheme community that it's the language of least restriction. You can do basically everything in it without problem. The problem is that everybody does in fact invent their own little mini language to do whatever they want because it's so easy to do some tactic abstraction and that results in these isolated islands that it's very difficult to communicate between people even though you've solved the problem it's very difficult to communicate to another person what you've done before they understand the whole suite of sub languages you've just invented in order to solve the problem whereas in APL that uniformity of expression and that uniformity of common vocabulary and language means that I've come to appreciate that as a tool for getting work done between people a lot more than I did before. Yes Well did you have a... did that answer the question? Okay Yeah. The way for what? Your thought pattern for doing a scheme versus APL wildly different. So there's a reason that I'm using APL now instead of scheme it's because I couldn't do APL in scheme. If I could have done APL in scheme I wouldn't be using APL right now. But the reason I'm using APL is because there was something about the language that I couldn't transfer back and that's an important key is there's a an HCI component to this a usability component involved in the syntax and the notation and everything else and it's going to go back to other languages. You can translate other ideas back but that what I would call some of the big key components don't. So you can try to do APL in other languages and it's not going to end up being APL. Yes I think you... Yeah Yes, so for example these are principles of design but there are many different aesthetic expressions of this. So when you see Morton do his code does not look anything like the way I do my code. And part of that is because we work in different problem domains. So there's a unique aesthetic for any given thing, right? So when you're doing poetry your aesthetic is different than if you're writing an urban fantasy novel and if you're doing an urban fantasy novel that's different than if you're writing a history book, right? But there are common themes of what good writing is that cross all of those. And the problem is APL is so artistically expressive in terms of your aesthetics that you can't come up with a style guide in the way that you would a Java style guide. You can't come up with like K and RC. There are multiple styles and they're all equally valid for different types of uses. So sometimes you might use more names in one case or more less names or something depending on what is best for the human interaction. Yeah I'm a bad one to ask about that. Although I really do want to demonstrate how to do a bit bit stuff, yeah. Yes. And those do follow a strict pattern. Yes. Are there sort of steps to go through and exercises to work with? You read the classics basically. You read the APL and APL idiom list. You read other people's code. You play with project or you try to solve problems and you see how other people have done it and you can begin to approach something like that. I'm trying to give us a tiny bit more structure and provide a more structured solution but it's not fully there yet. Well, thanks very much.