Welcome to episode 127 of Arraycast. I am your host, Connor, and today with us we have two panelists. I guess we can actually call that a panel. I've got Adam and Rich with us, so we're gonna go around and do brief introductions, and after that, we'll have uh a couple announcements, maybe just one. So we'll start with Adam and then we'll go to Rich.
AdamRight, I'm Adam Bossewski, and I do lots of APL things at Dialog Limited, where they gave me the title Head of Language Design 2.
RichI'm Rich Park. I also do some APL things, uh including training and media at Dialogue Limited.
ConorAnd as mentioned before, my name's Connor, host of ArrayCast. Massive fan of all the array languages, and I think that's it for introduction. So I believe we've got just the one announcement, and we'll go over to Rich for that.
RichYeah, so this spring we hosted the Dialogue North America user meeting in New York, and recently we've been releasing recordings of the presentations from that conference. So if you go to the Dialogue User Meeting YouTube channel, I'm sure we'll put links in the appropriate places. Uh, you can watch presentations from myself and a couple of other dialogue people and some users as well.
ConorAwesome. Yeah, I've seen a couple of those. I know I've bookmarked at least one of them. I think it was by Asher, but I could be wrong about that. I think he gave a talk on the latest and greatest things in dialogue APL. Probably most. Did he give a couple talks?
RichUh he did one that was sort of uh APL primitive developments um this century. And then leading up to the enhancements in dialogue version 20, which does include more than just primitives, but yeah.
ConorI can't remember which one I have. I've got them in a Google Doc. I love the feature in Google Doc where you you paste a link and then half a second later the YouTube icon with the name of the video replaces that link if you hit tab. Anyways, we will link those two talks, plus any of the other Dyna Talks that have come out if you weren't in New York for that uh meeting. And you can watch them on your own time, leave comments, get your questions answered. And with that announcement out of the way, I believe today, as we have been doing for the last couple episodes, we are going to live code some APL. I'm acting we actually didn't discuss is it gonna be Rich or is it gonna be Adam that's gonna screen share who's gonna who's gonna go first? Or maybe I'll just throw the problem out there and then whoever's more excited can screen share first. So I don't actually know. I guess you know, we we could be more prepared on this podcast. It's another Pearl Weekly Challenge, and I remember the problem very distinctly, uh, but I don't actually know the number. I think it was not today's because they usually drop on Mondays, but last week's. And the problem description is you're given a string, for instance, banana, and you're asked to sum the maximum count of a vowel, like the most frequent vowel and the most frequent consonant. Some sum the count of the most frequent vowel and the most frequent consonant. Yes. So for instance, if you have banana, that's what three A's and two N's? So the answer would be five. And you don't care about the B, because the frequency count of the B is one, and that's exceeded by the frequency count of the N, which is two. And if you've got a string like A B C, the answer is just going to be two, because you've got one B, one C for the consonants, one vowel, which is one plus one equals two. So a rather simple problem to state, and there's a lot of utilities in the array languages for generating alphabets and whatnot. But the interesting thing is that you have to split the vowels from the consonants, right? And need to keep the vocabulary. Yeah, we talked about that on the previous episode. So, anyways, now I get to kick my feet up and throw it over to both of you. I'm not sure. Yeah. Think a little bit. Or we can yeah, we can just chat before we show code. Or we don't even need to show code. We can make this an audio-friendly episode, which I'm sure we won't.
RichPurely in the brain. Um, I mean, the first thing that's going to my mind is yeah, it's like you said.
AdamThere's a definition question. Again, they're not so well spec'd, or at least not the way you described it. What happens if the if there's a word like uh where you have the same number uh of two different letters?
ConorUh it doesn't matter because you you're only caring about the count, not the value.
AdamYeah, but if it's the equal number of yeah, if the equal numbers of A's and E's, then do you need to count both of them, or is just how many there are one of them?
ConorNo, like think about it as creating a frequency count of A E I O U, and then you just do a max across those. Okay. Yeah. So I guess actually that that comes from my let's see, I went to week 380, and the problem, the exact problem description is you're given a string consisting of English letters, write a script to find the vowel and consonant with maximum frequency, return the sum of two frequencies. I'm sure it should say, of those two frequencies.
AdamAnd there's also a question of what is a constant, what is a uh a consonant and what is a vowel, but okay.
ConorYeah, let's just assume A E I O U are the vowels, and also it's not actually sorry, just just do one in lowercase. Yeah, yeah. It doesn't state it in the problem, but all the examples are lowercase, so I assumed lowercase. And it's an uninteresting complication to the problem, anyways, even if it were upper and lower.
AdamSo I have I have a solution. I don't know if it's if it's good or not, but uh it is a solution that I can show. I can build it up if you want me to. Sounds like a plan. Okay, so let me just arrange my window here to kinda be like this. Okay, and then I need to share my screen and see if I can find the right one.
ConorAnd Asher says in the chat that he enjoyed this problem because they got to use their new favorite fork. Okay. Will we find our way to Asher's favorite fork? Stay tuned on episode 127 of a ray cast.
AdamSo so I can build this up uh piece by piece. Here's the text. And what I would like to do then is for now, let's just look at the frequencies of the letters. So we do that with key. But we don't since we're going to look at uh consonants and vowels separately, we don't care which letter they are, then we can just look at the the frequencies themselves. I mean, we know this doesn't give us the information what they are, and this is just on the top like that. So saves a bit of framing there. Um and we want the maximum of that. But again, this is just looking at all the letters, but this is what we want to do on the vowels and on the consonants separately. So we can get the vowels by taking the intersection of the text with A E I O U, and we can get the consonants by removing the vowels. So we just need to sum all of that. We can build that up as a um as a nice over fork. Um, so we want to have the without uh plus over this thing here, so plus over the max of the tele key, we could call it over the intersection. And we want to bind that with a right argument of AEIO. So that means this is how the fork works. We get AIOU as a right argument of the intersection and as the right argument of the without. And then we sum the results, but of course they're the sets of characters. So before we sum them, we apply the max of the talia top right key on it. So this is this is the function, and we should apply that on button on the text. We have that already. We get five.
ConorDoes that work though? I think there's a bug in that.
AdamUh okay. What's the problem? I mean, there's a problem if we if there aren't any vowels, if there aren't any consonants.
ConorUh that's not the problem.
AdamWhat about the word mommy? Which one of them doesn't make this? So it's three M's and one of U R Y, right? That's four, as far as I can tell.
ConorOkay, so I'm misunder I'm misunderstanding, but the bug that I thought is that you're doing without the vowels, but how do you get consonants only? That's the intersection.
AdamThat's oh, but no, consonants only is without the vowels. Here, look, banana without vowels, B and N. Right? And and intersection. So even though the symbols don't resemble each other, they're sort of complementing each other. This one leaves behind from the left argument only the ones that are in the set on the right, and this one leaves behind on the left argument only the ones that are not in the set on the right.
ConorWell, now we have to have a discussion about these two glyphs, because that is very beautiful. And I did not think of that. And is this one of those things where I didn't think of it because it's not like symmetric?
RichUm because I yeah, my my thing, I did do the without well, the set functions are fairly underutilized, like yeah, people always forget to yeah.
AdamSo one thing I like to do is like the symmetric set difference. You can write like this. And so the union, that's all of the elements contributed by both arguments, and the intersections are the elements that are in both of them, and all of them without the ones that are in both, that's the symmetric difference. That's the ones that are only in one of them, not in the other one. And here we can sort of see the symmetries. You can even see that this shape is sort of related to these in a nice way. It's sort of a mixture of union and intersection symbols. So I don't, I mean, they are not symmetric in the sense that all three of them do not treat their left and right arguments the same. Without obviously cannot treat this left argument and right the same, where one of them has to be the data set, another one is the ones to remove. Intersection and union could have been symmetric, but it's it's more versatile that they're not. So they treat the left argument as the data set, just like without those. And the right argument is the uh the checking set, the lookup set, that that where we're keeping only the ones that are also in the right, or we take or we're keeping uh only the ones that are sorry, we're adding any that are uh missing that are that's for the union, right? And on the intersection, we're keeping only the ones that are also in the right. So we can give this a simple nice symbol. What uh what kind of solution did you have, Connor?
ConorUm well, this is like I said at the beginning, I'm always surprised, and this is another great example. Uh what's the best way? I'll drop it in this chat, and then you can uh am I imagining?
RichI'm imagining like do the full keys and then split out.
ConorOh wait, I just I just gave you the tiny apple. What language is the tiny apple?
AdamWell, I can try to translate it or go ahead and translate.
ConorOh, actually, I did I is this is number one or number two? It was number one. I mean, I think did I see Madeline? Madeline's in the chat. Uh I mean also too. I can here, I'll give you a RaBox link and then you can uh parse it a little bit better. Okay.
AdamWell, still don't understand how a Raebox can uh can know which valence of primitive that it needs to translate to.
ConorI'll drop it in the YouTube chat as well. I don't know, maybe Madel Madeline can uh give us her solution if she wants. Although are you gonna be able to screen share this now? I'm not sure. Not really.
AdamUh I mean I can, but then you're gonna lose uh it doesn't it doesn't actually translate very much. It it looks like this when it's translated. That's doesn't help. Um so it's a so but let's figure out what's going on here. Oh, this is the this is that count in or something like that? It's histogram, yeah. Yeah, so it's it's counting in itself. I mean we can define that, but it's basically a type of key.
ConorUh yeah, it's a key specialization if you want to think about it like that.
AdamYeah. Uh Silas asks if we need a quad C. I don't know what the problem specification was, so I did it just for lowercase, but yes, of course. If uh if it can take any case, then you have to throw a quad C on the right end of my solution. But that doesn't change much.
ConorYeah, I think we we stated earlier in the in the podcast that well, let's just assume lowercase because the casing adjustment isn't that interesting. This doesn't even look right. Um but basically the the description of what this is doing is the underbar semicolon is uh pair and quad L is lowercase alphabet, and so we're doing C quad A and oops, quad C quad A.
AdamYeah. And then we're we're binding that binding that with uh with the without. Yeah. And we're doing that on the left argument. So that's so this is uh this is a form here with all the right like that with a e i o u. But then um but then we are counting in each. Oh, okay. Oh, okay, I see what you mean. Right. So you you you have the vowels, the set of vowels, you have the set of um of letters, um, and then we're removing the set the vowels from the letters that gives us the consonants. Now we've got the consonants and uh and the vowels, and so for each one of them we uh want to remove, I believe, uh oh, for each one of them we're counting uh that's what it's doing, we're counting the occurrences in the entire um argument, and then we're taking the maximum of that. Okay, so I can I can restate this as we we do with it with uh so if we so the first thing is to generate the list of vowels and and uh we can write like this quad a quad C A I O U. This gives us the consonants. So um, and then we can pair this up with itself. So this is where we want comma over enclose um and we want uh behind here. This is not gonna work quite well, but let's just do it like this for now. Does this work? Uh what am I doing wrong here? Oh, okay. Sorry, I forgot the binding thing. But why is the without it's without yeah, judge without there you go. This is the consonants. We want that here. The problem is we need this, so it's better to do it like this. Okay, this gives us the uh the consonants and the vowels. Um and now uh for each of them we want to count the the occurrences of all of them in uh in the original. So let's just call this consonants and vowels. It's easier like to deal with like this. Right. So then we can say consonants and vowels, and we'll since we don't have the frequency count thing, we'll just do an outer product with the enclosed text. So this gives us this uh frequency table for each one of them, and then we can sum there. So if you bind this together for each of them, this gives us uh the sums for each one of them, and if you want the maximum, we can do that as well. Oh that doesn't work. Ah too many atops. So we use an inner product here, uh no. Okay, so one plus there. Okay, so this is this is the maximum uh occurrence of each one, right? Because there are two N's and three A's, and then we just need to uh sum all of that. That's that's essentially what's happening here. And the the thing about creating the consonants and vowels, that's just that's just a constant thing that gets bound inside the train. But it's largely the same thing as using key. What I did was I I gave key an operand that just counts the occurrences, right? So instead of doing doing this, we can literally replace this with um tally atop. This gives us um oh no, okay. We don't yeah, that's the problem with it. We want the key with a vocabulary, really. Right. So that's here's the problem. So we need C V and then we need to do uh intersection. Well, we can do intersection like this. There we go, and then the maximum getting rid of uh the maximum of the length area here. What? Oh, because binding there we go, and then we can sum this. So this is essentially the same thing as uh the as the tiny APL solution, but it's obviously very similar to uh to what I had. Because instead of I what I had was instead of taking the intersection of the consonants and the vowels, I just took the intersection of the vowels and the set difference from the vowels. And uh and the your solution that did a set difference with the vowels from the alphabet. So you just had went went via the alphabet for no particular reason.
ConorWell, the particular reason is that I didn't have the idiom of without union. Like it's it's uh I don't know, at least for me, it's a more natural step to start from like an alphabet than to make the jump that, like, oh, if I do without an intersection with just the vowel set, you can back your way into just the consonants and just the vowels. Like that's not an obvious uh thing. Or I don't know, maybe for some people.
RichHow far do you get I'm trying just prepend a IOU. In front of the text. Oh, the problem is that yeah, in front of the text, and then you can say, well, the first five results are from the vowels and do a segmented uh extrusion there, but the problem I but you don't know what the next ones are going to be. No, no, no, the key afterwards will do it, yeah. The key will sort that out, but you have to only subtract one from the first five results.
AdamOkay, so so if we if we do this, right, so we can see what they correspond to, but now we get rid of that. So that gives us all those counts. Then we do a a five take, yeah, comma drop, that's all of them. And here we want to say uh negative one plus the take. We can swap those afterwards, like that. And then we want the drop of that, but then we want the max of each of them separately as well. So you want this over max.
RichOh, yeah, okay. Right?
AdamI mean, I was looking at partitioning them, but that's and then we we change that to a plus, and then we swap these two sides so that we don't need the parentheses, we just do the tick on the right, like that. So this this works as well.
RichI'm not sure if I like it particularly, but uh it looks like you would need of you know comments to tell you what what was going on. Yeah, it's really it's doing a lot, it's doing one key and a um uh far fewer set operations. That's true.
AdamBut I mean if you're talking performance, this might be very expensive too.
RichUh I'll prepending some stuff.
ConorYeah, copies, yeah.
RichYeah.
ConorI have a question for Madeline in the chat. Uh, how do you do uh how do you use histogram on a string for the character counts? Should it work naturally? But right now when I do because that's the nice thing about Tiny Apple is they have the primitive that like naturally your brain jumps to. Like here we have to use key, or you can use the other product fork, but like when you have the primitive, that's like my brain and my heart are both attracted to the language that has that primitive. Um but then I'm thinking about the the thing just there that has the country. Yeah, yeah. And so now, like honestly, it's so beautiful. Like if if you it says you'd want a version of histogram that gives you a dictionary and just takes any cell. Oh, so is there no way like to s to change a string? Because that's the thing, a string is a character array. Uh you have to give it a dictionary.
AdamOkay, so here's another one we can maybe do. One second. Instead of let's try it. I'm not really, I haven't worked this through, but but maybe what we can do is we say A E I O U. Martin will not be amused here. Um, and then sort by that. I was wondering about that as well.
RichThat moves them up from you still have to do the lookups after, anyway. Yeah. Because you don't like at least with the keyed version, you know beforehand, well, there's gonna be five at the front that you're interested in differentiating. Oh, one second, one second, one second, one second.
AdamI have a crazy idea. It might not work out at all, but I have an interesting idea. Okay, so what happens if we go in here and say look inside here whether the particular character uh is a vowel or not, and then we look at the count. Okay, so now for each one of them of the of the grouping zero and and and one, we want those uh we want those the largest number. So I have a trick for that. So if we say negative one to the power of this, then that gives us a sign, and then we can multiply that with the tally. And now all we need to do is add the largest and the smallest, but flipping the the smallest one is going to be negative, so we don't want to we want to add its magnitude, but that's the same thing as subtracting. So the largest minus the smallest gives us the the what we wanted. Did anybody follow that? What just happened? So this is the whole solution. So Madeline says in the chat that it breaks if there are no consonants or vowels, but at any way it's broken if there are no consonants or no vowels. So we don't specify what I mean. Any of these solutions are going to be bad, right? Because you're going to do a reduction, the maximum reduction over an empty vector is going to give you negative infinity. So you're bad off either way. Um and the key, like as soon as we reach like this and key on on an empty thing, and then we we try to right. That's it's not gonna work. So all of these solutions use that, and even the count in is not going to help anything. You're just going to get empty vector, and then you max over that. So I don't I don't know if the problems specify what should happen if there aren't any. I guess I guess the vowel, all the vowels A E I U appear with a frequency of uh with a count of zero. So it really should give zero, right? If there aren't any. Yeah.
RichAll right, check this. Uh you have to predefine a result vector of two elements, both zeros, fine, which say the first one is the count of uh vowels, and the second one is oh sorry, the first one is actually the count of consonants, seconds the count of the. I also have to set squad iO to zero, right? You also have to well you can put a one plus if you want to.
AdamOkay, so we set quadril to zero, and then we we um update the the the value here, and then there's missing uh the last statement, which is to sum, right? Uh yeah, the last statement is to sum.
RichYeah. Uh I actually have started to grow to like this pattern of doing weird um manipulation within operators. But functional programmers will cry in the corner.
AdamYeah, well. I'll drink their tears. I mean, isn't that sort of similar to the what I did up here? But mine is yours are more generally applicable. You could have multiple groups. So Yeah, and you also had to well Well, not really, because it would be awkward to find out. You have to find is it in which group does it appear?
RichYeah, this one happens to come okay with two groups, but then so does with more groups it'll be.
AdamParity is also a two-group. Yeah. But if you were if you had multiple different groups, then I mean this is a lot of updating, right? You keep adding add one, add one, add one, add one.
RichThis is uh That's uh oh yeah, well no only per key. Yeah, but that's once per no, it's not adding okay, it's updating.
AdamYeah, it's it has to do with max max all the time. But the max is our scalar. It's when you say one.
RichThis is yeah, this is in principle more one potato, two potato, unless like array-oriented, I guess. Yeah. But it's something that when you uh learn about operators and stuff, tend to fall into a pattern initially of doing something, either doing like loads of stuff, I guess this is counts as doing loads of stuff in the operand. Or like getting the operand, like for example, in key, sometimes you're fighting with uh the fact that you get a matrix out. And either you'll I'll often do like a split transpose to get out uh what you call it, an exploded inverted table. Okay. As opposed to indexing into each of the columns. Whereas here you don't even have to worry about that because you're just dealing with the values directly, which I kind of like.
AdamSo if I go and get key with a vocabulary, how does this look? And uh so I guess I should show the URL so people have a chance just to look at it. Does it fit? Not really. GitHub there, blob. This will be awkward for people to see anyway. Um okay. So now this takes the vocabulary uh on on the left, and and now we can take the vowels A U and key with uh key with vocabulary on the text. This gives me the indices and for each one of them, and we just need to count each and do the max. Right? Uh max. So this gives us that. And if you and then we can take the other part of the alphabet, uh, so we say here. And this gives us the max consonants, and then we can just combine all of that. So by running key with vocabulary twice, it's maybe maybe more expensive. I'm not even sure how much how much more expensive they would be in an actual good implementation. This is just a model, but the actual implementation would only look for those, it would never collect information about them. Um, as well, it would be nice if we could detect that we just want the count so we don't actually have to keep the indices. Um so how would this look in practice? Well, we have to we have to do the same sort of thing as we had before with uh creating the C and V. But let's just say we have the consonants and the vowels. So for each one of them, we do the key with vocabulary on the right, so and then we do tell each and do a max, and then we sum everything, which means uh yeah. Does this one work with each one of them? Yes, because no, uh if they're yeah, because this one will always give five elements and 21 elements, right? Because because we we're always looking for something, we'll just give empty lists, so then this will just give all zeros and all zeros. We can try it. So if we if we do it with something that is uh like this, it should give three, right? And if we do something that has uh like this, it should give one. So that's so the key with vocabulary running it twice like this, it actually works. We can also, I mean it's not doesn't help much. We save two here, it doesn't help making it tacit really. It's just uh no, you can't do that because it's a it's an operator. So don't mind. I think this is maybe the easiest one to understand. In general, key with vocabulary is easier to understand than the normal key, because there's no function application. We're just saying, okay, what are all the indices for these elements?
RichYeah, and it usually involves less faff afterwards. Yeah. Which had just adds basically noise.
AdamYeah, let's add that in version 22. But it's yeah, in dialogue definitely we want to reach for key and for this sort of thing. Um oh, I mean we don't have to. We could okay. So here's okay, let's let's define sorting first. Now we got a sort primitive. I want I want that as well. Let's just call that A5 sending, as if we had a primitive for it. Okay, so now we have the text and we can we can sort it. That's banana sorted. Oh, it's my bad example really. We should have um uh an example where we have some some consonants first. Okay, we can do this one for now, but really what I want to do here is I want to take the vowels. Oh, is that is that even important? Uh yeah. Move them first. And sort sort with that. Why did we you sort it twice? You don't need to? Yeah, but why did I lose a an an N? What's T? Banana.
RichIndeed. Forget it. Uh that shouldn't matter.
Adam135, those are the A's.
RichAnd B and an N and N. Close that. That's fine. Okay, and the fact that uh does be kind not do the same?
AdamOh duh, my bad. Stupid me. This sort function doesn't take a left argument. Yeah, yeah. We can't do that. Okay. It has to be I mean you can't even do this. I mean it'd have to be sorted as like this. Yeah. There. My bad. Really? Oh this is take the left argument if it's there, otherwise the right argument. No, we can't do that. It has to be grayed like this. Uh doesn't that normally work? Yeah, yeah.
RichHere we go. Sorry. Uh, why was why was it getting rid of the No?
AdamBecause think about it, it's it's pre-processing the left argument, so it's just sorting, it's just making the grade vowels that are has nothing to do with the right.
RichOkay, yeah.
AdamYeah. Okay, so um it would be nice to have a sort primitive, but the sort, but it's wouldn't work for the sort by any by the sort order that's very special for the grade primitive. Anyway, let's let's just continue. Okay, so now we now we sort like this. So it doesn't actually make a difference in this case because we have a vowel in banana that comes earlier. Um but if we write something like uh bikini. Yeah, so you get the i's first and then the uh the b. So then we should that gives us four, as that should be the result.
RichOkay. You don't need two A's here, do you?
AdamYeah, you do, but if I want because my my idea was to put Oh, you you sort Yeah, I want to put to sort them so that the consecutive elements are are next to each other, like identical elements are next to each other. Then I wanted to group it like that, but we don't know where to split anyway. So it doesn't have the problem with the whole yeah, the whole approach tend to think about places. Well we can what we could do is we could add alphabet, even at the end. That doesn't matter, because now we're sorting. Okay. So now we now if we look at at where they're different from each other, that's where we need to split. So we take this and sp uh split uh split on that. That gives us our groups like this. I'm not saying it's a good solution, it's to say it's a it's a one not using key. And then we get we get these counts here. This is the actual count because we injected one, and now we just need to take uh do the five take and plus over max with a five draw. Is it a is it good? It's long, but I'm not using key. So at least I could do it like this. And I got to use the added grade, so that's something. Yeah, you're following Connor?
ConorUh not this last one. I uh kind of was I was working on figuring out how tiny STL worked, and so I uh I I wouldn't say I zoned out. Oh, yeah. I refocused my attention on uh tiny apple.
RichOh no, we saw oh no, it's a new one in the chat.
AdamOh yeah, well, so uh I just got this whole thing. I went to the petition. Uh let's keep it flat. Keep it flat, keep it flat. That's what you want to do, right? So we keep this flat here. Huh? Are you talking me or you're talking to Rich? Um both of you, whatever. I just to myself here. One second. Uh so without an outer product. Without an out of product, of course, yeah. Flat without out of products. So we do we do comparisons like this. Um we actually don't we actually might want to put this at the uh put a one at the end here, um, and then we just need to find the the distances between them. So we can do a where on that, and then uh that gives us the indices where we where we split over, and then we want to find the distances between them, like this, and and then and that's the one-off counts that we had before. We see that line, that's the same line as up here above, and then we do this, and finally we just need to do the the five thing take over max drop. Take oh plus plus over. There you go. So here is a solution that does not use key and uh does not use any nested arrays at all. It's just good old APL. I mean, old APLs didn't have the pairwise thing, but you do like one drop, one take type thing. Sorry, one drop, negative one drop, and then compare them. Yeah, old school. Oh, so alphabet, oh it's Asher speaking about that. You can do an out of product. So we've got the T here, and if we do an outer product with uh quote C quad A, yeah, that gives us gives us this. And but we should probably put it the opposite opposite side, so we get like a lot of rows like this. Um, but then we the problem is we have uh AE Ae I O Uh Union with that. So this makes sure that the first five rows, so the union with the alphabet like this, make it's the alphabet, but the vowels are first, right? So now if we if we compare that with our text, then the first five uh why is that not? Oh, we forgot the quote C. First five rows are the are the vowels, so that means these are the counts for every uh everything, and now we can do our classic by now, take plus over max drop. There you go. But of course, I mean, sure, this sort of has the key in this this is key, yeah, just an inefficient one. But this one is nice because we don't need to split up into two groups. Um wonder now whether we can if you go back to to a normal T here, if we say A E I O U and Union with that, yeah, that doesn't work because we don't get duplicates anymore. Uh huh. Okay, so how about if we say t uh intersection comma uh without with a e i or u. This just puts the vowels first. Oh, but we don't know what they are. Um we fix that. I wanted to get all of them in first. So if you put the right right argument here, now we know all the vowels come in first. In fact, we don't need all of them. We can use all the set functions in one. How do you like that? And so the union between those, oh, but we don't know how many we're adding. That's the problem. Okay, so so this one is fine. Okay, now we know we're adding one of each of the vowels. So now when we do the key and the tally, we're doing the tally, top, right? Right, so we know that the first five are for the vowels, and the last two, uh the one remaining ones after the those five are for the consonants. So now when we do the five, uh oh, we don't actually need to do the negative one first because we know what it we could we we do stupid, all those cases before we did the max of the subtraction one. We can just subtract one the end because we know we're going to get to too much, right? So now we take five take plus over uh max with drop, and then we get one more than what we need. So all we need to do is negative one plus. We but we know that. I think that one's pretty neat. We then now we're only using one key, we're not doing anything nested. Uh, we are not doing it on a a on a huge uh added text. This is this is just a reordering. This this literally just puts all the uh the vowels first. Well, why hold on? Why do we even need that? We don't um that's the same thing as we did before, right? Just concatenating this in front. Isn't that doesn't that come down to the same thing?
RichUh no, the difference of catenating just that in front, I think, was that well, this is why I'm slightly wondering about do you were you supposed to subtract one or two? Because the problem with concatenate with prepending with just the vowels was that you only added one to just the vowels count. So you had to subtract one from the first five.
AdamYeah, that's that's that's correct, right? This is a banana T, right?
RichSo so there are So I thought when you were doing all this set stuff that you were doing it so that you add it to both Yeah, but we no, we're not because I'm not going to add the consonants, there's no point.
AdamWhat was uh did we get to Ash's train? Or is that what we were looking at? It says well, he wish you came up with without G intersection, but I don't know what I don't understand what G is.
ConorJust a function.
AdamOh, just the is this the is this the old stuff, the original, the uh yes.
ConorWell Max without Max asked earlier, did we get to Asher's Fork? And then I guessed it was probably the one that Adam mentioned, the with our media. Uh, but it was not. And what is Asher's fork? We don't know. There's a it looks definitely like a couple of his messages were eaten, and so potentially he messaged it and it's being eaten. I know we tried to do something with a GitHub discussion at one point, but no one ever used that. So if it's still their Ash is ping us on.
AdamI'll just write him in open internally because when it's a colleague, you can write to them directly with somebody out there on the internet. How do they perform? It's sort of hard to tell how they perform because we need a large text, but I guess we can we can try. Uh one second. Asher has just sent his solution to me as well. Uh it is loading. Let's go back here. And so Asher said this. Wow, that's why such a long name.
RichThat's the name of the of the towel. Oh, okay.
AdamThis is just a test. Should we say hi to the people who say hi in chat? Marble Koma and Jacob Lookwood. Okay, so this is an okay, so he's doing the outer product, he's just implementing key here. Outer product with with the alphabet, and then yeah, it's essentially the same thing as we had before. But instead of doing set functions, it's implementing the set functions. Yeah, classic. So it's find the mask, do the do the two sets. Um, so it's really uh the same thing. So uh how do they perform? We can try. So if we all we need to do really is just create a giant thing to not print this. So this is a long text. Now we need to start defining these as uh we have to scroll back in the history to find all our definitions. Can we do that? Um where were we? There we go. So this was where the Asher says, isn't it nice to use replicate twice without needing to work around it the hybridness? Yes, that is nice. Okay, so this was the F. Doing this one, and then we had um the equivalent one of the tiny apple one. That's this one. Should we say TA on this one? Yeah, okay. And then we're gonna assume the constant of the and then yeah, because the CV only gets evaluated once, right? So that doesn't take any time. And then we had the key when we find Finally got this solution here. So this is a tiny apple with the key variant. Like that. Hopefully they will all work out correctly. What do we call this one? Oh that's the this one is is silly in this regard anyway. So this is the one that's single it's single key.
RichYeah, some powers. Yeah, this is the one that array oriented yeah. This is the one that used the negative numbers, right?
AdamLogic, arithmetic logic. Yeah. Sing single key with negative numbers. Okay. And then there was this one, the index index updating one. It's R gets zero zero. Quada well, we should say quad IO in the beginning, right? Oh, we already said it. That's fine. None of us really rely on it. And we update R with this. And then we return R uh plus slash uh R there. So that's the what do we call that? One potato, two potatoes? Potato solution. Yeah, so then there is key with vocabulary, that's this one.
RichUm wrap it up again.
AdamYeah, but how are we going to do that so that it's efficient? This is one function, this is one function. You just need to make another top here.
RichLike what did I mess up? Interesting. Anymore to the right?
AdamNo, no, it's okay. Oh good now. Key with vocabulary. I hope I'm getting all this right. Uh here's the here's the key with the vocabulary.
RichOh no, I gotta go in two minutes, so uh over both of them. I might have to watch the watch the watch the recording to see how this pans out. You're almost there, you're almost there. Yeah.
AdamAnd then we did the sorting. Oh, this is the this is getting silly, right? This is the flat sorting thing. What's the chance that I'm making a mistake here? So flat sort. And this is the but this is still doing yeah.
RichTwo sorts and all that. Is it worth adding the weird arithmetic one? I don't want completeness. What was the difference between these two? Uh you're finding indices and the differences the first one you uh what partitions.
AdamThat sort indices here. This is not gonna end well. Are they finding all these lines at the same time? Uh this one is the out of product one. Uh that's sort of silly there. But this is going to be bad because we have to do this thing over over and over again, even though it's a constant. So we can fix that by saying here. Out of product. And then we have got this one, which is pre-penned. There's so many of them. Prepenned, and then finally the SOF. Hey, it all worked.
ConorIt's only counting uh consonants? I was gonna say you didn't run any of these. How do we know that this worked at all? All we did is successfully stored.
RichWell, I'll find out after the fact because I've got a lot of things. Oh, this is wrong. Yeah. Uh great to see you all. Yes, and this one is bad.
ConorBye, Rich. I can no longer coast. I was coasting, folks. Rich and Adam were doing all the heavy lifting.
AdamI had a protein bar, and uh I have to be back in the game. Okay, so we've got uh we got all of these, and now we need to uh to try them all. So let's uh say the function names here. We got F, which was my original one. Uh T A was uh what was that about? Remember? Um yeah, there was the tiny APL. Tiny Apple. And then there was the tiny APL with based on key. Uh and then there was uh there was the S single key? SK single single key, single key with negative numbers, uh the one potato, two potato, one, key with a vocabulary, uh not number two. That's fine. Fs was the uh the flat sort, and then we got flat flat sort with indices. I don't know why the syntax coloring is all broken here, and then we got out of product, and we got asher uh we got pre, which was the pre prepending insertion thing, and then there was finally the the soft one, which was ashes. Okay, so these are all our functions, and for each function we want to pend it with long, so this gives us all the uh expressions that we that we want to run. Cmbx with cy DMBx uh those expressions are there it didn't actually work. What what's wrong with T A K? That's this one that works fine. T A K with a long one. Oh, I think I know what the problem is. Uh the long yeah, it's uppercase. I just need to make it lowercase. Let's try this. It's running. So meanwhile, while that's running in the chat, they're discussing whether you can you need multiple keys. Yeah, you can need keys inside keys. I've done that in like database queries, things like you are you want to group by and multiple times because key is really a group by. So inside the groups, you might want a a two-dimensional group by. So you want a table when one dimension you want the department in one dimension, you want the uh the quarter, something like that. So can't really see the graph here. Key with vocabulary looks like it gave the wrong result. Interesting. Big differences in the performance here. Um, we can look at that, but it doesn't really matter because the performance was so bad. Uh and key with vocabulary might have been the one we defined wrong, that's why it's only doing, but it doesn't matter. The fastest one is the preview one. Uh, but I mean it's tied with the SK was uh single key, and the tiny apple one that you came up with, Connor, is also very fast. Um and then the outer product one. So the problem the thing here is that the alphabet is very small, right? So that skews things a bit. If the alphabet was much smaller, then I think it would make a big difference. So we we can try that. So if we do um U is uh question mark 1E63 shape one one one four one one two. That's the number of characters in Unicode. This is the code points, and these are the characters. So here are a million Unicode characters, and then we're going to run it against Unicode characters. Oh, but this is not gonna work, of course not. We can't run it because now it's not well defined what is a consonant and what is a vowel, right? I can't tell you. So we it will for this particular problem we can't really say that the vocabulary is ever ever is ever big because it's really limited to the Latin alphabet. We can extend that to various other Latin alphabets that have got a few more characters each, but even if we do like Vietnamese, it's still a fairly small number of letters in the alphabet. If you want to do all of Unicode, then I mean it doesn't what is a vowel? It's not well defined. So there's no character class for Unicode, that's a vowel character or consonant. Don't work like that. It's not a real thing anyway, because the letter Y is sometimes one, sometimes the other, and silent letters, and um yeah, but it doesn't it doesn't so the the participant in the chat with the unpronounceable username uh something underscore underscore minus kd eight o z uh says call it unicode minus minus very loudly and just say the vowels but that still makes for very skewed here because it means one group of letters we're looking for is very small, the other one is is very large. And that that would mean that whenever any of the solutions that look up in the entire list of consonants is going to be very expensive, but the ones that look up in um just in the vowel list is going to be cheaper. So um we also have a request uh to look go over the solutions on ArrayBox. And you want to drive that, Connor?
ConorI can, but uh I'm gonna just have to overlay it on the uh screen you're looking at, and you'll have to switch to YouTube because uh I can't screen share on top of screen sharing.
AdamDon't worry about me.
ConorUm well actually, what did I uh let's see if we just do this. Will I get back the alright? That's the old one. Where's the one that I put in the chat more recently? I'm watching this episode on YouTube as we speak. Alright, so don't do that. Do this. I'll cover my face. Oh yeah, that's true. And uh look at that. It looks seamless, looks professional. And so, I mean, I went on a deep dive, which is why I missed like 80% of the solutions that uh you and Rich were covering. Because I mean actually, and we we can we can bring up this one as well, see if that works. So this was my original solution, which uh you covered and translated. But one thing that I realized, and we might need to zoom out a little bit, is that um might need to zoom out. You know what? We're gonna cover your face a little bit too, Adam. This is Prime Real Estate here, and uh you're still there, just hitting a little bit. And so this histogram primitive, let me go back here so I can monitor the chat still. I actually misunderstood what I was doing in this solution. I somehow magically stumbled into a working solution, but ultimately what I was trying to do. If we zoom back in on uh this, I was trying to do this. If we if we uh uncomment it. So I was I was trying, well, I mean actually, I wasn't trying to do this because I I didn't have the insight to do the without union fork. Very beautiful, and this is a famous, not famous, well, it it only really exists in my head and maybe like one other person because I've mentioned this like once or twice on YouTube videos or podcasts. This is what I call the the sci-fi tacit pattern. You've got a psi combinator inside a phi combinator. Wheo! And technically, it's a phi one combinator because it's a dyadic fork that we're partially applying. So that's not sci-fi like sci f I. It's a play on that, and it's P S I P H Y, P-H-I, aka the two combinators. Um, but ultimately, like when you think about this problem, you really just want to do a histogram count on the vowels that exist in your string and the consonants that exist in your string. And then you do a max reduce, you add them together, you're done. The problem is that there's no array language that has all of these primitives, which is why we're playing around with key, outer product, and then having fun and saying, what if we didn't have key, etc., etc. But really, like the simplest thing, and then also I show below here because Madeline in the chat, author of Tiny Apple, mentioned that this is coming, the quad V, aka lowercase vowels, is coming in 2027. May or may not have been a joke, nobody knows. But if we did have it, this would be even nicer. And then so we have, if you combine that with the without union, you then have your consonants and vowels, you call count, and that's the thing that I'll get back to in a sec. I wasn't calling count. Count just gets you the frequency counts of your individual characters or numbers in your array. I was actually calling histogram, which is the dyadic version of that. And uh, anyways, once you do this, you do your max, you call the psi combinator, add them together, you're good to go. I think I tried to do something like that. If you skip the fact that I missed the without union pattern, I was just trying to construct um a psi combinator, a sci-fi fork where you've got the vowels on one side, the count consonants on the other, and then I was trying to do I was trying to spell this pattern in the middle, but I could not for the life of me figure out how to get it to work. And I ended up, you know, you can tell I'm I'm you know twisting stuff around in order to do it in close, and then I've got this what I thought was count each, but it's actually a histogram each. And I guess the difference being if we if we open up a well, I guess we can do it below here. Um we comment this out for a sec. So if you've got I guess and so that's the thing, is banana, it doesn't work with it doesn't work with count, because it's apparently, and Madeline mentioned this in the chat, that uh it is defined as inverse indices or something like that. Um and and so yeah, that's the thing actually, Madeline. So I I missed the last couple um comments, but Madeline just mentioned you can actually do this with uh a selfie on count, which then comes in. How many A's are there, and you're good to go. The problem is that if you try to inject this into the middle here, you now no longer have the correct left and right arguments. And I am not a tacit ninja enough because like we have combined with we have we've partially applied like an argument on the right, and now we're like we're inside the fork and we're on the right tyne of the over combinator, the psi combinator. And so how how did that work? I understand how that worked because that's monadic, right?
AdamSo count this is monadic and it doesn't work. But if we Yeah, it doesn't actually work. But if you put if you just put the the selfie there, it uh it's so now it becomes now it becomes histogram, like we saw before.
ConorWhoops, and if we zoom out a bit, and then I guess I it now it becomes histogram where we're providing I guess the values that you want to count in order, like it's so it's it's like the bins of a histogram that you want to count. And so now you have like the or wait, I'm still doing something wrong. Ruben uh Virg, aka Madeline's just saying, no, no, just replace in the first tab. Okay, I thought I did that. If this works, well actually, I guess we gotta so your code didn't run before? What? I swear to god, you know, maybe it's too early in the morning. That's it, that's it. It's not that early in the morning, folks, though. It's 1113. It's almost afternoon. Um, first line of the first tab. Which one is the first tab? This is the first tab. Oh yeah, she's just uh a couple seconds behind us. How I don't know what I did earlier, folks. Uh, but I swear to god I tried this and it didn't work. Well, actually, I didn't swear to god. I just uh pretty sure I I tried this.
AdamSo there's a there's a backwards over, I think, in in tiny APL that allows you to get rid of the parentheses just because you can't use an atop operator here because of you need to parenthesize the right side.
ConorIs that gonna work? I don't think that's gonna work.
AdamWe have to glue them. You have to put an uh top, explicit atop between the max and the and the count in.
ConorOh my god, that apparently worked. Oh my god. Look at you, you're tiny APL Pro, Tiny Apple Pro.
AdamWow.
ConorI mean, I came up with a few of the primitives in tiny APL. So and if we do this, we can almost get the 2027 version of this. There is no quad V coming.
AdamIs there no quad V?
ConorWas that a joke?
AdamI didn't confirm in the chat it's a joke. Um of course not, because it makes no sense. You can't say those are the vowels, and that's just that's just it makes no sense.
ConorThings have to make sense for them to come true, you know. I don't know, maybe not in tiny apple. Um, and so this is god, you know, what are we talking about, folks? This is beautiful.
AdamI can't believe though, how did I make I mean uh Madeline says that the the circle uh on the bar is uh is her own invention of a backwards over. I mean, I've mentioned in in chat, I think all a long time ago, that very often it's a simple function on the left of over and a complex function, composite function on the right. So really it would be nice to have it the other way around. Uh but yeah.
ConorBut yeah, this is like uh this is what I was after when I started solving this, but then I failed to, you know, come up with this beautiful fork here. And so then I started messing around with stuff, and then I just ended up, you know, I ended up with this abomination, uh, thinking that, you know, I don't know, this was the best that you could do, but but boy oh boy was I wrong, folks. And this is you know, I was also thinking too, while you were doing that whole uh putting um all the previous defined solutions, like we gotta we gotta create, we gotta vibe code, a little other screen while we're working through the terminal. Whenever we have a solved solution, you just copy and paste it into like a little slot. And so like the five minutes that we spent going back and getting all the stuff, it was uh you know, there's a there's a nice, beautiful, you know, vibe-coded website where you can just drop them all in, hit a button, and uh hide the messiness of what we were doing there. But that's and it will just find all the definitions. No, no, just so like you're still working in the REPL, but if you just copy and paste each time you're done, like a little snippet, just copy it and paste to like okay, we're done with that, and then at the end you can come back and just then we hit a button, it rolls compare X, and uh and then it does some nice little whatever fancy animation. Um yeah, this is this is this is nice.
AdamIt's not I mean, uh is it significantly better than the key one? Oh, of course.
ConorI'm a I'm a code golfer at heart, you gotta understand, you know. Like that's uh it's yes, I understand. You know, when you guys were getting rid of like you were like you were doing the what did they call it, the broken keyboard exercise, where it's like what's the best you can do without this, and I'm just like, what? That's that's like you're stabbing the code golfer in the heart right there. It's like you can't take my primitives.
AdamWhat do you do if you've got a broken keyboard?
ConorIt's important. You just uh I don't know. That's the thing. Well, can I still get to every primitive? I think that's the thing, is I've got control space. As long as space isn't the broken key, I can always fuzzy find my way to the primitive key. Yeah, we've got things like I didn't actually know the name of uh so it's back tick back tick oh. Like I didn't know that. And even even pair, like I use pair all the time, but I can never remember it's back tick backtick semicolon. Literally, this is every time I want to type pair, I go back tick semicolon, and I'm like, oh, that's not it. And then I said, is it back tick, comma? That's not it, and I go, ah, whatever, I'll just I'll just do it. And then like I swear to god, every month I I learn it for like three days and then I forget. Um, because I guess like I said, I'm not I'm not coding in these languages on uh but the thing is is the broken keyboard, I got my I've gotten and even even if space is gone, I can do this, and then I can just fuzzy find my way, you know. There's multiple ways to get to these uh these primitives. Anyways, uh is it vastly better? I mean defined better. Is it more beautiful?
AdamYou want to put in put in the you can just type in in normal in dialogue APL thing. And the normal the the equivalent thing. So you want to place it in chat for you? Or oh sure, yeah. Or you want to you can you can I can dictate it.
ConorOkay, what are we doing here? This is the this is the open paren without plus it's wait, is this is this gonna be a non this is APL, so we're just doing it.
AdamThis is the dialogue APL one, but it might yeah, but just to compare what they look like. Uh open paren uh without plus over open paren. Uh without plus open paren. Oh over, yeah. Open yeah, you got that open paren here, and then uh max reduction.
ConorAnd I guess there's leg, that's why you're watching the YouTube channel. I'm watching the video, yeah. You can just keep talking, assume I'm doing it right, and then we'll correct it afterwards. Uh tally at top right tech, tally, top right tack, that's that one.
AdamAnd then after the key, you close the parent, and then you're missing the key. Yeah. Alright, I added it. Yeah.
ConorThe latency here, it's it's messing with us. Yeah. The intersection. Intersection.
AdamYeah, exactly. So then and then you finish the the rest, right? After the closing the parentheses, and then jot V for the vowels. Is that so what you mean you lose you are saving one character by doing the reverse and the reverse over. But other than And over the uh other than that, there's two characters less by having the additional primitive of the count in.
ConorYeah, but so I this is a interesting, I guess for the last nine minutes of this conversation, it's an interesting discussion of like yeah, I see your point.
AdamThis dialogue APL solution, so I guess maybe we can put uh you can also even it out a little bit by by if you don't define it with the vowels, but you just have the actual the actual function, right? So get rid of the outer parenthesis and the jot v. That makes that saves you two characters over a tiny APL that has to have its its white moons or whatever they're called.
ConorRight, right. I see, I see. But well, yeah, we'll we'll avoid that. But I definitely see your point. The the dialogue APL isn't much worse, or in other words, the tiny apple isn't much better. But I would my my affinity uh towards the tiny apple is that this primitive, even though I misunderstood it or misused it, I should say, uh, I'm still gonna go ahead and make the argument that the like if you were to measure the complexity, uh, which is obviously a very, very subjective thing, and you could argue that just like the the you know crescent parens and the tacit programming that exists in this, that could be the most you know complicated thing here. But I I'm a very I'm I'm a decent tacit programmer. Um and so when I look at the complexity in my mind of like the topics here, for me, like this is the thing that stands out as the most complex, or I don't know if complex is the right word, but you know, for plus or minus for some definition of the right word that I'm looking for, like I always, you know, there's so many things going on in here, like the key, the tally, the atop, the tack, when really all I want is frequency count. That's all I want. And like you can memorize this idiom as the frequency count that you want. Um, but like for me, having a single glyph, and I guess that's the thing, is this isn't even really fit frequency count. It's histogram with you know the uh well, yeah, it's it's it's four characters, right?
AdamThose are the that is really the difference in the length here, right? That we got taniotop right key, which I remember as a as a single thing. I know that that is exactly what's called histogram, right? Uh, and you got the epsilon over over.selfie, which is the histogram, right? Those those are two in either either way, you have to remember a phrase. You don't have a histogram primitive for self self-histogram or whatever you want to call it. Well, so the thing is he's doing here.
ConorMadeline early in the chat said that uh you know this doesn't work on uh Unicode strings. Uh it could, but I I think I don't know. I I might have missed I I might have missed part of the conversation, but if I recall correctly, like if we go over here, destroy this solution, and then we just go count on iota 4. It should just give us you know this. But if we go uh uh this it's not gonna work because the way that this is defined, I think, is the inverse of interval. Um and we could we could check to see if you can see.
AdamYou can't use it on character.
ConorSo uh inverse on where is this it? Is this how you spell it? Or indices? How do you spell indices? No, it's just a Yotanda bar. It's APL. Oh, right, right, right. I'm getting my I'm getting my languages mixed. Yeah, so it's just this, and then of course that makes sense uh that this doesn't work, right? But if this did work, you know, if this did work for your um, so what what would it it it would give? Yeah, I guess I don't know. I guess it's a little bit uh it's a little bit that and that's the thing. I've had this discussion as well um with uh Elias, creator of Cap, that I I lean probably not even arguably, definitely, it's just a fact that I lean like past pragmatic, way far to just like I just want things to work. And so one of the things that works in Tiny Apple is that if you lowercase, uh or if if you lowercase, if you use the max glyph, the min glyph on a string, but like technically, I asked Elias if he could implement this for cap. And he looked into it and considered it, but then said it it kind of breaks when you go to certain alphabets. And so like it's not a it's not a uh as as uh Marshall would say, it's not a very uh principled approach to implementing lowercase. And so I exchanged emails back and forth with Elias, it was just a couple, but he he said, you know, I I did consider it, but you kind of are doing something that's not you know holistically principled if you do this. That being said, I still like I still love this because the alternative in a lot of things, like I mean, I guess in in uh dialogue APL, it's quite nice, it's just quad C. But in I think Cap, it's like you know, you have to use like the system function, and then it's it's it's lower or something like that. And like, you know, like I said, I'm a code golfer at heart, and stuff like that, like when you can shave something down to a single character, and then it's also too it just it maps, you know. Uh I mean the the first I didn't invent this.
AdamUm uh the K language, at least some of them, uh, have the round down symbol, which is the underbar, does lowercase, it doesn't have round up, and therefore the problem doesn't exist so much. Why would you ever uppercase, right? In in high frequency trading land, why would you ever uppercase? Um, so and and notice all the K people tend to uh tend to write everything in lowercase, they never even use uppercase letters. Um so I extended that in like my extend uh or I took that idea into the extended dialogue APL many years ago now, and I used uppercase, lowercase, and more arithmetic. So I did things like minus would flip the case and um and the sign for monetic uh multiplication sign that that would give you the case, tell you which if it's uppercase or lowercase, and would give it like one for uppercase, negative one for lowercase, and zero for something that doesn't change case. Um and as uh as Jacob is saying, absolute value of a character is uppercase and negation is swap case. Yeah, but it doesn't it that's not quite right, actually. Absolute value, there are multiple issues with this. And I looked all into this when we were creating Quad C, and I I'll tell you a little bit about it here. Um the the problem so what Marshall complained about is they're not idempotent towards each other, right? Up um floor and ceiling, if you floor, then you have integers and they never change again. But if you lowercase, then you can uppercase afterwards. Never mind that there are strange things in Unicode where things are not mapping symmetrically, but even that that's already a warning sign that there's a problem there. Uh then the but there's actually different things. There's something called case mapping, and there's something called case folding, and they're not the same. So in most cases, you see case mapping and case uh folding to lowercase. So the case folding is just in two versions. There's fold to uppercase, fold to lowercase, that's actually another fold, but that that's so obscure, you don't care about it. Um but case uh fold to lowercase, which is what many people think of when they say lowercase, is not the same as uh as case sorry, case mapping to I mean I messed up. Um uppercase mapping, uppercase uh lowercase mapping. Mapping to lowercase is not the same as case folding. Case folding means unifying multiple letters that signify the same thing to a single character. So just like an uppercase uh A is the same thing as a lowercase a, linguistically speaking, we can fold the two of them together to become a single thing, which we choose arbitrarily that the lowercase form should be the standard form. Um but in some alphabet, some letters have uh variant forms. So for like in Greek, there's a final sigma, and the final sigma incre uh is the same thing linguistically sort of as the normal sigma, but it only appears at the end of a word. So if you want to unify all the sigmas, you take the uppercase sigma and the lowercase sigma and the lowercase final sigma. There is no uppercase final sigma, and they all get converted into um a single letter, which is the non-final lowercase sigma. Okay, but this doesn't map to floor and ceiling at all, you just can't do that. Um, so that's one problem. Another problem is that uh the Cherokee alphabet was originally defined only in uppercase, and then they added a lowercase form later, and therefore the normal form that when we fold is to uppercase, not to lowercase. And then there are other oddities like in uh in Turkish uh and I think also other Turkic languages, you got dotted i and undotted i. Um, so in English, uppercase i is not has no dot, lowercase i has a dot. But in Turkish, you've got uppercase i with a dot, and then lowcase form of that is lowcase i with a dot, and there's an uppercase i without a dot, and a lowcase form of that which is lowcase i without a dot. And they mean completely different things. And I believe somebody even got killed over the difference between them. Um so the mapping isn't actually as great as you might think. It seems cool at first, but it's not it's actually not that precise. Um, absolute value would be the normalization that would be the uh the case folding, and but it still doesn't quite work. Not to mention, if you're dealing with Unicode, there are actually different types of uppercasing, lower casing, and normalization things where do you allow a letter to become to change do you let do you allow a text to change length when you change the case? And you might think like what how does it change how does it change lengths? But that is the case. In in at least traditionally in German, if you take you know, you know, German has a double s or a set sharp s uh letter, it looks sort of like a Greek beta. And if you uppercase that traditionally it splits into two normal s's. But if you lowercase that again, you get two lowercase s's. Because you cannot auto-combine, it depends on the meaning of the word whether two uppercase s's combine into a single glyph, uh that is a lowercase uh double s. And then Unicode later added an uppercase double s and uh and that doesn't map from the lowercase one because Unicode has a stability policy. So all the tools that uppercase they tend to fail on that one letter because Unicode doesn't define it as being the uppercase of the its corresponding lowercase form. So everything is asymmetric. There's so many issues with this, and then comes the big kicker. Let's say you want to compare some data, right? Let's say you got a name of a person and an age, and you want to check, do some checking to see is are these two representations of the same person the same? So maybe it's spelled with uppercase and lowercase letters, and other ones only spelled in uppercase. And and when you've got these mixtures or maybe a nested form of uh of data, often you want to normalize all the character data, but you don't want to have to walk the whole structure to find the character data. So what Quad C does, which you probably never see, no pun intended, um is that uh it only touches character data. So you can actually uppercase lowercase numeric data or references or uh weird objects and things, and they will just stay as they are. And and if we if we overloaded the round up and round down primitives to touch letters as well, then you wouldn't be able to change the case of a whole structure, the character case of a whole structure of uh of data. You would have to walk walk it and single out the characters and convert only the those. Make sense? Or did I there was law and monologue here.
ConorNo, I I mean uh a couple people in the chat are are saying that it does seem like Wewa uh supports the ability to do this stuff with uh custom fill values and whatnot. But I mean your long monologue does highlight the point that I understand Unicode is very complicated, but I just want nice things. And guess what? A couple languages that I never use are gonna fall by the wayside. If I ever have my own array language, it's gonna be optimized for golfing folks and speed as well. But if there's some like Greek letter that doesn't have something and uh, you know, it it's a character that goes to multiple code points, guess what? That that the for the Greek folks out there, I do apologize, but whenever you go to type that letter and you're using my array language that is optimized for golfing, it's gonna be uh it's gonna be a sad day. Hopefully it's only one day out of your entire life. But um, I do understand that there's all these things that um yeah, it's it's if you really want, like I say, like you know, the martial principled approach, you shouldn't do those things. But I am much more in favor, uh not so much in like I'm not saying it makes it a language better or not, but just if I had my own ideal language, I always prefer a single, you know, the quad V. I know it's like of course that's a joke. Is it a joke? Sounds great to me, ship it, you know?
AdamLike if you're making a golfing language, so something like jelly, jelly has, I believe, built-ins both for the vowels with and without y. And like uppercase and lowercase and both cases, and like so it's got all six combinations of those and the consonants with and without y, uppercase and lowercase in both of them. Yeah, sure. For golfing language, you want that. Yeah. Uh but in it, but for practical and and certainly dialect cannot become a golfing language. And for practical applications, it's very useful to do this sort of thing. And that we are um you could even say that floor and ceiling should skip character data, should skip non-numeric data and and just round things. Uh but maybe maybe all arithmetic functions should uh skip non-numbers. Um, there's a actually there's another objection to this sort of thing, and that is that your langu the definition of your language depends on Unicode. So the language itself isn't stable. Um and even more sort of broad is that um maybe in the future, when we have contact with aliens and things, and they've got writing systems that are completely different from ours, Unicode will be replaced with something else. Today Unicode seems so universal, but it wasn't always. There were different ways of representing things before. Um, yeah, and as as Madeline saying, maybe Unicode version 50 has negative code points, and you want minus A to give the negated A. Yeah, who knows? Maybe we find we discover a new dimension, and like text in this dimension needs to be like text that progresses backwards in time, or like anti-meta text, or who knows? Like we we don't know what's going to be in the future. Um imagine if we had made the language design uh way back in time when nobody in the West that designed these things cared about other alphabets and things out there in the world. And then we lock down the primitives, we can't change the meaning of the primitives, that then we don't have a language to communicate in anymore. So if we lock down the meaning of these primitives based on a limited vocabulary of characters, and later we discover we actually need more, and now we can't change things. You really have this problem, right? You've got things like Windows APIs and JavaScript that um that limit themselves to 65,536 characters in the character set, because it was originally thought even by Unicode, right? It was thought that, oh, that's that'll be enough. We don't need uh need more characters, and then we extended Unicode to go up to well, not quite four bytes, but almost, and 1.1 million characters instead. And all of a sudden, those APIs, those languages are broken, right? If if you actually try to deal with Unicode text in JavaScript, you'll see that it's plain broken. I'm sure there are other languages that I'm less familiar with that are just plain broken. And you can you can easily write some JavaScript that creates a string that is impossible, a string that must not exist. And then if you catenate two or join, I guess it's called there, if you can join two strings that must not exist, you can all of a sudden have a valid string again. You get all kinds of nonsense comes out of this, and it's a huge pain for every application because today Unicode is generally represented using UTF-8, at least when it's in text form. Um you have to do all these weird conversions to uh to two bytes with surrogate pairs, and there's a there are blocks, two blocks of the Unicode character set that contain characters that must never appear because they're reserved for the surrogates that are indicators that you're relying on the legacy system. It's a huge mess. And and but Windows defined its API based on an old version of Unicode before it appeared to people that it needed more than that. Are we really so haughty as to say that the current Unicode with UTF-8 and the 1.1 million characters, that is the final? That's it, that that's all there will ever be. And if we want an array language to last forever, to be like a legacy for for the ages, should we define as primitives in terms of some something as fleeting as a character encoding? I think not. So system functions they can come and go, they have a lifespan of some decades. But primitives there forever. So by defining quad C, you know, okay, maybe Unicode will go away, replaced by something else in Galactic Code, and and we'll replace Quad C with, I don't know, quad G, who cares? And deprecate quad C. But if we had defined it in with terms of the arithmetic functions, then yeah, that's uh it's it's goner. What it's a goner? Yeah, the language is a goner, right?
ConorOh yeah.
AdamOne day in the future, contact with aliens and things, and we need like a billion different characters to represent all the different languages in the galaxy, right? And Unicode has as as uh Madeline said, uh Unicode has said there won't be any 18th plane, right? We're cutting it off at uh at 1,114,112 characters. And that's it. We've a stability policy, and we're never gonna exceed that, right? 640k is enough, folks. Go home.
ConorAnd you're the limits of your imagination are that you assume that the language and communication mechanism of these aliens is gonna be representable in some kind of uh you know written or printed language.
AdamWe we we don't direct language straight to the brain, you know.
ConorThere's no way to record it. It's just it's just alien, human, you know, even calling it a brain is limited, you know.
AdamThere's just gonna be some way to you know, the best word that we have to describe is telepathy, but it's the like we think about the representing dates. The year is 1970, right? How many digits do you need to represent the the year? Two, right? 70. What's going to happen in 30 years? We're not gonna be around. There'll be somebody else's problem to deal with that. So now the ISO standard is we represent years with four digits. That will be plenty, don't worry. Year 10,000, not my problem. And then all the software will break in year 9999. Man, this episode. Oh, right. So um in the chat, yeah, Jacob says uh assuming aliens will have case characters. Oh, we don't know. But but but Madeline is saying aliens actually have middle case as well. I mentioned it briefly before, but there are actually three cases in Unicode. Deal with that. Uh there's a middle case called title case, and there are only a handful of characters that have a title case, but they actually have three different cases. There's uppercase, lowercase, and title case on those characters. And Dimas's name begins with one of them. There you go, folks.
ConorWhat better way to end this? Definitely we didn't run off the Rails uh episode of a raycast talking about aliens and the cases. Yeah, we are the aliens. Yeah.
AdamOr these daimas. Look at the code you write, and the array languages that he implements like gotta be alien. It's got a title case character in his name.
ConorThere you go. The things you learn on a raycast. Alright, well, this has been very fun. Didn't realize when Rich left. You know, he was the only thing holding us together, you know.
AdamUm Do you think we'll be able to do a next episode? Have you how many bits have you reserved for the episode number?
ConorOh, it's fine. I think we've I think we can go. I mean, it's represented by ASCII, so even if we run out of numbers, which we won't, uh, we should be fine. I guess yeah, maybe we should do something special for next episode. It's not every it's not every episode you have a power of two, and they're becoming more and more rare.
AdamYes.
ConorAnyways, we will leave links in the description to the Pro Weekly Pro Weekly Challenge, the Dyna videos, and maybe the other stuff that uh we mentioned in this episode. I guess with that, we will say Happy Programming and thanks everybody that uh participated in the chat.