WEBVTT
00:00:12.160 --> 00:00:16.879
Welcome to episode 126 of Arraycast.
00:00:16.879 --> 00:00:26.239
I'm your host, Connor, and I'm with my temporary co-host, promoted, because he is the only panelist, which we will be talking about a little bit more.
00:00:26.239 --> 00:00:33.200
We're gonna go around and I guess do brief introductions because that's just the way we've always done things, and then we'll hop into a couple announcements.
00:00:33.200 --> 00:00:34.479
So over to Adam.
00:00:34.880 --> 00:00:35.280
Right.
00:00:35.280 --> 00:00:37.119
So two things coming up.
00:00:37.119 --> 00:00:42.960
The first one is the deadline for the APL Forge submission.
00:00:42.960 --> 00:00:44.560
It's the 22nd of June.
00:00:44.560 --> 00:00:48.000
So it's just coming up soon, uh in a week.
00:00:48.000 --> 00:00:56.240
Um, so that's the sort of competition where you can submit uh projects in or for APL.
00:00:56.240 --> 00:01:13.519
Um, and then we have a committee of people looking at that, and you can win a prize and a trip to the upcoming APL user meeting, uh dialogue APL user meeting, um, which is going to be in Eastbourne uh on the 12th to the 16th of October.
00:01:13.519 --> 00:01:25.840
Speaking of that, it's registration has begun, and well, you can't see the full schedule yet, but you can see what the workshops are going to be like um and the schedule for that.
00:01:25.840 --> 00:01:27.920
So you can have a look.
00:01:28.400 --> 00:01:28.799
All right.
00:01:28.799 --> 00:01:34.159
I think we technically skipped your brief introduction and went straight into announcements, but that's all right.
00:01:34.159 --> 00:01:35.760
Uh they know me by now.
00:01:35.760 --> 00:01:36.799
They know me.
00:01:36.799 --> 00:01:44.480
Um, I I actually also have a uh it's not an announcement, but it is a call to action of sorts.
00:01:44.480 --> 00:02:00.879
Uh so whether you're listening to this live or you're listening to this on the audio recording later, uh, we are looking to, and I know that there are a handful of folks that have reached out via email or Twitter DM or Discord.
00:02:00.879 --> 00:02:15.680
I have the people in mind that I'm thinking about that uh DM'd me on those platforms, and I think actually maybe one person reached out to us on array uh contact at arraycast.com about joining us as panelists.
00:02:15.680 --> 00:02:19.199
So we're looking to grow our team of one panelist team.
00:02:19.199 --> 00:02:21.120
I mean, Rich might be joining a little bit later.
00:02:21.120 --> 00:02:25.199
He's in a meeting right now, but uh just like last time, he might be joining us.
00:02:25.199 --> 00:02:41.039
If you are interested, uh, because we don't want to miss any of the informal applicants uh that might have emailed us anytime between what is was it, November of 2025 and now, send us an email if you're interested.
00:02:41.039 --> 00:02:43.520
Um we might be doing something a little bit differently.
00:02:43.520 --> 00:02:53.520
We might not be having necessarily all permanent panelists, we might just have rotating panelists, so different voices from episode, but you'll hear the same kind of recurring voices.
00:02:53.520 --> 00:02:58.800
If you're interested, uh drop us an email at contact at arraycast.com.
00:02:58.800 --> 00:03:12.800
If you want, add, you know, uh one or two or three sentences about uh why you'd be interested in joining as a panelist and your background, if any with array languages, you don't necessarily have to have uh array language experience.
00:03:12.800 --> 00:03:14.800
Uh and we'll go from there.
00:03:14.800 --> 00:03:56.400
On top of that, not only are we looking for panelists, but we are looking hopefully for someone to not fully replace Bob Terrio, but to replace the part of his job where he would reach out to guests and set up the you know recording timing schedules uh for guests, because we have a list of guests we'd like to start bringing on, but Adam and I are both very busy folks, and we thought seeing as we're growing the team and a part of that original team was someone that had the time to reach out to guests and uh set up the you know schedule of recordings, uh that'd be fantastic.
00:03:56.400 --> 00:04:18.240
So if you are not only interested in being a panelist, but would also like to do that, or you're not interested in being a panelist, but for whatever reason you like that kind of managerial organizational stuff and you'd like to be involved in kind of setting up who's gonna be the next guest and sending out those kinds of emails, uh also shoot us an email at arraycast contact at arraycast.com.
00:04:18.240 --> 00:04:20.000
And we'll leave it at that.
00:04:20.000 --> 00:04:32.959
So if you're interested, shoot us an email and we will review those over the next two weeks to four weeks, and then you'll probably hear some announcements on this podcast at some point, and we'll be reaching out to folks in between now and then.
00:04:32.959 --> 00:04:42.319
With those two announcements plus a call to action out of the way, links as always, not for the email, but for the two things that Adam mentioned will be in the show notes.
00:04:42.319 --> 00:04:48.000
We have another episode of Adam Live Codes and Connor Learns Things.
00:04:48.000 --> 00:04:52.480
Uh once again, we're gonna be solving a couple Pearl Weekly Challenge problems.
00:04:52.480 --> 00:04:54.319
Well, we'll guarantee we'll solve one.
00:04:54.319 --> 00:05:05.040
I think the first one's a little bit easier, and I actually don't have too much that I'm looking forward to like uh pick up a little tip or a trick here, although I'm sure I will in watching Adam do it.
00:05:05.040 --> 00:05:08.399
I'm more interested in getting to the second one, but uh we'll see.
00:05:08.399 --> 00:05:16.560
Maybe the first one will be more interesting than I anticipate, and it'll take up the whole one, and then we'll have to kick uh down the road the second one.
00:05:16.560 --> 00:05:25.839
So, I mean, I'm not sure if you want to screen share Adam, seeing as you're gonna be live coding in a sec, and then you we can uh describe the um what do you call it?
00:05:25.839 --> 00:05:29.600
Uh problem statement, uh, which I'm now trying to see you.
00:05:29.600 --> 00:05:33.839
Well, yeah, we'll just we'll let you live or are you are you gonna uh screen share?
00:05:33.839 --> 00:05:37.759
I I can, but I don't even know what the problem is yet, so I'm sort of scared here.
00:05:37.759 --> 00:05:46.160
He hasn't so I mean I I linked it in the uh the chat, and I guess actually that's probably everyone can see on the live stream, actually.
00:05:46.160 --> 00:05:51.120
It says Raycast 126 and uh pro weekly challenge uh 377.
00:05:51.120 --> 00:05:54.240
So if I close this, no one can see that anymore.
00:05:54.240 --> 00:06:01.600
Anyways, we'll wait for Adam to screen share, and I believe the problem has something to do with substrings.
00:06:02.079 --> 00:06:02.800
Uh okay.
00:06:02.800 --> 00:06:07.360
Well, I guess I can I can start sharing my screen and see if I open the right window here.
00:06:07.360 --> 00:06:08.639
Uh let's see.
00:06:08.639 --> 00:06:12.879
I've got like a thousand Chrome tabs.
00:06:12.879 --> 00:06:15.120
Let's see.
00:06:15.120 --> 00:06:19.120
So I believe this is uh this is the right page, 377.
00:06:19.120 --> 00:06:19.920
That's what you said.
00:06:19.920 --> 00:06:20.720
Yes.
00:06:20.720 --> 00:06:21.279
Okay.
00:06:21.279 --> 00:06:23.360
Let's see if I can figure out how to read this.
00:06:23.519 --> 00:06:25.839
You gotta scroll down all the way past this nonsense.
00:06:25.839 --> 00:06:27.199
They always do like recasts.
00:06:27.199 --> 00:06:31.680
Then they do stats and then they do task one.
00:06:31.839 --> 00:06:32.399
Here we go.
00:06:32.399 --> 00:06:32.959
Okay.
00:06:32.959 --> 00:06:35.680
I guess we can make this full screen to see this.
00:06:35.680 --> 00:06:37.199
You're given a string, great.
00:06:37.199 --> 00:06:43.360
Write a script to find whether any substring of length two is also present in the reverse of the given string.
00:06:43.360 --> 00:06:44.000
Okay.
00:06:44.560 --> 00:06:45.600
So pretty straightforward.
00:06:45.600 --> 00:06:48.480
The cut the problem is called reverse existence.
00:06:48.480 --> 00:06:49.600
You're given a string.
00:06:49.600 --> 00:06:55.360
The first example uh was ABC B A, I think.
00:06:55.360 --> 00:07:08.959
And the problem's asking you to return a Boolean, a one or a zero, based on whether any substring of length two exists, has its reverse in the string as well.
00:07:08.959 --> 00:07:15.040
So for the first example, AB exists as B A at the end of the string.
00:07:15.040 --> 00:07:20.480
And in general, any palindrome is gonna return true by definition.
00:07:20.480 --> 00:07:22.480
Um unless it only has one character.
00:07:22.480 --> 00:07:26.240
Yeah, I I guess I was about to say, unless if you have a one-character string.
00:07:26.240 --> 00:07:39.120
But then the string in example three, A B C D is gonna return false because it does not have um, I guess by definition, you're also gonna need duplicate characters.
00:07:39.279 --> 00:07:40.720
Um not that we're gonna check it out.
00:07:40.720 --> 00:07:43.759
If it's duplicate characters, then then yeah, of course.
00:07:43.759 --> 00:07:48.720
So I mean, maybe there's a a better way to do it, but I think very simple.
00:07:48.720 --> 00:07:59.439
If we start by looking at the pairs that are there, and then we can look at what at the pair is reversed, right, and check if any is a member.
00:07:59.439 --> 00:08:06.000
So these are those uh the reversed, and we want to check if there are members of itself.
00:08:06.000 --> 00:08:08.319
So they're all members, right?
00:08:08.319 --> 00:08:10.959
Because this is a f a palindrome like this.
00:08:10.959 --> 00:08:13.120
Uh so that's obvious.
00:08:13.120 --> 00:08:16.560
Um, A, B, C, D, all members.
00:08:16.560 --> 00:08:20.720
But if you want to do something the way they're not all members, maybe have a like a normal test?
00:08:20.720 --> 00:08:21.920
Banana, sure.
00:08:22.079 --> 00:08:22.240
Okay.
00:08:23.120 --> 00:08:25.759
Uh well, I was gonna say A B C D should return all zones.
00:08:25.759 --> 00:08:26.800
Oh no, this is a mistake.
00:08:26.800 --> 00:08:28.079
This is a mistake, this is a mistake.
00:08:28.079 --> 00:08:34.240
Uh the reason is that I I don't want to reverse the list of strings, I want to reverse the each in the list of strings.
00:08:34.240 --> 00:08:35.279
Okay, so there we go.
00:08:35.279 --> 00:08:40.399
So A B C D, and then none of these are right, and banana.
00:08:40.399 --> 00:08:41.919
These are right.
00:08:41.919 --> 00:08:45.679
So all we need to do is we want to see if there are any.
00:08:45.679 --> 00:08:47.759
So that will do it.
00:08:47.759 --> 00:08:53.840
This is not a proper function, it's just a sequence of of operations, but we can we can just wrap it.
00:08:53.840 --> 00:08:59.360
So this is how I'll do it initially, but I think we can be maybe slightly more clever.
00:08:59.600 --> 00:09:02.159
I was gonna say this is already better than what I did.
00:09:02.159 --> 00:09:03.279
Uh okay.
00:09:03.279 --> 00:09:06.320
What let me let me find the is it clear how it works?
00:09:06.320 --> 00:09:07.360
Everything, the structure of it.
00:09:07.360 --> 00:09:18.639
Why did I I guess that's the thing, is I I don't have my membership and find and uh the epsilon um functions, I guess, committed.
00:09:18.639 --> 00:09:22.720
And so I always do that thing where you like uh just try one, make a mask.
00:09:22.720 --> 00:09:27.279
Yeah, but I basically, but I I guess I did it one by one.
00:09:27.279 --> 00:09:32.639
I didn't um so like I have like a reverse of each one at a time.
00:09:32.639 --> 00:09:34.320
It's so much more complicated.
00:09:34.480 --> 00:09:40.320
Um, this is so we have a question in the in the chat if it's guaranteed to be only two letters, but yes, that's the problem.
00:09:40.320 --> 00:09:42.480
Yeah, just find the substring and link two.
00:09:42.480 --> 00:09:44.960
So this is this will be here's another thing we can do.
00:09:44.960 --> 00:09:52.000
Uh we could put a swap here, which is the same thing as giving a negative two over here, but that doesn't really matter for now.
00:09:52.000 --> 00:09:55.759
Um, and that gives us also the reversed substrings.
00:09:55.759 --> 00:09:59.360
So we could look at whether these are members, right?
00:09:59.360 --> 00:10:00.879
So we can actually make it a little trained.
00:10:00.879 --> 00:10:04.240
This is excessive work because we're making, I mean, it doesn't really matter.
00:10:04.240 --> 00:10:08.720
We're making um the the substrings twice.
00:10:08.720 --> 00:10:18.240
So we can say, are the normal order length to substrings members of the reverse order member linked to substrings?
00:10:18.240 --> 00:10:20.320
And then we can write that.
00:10:20.320 --> 00:10:24.000
So that's I mean, that's just a different way of stating it.
00:10:24.000 --> 00:10:26.960
Whether we generate them from that, I'll say it in a different way.
00:10:26.960 --> 00:10:28.960
Doesn't really make a difference.
00:10:29.919 --> 00:10:36.799
Yeah, this is well, like I said at the beginning, probably I was gonna learn something even though I wasn't expecting this to be the problem.
00:10:36.799 --> 00:10:43.279
But yeah, this I don't know why because I guess, yeah, once this is the membership glyph.
00:10:43.279 --> 00:10:56.480
Yeah, and if you've got substrings against substrings, I guess that's the thing, is I didn't think to search the substrings in the reverse substrings.
00:10:56.480 --> 00:11:01.840
I kept substrings versus a string, and so then I guess you could do that.
00:11:01.840 --> 00:11:03.919
Yeah, yeah, but it's a way worse idea.
00:11:04.080 --> 00:11:08.720
Um, but if you do that, it's a if you if you do it like this, right?
00:11:08.720 --> 00:11:21.120
And then for each one of these, we want, I mean, we want to find out if it's a member or if it's found in the entire string.
00:11:21.120 --> 00:11:23.440
Oops, a mistake I make here.
00:11:23.440 --> 00:11:25.039
Oh, missing the argument.
00:11:25.039 --> 00:11:29.600
And we don't need an each, we need the each over here.
00:11:29.600 --> 00:11:30.399
There you go.
00:11:30.399 --> 00:11:44.320
So now we say for for each, we get a mask of the places where it appears, which would be more interesting if we're actually looking for specific places where specific substrings are found, but it we're not, so it doesn't really matter.
00:11:44.320 --> 00:11:52.960
So we all we need to do is see if there's anyone in here anywhere, which we could couple different ways, you can I mean just like that, we'll do it.
00:11:53.279 --> 00:11:55.840
That was not one of the ones I was thinking of.
00:11:56.159 --> 00:12:10.879
I was thinking of uh or ravel or or um yeah, we also know they're the same length, so I guess we could even do it with a rank, but I mean it's there are many different ways of doing it, they're not especially attractive.
00:12:10.879 --> 00:12:12.480
We're looking way too much here.
00:12:13.440 --> 00:12:27.039
So, my I have a question about why did you default to enclosing the original string um versus I guess when I did it you could have bound it like this instead.
00:12:27.440 --> 00:12:28.559
Yeah, that's what I did.
00:12:30.080 --> 00:12:46.000
And this is why I wanted to do the problem uh in the first place, is because in order to if this is the way that you originally spell it, which is what I did, um minus the find find, I did uh or reduce or reduce.
00:12:46.000 --> 00:13:00.720
In order to go from order to go from that uh to tacit, you end up having to kind of do the backflip in order to get what you originally put, which is enclosing the string in order to put it in a flip.
00:13:00.720 --> 00:13:06.320
It's one uh it's one worth getting to hear from you.
00:13:06.320 --> 00:13:10.720
Why did you put the why did you do the enclose original string first?
00:13:10.720 --> 00:13:15.840
Uh and probably we should slow down a bit to explain this to the audio only listener.
00:13:15.840 --> 00:13:19.039
And then also too, this is like a trick that I learned.
00:13:19.039 --> 00:13:21.279
I I consider it a trick at one point.
00:13:21.279 --> 00:13:25.360
Um wait, I actually don't know, I don't actually understand what you've done now.
00:13:25.519 --> 00:13:34.240
So you've avoided or no, you have uh uh commuted because it's a it's a fork over here, an AGH fork on the left.
00:13:34.240 --> 00:13:44.639
So that means it's it has to be parenthesized or bound, but we can't bind the two to a derived function anyway on the left, so we have to parenthesize anyway.
00:13:44.639 --> 00:13:48.320
So then I just immediately went for okay, I'll swap the arguments.
00:13:48.320 --> 00:13:51.039
Um and that's that's what I did here.
00:13:51.360 --> 00:13:57.919
Yeah, that's really that's really hard to do because you're doing uh each on the dyadic and then a commute in order to do the enclose.
00:13:57.919 --> 00:14:03.279
That's uh yeah, if you're seeing that for the first time and trying to parse that, uh it's a bit tricky.
00:14:03.279 --> 00:14:09.360
But yeah, walk us through so is why you reach for the enclose first and then this in general.
00:14:09.840 --> 00:14:17.840
I I don't know if we call it more functional, but like I prefer keeping things in their right places instead of composing them.
00:14:17.840 --> 00:14:21.600
Composing on the with a what's not called composition, it's called binding.
00:14:21.600 --> 00:14:33.519
Binding a right argument is somewhat messy because it converts a dadic function to monetic function with the remaining argument slot being on the left.
00:14:33.519 --> 00:14:38.399
But being that it's now a derived monetic function, that argument goes on the right.
00:14:38.399 --> 00:14:41.440
So maybe that's a bit complicated to explain in this context.
00:14:41.440 --> 00:14:43.200
But let's take minus, for example.
00:14:43.200 --> 00:14:47.679
So if you write like 10 10 jut minus, that's a monetic function.
00:14:47.679 --> 00:14:49.120
It's pretty easy to understand.
00:14:49.120 --> 00:14:50.080
It's 10 minus.
00:14:50.080 --> 00:14:53.519
But if instead we wanted to write the minus 10 function, right?
00:14:53.519 --> 00:14:57.840
So this takes an argument over here, so it's 10 minus 100, negative 90.
00:14:57.840 --> 00:15:17.200
If we wanted to write the minus 10 function, which we'll have to parenthesize in in application, but that's not so important, and then the argument over here, then notice that uh this argument which appears to the right, um, the argument to the minus 10 function actually becomes the left argument to minus, even though there's no explicit swapping going on.
00:15:17.200 --> 00:15:19.519
That means things are jumping around a bit.
00:15:19.519 --> 00:15:29.840
I prefer right arguments to remain right arguments, left arguments to remain left arguments, or being explicit about the swapping, which we can do with the commute operator.
00:15:29.840 --> 00:15:37.919
So so that would might be one reason why I prefer to enclose on the right instead of binding.
00:15:37.919 --> 00:15:39.440
But sometimes I'll do it.
00:15:39.840 --> 00:15:40.639
That makes sense.
00:15:40.799 --> 00:15:44.559
And then well it's also not a very meaningful function.
00:15:44.559 --> 00:15:49.360
I mean, if you bind an argument, you sort of want the derived function to be meaningful.
00:15:49.360 --> 00:15:52.080
But what is the find in omega function?
00:15:52.080 --> 00:15:54.080
This is a weird thing.
00:15:54.080 --> 00:15:59.759
It's like look for them look for ones, that's a meaningful function, but not look in something.
00:16:00.159 --> 00:16:00.559
Right.
00:16:00.559 --> 00:16:01.919
And then explain.
00:16:01.919 --> 00:16:02.960
So that makes sense.
00:16:02.960 --> 00:16:36.960
It walk people through this um enclosing uh a string or a vector and then performing the dyadic operation each time, because a lot of times, especially when you have the original pattern where you're trying to bind, you know, partially apply an argument to a dyadic function in order to apply something over, like it took me a while just to stumble into this kind of pattern, whereas, like if you want to turn that into tacit, the pattern is to enclose it and then do some dyadic operation each.
00:16:36.960 --> 00:16:37.440
Yeah.
00:16:37.440 --> 00:16:42.960
Like one, is there like documentation somewhere to point people at this?
00:16:42.960 --> 00:16:48.000
And and if even if not, like uh what's the uh path?
00:16:48.000 --> 00:17:00.720
Is it is the path to discovering this just that is the more and more you program an APL, at some point you will kind of stumble into this pattern, and then you'll if you're lucky, store it in your vault of way of ways to solve things tacitly?
00:17:01.600 --> 00:17:23.440
So I I don't know, we can look at the documentation for it, but I think uh it is a problem people have with the each operator, is that especially if they come from another programming background and they think of they think each is just oh that's just my map, but it's not then they then they expect a single thing on the left and multiple things on the right, expect it to to map over.
00:17:23.440 --> 00:17:42.880
So if we take like um A B C and we want to catenate just for ease of usage here with uh X, Y, Z, I think so it the actual mapping, which really means stepping over elements, right, with sort of iterating, um appears on both sides.
00:17:42.880 --> 00:17:45.039
So uh it's a double map.
00:17:45.039 --> 00:18:04.960
This usually would have to write this either with um explicit iterator counter that you then index in other languages, or you have to do a single map that includes the iterator and then use a single indexing for the other arguments, which makes it asymmetric, but each is completely symmetric in the API.
00:18:04.960 --> 00:18:08.880
So the way it works is that we have got the scale extension.
00:18:08.880 --> 00:18:24.160
We can have a single element, um that's a bad example that maps to both uh to all to all the elements of the other argument, and we can have we can start off with many on the left and have a single thing on the right, and it will map the other way.
00:18:24.160 --> 00:18:30.160
We can even have a single on both sides that's also allowed, then we get an an enclosed result.
00:18:30.160 --> 00:18:37.359
So the way to so we can sort of say the one to many is a solved problem.
00:18:37.359 --> 00:18:45.119
So if we want uh one side to be considered one, you sort of want to reduce the problem to that date.
00:18:45.119 --> 00:18:51.440
So we need to change this vector that's on one side or any array really to a scalar, and we do that by an enclosure.
00:18:51.440 --> 00:19:07.839
So each actually opens up enclosures, actually digs into an array, which can be a little bit hard to spot when you're dealing with simple arrays because we've got this floating array model, but really it's it's reducing the depth um of the arguments by one.
00:19:07.839 --> 00:19:24.480
And re what it happens here with the um with the each, where we've got an array with multiple elements on the left and a single array that contains multiple elements on the right, is that we reduce the enclosure level by one on both sides.
00:19:24.480 --> 00:19:31.440
So that's so we take first the first element of the array on the left, and then on there's only a single element on the right.
00:19:31.440 --> 00:19:36.240
So we take that element and disclose that as well, which reveals the entire array that's inside.
00:19:36.240 --> 00:19:41.279
And then we do the same thing with the second element on the left and open up on the right and gives it an entire array.
00:19:41.279 --> 00:19:45.680
That's why effectively it becomes a many on the left to one on the right.
00:19:45.680 --> 00:19:53.119
I know the K language has like explicit separate each operators or adverbs, like each left and each right.
00:19:53.119 --> 00:20:01.039
Um, but in APL, that's because they don't have, I mean, the cause, they don't have the concept of an enclosure, a scalar enclosure.
00:20:01.039 --> 00:20:03.200
You can only do one element lists.
00:20:03.200 --> 00:20:05.279
So it's a whole different way of doing things.
00:20:05.279 --> 00:20:11.599
We can write an each left each right operator in APL, but it's easier to do it like this.
00:20:11.599 --> 00:20:18.880
And so too, we can yeah, so this this maps each element on the left to the entire array on the right.
00:20:18.880 --> 00:20:28.000
And similarly, we can do an enclosed the array on the left and the catenate each to an unenclosed array on the right, and that maps it the other way.
00:20:28.000 --> 00:20:29.599
So these are the two different types of each.
00:20:29.599 --> 00:20:35.920
And then again, as before, we can just do a simple each with no enclosures and that pairs up the individual elements.
00:20:35.920 --> 00:20:41.279
It sort of hints at an operator that's missing, the depth operator, which PQN has.
00:20:41.279 --> 00:20:43.279
I think that was in my initiative.
00:20:43.279 --> 00:20:55.440
Uh J actually has it called the level at operator or adverb, but isn't much use there because J is much more about um dealing with higher rank than deeper depth.
00:20:55.440 --> 00:21:00.079
And then the complete equivalent thing is that we can bind.
00:21:00.079 --> 00:21:09.440
So the binding, uh this long left scope of operators, so the each here sees if we write quote a b c quote jot comma each.
00:21:09.440 --> 00:21:14.480
So the each sees the quote a bc quote jot, comma, as a single thing.
00:21:14.480 --> 00:21:26.079
It's a single derived monetic function that's applied to each element on the right, and that's why it has that effect uh of concatenating the entire left side because it's been bound into the function to each element on the right.
00:21:26.079 --> 00:21:31.759
The other way is interesting because we can't just put uh a jot on the other side.
00:21:31.759 --> 00:21:34.240
That doesn't make sense syntactically.
00:21:34.240 --> 00:21:47.119
We do want the jot in this position immediately to the right of the concatenation function, but we have to put the operand to um to the bind operator immediately next to that as well.
00:21:47.119 --> 00:22:04.480
And then some people end up in the especially with a neuter APL writing something like this where we have got a left argument and then comma jot right argument each, but that's not right, of course, because the comma jot right argument each is a Single derived monetic function, it takes a single argument, which is on the right.
00:22:04.480 --> 00:22:13.599
So the ABC now needs to move over to the right to get that effect we had before, which is that's the sort of thing that can be confusing.
00:22:13.599 --> 00:22:19.680
Like positionally on the line of code, the left argument is on the right, and the right argument is on the left.
00:22:19.920 --> 00:22:26.880
Yeah, at least for me though, when I was learning APL, this was easier to get to.
00:22:26.880 --> 00:22:32.000
Um because it well, I guess it just depends on the order that you learn things.
00:22:32.000 --> 00:22:42.079
But like for me, coming from Haskell, um where partial application and like binding is very common, it it maps like very easily to APL, right?
00:22:42.079 --> 00:22:46.000
You have your bind operator and you can partially apply something on the left or right.
00:22:46.000 --> 00:23:09.039
And so if you know that you're trying to fix something uh and you're trying to apply that unary operation, it's easier to without learning the uh, I guess, uh full uh depth or like comprehensively understanding what each is doing and how if you're adjusting it's um you know the with enclose, like that's uh an extra thing that you need to learn.
00:23:09.039 --> 00:23:16.160
And you can get to what's on the screen right now, just partially applying something on the right, putting that on the left, and then eaching it over whatever you need to.
00:23:16.160 --> 00:23:27.519
And so that was typically the way that I would do things until I actually don't know how I I guess one day I just was messing around, yeah, and then I was like, Oh yeah, if you enclose it, I guess that kind of makes sense.
00:23:27.519 --> 00:23:40.640
You're um although I would have I ever explained that what was happening is that the each was reducing um the depth by one, and uh I don't think that's how I would have ever explained it.
00:23:40.640 --> 00:23:48.799
Uh I think I was I think I just knew it as like a little idiom that you enclose something on the right and then then it'll apply over the whole thing.
00:23:48.960 --> 00:23:59.759
Um so I mean I guess J is a bit more formal about things in a way is good, but I think practically speaking, pragmatically speaking, it just comes in your way more often that it does your service.
00:23:59.759 --> 00:24:10.480
So there in J, they don't have a each primitive, but they do have an each like standard library word, and it's all it is is under this close.
00:24:10.480 --> 00:24:16.319
But the under they have is they have two different types of compositional operators.
00:24:16.319 --> 00:24:22.640
Uh the the close and uh white, I don't remember what the other word is, uh uh application.
00:24:22.640 --> 00:24:38.480
And so what it does is it it does an operation, but on each um element or on each cell, um it it does some application, and then it applies the function and it joins everything to back together again.
00:24:38.480 --> 00:24:47.519
So really we can see each as being a uh rank zero under disclose thing.
00:24:47.519 --> 00:24:52.880
So or or well, we say all the way around, it's this close under rank zero.
00:24:52.880 --> 00:25:02.559
So if we if we think about it, this we can try to define the dyadic uh each, but let's just do it for a single single thing.
00:25:02.559 --> 00:25:05.920
Well, actually, let's make a monadic because it doesn't really matter, the pattern is the same.
00:25:05.920 --> 00:25:19.519
So let's let's make the each operator, and all it does is we have an argument and we have a function that we are applying rank zero that's on every um element if you want.
00:25:19.519 --> 00:25:27.359
But before we apply the function, we're going to um apply it a disclose first if you want.
00:25:27.359 --> 00:25:41.200
But since it's rank zero means there will only be one element, so there's no difference between uh a mix and they um and a first, they just disclose, and then when we are done, then we package it down again with an in-close.
00:25:41.200 --> 00:25:42.240
So this is sort of an under.
00:25:42.240 --> 00:25:44.079
We don't have the under operator yet, right?
00:25:44.079 --> 00:25:50.720
So but we are disclosing, applying the function, and enclosing, and then that gets collected into the argument.
00:25:50.720 --> 00:26:01.920
So we can see here if you say abc df, so we can do a reverse each and reverse with our fancy new operator, each gives the same result.
00:26:01.920 --> 00:26:04.319
This is really the definition of each.
00:26:04.319 --> 00:26:16.480
And the dyadic form is exactly the same, except instead of applying um with an uh function atop this close, it would be a function over this close.
00:26:16.480 --> 00:26:19.599
So we're just applying pre-processing to to both sides.
00:26:19.599 --> 00:26:21.920
That's the whole definition of it.
00:26:21.920 --> 00:26:25.119
Uh, then we need an alpha over here.
00:26:25.119 --> 00:26:36.319
So now you can see that it's explicit that this disclosing, and then you can also see why uh why enclosing sort of negates the preprocessing of that side.
00:26:36.319 --> 00:26:47.119
If we enclosed omega here, then we then when we apply rank zero on omega, that's the entire array, because it's enclosed, so that's a scalar, that's the whole thing.
00:26:47.119 --> 00:26:48.640
So that doesn't matter on the right.
00:26:48.640 --> 00:26:57.519
On the left, of course, if we have multiple elements, it will go into each element, and then we disclose it, which it's just a single enclosure, so that gives us what's inside it.
00:26:57.519 --> 00:27:01.839
And on the left, we it does its thing on each element, and so on.
00:27:01.839 --> 00:27:02.799
Does that make sense?
00:27:03.119 --> 00:27:16.319
It does, and uh, maybe I will take the time to add chapters to this YouTube live stream after it's done recording, and I'll call this each deep time each deep dive and tacit tips or something like that.
00:27:16.480 --> 00:27:28.799
And so then we can just point people to the timestamp uh whenever they have questions about because this is TC is a trace operator uh in the defense workspace that draws out.
00:27:28.799 --> 00:27:31.920
Let's turn off boxing here, it will be very flooded.
00:27:31.920 --> 00:27:38.079
Um it draws out on the screen um the steps of computation wherever we insert it.
00:27:38.079 --> 00:27:41.039
So it's just a magnetic operator, we can attach it to any function.
00:27:41.039 --> 00:27:45.440
So if we attach it to every function, then we can we can see exactly what's going on.
00:27:45.440 --> 00:27:57.119
So here this function the disc close and we'll put a tc on that, and the main function we can put a tc on that, and the in-close we could put a tc on that.
00:27:57.119 --> 00:28:02.480
Okay, so we're redefining our each like that, and now we're doing what we did before.
00:28:02.480 --> 00:28:08.400
A b c comma each xn.
00:28:08.400 --> 00:28:14.160
So we can see here that it first thing it does is disclosing the x gives us x.
00:28:14.160 --> 00:28:16.079
Disclosing the a gives us a.
00:28:16.079 --> 00:28:18.000
That's there's not much there to do.
00:28:18.000 --> 00:28:19.200
We're picking those, right?
00:28:19.200 --> 00:28:23.680
And then we concatenating a and x together that gives us part of the result.
00:28:23.680 --> 00:28:25.680
And then we take the next step.
00:28:25.680 --> 00:28:30.240
We enclose that result, and that goes into our result array.
00:28:30.240 --> 00:28:31.759
And then we take the next one.
00:28:31.759 --> 00:28:34.720
The y's and the b's and so on, that we'll step through.
00:28:34.720 --> 00:28:41.519
Now, if we enclose here, we can't really see much, but we'll see a little bit of the spacing will be increased.
00:28:41.519 --> 00:28:45.920
So we can see that there's extra spacing here that sort of indicates that it's in-close.
00:28:45.920 --> 00:28:49.440
So we're disclosing that, and that gives us the unpackaged form.
00:28:49.440 --> 00:28:52.319
So it's just just negation of that in-close.
00:28:52.319 --> 00:28:54.559
Rest of it is sort of the same.
00:28:54.559 --> 00:28:56.880
Um, all right.
00:28:57.039 --> 00:28:59.200
Well, I mean, we've spent 30 minutes on the first problem.
00:28:59.519 --> 00:29:01.279
I think we've got not quite yet.
00:29:01.279 --> 00:29:03.680
There are other ways to do it because this is the pro with your problem.
00:29:03.680 --> 00:29:05.440
So we've got to solve this with regex, man.
00:29:05.440 --> 00:29:06.960
Otherwise, it's all right.
00:29:06.960 --> 00:29:08.000
Well, we'll let you see.
00:29:08.000 --> 00:29:36.079
We'll we'll time box the regex solution to uh to uh how well how quickly I think I can do it pretty quickly because we want we want the one letter followed by um another letter, which uh no obscening thoughts here, uh and then we want any any sequence of characters followed by the second one and then the first one, right?
00:29:36.079 --> 00:29:43.279
This would mean if we have if this matches anywhere, then we've then the answer is true, right?
00:29:43.279 --> 00:29:46.319
So abc D shouldn't match any, we've got nothing.
00:29:46.319 --> 00:29:48.319
A B C B A.
00:29:48.319 --> 00:29:49.759
We found that, right?
00:29:49.759 --> 00:29:55.759
So that's the first two and the last two, but we're not actually interested in whether or not uh and where what the answer is here.
00:29:55.759 --> 00:29:58.559
We just want to know if there is such a thing.
00:29:58.559 --> 00:30:01.039
And banana, we found an anna, right?
00:30:01.039 --> 00:30:03.920
So we found an followed by something followed by na.
00:30:03.920 --> 00:30:12.319
There might be multi multiple of them, but it doesn't matter because the first one is going to find, well, is is enough.
00:30:12.319 --> 00:30:19.279
So if we write like uh a b a and uh xyx, we should we'll find two.
00:30:19.279 --> 00:30:27.680
All we need to know is how many are there, and then we can take the sign of that or see if is one greater than uh sorry.
00:30:27.680 --> 00:30:31.279
Yeah, yeah, is it more more than equal to one?
00:30:31.279 --> 00:30:33.599
So that would be the solution as well.
00:30:33.920 --> 00:30:38.559
That was very fast and uh still not as short as the APL though.
00:30:38.559 --> 00:30:43.680
Um no, I know I well technically it is APL, but not your original solution.
00:30:43.680 --> 00:31:05.359
Asher in the chat, in the APL, which I believe is your co-worker, um says that uh he just posted a bunch of wacky ways to do the original problem ordered from clear to short, but I think I think YouTube is eating all of those solutions.
00:31:05.359 --> 00:31:08.559
So you can just send them to me in in normal chat.
00:31:08.559 --> 00:31:17.920
I was gonna say either send them to me, get them, but in general, that's only a good solution for viewers that know uh how to send them to you.
00:31:17.920 --> 00:31:30.400
So I'm going to array cast github repo, and I'm creating uh a new chat, and I guess we'll just call these um what do we do?
00:31:30.400 --> 00:31:34.079
We call this uh I guess it is a podcast episode.
00:31:34.400 --> 00:31:37.920
So here are here are Esher's uh solutions.
00:31:37.920 --> 00:31:55.440
So what's going on here is he's doing an auto product of the array with itself, and then he's looking at whether we have any diagonal matches and any full matches that would be if they are right.
00:31:55.440 --> 00:32:03.359
So any diagonal matches that's if we have a reversal, and any full matches would be if we have duplicates, I believe.
00:32:03.359 --> 00:32:14.240
And so and he flattens that and I and find out if there's any uh anyone in that seems a bit overkill to me, but sure.
00:32:14.240 --> 00:32:26.319
This is a similar that's exactly the same, just instead of looking for these patterns, then he's just doing rotations in to match things up, and then seeing if there are any such patterns.
00:32:26.319 --> 00:32:37.519
He's still more of this idea finding the indices and seeing if uh if there are any indices that are off by one from each other.
00:32:37.519 --> 00:32:39.119
Okay, that's what you mean by wacky.
00:32:39.119 --> 00:32:44.720
Yeah, uh, I agree with him that uh wacky wacky is a good description of these.
00:32:46.480 --> 00:32:53.119
And if other folks have solutions, because last time we got uh a very cool Wii Wa solution at the tail end.
00:32:53.119 --> 00:33:06.720
Um but yeah, J, BQN, any Ray languages, tiny Apple, feel free to you could try posting them in the YouTube chat, and then uh if it doesn't work there, you can post them in the GitHub discussion link to Raycast.
00:33:06.720 --> 00:33:08.319
Uh all right, let's move on.
00:33:08.319 --> 00:33:09.920
Thank you for those submissions, Asher.
00:33:09.920 --> 00:33:12.720
Those are um uh very cool.
00:33:12.720 --> 00:33:28.160
I am very interested to see uh Adam solve this because my solution to this was pretty terrible, and he already improved upon the first problem, so I'm he's almost guaranteed to improve upon the second problem.
00:33:28.160 --> 00:33:31.039
The question is, how nice will it end up being?
00:33:31.039 --> 00:33:32.240
Time will tell.
00:33:32.240 --> 00:33:45.920
And the problem statement is prefix suffix, write a script to find if two strings in a given array, which is uh an array of strings, uh, such that to find if two strings in that uh array of strings.
00:33:45.920 --> 00:33:48.480
So there are only two strings in the in the array of strings.
00:33:48.480 --> 00:33:49.200
No, no, no.
00:33:49.200 --> 00:34:00.160
There are multiple strings, but you're looking for two strings within the array of strings where string one is a prefix and suffix of string two.
00:34:00.160 --> 00:34:00.960
Oh, okay.
00:34:00.960 --> 00:34:02.880
You you perform that option.
00:34:03.359 --> 00:34:05.519
This is this is a bad bad formulation, right?
00:34:05.519 --> 00:34:12.719
It says write a script request if the two strings, if there are two strings, string one and string two, such that, right?
00:34:12.719 --> 00:34:17.920
So string one is a prefix and suffix of string two, return the total count of such pairs.
00:34:17.920 --> 00:34:27.679
Okay, so uh we I guess the easiest thing is I mean, we could do fancy stuff for performance with looking at the length and sorting out things that would be impossible.
00:34:27.679 --> 00:34:34.639
Um but easiest thing is just to uh to do an outer product.
00:34:34.639 --> 00:34:38.559
Let's start by uh importing this.
00:34:38.559 --> 00:34:41.599
Array is quite JSON.
00:34:41.599 --> 00:34:44.079
We've got to turn JSON this off.
00:34:44.079 --> 00:34:45.679
Okay, so we've got our array.
00:34:45.679 --> 00:34:47.280
Maybe we should turn boxing on again.
00:34:47.280 --> 00:34:48.639
Box on.
00:34:48.639 --> 00:34:58.559
Okay, so we've got our strings here, and then we want to find out how many are uh uh prefixes and suffixes of each other.
00:34:58.559 --> 00:35:01.760
So first we have to figure out what is mean it's a prefix and a suffix.
00:35:01.760 --> 00:35:11.679
So I think the I mean we could do a find and look at the at the beginning at the end whether there's a one, but I think it's easiest to just do a reversal.
00:35:11.679 --> 00:35:18.719
So let's say these are again sort of funny examples, but okay, let's take a b a uh that's a bad example again.
00:35:18.719 --> 00:35:23.519
Okay, let's do a b and do ab X.
00:35:23.519 --> 00:35:27.840
So here this is a a prefix and a suffix.
00:35:27.840 --> 00:35:31.920
So for prefix, there's I like to compose things like this.
00:35:31.920 --> 00:35:36.000
So it's the uh no, it's not even that, it's the first.
00:35:36.000 --> 00:35:36.400
Sorry.
00:35:36.400 --> 00:35:38.159
The first of the find.
00:35:38.159 --> 00:35:40.239
That that is the prefix function.
00:35:40.239 --> 00:35:42.960
That means the left argument is a prefix of the right argument.
00:35:42.960 --> 00:35:51.440
It's technically speaking on lots of unnecessary work, but hopefully one day if my colleagues will do their job right, this will be optimized and it will stop looking.
00:35:51.440 --> 00:36:03.199
Like this composition, or even with a thunk or something, it will stop looking after the first element because this it will never return true otherwise, uh, because we throw away everything but the first element.
00:36:03.199 --> 00:36:05.199
But this is this is the first, right?
00:36:05.199 --> 00:36:12.320
Now, for suffix, the easiest thing to check is whether this in reverse appears at the end over here.
00:36:12.320 --> 00:36:17.440
So we can just do that with a uh with an over reverse.
00:36:17.440 --> 00:36:21.039
So if we say make this AC, it'll say no there, right?
00:36:21.039 --> 00:36:23.760
So we need to apply this function twice.
00:36:23.760 --> 00:36:24.800
One with with the over.
00:36:24.800 --> 00:36:29.280
We can't factor that out because it's really two different sets of data it's working on.
00:36:29.280 --> 00:36:38.480
So if we want to make sure that both of these are true, we write first a top find, and first atop find over reverse.
00:36:38.480 --> 00:36:52.400
So this is the uh this means that the condition here has been met, and uh then we want to do this as an outer product on all the the array of of strings.
00:36:52.400 --> 00:36:53.840
So that's this.
00:36:53.840 --> 00:37:05.039
Now um they say the result is is four here, but of course there's a diagonal going down here, so that's a bit of a problem, right?
00:37:05.039 --> 00:37:09.760
Because they apparently they don't count uh duplicates, right?
00:37:09.760 --> 00:37:13.440
You can't say the string one is both a suffix and a prefix of itself.
00:37:13.440 --> 00:37:26.639
And where but I suppose they do say that uh well interesting, an interesting thing is what if it's a complete match as well, if they have the same length and they are because if the duplicates in the same way.
00:37:26.639 --> 00:37:28.800
There is an example below.
00:37:28.800 --> 00:37:31.840
Let's see.
00:37:31.840 --> 00:37:33.280
No, this one, yeah.
00:37:33.280 --> 00:37:34.239
The one.
00:37:34.239 --> 00:37:34.719
Okay.
00:37:34.719 --> 00:37:42.400
That is interesting as well, because if you take that example, abab abab, right?
00:37:42.400 --> 00:37:46.800
So so there they don't count the duplicates either.
00:37:46.800 --> 00:37:57.440
I would say that the first abab is a prefix and suffix of the second above, and the second above is also a prefix and suffix of the um of the first one, right?
00:37:57.440 --> 00:37:59.039
But they don't say that either.
00:37:59.039 --> 00:38:07.760
So apparently what we have to do is we have to mask out half the triangle, just in case, um, and and the middle diagonal.
00:38:07.760 --> 00:38:10.239
So we can we can do that.
00:38:10.239 --> 00:38:17.440
So if we if we look at a masking here, so if we make we can try to start with this.
00:38:17.440 --> 00:38:20.079
Oops, sorry, that should be this.
00:38:20.079 --> 00:38:28.239
This is a a masking triangle to isolate just the elements that we want on the strictly top right corner.
00:38:28.239 --> 00:38:31.360
So this would be with a count.
00:38:31.360 --> 00:38:34.639
We want to tie these together, the top over here.
00:38:34.639 --> 00:38:36.239
That's our function.
00:38:36.239 --> 00:38:40.400
And we can adjourn that in here, this and this.
00:38:40.400 --> 00:38:46.239
So this gives us our matrix, and all we need to do now is count how many ones there are.
00:38:46.239 --> 00:38:48.719
So we can do that, there are multiple ways to do that.
00:38:48.719 --> 00:39:01.599
But classic one is the sum of the rabble that's for it's looks sort of noisy, but it it's fairly readable, especially if you put them spaces in.
00:39:01.920 --> 00:39:07.360
That's uh God mode APL programming, folks, that you just witnessed there.
00:39:07.360 --> 00:39:14.480
And um uh let's all just have a moment of silence for this beautiful expression that uh Adam has uh put on.
00:39:14.480 --> 00:39:16.719
Rich, what are you doing in the chat?
00:39:16.719 --> 00:39:20.079
You're supposed to be on this podcast right now.
00:39:20.079 --> 00:39:21.920
Join the call, man.
00:39:21.920 --> 00:39:24.880
Or is or is he is he virtually attending another meeting?
00:39:24.880 --> 00:39:26.159
Uh and I don't know.
00:39:26.159 --> 00:39:30.320
He might he might be in another meeting but secretly looking at this.
00:39:30.559 --> 00:39:34.239
Yeah, we call them uh Rich says that it's two tested.
00:39:34.880 --> 00:39:36.320
Uh I disagree.
00:39:36.320 --> 00:39:43.199
Um, well, so my first comments are is that mine actually isn't too far off.
00:39:43.199 --> 00:39:53.519
So I I mean I had the prefix idiom um first composed with uh or I guess it's is it find is the name of the glyph?
00:39:53.519 --> 00:39:55.920
Yeah, first composed with find.
00:39:55.920 --> 00:39:59.440
I didn't I missed this over trick.
00:39:59.440 --> 00:40:14.239
So I think my first thought was what I wanted to do was under, but I guess it doesn't need to be under because you need to reverse it at the end, it doesn't matter.
00:40:14.239 --> 00:40:14.800
Exactly.
00:40:14.800 --> 00:40:16.960
So is that is that a general rule of thumb?
00:40:16.960 --> 00:40:22.559
So yeah, my my for for those you know that uh are only APLs and not familiar with under.
00:40:22.559 --> 00:40:24.800
I mean, every uh is everyone familiar with under?
00:40:24.800 --> 00:40:39.280
Under is like you know, as Adam likes to say, under anesthesia, you apply an operation and uh then you do some other operation and then you apply the reverse if there is you know a defined one for that.
00:40:39.280 --> 00:40:43.199
So under reverse, the inverse or reverse of reverse is reverse.
00:40:43.199 --> 00:40:46.559
Yeah, clip that, put that in a TikTok.
00:40:46.559 --> 00:40:55.039
And uh but in this case, because you are just getting back a scalar, you don't need to reverse the result.
00:40:55.039 --> 00:40:57.519
And so, yeah, that's my question.
00:40:57.519 --> 00:40:58.639
Is that a general rule?
00:40:58.639 --> 00:41:06.400
If you only need to apply an operation and you don't need to worry about like undoing that operation, can you always use over?
00:41:06.400 --> 00:41:08.239
I guess not really.
00:41:08.239 --> 00:41:15.519
It's only in the case where you have two arguments, and also I don't even think under necessarily would have worked for this, would it?
00:41:15.679 --> 00:41:20.559
Oh no, under would have worked because the result is a scalar, and reversing a scalar, it doesn't do anything.
00:41:20.559 --> 00:41:21.760
So right, right, right.
00:41:22.000 --> 00:41:23.119
It wouldn't have made a difference.
00:41:23.119 --> 00:41:24.960
It's just unnecessary.
00:41:24.960 --> 00:41:34.639
And so, anyways, that was the first thing that I saw that you did was the over reverse, which is really nice, and then I did it something a little bit different.
00:41:34.639 --> 00:41:41.119
Instead of building up the upper triangular matrix and masking things out, I did a here.
00:41:41.119 --> 00:41:42.559
Let's let's admit Rich.
00:41:42.559 --> 00:41:53.119
Uh look at that from YouTube comment section to uh to uh 48 minute uh joining guests.
00:41:53.119 --> 00:41:53.840
Welcome, Rich.
00:41:53.840 --> 00:42:00.960
We're deep in Pearl Weekly 377, and now you're here to reign on our tacit parade.
00:42:01.199 --> 00:42:07.119
Look, all I'm saying is look at that a top, a top abomination, a top a nation.
00:42:07.840 --> 00:42:08.800
A top a nation.
00:42:08.800 --> 00:42:18.239
Let me tell you, this line of code is gonna get more people into APL than this like JavaScript looking like everything's got a variable name.
00:42:18.239 --> 00:42:19.760
That's my that's my pitch.
00:42:20.639 --> 00:42:23.599
Well, I didn't I said it was too tacit.
00:42:23.599 --> 00:42:34.639
I didn't say you should name every part of it and then also too, look at him not aligning these arrows.
00:42:35.760 --> 00:42:38.880
I could go back and fix that in post or whatever you want to call it.
00:42:38.880 --> 00:42:40.159
Is it if this helps you?
00:42:40.159 --> 00:42:42.800
Array box does it automatically.
00:42:42.800 --> 00:42:47.760
Uh um but yeah, the while Adam is still typing this up.
00:42:47.760 --> 00:42:51.440
Uh it does a little bit.
00:42:51.440 --> 00:42:52.960
Um, okay.
00:42:52.960 --> 00:43:04.800
And uh but the thing, so the I was saying that the thing that um uh Adam did where he was uh building up the upper triangular matrix and then masking things out.
00:43:04.800 --> 00:43:26.079
Uh instead of doing that, I did like a uh and I don't know if this is an idiom, but it's a pattern that I use sometimes where you just you get an IOTA sequence, you rotate your original array of strings um by your iota sequence, and then you perform an operation where you have you know one string versus the rest of the string.
00:43:26.079 --> 00:43:31.039
So kind of like the head tail trick if you're familiar with Haskell, which which one's better?
00:43:31.039 --> 00:43:32.719
Uh you know, pick your poison.
00:43:32.960 --> 00:43:37.840
Well, I was wondering when I was watching that, is this is the description they often are ambiguous.
00:43:37.840 --> 00:43:40.400
Is it ambiguous enough to say we go?
00:43:40.400 --> 00:43:45.039
You could just stick a unique on the inputs and then get the number out.
00:43:45.519 --> 00:43:55.440
The description is ambiguous enough, but um I think it's not enough examples that is not gonna end up working.
00:43:56.320 --> 00:43:57.119
Yeah, right.
00:43:57.119 --> 00:44:00.480
Unique might not work, it's just that it doesn't I don't know.
00:44:00.480 --> 00:44:01.599
I don't know about this thing.
00:44:01.599 --> 00:44:03.039
They say there's only one.
00:44:03.039 --> 00:44:05.519
And we do things with themselves.
00:44:05.519 --> 00:44:06.880
Yeah, we do things with themselves.
00:44:06.880 --> 00:44:07.679
So you should count it.
00:44:07.679 --> 00:44:08.800
Yeah, I think that will work.
00:44:08.800 --> 00:44:15.119
Um but we also it's not enough because this will you still need to take them away from themselves.
00:44:15.119 --> 00:44:18.079
So you still need to do something about the diagonal.
00:44:18.079 --> 00:44:20.639
So certainly that's not going to be enough.
00:44:20.639 --> 00:44:31.519
Because you even if we take the first one, uh, we said like uh every everything in every every string gets a match on its own because it's its own prefix and suffix.
00:44:31.519 --> 00:44:32.159
Yeah.
00:44:32.159 --> 00:44:36.880
So therefore taking away the is not going to yeah, so you have to get rid of the diagonal.
00:44:36.880 --> 00:44:41.519
Getting rid of the diagonal, you might as well just get rid of the duplicates with the doing top right instead of diagonal.
00:44:41.519 --> 00:44:43.840
It's a matter of switching this for an equal sign.
00:44:43.840 --> 00:44:45.920
So that doesn't really help.
00:44:45.920 --> 00:44:47.679
But maybe this is more readable.
00:44:47.679 --> 00:44:52.400
And we could even define this as a function and then apply it at the end.
00:44:52.639 --> 00:44:55.519
Um it's a possibility.
00:44:55.519 --> 00:44:59.280
I really just mean once you've got that many atops, it's a deepen.
00:45:00.320 --> 00:45:06.159
No, it's but that's the it doesn't really help because if you go back to this, and you're saying you've got lots of atops.
00:45:06.159 --> 00:45:08.480
Let's try to see how what it looks like as a defen then.
00:45:08.480 --> 00:45:10.960
So yeah, this is a defense deephon at all.
00:45:10.960 --> 00:45:12.320
This is like that case.
00:45:12.480 --> 00:45:18.800
That's uh your your the far right outer product, you know, I'd leave that.
00:45:19.360 --> 00:45:20.000
You leave that.
00:45:20.000 --> 00:45:22.320
So this is a deefen, and then this.
00:45:22.320 --> 00:45:27.519
I mean, okay, you're gonna compare this with with this, you say.
00:45:28.079 --> 00:45:43.679
Yeah, in so much as an argument that has been made many times by many people, that here you can sort of see plainly what bits are applied monadically and to the argument, whereas with if we put in a little bit of spacing like this.
00:45:43.679 --> 00:45:45.840
Well, meh.
00:45:45.840 --> 00:45:46.559
No?
00:45:46.559 --> 00:45:50.320
No, I still think the defense just a bit more at a glance.
00:45:50.320 --> 00:45:55.599
Oh, you can but you know, this is uh very controversial topic.
00:45:55.920 --> 00:46:09.360
Well, I was gonna say we can dedicate the last uh 38 minutes of episode 126 to uh once again how much tacit is too tacit, because we've got, I mean, the audio listener is just being like, what are they talking about?
00:46:09.360 --> 00:46:10.880
They're just all like, what about nah?
00:46:10.880 --> 00:46:11.599
Uh-uh.
00:46:11.599 --> 00:46:13.840
And we've got three solutions.
00:46:13.840 --> 00:46:15.280
We at one point had four.
00:46:15.280 --> 00:46:21.280
If you remove the spaces from the original tacit, and there's a plane flying above uh me right now.
00:46:21.280 --> 00:46:26.480
I'm not sure if that's getting picked up, but you know, the first one on screen is the most tacit.
00:46:26.480 --> 00:46:45.360
It's it's gonna for those that like uh, or sorry, it's the most explicit, for those that like tacit programming, it's gonna break your heart because the uh two character three if you're using the compose glyph uh has been named prefix, which is six characters, you know, a few more if you include the spaces and the assignment.
00:46:45.360 --> 00:46:48.800
Uh and then it's omnifix for looking at the prefix.
00:46:49.280 --> 00:46:53.519
Oh, it is still completely tacit up until the last line.
00:46:53.519 --> 00:46:56.719
It's just that it's the the composed functions.
00:46:56.719 --> 00:46:58.880
Adam, if you're talking, you're muted.
00:46:58.880 --> 00:47:00.239
Or am I?
00:47:01.119 --> 00:47:03.119
Or Adam, if Adam's talking, yes, you software.
00:47:03.119 --> 00:47:10.159
Um, which probably just was his uh um headphones microphone cutting out of it.
00:47:10.320 --> 00:47:19.599
All right, this is very this is functional programming people of this sort of thing, you know, compose your functions into new named functions and then recompose those functions.
00:47:19.599 --> 00:47:20.639
Can you hear me?
00:47:20.639 --> 00:47:22.239
Yeah, I can hear you, Adam.
00:47:22.239 --> 00:47:22.960
You sound good now.
00:47:23.119 --> 00:47:34.800
Yeah, so so I'm saying the yeah, that it's sort of what's the point of making it verbose and readable when you could take the time to slowly go through if it's slow, right?
00:47:34.800 --> 00:47:35.760
To go through these parts.
00:47:35.760 --> 00:47:37.440
I'm not saying you should remove all the spacing.
00:47:37.440 --> 00:47:44.639
The spacing, I think the spacing here can help a little bit to see the structure, but there's like it does what it says on the tin, right?
00:47:44.639 --> 00:47:46.239
This what do you mean by ones?
00:47:46.239 --> 00:47:51.280
It's ambiguous, but this is completely unambiguous, at least if you know that it's a monetic context.
00:47:51.280 --> 00:47:53.840
And the same thing here, like okay, the top right corner.
00:47:53.840 --> 00:47:56.320
I guess that that's works as a name for it.
00:47:56.320 --> 00:47:57.119
Although it calls it.
00:48:01.199 --> 00:48:02.719
It's a in this case, yeah.
00:48:02.719 --> 00:48:04.480
But that's uh, not ourselves, exactly.
00:48:04.480 --> 00:48:05.840
You want to name things differently.
00:48:07.760 --> 00:48:12.400
I can this sort of construct is so common that I'll instantly recognize it.
00:48:12.400 --> 00:48:16.719
I mean we maybe replace some of these with jots instead if you want, but it's it's the same thing.
00:48:16.719 --> 00:48:20.239
Right, but mod argues well again, I don't remember.
00:48:20.239 --> 00:48:21.199
And this one as well.
00:48:21.199 --> 00:48:23.039
This one is the is the tough one, right?
00:48:23.199 --> 00:48:24.960
Where we this one is slightly harder to read.
00:48:24.960 --> 00:48:32.960
I didn't even get to the finish uh describing in an audible way what all of the things look like.
00:48:32.960 --> 00:48:34.480
Is it even possible?
00:48:35.199 --> 00:48:54.480
Oh uh yeah, I mean so the the descriptions of them were and I guess well that's a good point, is that the I said the most explicit, but really that is Rich was correct to point out that technically the first four lines where you're assigning names to uh components of the full tacit expression, that's all tacit.
00:48:54.480 --> 00:48:56.400
It's actually it's just naming.
00:48:56.400 --> 00:48:57.760
What do you what do you technically call that?
00:48:57.840 --> 00:49:06.079
It's I mean that's very if you look at any of the D Funds workspace, defense.dialog.com, look at the code in there, it's very that flavor.
00:49:06.079 --> 00:49:21.119
It's name a line uh as a definition of a thing, and then compose all the definitions or put all the definitions together into the final answer, which is and it was very much inspired by uh functional programming, that way of writing stuff.
00:49:21.119 --> 00:49:26.079
The pure symbol thing is slightly more controversial, if anything.
00:49:26.320 --> 00:49:39.679
So we have a comment from the unpronounceable participant name in the chat saying that uh the tacit code is unambiguous if you know the aerity, but with hardware keeping track of all the atops here.
00:49:39.679 --> 00:49:40.559
That's what I'm saying.
00:49:40.559 --> 00:49:43.199
But actually, atops tell you what the arity is.
00:49:43.199 --> 00:49:47.199
If you have an atop, you know that whatever's on the left is called monetically.
00:49:47.199 --> 00:49:48.159
There's no other way.
00:49:48.159 --> 00:49:55.360
So if you go up and read I'm just you know that this plus is not a pairwise plus, right?
00:49:55.360 --> 00:50:02.000
It's and you know that this outer product here is monetic, and because of that atop, and you know that here yeah, yeah.
00:50:02.000 --> 00:50:04.000
So all the all of these, the same thing goes here.
00:50:04.079 --> 00:50:26.559
If you know that you have to read several of those to figure that out, and each piece, and it's not yeah, and it's like in the fork, you know, you've got some extra noise to detangle between the tops that are either side of the and, whereas the omega, like that's one omega, and then the rest just reads as and just passes as APL.
00:50:26.559 --> 00:50:27.360
Yeah.
00:50:27.360 --> 00:50:31.599
So you've got one indicator there saying this is uh monadic.
00:50:31.599 --> 00:50:36.079
Whereas in your like a top account, a top outer product.
00:50:36.400 --> 00:50:45.760
So maybe maybe some kind of um um compromise thing where we we'll just define the omnifix immediately.
00:50:45.760 --> 00:50:49.119
We say this is what the solution asks for, right?
00:50:49.119 --> 00:50:53.119
We we really it's trying it's defining this term of omnifix.
00:50:53.119 --> 00:50:58.239
So we're saying omnifix is space it out nicely.
00:50:58.239 --> 00:51:06.880
Uh this and what we want is then the rest of this.
00:51:06.880 --> 00:51:09.760
I mean these are some qualifications.
00:51:09.760 --> 00:51:13.920
How about that?
00:51:14.239 --> 00:51:17.920
Oh, I see that array box kind of link.
00:51:17.920 --> 00:51:20.000
Open my link, Adam.
00:51:20.000 --> 00:51:21.920
I wanted to see how crazy it looks.
00:51:21.920 --> 00:51:22.639
Uh okay.
00:51:22.639 --> 00:51:32.639
I mean, I'll say to that respelling that my problem wasn't with the the omnific side of it, it was the other side of it that I'm not a fan of.
00:51:32.639 --> 00:51:37.920
I do this is quite interesting that uh array box only you know can deconstruct.
00:51:37.920 --> 00:51:41.760
And the thing is the facet function, it can't do this with a defense.
00:51:42.079 --> 00:51:51.199
If you if you uh like if you go to the parenthesized component and you just select that and then you go shift enter, uh you know, it'll zoom in on that.
00:51:51.199 --> 00:51:52.719
And then I didn't add this feature.
00:51:52.719 --> 00:51:59.920
If you go and hover over each of the glyphs in in there, like uh a user went and added this, and so that's so nice.
00:51:59.920 --> 00:52:00.960
Yeah, love it.
00:52:00.960 --> 00:52:09.119
Anyways, like I'm not saying this is an argument for you know, one versus this is this is a tool to help you get over the deficiency, yeah.
00:52:09.360 --> 00:52:21.519
Uh you know, that it's um that you call it deficiency, but I'm saying uh a dictionary is a tool to help you get over the deficiency of the language that the words don't hold on.
00:52:21.519 --> 00:52:26.800
The words too many words the words in in English, for example, do not carry their own meaning, right?
00:52:26.800 --> 00:52:28.400
They only define the dictionary.
00:52:28.480 --> 00:52:32.079
So clearly every actually they're not they're not really even defined in the dictionary.
00:52:32.320 --> 00:52:39.440
No, no, I know, but in principle they define the dictionary, but it's all just circular definitions according to dictionary sellers that are defined in it.
00:52:39.440 --> 00:52:46.400
Okay, but but but so clearly we should include the dictionary entry for every word we say every time we say it.
00:52:46.400 --> 00:52:54.159
That's great for a language learner, but for somebody who gains proficiency in the language, you don't want to log a dictionary with you all the time.
00:52:54.159 --> 00:52:56.159
And I don't need this anymore.
00:52:56.159 --> 00:53:01.440
At some point, you have to stand on your own feet, you have to can't just define everything from basics all the time.
00:53:01.440 --> 00:53:03.920
Um, what was that that talk by Guy Steele?
00:53:03.920 --> 00:53:08.960
Um where he starts off his talk, yeah, growing a language, right?
00:53:08.960 --> 00:53:18.960
Yeah, it's it's painful if you were to start every talk, every paper, everything you do, every product growing things, everything from like some bare bones vocabulary.
00:53:18.960 --> 00:53:21.360
We make an assumption about the reader.
00:53:21.679 --> 00:53:33.199
It's a fair point, and it might be I'm just uh slightly I just haven't still haven't grown over my bias of uh against the maybe it's just the the glyph that's used for a top uh or something.
00:53:33.599 --> 00:53:38.320
That is an unfortunate pairing that makes it look noisy and and stuff.
00:53:38.480 --> 00:53:39.360
Uh yes.
00:53:42.559 --> 00:53:54.960
Well, you know, maybe I should maybe this is an experiment I should do is force myself to I th I think the the interesting thing is that like I also agree that like this is a bit noisy, but my thought is not that like tacit is the problem.
00:53:54.960 --> 00:54:05.039
My thought is that like wouldn't it be great if there was a glyph for uh you know the uh upper triangular matrix.
00:54:05.039 --> 00:54:17.599
Um, you know, so if you could just if there was a uh a higher order function or an operator that if you passed it less, it would give you that matrix, and then like it completely collapses like six glyphs into one.
00:54:17.599 --> 00:54:20.320
And and also two, we're technically repeating the prefix.
00:54:20.320 --> 00:54:31.920
So like I'm not saying there should be a glyph for is prefix, but like my my thought is is there a way to like contort this in order to only have those three glyphs once?
00:54:32.400 --> 00:54:41.599
Um uh Marshall's what is a primitive uh post, his document in BQN, because that's kind of what you're speaking to there.
00:54:41.760 --> 00:54:51.840
Is well, I mean, I I find myself liking Tiny Apple when I'm just like solving these trivial problems the most, because like whenever you want a glyph, it's usually there.
00:54:51.840 --> 00:54:57.599
And I don't actually think tiny apple has a upper triangular um matrix glyph.
00:54:57.679 --> 00:55:00.719
Um, but I was a notation had that if I remember right.
00:55:00.719 --> 00:55:01.440
Did it?
00:55:01.440 --> 00:55:03.599
Uh yeah we go, let's bring it back.
00:55:03.679 --> 00:55:05.599
Let's make APL great great again.
00:55:06.880 --> 00:55:08.800
Make APL glyph again.
00:55:08.800 --> 00:55:14.559
Um I if I remember right, it had like these I mean clearly, yeah.
00:55:14.559 --> 00:55:20.400
I mean symbols that was there were like little squares with dots in the corners and slashes.
00:55:20.719 --> 00:55:26.079
Um it's a fairly common technique, right?
00:55:26.079 --> 00:55:27.360
Uh in APL lands.
00:55:27.360 --> 00:55:29.440
Look at this over here.
00:55:29.599 --> 00:55:32.000
Maybe I should open up just this frame here.
00:55:32.000 --> 00:55:33.760
Oh, special indices.
00:55:33.760 --> 00:55:34.559
Yeah.
00:55:34.559 --> 00:55:35.760
Hell yeah.
00:55:35.760 --> 00:55:48.320
And we find that is the Unicode upper no, I'm not sure if they had that, but here uh I found the upper right.
00:55:48.320 --> 00:55:49.280
Look at this.
00:55:49.280 --> 00:55:53.199
So these upper left triangle, upper right triangle, lower left, lower right.
00:55:53.199 --> 00:56:02.400
And if I remember right, there are a bunch more that are uh defined that like if there's a slash going through them, then it includes the diagonal.
00:56:02.400 --> 00:56:03.280
That's amazing.
00:56:03.280 --> 00:56:04.480
Madeline, get on it.
00:56:04.480 --> 00:56:06.079
There's there's the glyphs.
00:56:06.400 --> 00:56:20.960
But that's the thing, is like I I think so often, like the you know, optimal or ideal solution in in array languages is so strongly informed by the glyphs that you have access to.
00:56:20.960 --> 00:56:45.199
Like, and like that sounds like an obvious statement, but when you're switching between array languages and you know it takes four or five glyphs to spell something versus a single glyph, like and then potentially there's a two-glyph way to spell it in uh the language where it was five or six to spell that uh thing that was a glyph, like that that affects like the way I want to spell something, especially if like performance is not a concern, right?
00:56:45.519 --> 00:56:55.840
Well, I was gonna ask Adam with the longest APL experience about the time before key, which is before I even joined dialogue or knew anything about APL.
00:56:55.840 --> 00:56:56.239
Yeah.
00:56:56.239 --> 00:57:07.280
But considering what it is and and what it does and how it's used, it is one of those things that boggles the mind a little bit that that people would do things before and else what before key.
00:57:07.280 --> 00:57:10.800
People did things before nested arrays, yeah.
00:57:10.960 --> 00:57:19.760
Yeah, so uh out of product, yes, but reluctantly because this performance would be obvious dangerous, right?
00:57:19.760 --> 00:57:21.920
So you want to do whatever you can to avoid that.
00:57:22.079 --> 00:57:30.400
But writing um and what everyone would just walk around with a little uh group bar operator or something they would use?
00:57:30.719 --> 00:57:37.119
Not necessarily, but I think there were for things that were that were critical, people would write some bespoke code, right?
00:57:37.119 --> 00:57:45.519
So even now key has performance issues in the general case, but in certain specific cases it's good, and that sort of comes back to the same thing.
00:57:45.519 --> 00:57:53.440
If you know what exactly your problem is, you can write some bespoke code that's really uh really good and fast and simpler than what it needs to be in general.
00:57:53.440 --> 00:57:58.719
Uh so I think people did that more, and the same thing goes to the the the Boolean techniques, right?
00:57:58.960 --> 00:58:18.320
You can now we have fancy things like pairwise application and uh and we can right that always gets me in the introductory APL tutorials uh in a in a good number of them, it introduces uh pairwise difference as a one drop minus the neg one drop.
00:58:18.320 --> 00:58:25.840
Even though for quite a while pairwise difference as a windowed reduction has existed.
00:58:25.840 --> 00:58:26.320
Yeah.
00:58:26.320 --> 00:58:29.119
And yet they always still seem to introduce it that way.
00:58:29.119 --> 00:58:31.440
I guess because that's what you see in real code.
00:58:31.440 --> 00:58:32.239
Yeah, yeah.
00:58:32.559 --> 00:58:33.679
I think that's true.
00:58:33.679 --> 00:58:40.800
Uh I think that's a lot of it's just legacy that and and the pairwise thing wasn't introduced until later, so people just get stuck with that.
00:58:40.800 --> 00:58:47.599
Um I mean dialogue has had tally since version 14, together with key.
00:58:47.599 --> 00:58:53.199
Nevertheless, people write the first of the shape all the time, or even one pick shape.
00:58:53.199 --> 00:58:54.559
Uh creatures.
00:58:54.559 --> 00:58:57.840
Yeah, people tend it works, right?
00:58:57.840 --> 00:59:01.440
It doesn't if mostly yeah, it doesn't even really cost.
00:59:01.440 --> 00:59:04.639
I think I think yeah, people wrote up more bespoke code like this.
00:59:04.639 --> 00:59:11.519
There's a comment here in the in the chat saying spelling things with more clips can give you insight into the implementation of algorithms.
00:59:11.519 --> 00:59:12.800
Yes, I think that's true.
00:59:12.800 --> 00:59:24.000
Like how we wrote earlier um each in terms of rank and open as a good disclose and and in-close, I think gives you more insight into what's actually happening.
00:59:24.000 --> 00:59:32.000
I think it's a good thing to try to model a model more complicated primitives in terms of simpler primitives to get insight into the case.
00:59:32.400 --> 00:59:51.840
There's a good post by Roger Huey about um the inner product and the rank operator, and doing a certain spelling of inner product using reductions and the rank operator uh gave him a a way to implement in C that was better than what they'd been doing before.
00:59:52.159 --> 00:59:52.960
Oh interesting.
00:59:53.199 --> 00:59:55.519
I wonder if I can dig that up somewhere.
00:59:57.039 --> 01:00:02.960
Yeah, I think you can also you can also understand some of the notation better.
01:00:02.960 --> 01:00:09.760
So a lot of these newer APLs have rationalized their the outer product to be a monetic operator.
01:00:09.760 --> 01:00:20.239
But there's a reason why it looks like it's a dyadic operator with some weird uh left operand, and that's because you can there's actually a relationship between outer product and inner product.
01:00:20.239 --> 01:00:31.840
Um if we if we took um one, two, three plus the times uh ten, twenty, thirty, you got 140.
01:00:31.840 --> 01:00:38.079
And so this is one times ten plus two times twenty, just three times thirty, and then add it together.
01:00:38.079 --> 01:00:44.000
But so the outer product, like this, you can actually see it here.
01:00:44.000 --> 01:00:47.280
So one times ten, two times twenty, three times thirty.
01:00:47.280 --> 01:00:54.960
So if we apply the diagonal, which we can do in this case it's not really important what the diagonal is, but this is the diagonal, and then we sum it.
01:00:54.960 --> 01:01:09.679
Okay, so the inner product plus the times is the plus function applied over the diagonal, uh is the the plus function reduced over the diagonals of this outer product.
01:01:09.679 --> 01:01:15.039
And if we don't do that part, then obviously we get the outer product.
01:01:15.039 --> 01:01:30.559
So let's let's write a model sort of for of the of the outer uh of not of the outer or inner product, but of the dot so we're going to write it so we can define later what actually the outer product does, but let's just say that that is a um a given thing.
01:01:30.559 --> 01:01:38.480
So we have the outer is alpha alpha alpha uh alpha alpha omega, right?
01:01:38.480 --> 01:01:44.480
And then we check, uh sorry, that's wrong, it's the right upper end.
01:01:44.480 --> 01:01:49.760
And then we check if um some null function is equal.
01:01:49.760 --> 01:01:51.760
So let's just use zero for now.
01:01:51.760 --> 01:01:58.159
So if zero and matches, or we can even say just look at the name class, right?
01:01:58.159 --> 01:02:01.440
So it's forward equal a tx of alpha alpha.
01:02:01.440 --> 01:02:12.079
So so this gives us the name class, which let's say is going to be three if it's a function, it's two if it's an array, so if uh if it's two, so if it's a zero or any other value actually, then we just return outer.
01:02:12.079 --> 01:02:16.719
Otherwise, we do, and this will only work on matrices, but it doesn't really matter.
01:02:16.719 --> 01:02:22.719
Uh we do the left function reduction over the uh diagonal of outer.
01:02:22.719 --> 01:02:31.039
Okay, so now we can write one, two, three, z and then zero uh yeah, that's fine actually.
01:02:31.039 --> 01:02:38.480
Dot times 10 20 30 is the outer product, and the inner product is this.
01:02:38.480 --> 01:02:57.119
So if we see the zero here as a sort of null function, meaning if you try to if you have an operation called the reduce over diagonal, so you do an alpha alpha reduce over diagonal, but alpha alpha is a null function, so we do a null reduce over diagonal, that means don't actually do any reducing over diagonal, then we just get the outer product.
01:02:57.119 --> 01:03:05.199
So we so originally jot wasn't used as bind and uh and the composition at all, it was only for this.
01:03:05.199 --> 01:03:08.400
So jot was it was even called nil, I think.
01:03:08.400 --> 01:03:10.400
So it was just a nil dot times.
01:03:10.400 --> 01:03:14.639
Meaning don't do that reduction over the diagonal thing, skip that step.
01:03:14.639 --> 01:03:18.400
It's a placeholder for a null function, and now they're consistent, right?
01:03:18.400 --> 01:03:19.360
Like now it makes sense.
01:03:19.360 --> 01:03:22.079
If you have a null null function, then you don't do it.
01:03:22.079 --> 01:03:33.840
And there were there were this concept would later um extend it to other operators as well, but never they never found them their way into uh mainstream APL, including dialogue APL.
01:03:33.840 --> 01:03:42.639
So, for example, we have the power operator, which keeps applying a function until something holds true, usually a fixed point, but it could be anything, right?
01:03:42.639 --> 01:03:50.559
It could be a greater than, could be something, something external, some custom tests on on the successive iterations.
01:03:50.559 --> 01:03:52.880
So until this condition holds true.
01:03:52.880 --> 01:03:56.480
And if you use the nil function, then it's forever.
01:03:56.480 --> 01:03:58.880
So that's the fixed point, I think.
01:03:58.880 --> 01:04:02.719
Or we could you say it's it's has a number, you do it five times, right?
01:04:02.719 --> 01:04:05.360
But nil means just keep going forever.
01:04:05.360 --> 01:04:12.000
Um that wasn't implemented because it has an option for fixed point, yeah.
01:04:12.000 --> 01:04:14.159
This yeah, this was how you you write it.
01:04:14.159 --> 01:04:20.800
Um I think it didn't even have a function, I think it was just originally a number and then and then fixed point.
01:04:20.800 --> 01:04:23.280
And that just means there's no particular number.
01:04:23.280 --> 01:04:25.360
It's not even infinity, isn't really true either.
01:04:25.360 --> 01:04:29.039
That's what J uses, but it's not infinite times, it's until it's stable.
01:04:29.039 --> 01:04:32.159
It's until until it doesn't make a difference anymore.
01:04:32.159 --> 01:04:45.360
And I think there were there were other ideas for very for operators having slots unoccupied in uh so I can't quite think of what they would be, but I think we could look them up.
01:04:45.360 --> 01:04:55.760
So sometimes I think comp decomposing things into simpler primitives could sort of give you insights about how things work, how they're connected to each other.
01:04:55.760 --> 01:05:03.039
And if you replace that out-of-product notation with some other notation, just another operator, then you lose the connection between inner and outer product.
01:05:03.039 --> 01:05:06.800
There's a reason why they're named like that, inner and outer product, because they're really related.
01:05:06.800 --> 01:05:09.199
They're both products of a sort.
01:05:09.199 --> 01:05:14.719
Anyway, we did we look we didn't even look at other ways of solving this.
01:05:14.719 --> 01:05:18.320
Because now we did the the the beginning and end thing.
01:05:18.320 --> 01:05:21.679
We another way we could we we did it with the find.
01:05:21.679 --> 01:05:28.559
Another way we could do it is uh taking a prefix of a length, but uh it still get pretty dirty.
01:05:28.559 --> 01:05:51.599
We still have a ray here, so we still need an an outer product, but then we still need the masking, all of that we still need uh in principle we could do something like we could get the we could we can save on the computation by by computing the the combinations uh combinations table um and then only applying those.
01:05:51.599 --> 01:05:55.280
So I think we have got um what's cmat?
01:05:55.280 --> 01:05:58.320
C mat three.
01:05:58.320 --> 01:05:59.599
Oh that's all right.
01:05:59.599 --> 01:06:02.079
Do you also have three isn't hanging out?
01:06:03.039 --> 01:06:03.920
No, you're right.
01:06:03.920 --> 01:06:04.719
It is a number.
01:06:04.719 --> 01:06:07.440
Oh, um, no, C mat's dyadic.
01:06:07.440 --> 01:06:10.000
P mat is the one addict one.
01:06:10.320 --> 01:06:15.920
Oh, because we want to we want to take okay, we want to do how many ways we can be two two two out of two out of three.
01:06:15.920 --> 01:06:16.559
Yeah, okay.
01:06:16.559 --> 01:06:19.840
So it's it's the same syntax as the exclamation part, right?
01:06:19.840 --> 01:06:24.239
That's yeah, that's counting how many they are, and this one is telling you what they are.
01:06:24.239 --> 01:06:25.119
Right.
01:06:25.119 --> 01:06:27.280
So these are all the ones we need to test.
01:06:27.280 --> 01:06:32.079
And so if we got array over here, there are only four, and we need to choose two at a time.
01:06:32.079 --> 01:06:35.519
So these are all the different combinations we need to test.
01:06:35.519 --> 01:06:41.679
But that's not really we do need the ordering as long as they're unique, right?
01:06:41.679 --> 01:06:43.199
Because it could be one or the other.
01:06:43.199 --> 01:06:46.719
So I think actually we need PMAT permutations.
01:06:47.280 --> 01:06:54.400
Uh but that only gives us Yeah, I think I was playing with something to generate combinations of things.
01:06:54.400 --> 01:06:56.079
And no, yeah, exactly.
01:06:56.079 --> 01:06:59.280
I only could basically need to do like a both.
01:06:59.280 --> 01:07:01.599
You want all the permutations.
01:07:02.000 --> 01:07:18.079
Yeah, this is where we need we need NARS 2000's uh double exclamation point uh operator that allows you to specify exactly yeah, it has like it has like a compound operand or something that allows you to say, like, do you put the balls back again after you use them?
01:07:18.079 --> 01:07:19.599
And does the ordering matter?
01:07:19.599 --> 01:07:27.280
And all those there's like the six-fold way or some uh of of doing things twelve fold, I can't remember how it is.
01:07:27.280 --> 01:07:31.440
Um but we I mean we could do this and it's reverse, right?
01:07:31.440 --> 01:07:32.480
That just makes sense.
01:07:32.639 --> 01:07:35.519
I mean, in the case of two and four, that is definitely sufficient.
01:07:35.519 --> 01:07:50.400
In general, you do uh you take your C Mat and then you get the P mat of that length, and then you do a uh basically a row wise out a product where you take all of the combinations, and then you're probably gonna do get a bunch of duplicates as a result of that.
01:07:50.400 --> 01:07:52.079
But why can't we just end?
01:07:52.079 --> 01:07:53.519
Why can't we just do this?
01:07:53.519 --> 01:07:56.480
No, in this case you can just do this because there's only two.
01:07:56.480 --> 01:07:59.199
But in general, oh that's what you mean.
01:07:59.199 --> 01:08:00.000
Yeah, the reverse.
01:08:00.400 --> 01:08:02.559
In our case, there will only ever be two, right?
01:08:02.559 --> 01:08:03.360
Exactly, yeah.
01:08:03.360 --> 01:08:13.679
So these these are all the different possibilities, and there can't be any uh any duplicates because cmet doesn't care about the ordering, so therefore they'll always be sorted, and then no they never know overlap with themselves.
01:08:13.679 --> 01:08:15.440
So these are all the ones we need to check.
01:08:15.440 --> 01:08:28.560
Okay, so now if we take array and do this, so these are all the uh the pairs that we need to check, and then we just need we we don't have our function anymore, but we can just define that, right?
01:08:28.560 --> 01:08:42.159
So we can say the the prefix and uh the suffix, and we just need to check whether that's the case for each one of them, and then we ask, are there any?
01:08:42.159 --> 01:08:45.039
You still with me, Connor?
01:08:45.359 --> 01:08:46.239
Yeah, yeah, I'm still here.
01:08:46.239 --> 01:08:47.760
Just watching and join, you know.
01:08:47.760 --> 01:08:54.479
So we can write this Monday night football except I don't watch football, I watch people coding APL.
01:08:54.880 --> 01:08:55.840
Here we go.
01:08:55.840 --> 01:08:59.680
So this uh we think we have the problem of the duplicates though.
01:08:59.680 --> 01:09:02.880
Like if we say ab and ab.
01:09:02.880 --> 01:09:04.560
Oh no.
01:09:05.199 --> 01:09:09.199
Uh no, because why?
01:09:09.199 --> 01:09:13.119
Because the C M doesn't give you with itself.
01:09:13.119 --> 01:09:16.640
Yeah, there's no duplicate indices in the in that matrix, is there?
01:09:16.640 --> 01:09:18.079
There's no one, two.
01:09:18.079 --> 01:09:20.399
This doesn't care, right?
01:09:20.399 --> 01:09:24.000
So yeah, it doesn't give you one, one, and two, two.
01:09:24.720 --> 01:09:28.560
No, but why doesn't this oh we don't know because we want to count them, that's the problem.
01:09:28.560 --> 01:09:29.520
That's my mistake here.
01:09:29.520 --> 01:09:30.079
Oh, right.
01:09:30.079 --> 01:09:31.119
I did an R.
01:09:31.119 --> 01:09:34.079
Yeah, so this will give us this will give us two.
01:09:34.079 --> 01:09:37.840
So we need to do uh unique first.
01:09:37.840 --> 01:09:39.039
Oh, sorry.
01:09:39.039 --> 01:09:40.640
Yeah, yeah, I'm catching up.
01:09:40.640 --> 01:09:50.159
Um which I guess we can do that on the well, there will never be any duplicates in here, and we don't know what there are.
01:09:50.159 --> 01:09:55.199
We need to sort of take away the you take the uniques before we even start, right?
01:09:55.199 --> 01:09:57.520
So I think we can just do that.
01:09:57.520 --> 01:10:00.319
Did I make a mistake here?
01:10:00.640 --> 01:10:06.319
Yeah, they don't have an example, do they, where it's there are different ones, but two of them are the same.
01:10:06.720 --> 01:10:08.560
What what mistake did I make here?
01:10:08.560 --> 01:10:14.000
F what you excuse two.
01:10:14.000 --> 01:10:19.600
And if I do this, we get a nonsense result.
01:10:19.600 --> 01:10:21.359
Uh let's look at that.
01:10:21.359 --> 01:10:22.720
What's actually happening here?
01:10:22.720 --> 01:10:27.279
Maybe maybe CMET is not happy when it's one, there's only one.
01:10:27.760 --> 01:10:30.159
Oh, it's not, it's yeah, it's a stranding.
01:10:30.159 --> 01:10:32.800
You gotta include simple as well, do you?
01:10:33.279 --> 01:10:35.359
No, that should be fine.
01:10:35.680 --> 01:10:37.359
Oh, that's the problem.
01:10:37.600 --> 01:10:38.960
How do you take two?
01:10:38.960 --> 01:10:39.920
From one.
01:10:39.920 --> 01:10:41.039
From one.
01:10:41.039 --> 01:10:42.319
Oh well.
01:10:42.319 --> 01:10:44.720
That's the problem.
01:10:44.720 --> 01:10:49.520
So I mean we could just throw in the unique here.
01:10:49.520 --> 01:10:53.680
It's slightly wasteful, but too bad.
01:10:53.680 --> 01:11:00.319
Which means we can also throw the unique in in so we don't have to compare the values themselves, we can compare in here.
01:11:00.319 --> 01:11:02.399
So what actually happens here?
01:11:02.399 --> 01:11:05.920
Two, one, and what's the problem is that they are the same.
01:11:05.920 --> 01:11:09.119
Yeah, but the indice, the CMAP doesn't tell you that.
01:11:09.359 --> 01:11:10.399
Yeah, the C no, they're not.
01:11:10.399 --> 01:11:11.359
It doesn't know.
01:11:11.359 --> 01:11:12.079
It doesn't know.
01:11:12.079 --> 01:11:15.119
Oh, so you do have to do it outside this actually.
01:11:15.119 --> 01:11:16.239
Yeah, I think so.
01:11:16.239 --> 01:11:18.479
Apply the unique to the indices, yeah.
01:11:18.720 --> 01:11:21.600
Okay, so this is another solution that's sort of sort of neat.
01:11:21.600 --> 01:11:23.600
Get rid of that here.
01:11:23.600 --> 01:11:26.239
But of course, it relies on a bunch of code in the CMAP.
01:11:26.239 --> 01:11:27.039
Yeah, yeah.
01:11:27.039 --> 01:11:33.760
I was gonna say it's kind of big fat dependency on a big fat loopy unless it's yeah, dependent.
01:11:33.760 --> 01:11:44.960
Looks like they're any loops, but they are because we'd actually taken this giant function and uh actually it's this one, I think, and reducing over a whole bunch of things.
01:11:44.960 --> 01:11:47.439
So that's actually just it, it's iterative.
01:11:47.439 --> 01:11:51.439
But it might still be I will still be faster, I believe.
01:11:51.439 --> 01:11:54.159
Well, it's because it's not doing an outer product.
01:11:54.640 --> 01:11:55.039
Yeah.
01:11:55.039 --> 01:11:58.880
Well, yeah, I think there's going to be a crossover.
01:11:58.880 --> 01:12:00.479
There'll be a point there.
01:12:00.479 --> 01:12:06.640
Early on, the outer product is probably gonna be just because that's optimized.
01:12:06.880 --> 01:12:15.039
Yeah, because we couldn't, by the way, if we go back all the way, uh it's a long way, it wouldn't matter here.
01:12:15.039 --> 01:12:23.279
But the omnifix, we did we did a single outer product with omnifix, but we could actually break out the outer product into these two.
01:12:23.279 --> 01:12:31.279
So if we take our whole solution here, uh it's not going to be shorter, but it might be slightly easier to understand if you do it like this.
01:12:31.279 --> 01:12:33.600
We gotta get a JX butt on here.
01:12:33.760 --> 01:12:34.800
Let me see the comment.
01:12:34.800 --> 01:12:36.560
Do you know about outfix?
01:12:37.119 --> 01:12:43.520
Yeah, Oracle's mentioning uh J's outfix is useful for this pattern where you want to ignore self-comparisons.
01:12:44.560 --> 01:12:46.560
Uh yeah, didn't we?
01:12:46.560 --> 01:12:53.920
We had such a problem once upon a time on the ray cast where we looked at uh the sum of the array except for every element.
01:12:53.920 --> 01:12:56.159
We also want to ignore itself.
01:12:56.159 --> 01:13:02.800
Anyway, so so this is another another formulation that's I can exactly fit.
01:13:02.800 --> 01:13:05.760
We sort of make smaller outer products.
01:13:05.760 --> 01:13:14.720
These are all the suffixes, and these are all the prefixes, and this is the top right uh triangle, and this is summation step by step.
01:13:14.720 --> 01:13:23.600
Also, here you said that writing things testedly requires greater discipline to keep your codes um digestible.
01:13:23.600 --> 01:13:27.199
So, what is Chase Chase outfix?
01:13:28.640 --> 01:13:35.760
And just a heads up, I have to leave it five minutes from now, so we gotta hard stop them.
01:13:35.760 --> 01:13:42.159
But yeah, maybe the last thing we can do is look at the well, like we mentioned at the beginning, we're looking to build out our panel.
01:13:42.159 --> 01:13:44.640
So hopefully we will be adding uh a J.
01:13:50.000 --> 01:13:51.520
Infix dependent X.
01:13:51.520 --> 01:14:02.720
So yeah, we want the outer the outer two, but I don't yeah, this sort of thing, but I'm not really sure how how you'd use it like this.
01:14:02.720 --> 01:14:06.560
It's not not really my word.
01:14:06.560 --> 01:14:15.920
So what was uh array we had over here?
01:14:15.920 --> 01:14:27.199
Uh well let's say an example full solution of sorts is it's J, so it won't win any brevity always in here.
01:14:27.199 --> 01:14:38.159
But I'm not sure I'm not sure what to write because like the okay, so we want two, but I'm not even sure what the negative thing is.
01:14:38.479 --> 01:14:43.520
Uh uh success representative one is for like sliding window and one is for chunks.
01:14:43.520 --> 01:14:44.720
Oh yeah.
01:14:45.039 --> 01:14:49.359
But how does that how does that help us here?
01:14:49.359 --> 01:14:53.279
I mean it no, this is infix.
01:14:53.279 --> 01:14:55.039
This is not outfix, right?
01:14:55.039 --> 01:14:59.439
There's all the okay, so we got something here in the chat.
01:14:59.439 --> 01:15:02.720
Let's do this in the array.
01:15:02.720 --> 01:15:05.359
Okay, I see.
01:15:05.359 --> 01:15:07.359
So it's just for the pairing, right?
01:15:07.359 --> 01:15:14.159
So it's using this thing that we had before with the outfix, all the all the means with single element removed, right?
01:15:14.159 --> 01:15:15.680
That's what it's using here.
01:15:15.680 --> 01:15:22.399
And then we are pairing them up, but we still need to go for each one of them and check whether they are prefixes and suffixes.
01:15:22.399 --> 01:15:28.560
This doesn't solve the even though it's called outfix, it doesn't actually solve solve the problem of prefixes and outfixes.
01:15:29.039 --> 01:15:31.840
This just sharing issue.
01:15:31.840 --> 01:15:36.319
Yeah, of getting the combinations without the self-combination.
01:15:36.319 --> 01:15:38.880
Oh, there's an array.
01:15:39.600 --> 01:15:41.119
No, that got eaten somehow.
01:15:41.119 --> 01:15:53.840
If you go post it on uh Yeah, I can't I can't see their butt the people that's the annoying thing in YouTube that it doesn't tell people when their message got rejected, it just silently eats them for you unless you see them, but nobody else can see it.
01:15:54.000 --> 01:15:58.079
So yeah, if you add the link here, Adam can go post it.
01:15:59.359 --> 01:16:02.000
Yeah, but it might take time to do that.
01:16:02.000 --> 01:16:03.680
You have to do a PR, no?
01:16:03.840 --> 01:16:05.359
No, no, it's just a comment.
01:16:05.680 --> 01:16:06.880
Oh, it's a comment there.
01:16:07.039 --> 01:16:07.279
Okay.
01:16:07.279 --> 01:16:08.880
No, you just have to see F5.
01:16:08.880 --> 01:16:10.960
Hopefully it happens in the next 120 seconds.
01:16:10.960 --> 01:16:13.439
Otherwise, I'm pulling the plug on the stream.
01:16:15.760 --> 01:16:17.199
I just had a lean on F5.
01:16:17.520 --> 01:16:20.000
Or if I if if I had a uh what do you call it?
01:16:20.000 --> 01:16:34.880
Uh uh if I was like Big Brother, I could I could uh have some dashboard that shows all the links being created on a Ray box, but unfortunately I I don't have that, so it's not there.
01:16:35.119 --> 01:16:40.960
I mean with uh I there might be clear I oh it has fine, so we can actually do the same thing.
01:16:40.960 --> 01:16:42.399
J has fine.
01:16:42.399 --> 01:16:44.079
Sure, can you do it in 30 seconds?
01:16:44.079 --> 01:16:46.560
No, but I can show the I can show the principle.
01:16:46.560 --> 01:16:48.000
I think it's called like E dot.
01:16:48.000 --> 01:16:54.880
So if we say uh AB and then they will find it there, right?
01:16:54.880 --> 01:16:56.239
That thing.
01:16:56.239 --> 01:16:58.960
And then we need the first of that, etc.
01:16:58.960 --> 01:17:06.079
Right, and so that will be the same thing, it's exactly like it's just translation character of a character, basically, of the of the APL code.
01:17:06.079 --> 01:17:11.680
So we'll leave it as an exercise to the viewer, uh, to figure out how that how to do that.
01:17:11.680 --> 01:17:12.880
Okay, Connor?
01:17:12.880 --> 01:17:14.000
All right.
01:17:15.439 --> 01:17:18.960
Yeah, uh, I I think someone did just post.
01:17:18.960 --> 01:17:29.439
I guess maybe there's a hack that if you uh there's this like what looks like a Mandarin symbol for when, which is language.
01:17:29.439 --> 01:17:36.000
Um if you put something like that, uh, it enables you to to like post the array language.
01:17:36.000 --> 01:17:41.039
I don't know what that hack is, but or or maybe maybe we can see it, but the other users can't see it.
01:17:41.039 --> 01:17:45.119
I'm not seeing it, so oh there we we got something.
01:17:45.119 --> 01:17:46.000
Oh, I see.
01:17:46.000 --> 01:17:52.239
So it says there's a J1 liner shows up afterwards if you choose show all messages in the chat filter.
01:17:52.239 --> 01:17:53.760
Uh all right.
01:17:53.760 --> 01:17:54.960
Well, we'll figure that out.
01:17:54.960 --> 01:18:03.760
Maybe there's a setting on these live streams where I can just say allow all spam and uh yeah, so depending on this okay.
01:18:03.840 --> 01:18:11.439
So here we have the the finding thing, and this is uh an or.
01:18:11.439 --> 01:18:15.359
Oh, yeah, I'm not sure whether we do a first there, but okay.
01:18:15.359 --> 01:18:20.319
Oh yeah, it's just finding if there's a I think I don't think this is right, but I'm not entirely sure.
01:18:20.319 --> 01:18:28.000
Because this looks to me like it's an an or reduction atop this, and I think it has to be a first of that instead.
01:18:28.000 --> 01:18:30.479
That's my my feeling at least.
01:18:30.880 --> 01:18:36.399
All right, well, in the future we'll have a J Pro, and so we'll never find ourselves in this J pickle.
01:18:36.399 --> 01:18:43.359
And uh as we mentioned at the top, reach out to us at uh contact at array c uh array cast.
01:18:43.359 --> 01:18:44.560
Boy, oh boy.
01:18:44.560 --> 01:18:48.399
Yeah, I guess you have to do it for a hundred episodes before you can nail it like Bob did every time.
01:18:48.399 --> 01:18:55.840
Contact at raycast.com and we'll be monitoring uh yeah, looking for your guys' emails.
01:18:56.000 --> 01:19:01.119
And with that, we will say crushed it.
00:00:12.160 --> 00:00:16.879
Welcome to episode 126 of Arraycast.
00:00:16.879 --> 00:00:26.239
I'm your host, Connor, and I'm with my temporary co-host, promoted, because he is the only panelist, which we will be talking about a little bit more.
00:00:26.239 --> 00:00:33.200
We're gonna go around and I guess do brief introductions because that's just the way we've always done things, and then we'll hop into a couple announcements.
00:00:33.200 --> 00:00:34.479
So over to Adam.
00:00:34.880 --> 00:00:35.280
Right.
00:00:35.280 --> 00:00:37.119
So two things coming up.
00:00:37.119 --> 00:00:42.960
The first one is the deadline for the APL Forge submission.
00:00:42.960 --> 00:00:44.560
It's the 22nd of June.
00:00:44.560 --> 00:00:48.000
So it's just coming up soon, uh in a week.
00:00:48.000 --> 00:00:56.240
Um, so that's the sort of competition where you can submit uh projects in or for APL.
00:00:56.240 --> 00:01:13.519
Um, and then we have a committee of people looking at that, and you can win a prize and a trip to the upcoming APL user meeting, uh dialogue APL user meeting, um, which is going to be in Eastbourne uh on the 12th to the 16th of October.
00:01:13.519 --> 00:01:25.840
Speaking of that, it's registration has begun, and well, you can't see the full schedule yet, but you can see what the workshops are going to be like um and the schedule for that.
00:01:25.840 --> 00:01:27.920
So you can have a look.
00:01:28.400 --> 00:01:28.799
All right.
00:01:28.799 --> 00:01:34.159
I think we technically skipped your brief introduction and went straight into announcements, but that's all right.
00:01:34.159 --> 00:01:35.760
Uh they know me by now.
00:01:35.760 --> 00:01:36.799
They know me.
00:01:36.799 --> 00:01:44.480
Um, I I actually also have a uh it's not an announcement, but it is a call to action of sorts.
00:01:44.480 --> 00:02:00.879
Uh so whether you're listening to this live or you're listening to this on the audio recording later, uh, we are looking to, and I know that there are a handful of folks that have reached out via email or Twitter DM or Discord.
00:02:00.879 --> 00:02:15.680
I have the people in mind that I'm thinking about that uh DM'd me on those platforms, and I think actually maybe one person reached out to us on array uh contact at arraycast.com about joining us as panelists.
00:02:15.680 --> 00:02:19.199
So we're looking to grow our team of one panelist team.
00:02:19.199 --> 00:02:21.120
I mean, Rich might be joining a little bit later.
00:02:21.120 --> 00:02:25.199
He's in a meeting right now, but uh just like last time, he might be joining us.
00:02:25.199 --> 00:02:41.039
If you are interested, uh, because we don't want to miss any of the informal applicants uh that might have emailed us anytime between what is was it, November of 2025 and now, send us an email if you're interested.
00:02:41.039 --> 00:02:43.520
Um we might be doing something a little bit differently.
00:02:43.520 --> 00:02:53.520
We might not be having necessarily all permanent panelists, we might just have rotating panelists, so different voices from episode, but you'll hear the same kind of recurring voices.
00:02:53.520 --> 00:02:58.800
If you're interested, uh drop us an email at contact at arraycast.com.
00:02:58.800 --> 00:03:12.800
If you want, add, you know, uh one or two or three sentences about uh why you'd be interested in joining as a panelist and your background, if any with array languages, you don't necessarily have to have uh array language experience.
00:03:12.800 --> 00:03:14.800
Uh and we'll go from there.
00:03:14.800 --> 00:03:56.400
On top of that, not only are we looking for panelists, but we are looking hopefully for someone to not fully replace Bob Terrio, but to replace the part of his job where he would reach out to guests and set up the you know recording timing schedules uh for guests, because we have a list of guests we'd like to start bringing on, but Adam and I are both very busy folks, and we thought seeing as we're growing the team and a part of that original team was someone that had the time to reach out to guests and uh set up the you know schedule of recordings, uh that'd be fantastic.
00:03:56.400 --> 00:04:18.240
So if you are not only interested in being a panelist, but would also like to do that, or you're not interested in being a panelist, but for whatever reason you like that kind of managerial organizational stuff and you'd like to be involved in kind of setting up who's gonna be the next guest and sending out those kinds of emails, uh also shoot us an email at arraycast contact at arraycast.com.
00:04:18.240 --> 00:04:20.000
And we'll leave it at that.
00:04:20.000 --> 00:04:32.959
So if you're interested, shoot us an email and we will review those over the next two weeks to four weeks, and then you'll probably hear some announcements on this podcast at some point, and we'll be reaching out to folks in between now and then.
00:04:32.959 --> 00:04:42.319
With those two announcements plus a call to action out of the way, links as always, not for the email, but for the two things that Adam mentioned will be in the show notes.
00:04:42.319 --> 00:04:48.000
We have another episode of Adam Live Codes and Connor Learns Things.
00:04:48.000 --> 00:04:52.480
Uh once again, we're gonna be solving a couple Pearl Weekly Challenge problems.
00:04:52.480 --> 00:04:54.319
Well, we'll guarantee we'll solve one.
00:04:54.319 --> 00:05:05.040
I think the first one's a little bit easier, and I actually don't have too much that I'm looking forward to like uh pick up a little tip or a trick here, although I'm sure I will in watching Adam do it.
00:05:05.040 --> 00:05:08.399
I'm more interested in getting to the second one, but uh we'll see.
00:05:08.399 --> 00:05:16.560
Maybe the first one will be more interesting than I anticipate, and it'll take up the whole one, and then we'll have to kick uh down the road the second one.
00:05:16.560 --> 00:05:25.839
So, I mean, I'm not sure if you want to screen share Adam, seeing as you're gonna be live coding in a sec, and then you we can uh describe the um what do you call it?
00:05:25.839 --> 00:05:29.600
Uh problem statement, uh, which I'm now trying to see you.
00:05:29.600 --> 00:05:33.839
Well, yeah, we'll just we'll let you live or are you are you gonna uh screen share?
00:05:33.839 --> 00:05:37.759
I I can, but I don't even know what the problem is yet, so I'm sort of scared here.
00:05:37.759 --> 00:05:46.160
He hasn't so I mean I I linked it in the uh the chat, and I guess actually that's probably everyone can see on the live stream, actually.
00:05:46.160 --> 00:05:51.120
It says Raycast 126 and uh pro weekly challenge uh 377.
00:05:51.120 --> 00:05:54.240
So if I close this, no one can see that anymore.
00:05:54.240 --> 00:06:01.600
Anyways, we'll wait for Adam to screen share, and I believe the problem has something to do with substrings.
00:06:02.079 --> 00:06:02.800
Uh okay.
00:06:02.800 --> 00:06:07.360
Well, I guess I can I can start sharing my screen and see if I open the right window here.
00:06:07.360 --> 00:06:08.639
Uh let's see.
00:06:08.639 --> 00:06:12.879
I've got like a thousand Chrome tabs.
00:06:12.879 --> 00:06:15.120
Let's see.
00:06:15.120 --> 00:06:19.120
So I believe this is uh this is the right page, 377.
00:06:19.120 --> 00:06:19.920
That's what you said.
00:06:19.920 --> 00:06:20.720
Yes.
00:06:20.720 --> 00:06:21.279
Okay.
00:06:21.279 --> 00:06:23.360
Let's see if I can figure out how to read this.
00:06:23.519 --> 00:06:25.839
You gotta scroll down all the way past this nonsense.
00:06:25.839 --> 00:06:27.199
They always do like recasts.
00:06:27.199 --> 00:06:31.680
Then they do stats and then they do task one.
00:06:31.839 --> 00:06:32.399
Here we go.
00:06:32.399 --> 00:06:32.959
Okay.
00:06:32.959 --> 00:06:35.680
I guess we can make this full screen to see this.
00:06:35.680 --> 00:06:37.199
You're given a string, great.
00:06:37.199 --> 00:06:43.360
Write a script to find whether any substring of length two is also present in the reverse of the given string.
00:06:43.360 --> 00:06:44.000
Okay.
00:06:44.560 --> 00:06:45.600
So pretty straightforward.
00:06:45.600 --> 00:06:48.480
The cut the problem is called reverse existence.
00:06:48.480 --> 00:06:49.600
You're given a string.
00:06:49.600 --> 00:06:55.360
The first example uh was ABC B A, I think.
00:06:55.360 --> 00:07:08.959
And the problem's asking you to return a Boolean, a one or a zero, based on whether any substring of length two exists, has its reverse in the string as well.
00:07:08.959 --> 00:07:15.040
So for the first example, AB exists as B A at the end of the string.
00:07:15.040 --> 00:07:20.480
And in general, any palindrome is gonna return true by definition.
00:07:20.480 --> 00:07:22.480
Um unless it only has one character.
00:07:22.480 --> 00:07:26.240
Yeah, I I guess I was about to say, unless if you have a one-character string.
00:07:26.240 --> 00:07:39.120
But then the string in example three, A B C D is gonna return false because it does not have um, I guess by definition, you're also gonna need duplicate characters.
00:07:39.279 --> 00:07:40.720
Um not that we're gonna check it out.
00:07:40.720 --> 00:07:43.759
If it's duplicate characters, then then yeah, of course.
00:07:43.759 --> 00:07:48.720
So I mean, maybe there's a a better way to do it, but I think very simple.
00:07:48.720 --> 00:07:59.439
If we start by looking at the pairs that are there, and then we can look at what at the pair is reversed, right, and check if any is a member.
00:07:59.439 --> 00:08:06.000
So these are those uh the reversed, and we want to check if there are members of itself.
00:08:06.000 --> 00:08:08.319
So they're all members, right?
00:08:08.319 --> 00:08:10.959
Because this is a f a palindrome like this.
00:08:10.959 --> 00:08:13.120
Uh so that's obvious.
00:08:13.120 --> 00:08:16.560
Um, A, B, C, D, all members.
00:08:16.560 --> 00:08:20.720
But if you want to do something the way they're not all members, maybe have a like a normal test?
00:08:20.720 --> 00:08:21.920
Banana, sure.
00:08:22.079 --> 00:08:22.240
Okay.
00:08:23.120 --> 00:08:25.759
Uh well, I was gonna say A B C D should return all zones.
00:08:25.759 --> 00:08:26.800
Oh no, this is a mistake.
00:08:26.800 --> 00:08:28.079
This is a mistake, this is a mistake.
00:08:28.079 --> 00:08:34.240
Uh the reason is that I I don't want to reverse the list of strings, I want to reverse the each in the list of strings.
00:08:34.240 --> 00:08:35.279
Okay, so there we go.
00:08:35.279 --> 00:08:40.399
So A B C D, and then none of these are right, and banana.
00:08:40.399 --> 00:08:41.919
These are right.
00:08:41.919 --> 00:08:45.679
So all we need to do is we want to see if there are any.
00:08:45.679 --> 00:08:47.759
So that will do it.
00:08:47.759 --> 00:08:53.840
This is not a proper function, it's just a sequence of of operations, but we can we can just wrap it.
00:08:53.840 --> 00:08:59.360
So this is how I'll do it initially, but I think we can be maybe slightly more clever.
00:08:59.600 --> 00:09:02.159
I was gonna say this is already better than what I did.
00:09:02.159 --> 00:09:03.279
Uh okay.
00:09:03.279 --> 00:09:06.320
What let me let me find the is it clear how it works?
00:09:06.320 --> 00:09:07.360
Everything, the structure of it.
00:09:07.360 --> 00:09:18.639
Why did I I guess that's the thing, is I I don't have my membership and find and uh the epsilon um functions, I guess, committed.
00:09:18.639 --> 00:09:22.720
And so I always do that thing where you like uh just try one, make a mask.
00:09:22.720 --> 00:09:27.279
Yeah, but I basically, but I I guess I did it one by one.
00:09:27.279 --> 00:09:32.639
I didn't um so like I have like a reverse of each one at a time.
00:09:32.639 --> 00:09:34.320
It's so much more complicated.
00:09:34.480 --> 00:09:40.320
Um, this is so we have a question in the in the chat if it's guaranteed to be only two letters, but yes, that's the problem.
00:09:40.320 --> 00:09:42.480
Yeah, just find the substring and link two.
00:09:42.480 --> 00:09:44.960
So this is this will be here's another thing we can do.
00:09:44.960 --> 00:09:52.000
Uh we could put a swap here, which is the same thing as giving a negative two over here, but that doesn't really matter for now.
00:09:52.000 --> 00:09:55.759
Um, and that gives us also the reversed substrings.
00:09:55.759 --> 00:09:59.360
So we could look at whether these are members, right?
00:09:59.360 --> 00:10:00.879
So we can actually make it a little trained.
00:10:00.879 --> 00:10:04.240
This is excessive work because we're making, I mean, it doesn't really matter.
00:10:04.240 --> 00:10:08.720
We're making um the the substrings twice.
00:10:08.720 --> 00:10:18.240
So we can say, are the normal order length to substrings members of the reverse order member linked to substrings?
00:10:18.240 --> 00:10:20.320
And then we can write that.
00:10:20.320 --> 00:10:24.000
So that's I mean, that's just a different way of stating it.
00:10:24.000 --> 00:10:26.960
Whether we generate them from that, I'll say it in a different way.
00:10:26.960 --> 00:10:28.960
Doesn't really make a difference.
00:10:29.919 --> 00:10:36.799
Yeah, this is well, like I said at the beginning, probably I was gonna learn something even though I wasn't expecting this to be the problem.
00:10:36.799 --> 00:10:43.279
But yeah, this I don't know why because I guess, yeah, once this is the membership glyph.
00:10:43.279 --> 00:10:56.480
Yeah, and if you've got substrings against substrings, I guess that's the thing, is I didn't think to search the substrings in the reverse substrings.
00:10:56.480 --> 00:11:01.840
I kept substrings versus a string, and so then I guess you could do that.
00:11:01.840 --> 00:11:03.919
Yeah, yeah, but it's a way worse idea.
00:11:04.080 --> 00:11:08.720
Um, but if you do that, it's a if you if you do it like this, right?
00:11:08.720 --> 00:11:21.120
And then for each one of these, we want, I mean, we want to find out if it's a member or if it's found in the entire string.
00:11:21.120 --> 00:11:23.440
Oops, a mistake I make here.
00:11:23.440 --> 00:11:25.039
Oh, missing the argument.
00:11:25.039 --> 00:11:29.600
And we don't need an each, we need the each over here.
00:11:29.600 --> 00:11:30.399
There you go.
00:11:30.399 --> 00:11:44.320
So now we say for for each, we get a mask of the places where it appears, which would be more interesting if we're actually looking for specific places where specific substrings are found, but it we're not, so it doesn't really matter.
00:11:44.320 --> 00:11:52.960
So we all we need to do is see if there's anyone in here anywhere, which we could couple different ways, you can I mean just like that, we'll do it.
00:11:53.279 --> 00:11:55.840
That was not one of the ones I was thinking of.
00:11:56.159 --> 00:12:10.879
I was thinking of uh or ravel or or um yeah, we also know they're the same length, so I guess we could even do it with a rank, but I mean it's there are many different ways of doing it, they're not especially attractive.
00:12:10.879 --> 00:12:12.480
We're looking way too much here.
00:12:13.440 --> 00:12:27.039
So, my I have a question about why did you default to enclosing the original string um versus I guess when I did it you could have bound it like this instead.
00:12:27.440 --> 00:12:28.559
Yeah, that's what I did.
00:12:30.080 --> 00:12:46.000
And this is why I wanted to do the problem uh in the first place, is because in order to if this is the way that you originally spell it, which is what I did, um minus the find find, I did uh or reduce or reduce.
00:12:46.000 --> 00:13:00.720
In order to go from order to go from that uh to tacit, you end up having to kind of do the backflip in order to get what you originally put, which is enclosing the string in order to put it in a flip.
00:13:00.720 --> 00:13:06.320
It's one uh it's one worth getting to hear from you.
00:13:06.320 --> 00:13:10.720
Why did you put the why did you do the enclose original string first?
00:13:10.720 --> 00:13:15.840
Uh and probably we should slow down a bit to explain this to the audio only listener.
00:13:15.840 --> 00:13:19.039
And then also too, this is like a trick that I learned.
00:13:19.039 --> 00:13:21.279
I I consider it a trick at one point.
00:13:21.279 --> 00:13:25.360
Um wait, I actually don't know, I don't actually understand what you've done now.
00:13:25.519 --> 00:13:34.240
So you've avoided or no, you have uh uh commuted because it's a it's a fork over here, an AGH fork on the left.
00:13:34.240 --> 00:13:44.639
So that means it's it has to be parenthesized or bound, but we can't bind the two to a derived function anyway on the left, so we have to parenthesize anyway.
00:13:44.639 --> 00:13:48.320
So then I just immediately went for okay, I'll swap the arguments.
00:13:48.320 --> 00:13:51.039
Um and that's that's what I did here.
00:13:51.360 --> 00:13:57.919
Yeah, that's really that's really hard to do because you're doing uh each on the dyadic and then a commute in order to do the enclose.
00:13:57.919 --> 00:14:03.279
That's uh yeah, if you're seeing that for the first time and trying to parse that, uh it's a bit tricky.
00:14:03.279 --> 00:14:09.360
But yeah, walk us through so is why you reach for the enclose first and then this in general.
00:14:09.840 --> 00:14:17.840
I I don't know if we call it more functional, but like I prefer keeping things in their right places instead of composing them.
00:14:17.840 --> 00:14:21.600
Composing on the with a what's not called composition, it's called binding.
00:14:21.600 --> 00:14:33.519
Binding a right argument is somewhat messy because it converts a dadic function to monetic function with the remaining argument slot being on the left.
00:14:33.519 --> 00:14:38.399
But being that it's now a derived monetic function, that argument goes on the right.
00:14:38.399 --> 00:14:41.440
So maybe that's a bit complicated to explain in this context.
00:14:41.440 --> 00:14:43.200
But let's take minus, for example.
00:14:43.200 --> 00:14:47.679
So if you write like 10 10 jut minus, that's a monetic function.
00:14:47.679 --> 00:14:49.120
It's pretty easy to understand.
00:14:49.120 --> 00:14:50.080
It's 10 minus.
00:14:50.080 --> 00:14:53.519
But if instead we wanted to write the minus 10 function, right?
00:14:53.519 --> 00:14:57.840
So this takes an argument over here, so it's 10 minus 100, negative 90.
00:14:57.840 --> 00:15:17.200
If we wanted to write the minus 10 function, which we'll have to parenthesize in in application, but that's not so important, and then the argument over here, then notice that uh this argument which appears to the right, um, the argument to the minus 10 function actually becomes the left argument to minus, even though there's no explicit swapping going on.
00:15:17.200 --> 00:15:19.519
That means things are jumping around a bit.
00:15:19.519 --> 00:15:29.840
I prefer right arguments to remain right arguments, left arguments to remain left arguments, or being explicit about the swapping, which we can do with the commute operator.
00:15:29.840 --> 00:15:37.919
So so that would might be one reason why I prefer to enclose on the right instead of binding.
00:15:37.919 --> 00:15:39.440
But sometimes I'll do it.
00:15:39.840 --> 00:15:40.639
That makes sense.
00:15:40.799 --> 00:15:44.559
And then well it's also not a very meaningful function.
00:15:44.559 --> 00:15:49.360
I mean, if you bind an argument, you sort of want the derived function to be meaningful.
00:15:49.360 --> 00:15:52.080
But what is the find in omega function?
00:15:52.080 --> 00:15:54.080
This is a weird thing.
00:15:54.080 --> 00:15:59.759
It's like look for them look for ones, that's a meaningful function, but not look in something.
00:16:00.159 --> 00:16:00.559
Right.
00:16:00.559 --> 00:16:01.919
And then explain.
00:16:01.919 --> 00:16:02.960
So that makes sense.
00:16:02.960 --> 00:16:36.960
It walk people through this um enclosing uh a string or a vector and then performing the dyadic operation each time, because a lot of times, especially when you have the original pattern where you're trying to bind, you know, partially apply an argument to a dyadic function in order to apply something over, like it took me a while just to stumble into this kind of pattern, whereas, like if you want to turn that into tacit, the pattern is to enclose it and then do some dyadic operation each.
00:16:36.960 --> 00:16:37.440
Yeah.
00:16:37.440 --> 00:16:42.960
Like one, is there like documentation somewhere to point people at this?
00:16:42.960 --> 00:16:48.000
And and if even if not, like uh what's the uh path?
00:16:48.000 --> 00:17:00.720
Is it is the path to discovering this just that is the more and more you program an APL, at some point you will kind of stumble into this pattern, and then you'll if you're lucky, store it in your vault of way of ways to solve things tacitly?
00:17:01.600 --> 00:17:23.440
So I I don't know, we can look at the documentation for it, but I think uh it is a problem people have with the each operator, is that especially if they come from another programming background and they think of they think each is just oh that's just my map, but it's not then they then they expect a single thing on the left and multiple things on the right, expect it to to map over.
00:17:23.440 --> 00:17:42.880
So if we take like um A B C and we want to catenate just for ease of usage here with uh X, Y, Z, I think so it the actual mapping, which really means stepping over elements, right, with sort of iterating, um appears on both sides.
00:17:42.880 --> 00:17:45.039
So uh it's a double map.
00:17:45.039 --> 00:18:04.960
This usually would have to write this either with um explicit iterator counter that you then index in other languages, or you have to do a single map that includes the iterator and then use a single indexing for the other arguments, which makes it asymmetric, but each is completely symmetric in the API.
00:18:04.960 --> 00:18:08.880
So the way it works is that we have got the scale extension.
00:18:08.880 --> 00:18:24.160
We can have a single element, um that's a bad example that maps to both uh to all to all the elements of the other argument, and we can have we can start off with many on the left and have a single thing on the right, and it will map the other way.
00:18:24.160 --> 00:18:30.160
We can even have a single on both sides that's also allowed, then we get an an enclosed result.
00:18:30.160 --> 00:18:37.359
So the way to so we can sort of say the one to many is a solved problem.
00:18:37.359 --> 00:18:45.119
So if we want uh one side to be considered one, you sort of want to reduce the problem to that date.
00:18:45.119 --> 00:18:51.440
So we need to change this vector that's on one side or any array really to a scalar, and we do that by an enclosure.
00:18:51.440 --> 00:19:07.839
So each actually opens up enclosures, actually digs into an array, which can be a little bit hard to spot when you're dealing with simple arrays because we've got this floating array model, but really it's it's reducing the depth um of the arguments by one.
00:19:07.839 --> 00:19:24.480
And re what it happens here with the um with the each, where we've got an array with multiple elements on the left and a single array that contains multiple elements on the right, is that we reduce the enclosure level by one on both sides.
00:19:24.480 --> 00:19:31.440
So that's so we take first the first element of the array on the left, and then on there's only a single element on the right.
00:19:31.440 --> 00:19:36.240
So we take that element and disclose that as well, which reveals the entire array that's inside.
00:19:36.240 --> 00:19:41.279
And then we do the same thing with the second element on the left and open up on the right and gives it an entire array.
00:19:41.279 --> 00:19:45.680
That's why effectively it becomes a many on the left to one on the right.
00:19:45.680 --> 00:19:53.119
I know the K language has like explicit separate each operators or adverbs, like each left and each right.
00:19:53.119 --> 00:20:01.039
Um, but in APL, that's because they don't have, I mean, the cause, they don't have the concept of an enclosure, a scalar enclosure.
00:20:01.039 --> 00:20:03.200
You can only do one element lists.
00:20:03.200 --> 00:20:05.279
So it's a whole different way of doing things.
00:20:05.279 --> 00:20:11.599
We can write an each left each right operator in APL, but it's easier to do it like this.
00:20:11.599 --> 00:20:18.880
And so too, we can yeah, so this this maps each element on the left to the entire array on the right.
00:20:18.880 --> 00:20:28.000
And similarly, we can do an enclosed the array on the left and the catenate each to an unenclosed array on the right, and that maps it the other way.
00:20:28.000 --> 00:20:29.599
So these are the two different types of each.
00:20:29.599 --> 00:20:35.920
And then again, as before, we can just do a simple each with no enclosures and that pairs up the individual elements.
00:20:35.920 --> 00:20:41.279
It sort of hints at an operator that's missing, the depth operator, which PQN has.
00:20:41.279 --> 00:20:43.279
I think that was in my initiative.
00:20:43.279 --> 00:20:55.440
Uh J actually has it called the level at operator or adverb, but isn't much use there because J is much more about um dealing with higher rank than deeper depth.
00:20:55.440 --> 00:21:00.079
And then the complete equivalent thing is that we can bind.
00:21:00.079 --> 00:21:09.440
So the binding, uh this long left scope of operators, so the each here sees if we write quote a b c quote jot comma each.
00:21:09.440 --> 00:21:14.480
So the each sees the quote a bc quote jot, comma, as a single thing.
00:21:14.480 --> 00:21:26.079
It's a single derived monetic function that's applied to each element on the right, and that's why it has that effect uh of concatenating the entire left side because it's been bound into the function to each element on the right.
00:21:26.079 --> 00:21:31.759
The other way is interesting because we can't just put uh a jot on the other side.
00:21:31.759 --> 00:21:34.240
That doesn't make sense syntactically.
00:21:34.240 --> 00:21:47.119
We do want the jot in this position immediately to the right of the concatenation function, but we have to put the operand to um to the bind operator immediately next to that as well.
00:21:47.119 --> 00:22:04.480
And then some people end up in the especially with a neuter APL writing something like this where we have got a left argument and then comma jot right argument each, but that's not right, of course, because the comma jot right argument each is a Single derived monetic function, it takes a single argument, which is on the right.
00:22:04.480 --> 00:22:13.599
So the ABC now needs to move over to the right to get that effect we had before, which is that's the sort of thing that can be confusing.
00:22:13.599 --> 00:22:19.680
Like positionally on the line of code, the left argument is on the right, and the right argument is on the left.
00:22:19.920 --> 00:22:26.880
Yeah, at least for me though, when I was learning APL, this was easier to get to.
00:22:26.880 --> 00:22:32.000
Um because it well, I guess it just depends on the order that you learn things.
00:22:32.000 --> 00:22:42.079
But like for me, coming from Haskell, um where partial application and like binding is very common, it it maps like very easily to APL, right?
00:22:42.079 --> 00:22:46.000
You have your bind operator and you can partially apply something on the left or right.
00:22:46.000 --> 00:23:09.039
And so if you know that you're trying to fix something uh and you're trying to apply that unary operation, it's easier to without learning the uh, I guess, uh full uh depth or like comprehensively understanding what each is doing and how if you're adjusting it's um you know the with enclose, like that's uh an extra thing that you need to learn.
00:23:09.039 --> 00:23:16.160
And you can get to what's on the screen right now, just partially applying something on the right, putting that on the left, and then eaching it over whatever you need to.
00:23:16.160 --> 00:23:27.519
And so that was typically the way that I would do things until I actually don't know how I I guess one day I just was messing around, yeah, and then I was like, Oh yeah, if you enclose it, I guess that kind of makes sense.
00:23:27.519 --> 00:23:40.640
You're um although I would have I ever explained that what was happening is that the each was reducing um the depth by one, and uh I don't think that's how I would have ever explained it.
00:23:40.640 --> 00:23:48.799
Uh I think I was I think I just knew it as like a little idiom that you enclose something on the right and then then it'll apply over the whole thing.
00:23:48.960 --> 00:23:59.759
Um so I mean I guess J is a bit more formal about things in a way is good, but I think practically speaking, pragmatically speaking, it just comes in your way more often that it does your service.
00:23:59.759 --> 00:24:10.480
So there in J, they don't have a each primitive, but they do have an each like standard library word, and it's all it is is under this close.
00:24:10.480 --> 00:24:16.319
But the under they have is they have two different types of compositional operators.
00:24:16.319 --> 00:24:22.640
Uh the the close and uh white, I don't remember what the other word is, uh uh application.
00:24:22.640 --> 00:24:38.480
And so what it does is it it does an operation, but on each um element or on each cell, um it it does some application, and then it applies the function and it joins everything to back together again.
00:24:38.480 --> 00:24:47.519
So really we can see each as being a uh rank zero under disclose thing.
00:24:47.519 --> 00:24:52.880
So or or well, we say all the way around, it's this close under rank zero.
00:24:52.880 --> 00:25:02.559
So if we if we think about it, this we can try to define the dyadic uh each, but let's just do it for a single single thing.
00:25:02.559 --> 00:25:05.920
Well, actually, let's make a monadic because it doesn't really matter, the pattern is the same.
00:25:05.920 --> 00:25:19.519
So let's let's make the each operator, and all it does is we have an argument and we have a function that we are applying rank zero that's on every um element if you want.
00:25:19.519 --> 00:25:27.359
But before we apply the function, we're going to um apply it a disclose first if you want.
00:25:27.359 --> 00:25:41.200
But since it's rank zero means there will only be one element, so there's no difference between uh a mix and they um and a first, they just disclose, and then when we are done, then we package it down again with an in-close.
00:25:41.200 --> 00:25:42.240
So this is sort of an under.
00:25:42.240 --> 00:25:44.079
We don't have the under operator yet, right?
00:25:44.079 --> 00:25:50.720
So but we are disclosing, applying the function, and enclosing, and then that gets collected into the argument.
00:25:50.720 --> 00:26:01.920
So we can see here if you say abc df, so we can do a reverse each and reverse with our fancy new operator, each gives the same result.
00:26:01.920 --> 00:26:04.319
This is really the definition of each.
00:26:04.319 --> 00:26:16.480
And the dyadic form is exactly the same, except instead of applying um with an uh function atop this close, it would be a function over this close.
00:26:16.480 --> 00:26:19.599
So we're just applying pre-processing to to both sides.
00:26:19.599 --> 00:26:21.920
That's the whole definition of it.
00:26:21.920 --> 00:26:25.119
Uh, then we need an alpha over here.
00:26:25.119 --> 00:26:36.319
So now you can see that it's explicit that this disclosing, and then you can also see why uh why enclosing sort of negates the preprocessing of that side.
00:26:36.319 --> 00:26:47.119
If we enclosed omega here, then we then when we apply rank zero on omega, that's the entire array, because it's enclosed, so that's a scalar, that's the whole thing.
00:26:47.119 --> 00:26:48.640
So that doesn't matter on the right.
00:26:48.640 --> 00:26:57.519
On the left, of course, if we have multiple elements, it will go into each element, and then we disclose it, which it's just a single enclosure, so that gives us what's inside it.
00:26:57.519 --> 00:27:01.839
And on the left, we it does its thing on each element, and so on.
00:27:01.839 --> 00:27:02.799
Does that make sense?
00:27:03.119 --> 00:27:16.319
It does, and uh, maybe I will take the time to add chapters to this YouTube live stream after it's done recording, and I'll call this each deep time each deep dive and tacit tips or something like that.
00:27:16.480 --> 00:27:28.799
And so then we can just point people to the timestamp uh whenever they have questions about because this is TC is a trace operator uh in the defense workspace that draws out.
00:27:28.799 --> 00:27:31.920
Let's turn off boxing here, it will be very flooded.
00:27:31.920 --> 00:27:38.079
Um it draws out on the screen um the steps of computation wherever we insert it.
00:27:38.079 --> 00:27:41.039
So it's just a magnetic operator, we can attach it to any function.
00:27:41.039 --> 00:27:45.440
So if we attach it to every function, then we can we can see exactly what's going on.
00:27:45.440 --> 00:27:57.119
So here this function the disc close and we'll put a tc on that, and the main function we can put a tc on that, and the in-close we could put a tc on that.
00:27:57.119 --> 00:28:02.480
Okay, so we're redefining our each like that, and now we're doing what we did before.
00:28:02.480 --> 00:28:08.400
A b c comma each xn.
00:28:08.400 --> 00:28:14.160
So we can see here that it first thing it does is disclosing the x gives us x.
00:28:14.160 --> 00:28:16.079
Disclosing the a gives us a.
00:28:16.079 --> 00:28:18.000
That's there's not much there to do.
00:28:18.000 --> 00:28:19.200
We're picking those, right?
00:28:19.200 --> 00:28:23.680
And then we concatenating a and x together that gives us part of the result.
00:28:23.680 --> 00:28:25.680
And then we take the next step.
00:28:25.680 --> 00:28:30.240
We enclose that result, and that goes into our result array.
00:28:30.240 --> 00:28:31.759
And then we take the next one.
00:28:31.759 --> 00:28:34.720
The y's and the b's and so on, that we'll step through.
00:28:34.720 --> 00:28:41.519
Now, if we enclose here, we can't really see much, but we'll see a little bit of the spacing will be increased.
00:28:41.519 --> 00:28:45.920
So we can see that there's extra spacing here that sort of indicates that it's in-close.
00:28:45.920 --> 00:28:49.440
So we're disclosing that, and that gives us the unpackaged form.
00:28:49.440 --> 00:28:52.319
So it's just just negation of that in-close.
00:28:52.319 --> 00:28:54.559
Rest of it is sort of the same.
00:28:54.559 --> 00:28:56.880
Um, all right.
00:28:57.039 --> 00:28:59.200
Well, I mean, we've spent 30 minutes on the first problem.
00:28:59.519 --> 00:29:01.279
I think we've got not quite yet.
00:29:01.279 --> 00:29:03.680
There are other ways to do it because this is the pro with your problem.
00:29:03.680 --> 00:29:05.440
So we've got to solve this with regex, man.
00:29:05.440 --> 00:29:06.960
Otherwise, it's all right.
00:29:06.960 --> 00:29:08.000
Well, we'll let you see.
00:29:08.000 --> 00:29:36.079
We'll we'll time box the regex solution to uh to uh how well how quickly I think I can do it pretty quickly because we want we want the one letter followed by um another letter, which uh no obscening thoughts here, uh and then we want any any sequence of characters followed by the second one and then the first one, right?
00:29:36.079 --> 00:29:43.279
This would mean if we have if this matches anywhere, then we've then the answer is true, right?
00:29:43.279 --> 00:29:46.319
So abc D shouldn't match any, we've got nothing.
00:29:46.319 --> 00:29:48.319
A B C B A.
00:29:48.319 --> 00:29:49.759
We found that, right?
00:29:49.759 --> 00:29:55.759
So that's the first two and the last two, but we're not actually interested in whether or not uh and where what the answer is here.
00:29:55.759 --> 00:29:58.559
We just want to know if there is such a thing.
00:29:58.559 --> 00:30:01.039
And banana, we found an anna, right?
00:30:01.039 --> 00:30:03.920
So we found an followed by something followed by na.
00:30:03.920 --> 00:30:12.319
There might be multi multiple of them, but it doesn't matter because the first one is going to find, well, is is enough.
00:30:12.319 --> 00:30:19.279
So if we write like uh a b a and uh xyx, we should we'll find two.
00:30:19.279 --> 00:30:27.680
All we need to know is how many are there, and then we can take the sign of that or see if is one greater than uh sorry.
00:30:27.680 --> 00:30:31.279
Yeah, yeah, is it more more than equal to one?
00:30:31.279 --> 00:30:33.599
So that would be the solution as well.
00:30:33.920 --> 00:30:38.559
That was very fast and uh still not as short as the APL though.
00:30:38.559 --> 00:30:43.680
Um no, I know I well technically it is APL, but not your original solution.
00:30:43.680 --> 00:31:05.359
Asher in the chat, in the APL, which I believe is your co-worker, um says that uh he just posted a bunch of wacky ways to do the original problem ordered from clear to short, but I think I think YouTube is eating all of those solutions.
00:31:05.359 --> 00:31:08.559
So you can just send them to me in in normal chat.
00:31:08.559 --> 00:31:17.920
I was gonna say either send them to me, get them, but in general, that's only a good solution for viewers that know uh how to send them to you.
00:31:17.920 --> 00:31:30.400
So I'm going to array cast github repo, and I'm creating uh a new chat, and I guess we'll just call these um what do we do?
00:31:30.400 --> 00:31:34.079
We call this uh I guess it is a podcast episode.
00:31:34.400 --> 00:31:37.920
So here are here are Esher's uh solutions.
00:31:37.920 --> 00:31:55.440
So what's going on here is he's doing an auto product of the array with itself, and then he's looking at whether we have any diagonal matches and any full matches that would be if they are right.
00:31:55.440 --> 00:32:03.359
So any diagonal matches that's if we have a reversal, and any full matches would be if we have duplicates, I believe.
00:32:03.359 --> 00:32:14.240
And so and he flattens that and I and find out if there's any uh anyone in that seems a bit overkill to me, but sure.
00:32:14.240 --> 00:32:26.319
This is a similar that's exactly the same, just instead of looking for these patterns, then he's just doing rotations in to match things up, and then seeing if there are any such patterns.
00:32:26.319 --> 00:32:37.519
He's still more of this idea finding the indices and seeing if uh if there are any indices that are off by one from each other.
00:32:37.519 --> 00:32:39.119
Okay, that's what you mean by wacky.
00:32:39.119 --> 00:32:44.720
Yeah, uh, I agree with him that uh wacky wacky is a good description of these.
00:32:46.480 --> 00:32:53.119
And if other folks have solutions, because last time we got uh a very cool Wii Wa solution at the tail end.
00:32:53.119 --> 00:33:06.720
Um but yeah, J, BQN, any Ray languages, tiny Apple, feel free to you could try posting them in the YouTube chat, and then uh if it doesn't work there, you can post them in the GitHub discussion link to Raycast.
00:33:06.720 --> 00:33:08.319
Uh all right, let's move on.
00:33:08.319 --> 00:33:09.920
Thank you for those submissions, Asher.
00:33:09.920 --> 00:33:12.720
Those are um uh very cool.
00:33:12.720 --> 00:33:28.160
I am very interested to see uh Adam solve this because my solution to this was pretty terrible, and he already improved upon the first problem, so I'm he's almost guaranteed to improve upon the second problem.
00:33:28.160 --> 00:33:31.039
The question is, how nice will it end up being?
00:33:31.039 --> 00:33:32.240
Time will tell.
00:33:32.240 --> 00:33:45.920
And the problem statement is prefix suffix, write a script to find if two strings in a given array, which is uh an array of strings, uh, such that to find if two strings in that uh array of strings.
00:33:45.920 --> 00:33:48.480
So there are only two strings in the in the array of strings.
00:33:48.480 --> 00:33:49.200
No, no, no.
00:33:49.200 --> 00:34:00.160
There are multiple strings, but you're looking for two strings within the array of strings where string one is a prefix and suffix of string two.
00:34:00.160 --> 00:34:00.960
Oh, okay.
00:34:00.960 --> 00:34:02.880
You you perform that option.
00:34:03.359 --> 00:34:05.519
This is this is a bad bad formulation, right?
00:34:05.519 --> 00:34:12.719
It says write a script request if the two strings, if there are two strings, string one and string two, such that, right?
00:34:12.719 --> 00:34:17.920
So string one is a prefix and suffix of string two, return the total count of such pairs.
00:34:17.920 --> 00:34:27.679
Okay, so uh we I guess the easiest thing is I mean, we could do fancy stuff for performance with looking at the length and sorting out things that would be impossible.
00:34:27.679 --> 00:34:34.639
Um but easiest thing is just to uh to do an outer product.
00:34:34.639 --> 00:34:38.559
Let's start by uh importing this.
00:34:38.559 --> 00:34:41.599
Array is quite JSON.
00:34:41.599 --> 00:34:44.079
We've got to turn JSON this off.
00:34:44.079 --> 00:34:45.679
Okay, so we've got our array.
00:34:45.679 --> 00:34:47.280
Maybe we should turn boxing on again.
00:34:47.280 --> 00:34:48.639
Box on.
00:34:48.639 --> 00:34:58.559
Okay, so we've got our strings here, and then we want to find out how many are uh uh prefixes and suffixes of each other.
00:34:58.559 --> 00:35:01.760
So first we have to figure out what is mean it's a prefix and a suffix.
00:35:01.760 --> 00:35:11.679
So I think the I mean we could do a find and look at the at the beginning at the end whether there's a one, but I think it's easiest to just do a reversal.
00:35:11.679 --> 00:35:18.719
So let's say these are again sort of funny examples, but okay, let's take a b a uh that's a bad example again.
00:35:18.719 --> 00:35:23.519
Okay, let's do a b and do ab X.
00:35:23.519 --> 00:35:27.840
So here this is a a prefix and a suffix.
00:35:27.840 --> 00:35:31.920
So for prefix, there's I like to compose things like this.
00:35:31.920 --> 00:35:36.000
So it's the uh no, it's not even that, it's the first.
00:35:36.000 --> 00:35:36.400
Sorry.
00:35:36.400 --> 00:35:38.159
The first of the find.
00:35:38.159 --> 00:35:40.239
That that is the prefix function.
00:35:40.239 --> 00:35:42.960
That means the left argument is a prefix of the right argument.
00:35:42.960 --> 00:35:51.440
It's technically speaking on lots of unnecessary work, but hopefully one day if my colleagues will do their job right, this will be optimized and it will stop looking.
00:35:51.440 --> 00:36:03.199
Like this composition, or even with a thunk or something, it will stop looking after the first element because this it will never return true otherwise, uh, because we throw away everything but the first element.
00:36:03.199 --> 00:36:05.199
But this is this is the first, right?
00:36:05.199 --> 00:36:12.320
Now, for suffix, the easiest thing to check is whether this in reverse appears at the end over here.
00:36:12.320 --> 00:36:17.440
So we can just do that with a uh with an over reverse.
00:36:17.440 --> 00:36:21.039
So if we say make this AC, it'll say no there, right?
00:36:21.039 --> 00:36:23.760
So we need to apply this function twice.
00:36:23.760 --> 00:36:24.800
One with with the over.
00:36:24.800 --> 00:36:29.280
We can't factor that out because it's really two different sets of data it's working on.
00:36:29.280 --> 00:36:38.480
So if we want to make sure that both of these are true, we write first a top find, and first atop find over reverse.
00:36:38.480 --> 00:36:52.400
So this is the uh this means that the condition here has been met, and uh then we want to do this as an outer product on all the the array of of strings.
00:36:52.400 --> 00:36:53.840
So that's this.
00:36:53.840 --> 00:37:05.039
Now um they say the result is is four here, but of course there's a diagonal going down here, so that's a bit of a problem, right?
00:37:05.039 --> 00:37:09.760
Because they apparently they don't count uh duplicates, right?
00:37:09.760 --> 00:37:13.440
You can't say the string one is both a suffix and a prefix of itself.
00:37:13.440 --> 00:37:26.639
And where but I suppose they do say that uh well interesting, an interesting thing is what if it's a complete match as well, if they have the same length and they are because if the duplicates in the same way.
00:37:26.639 --> 00:37:28.800
There is an example below.
00:37:28.800 --> 00:37:31.840
Let's see.
00:37:31.840 --> 00:37:33.280
No, this one, yeah.
00:37:33.280 --> 00:37:34.239
The one.
00:37:34.239 --> 00:37:34.719
Okay.
00:37:34.719 --> 00:37:42.400
That is interesting as well, because if you take that example, abab abab, right?
00:37:42.400 --> 00:37:46.800
So so there they don't count the duplicates either.
00:37:46.800 --> 00:37:57.440
I would say that the first abab is a prefix and suffix of the second above, and the second above is also a prefix and suffix of the um of the first one, right?
00:37:57.440 --> 00:37:59.039
But they don't say that either.
00:37:59.039 --> 00:38:07.760
So apparently what we have to do is we have to mask out half the triangle, just in case, um, and and the middle diagonal.
00:38:07.760 --> 00:38:10.239
So we can we can do that.
00:38:10.239 --> 00:38:17.440
So if we if we look at a masking here, so if we make we can try to start with this.
00:38:17.440 --> 00:38:20.079
Oops, sorry, that should be this.
00:38:20.079 --> 00:38:28.239
This is a a masking triangle to isolate just the elements that we want on the strictly top right corner.
00:38:28.239 --> 00:38:31.360
So this would be with a count.
00:38:31.360 --> 00:38:34.639
We want to tie these together, the top over here.
00:38:34.639 --> 00:38:36.239
That's our function.
00:38:36.239 --> 00:38:40.400
And we can adjourn that in here, this and this.
00:38:40.400 --> 00:38:46.239
So this gives us our matrix, and all we need to do now is count how many ones there are.
00:38:46.239 --> 00:38:48.719
So we can do that, there are multiple ways to do that.
00:38:48.719 --> 00:39:01.599
But classic one is the sum of the rabble that's for it's looks sort of noisy, but it it's fairly readable, especially if you put them spaces in.
00:39:01.920 --> 00:39:07.360
That's uh God mode APL programming, folks, that you just witnessed there.
00:39:07.360 --> 00:39:14.480
And um uh let's all just have a moment of silence for this beautiful expression that uh Adam has uh put on.
00:39:14.480 --> 00:39:16.719
Rich, what are you doing in the chat?
00:39:16.719 --> 00:39:20.079
You're supposed to be on this podcast right now.
00:39:20.079 --> 00:39:21.920
Join the call, man.
00:39:21.920 --> 00:39:24.880
Or is or is he is he virtually attending another meeting?
00:39:24.880 --> 00:39:26.159
Uh and I don't know.
00:39:26.159 --> 00:39:30.320
He might he might be in another meeting but secretly looking at this.
00:39:30.559 --> 00:39:34.239
Yeah, we call them uh Rich says that it's two tested.
00:39:34.880 --> 00:39:36.320
Uh I disagree.
00:39:36.320 --> 00:39:43.199
Um, well, so my first comments are is that mine actually isn't too far off.
00:39:43.199 --> 00:39:53.519
So I I mean I had the prefix idiom um first composed with uh or I guess it's is it find is the name of the glyph?
00:39:53.519 --> 00:39:55.920
Yeah, first composed with find.
00:39:55.920 --> 00:39:59.440
I didn't I missed this over trick.
00:39:59.440 --> 00:40:14.239
So I think my first thought was what I wanted to do was under, but I guess it doesn't need to be under because you need to reverse it at the end, it doesn't matter.
00:40:14.239 --> 00:40:14.800
Exactly.
00:40:14.800 --> 00:40:16.960
So is that is that a general rule of thumb?
00:40:16.960 --> 00:40:22.559
So yeah, my my for for those you know that uh are only APLs and not familiar with under.
00:40:22.559 --> 00:40:24.800
I mean, every uh is everyone familiar with under?
00:40:24.800 --> 00:40:39.280
Under is like you know, as Adam likes to say, under anesthesia, you apply an operation and uh then you do some other operation and then you apply the reverse if there is you know a defined one for that.
00:40:39.280 --> 00:40:43.199
So under reverse, the inverse or reverse of reverse is reverse.
00:40:43.199 --> 00:40:46.559
Yeah, clip that, put that in a TikTok.
00:40:46.559 --> 00:40:55.039
And uh but in this case, because you are just getting back a scalar, you don't need to reverse the result.
00:40:55.039 --> 00:40:57.519
And so, yeah, that's my question.
00:40:57.519 --> 00:40:58.639
Is that a general rule?
00:40:58.639 --> 00:41:06.400
If you only need to apply an operation and you don't need to worry about like undoing that operation, can you always use over?
00:41:06.400 --> 00:41:08.239
I guess not really.
00:41:08.239 --> 00:41:15.519
It's only in the case where you have two arguments, and also I don't even think under necessarily would have worked for this, would it?
00:41:15.679 --> 00:41:20.559
Oh no, under would have worked because the result is a scalar, and reversing a scalar, it doesn't do anything.
00:41:20.559 --> 00:41:21.760
So right, right, right.
00:41:22.000 --> 00:41:23.119
It wouldn't have made a difference.
00:41:23.119 --> 00:41:24.960
It's just unnecessary.
00:41:24.960 --> 00:41:34.639
And so, anyways, that was the first thing that I saw that you did was the over reverse, which is really nice, and then I did it something a little bit different.
00:41:34.639 --> 00:41:41.119
Instead of building up the upper triangular matrix and masking things out, I did a here.
00:41:41.119 --> 00:41:42.559
Let's let's admit Rich.
00:41:42.559 --> 00:41:53.119
Uh look at that from YouTube comment section to uh to uh 48 minute uh joining guests.
00:41:53.119 --> 00:41:53.840
Welcome, Rich.
00:41:53.840 --> 00:42:00.960
We're deep in Pearl Weekly 377, and now you're here to reign on our tacit parade.
00:42:01.199 --> 00:42:07.119
Look, all I'm saying is look at that a top, a top abomination, a top a nation.
00:42:07.840 --> 00:42:08.800
A top a nation.
00:42:08.800 --> 00:42:18.239
Let me tell you, this line of code is gonna get more people into APL than this like JavaScript looking like everything's got a variable name.
00:42:18.239 --> 00:42:19.760
That's my that's my pitch.
00:42:20.639 --> 00:42:23.599
Well, I didn't I said it was too tacit.
00:42:23.599 --> 00:42:34.639
I didn't say you should name every part of it and then also too, look at him not aligning these arrows.
00:42:35.760 --> 00:42:38.880
I could go back and fix that in post or whatever you want to call it.
00:42:38.880 --> 00:42:40.159
Is it if this helps you?
00:42:40.159 --> 00:42:42.800
Array box does it automatically.
00:42:42.800 --> 00:42:47.760
Uh um but yeah, the while Adam is still typing this up.
00:42:47.760 --> 00:42:51.440
Uh it does a little bit.
00:42:51.440 --> 00:42:52.960
Um, okay.
00:42:52.960 --> 00:43:04.800
And uh but the thing, so the I was saying that the thing that um uh Adam did where he was uh building up the upper triangular matrix and then masking things out.
00:43:04.800 --> 00:43:26.079
Uh instead of doing that, I did like a uh and I don't know if this is an idiom, but it's a pattern that I use sometimes where you just you get an IOTA sequence, you rotate your original array of strings um by your iota sequence, and then you perform an operation where you have you know one string versus the rest of the string.
00:43:26.079 --> 00:43:31.039
So kind of like the head tail trick if you're familiar with Haskell, which which one's better?
00:43:31.039 --> 00:43:32.719
Uh you know, pick your poison.
00:43:32.960 --> 00:43:37.840
Well, I was wondering when I was watching that, is this is the description they often are ambiguous.
00:43:37.840 --> 00:43:40.400
Is it ambiguous enough to say we go?
00:43:40.400 --> 00:43:45.039
You could just stick a unique on the inputs and then get the number out.
00:43:45.519 --> 00:43:55.440
The description is ambiguous enough, but um I think it's not enough examples that is not gonna end up working.
00:43:56.320 --> 00:43:57.119
Yeah, right.
00:43:57.119 --> 00:44:00.480
Unique might not work, it's just that it doesn't I don't know.
00:44:00.480 --> 00:44:01.599
I don't know about this thing.
00:44:01.599 --> 00:44:03.039
They say there's only one.
00:44:03.039 --> 00:44:05.519
And we do things with themselves.
00:44:05.519 --> 00:44:06.880
Yeah, we do things with themselves.
00:44:06.880 --> 00:44:07.679
So you should count it.
00:44:07.679 --> 00:44:08.800
Yeah, I think that will work.
00:44:08.800 --> 00:44:15.119
Um but we also it's not enough because this will you still need to take them away from themselves.
00:44:15.119 --> 00:44:18.079
So you still need to do something about the diagonal.
00:44:18.079 --> 00:44:20.639
So certainly that's not going to be enough.
00:44:20.639 --> 00:44:31.519
Because you even if we take the first one, uh, we said like uh every everything in every every string gets a match on its own because it's its own prefix and suffix.
00:44:31.519 --> 00:44:32.159
Yeah.
00:44:32.159 --> 00:44:36.880
So therefore taking away the is not going to yeah, so you have to get rid of the diagonal.
00:44:36.880 --> 00:44:41.519
Getting rid of the diagonal, you might as well just get rid of the duplicates with the doing top right instead of diagonal.
00:44:41.519 --> 00:44:43.840
It's a matter of switching this for an equal sign.
00:44:43.840 --> 00:44:45.920
So that doesn't really help.
00:44:45.920 --> 00:44:47.679
But maybe this is more readable.
00:44:47.679 --> 00:44:52.400
And we could even define this as a function and then apply it at the end.
00:44:52.639 --> 00:44:55.519
Um it's a possibility.
00:44:55.519 --> 00:44:59.280
I really just mean once you've got that many atops, it's a deepen.
00:45:00.320 --> 00:45:06.159
No, it's but that's the it doesn't really help because if you go back to this, and you're saying you've got lots of atops.
00:45:06.159 --> 00:45:08.480
Let's try to see how what it looks like as a defen then.
00:45:08.480 --> 00:45:10.960
So yeah, this is a defense deephon at all.
00:45:10.960 --> 00:45:12.320
This is like that case.
00:45:12.480 --> 00:45:18.800
That's uh your your the far right outer product, you know, I'd leave that.
00:45:19.360 --> 00:45:20.000
You leave that.
00:45:20.000 --> 00:45:22.320
So this is a deefen, and then this.
00:45:22.320 --> 00:45:27.519
I mean, okay, you're gonna compare this with with this, you say.
00:45:28.079 --> 00:45:43.679
Yeah, in so much as an argument that has been made many times by many people, that here you can sort of see plainly what bits are applied monadically and to the argument, whereas with if we put in a little bit of spacing like this.
00:45:43.679 --> 00:45:45.840
Well, meh.
00:45:45.840 --> 00:45:46.559
No?
00:45:46.559 --> 00:45:50.320
No, I still think the defense just a bit more at a glance.
00:45:50.320 --> 00:45:55.599
Oh, you can but you know, this is uh very controversial topic.
00:45:55.920 --> 00:46:09.360
Well, I was gonna say we can dedicate the last uh 38 minutes of episode 126 to uh once again how much tacit is too tacit, because we've got, I mean, the audio listener is just being like, what are they talking about?
00:46:09.360 --> 00:46:10.880
They're just all like, what about nah?
00:46:10.880 --> 00:46:11.599
Uh-uh.
00:46:11.599 --> 00:46:13.840
And we've got three solutions.
00:46:13.840 --> 00:46:15.280
We at one point had four.
00:46:15.280 --> 00:46:21.280
If you remove the spaces from the original tacit, and there's a plane flying above uh me right now.
00:46:21.280 --> 00:46:26.480
I'm not sure if that's getting picked up, but you know, the first one on screen is the most tacit.
00:46:26.480 --> 00:46:45.360
It's it's gonna for those that like uh, or sorry, it's the most explicit, for those that like tacit programming, it's gonna break your heart because the uh two character three if you're using the compose glyph uh has been named prefix, which is six characters, you know, a few more if you include the spaces and the assignment.
00:46:45.360 --> 00:46:48.800
Uh and then it's omnifix for looking at the prefix.
00:46:49.280 --> 00:46:53.519
Oh, it is still completely tacit up until the last line.
00:46:53.519 --> 00:46:56.719
It's just that it's the the composed functions.
00:46:56.719 --> 00:46:58.880
Adam, if you're talking, you're muted.
00:46:58.880 --> 00:47:00.239
Or am I?
00:47:01.119 --> 00:47:03.119
Or Adam, if Adam's talking, yes, you software.
00:47:03.119 --> 00:47:10.159
Um, which probably just was his uh um headphones microphone cutting out of it.
00:47:10.320 --> 00:47:19.599
All right, this is very this is functional programming people of this sort of thing, you know, compose your functions into new named functions and then recompose those functions.
00:47:19.599 --> 00:47:20.639
Can you hear me?
00:47:20.639 --> 00:47:22.239
Yeah, I can hear you, Adam.
00:47:22.239 --> 00:47:22.960
You sound good now.
00:47:23.119 --> 00:47:34.800
Yeah, so so I'm saying the yeah, that it's sort of what's the point of making it verbose and readable when you could take the time to slowly go through if it's slow, right?
00:47:34.800 --> 00:47:35.760
To go through these parts.
00:47:35.760 --> 00:47:37.440
I'm not saying you should remove all the spacing.
00:47:37.440 --> 00:47:44.639
The spacing, I think the spacing here can help a little bit to see the structure, but there's like it does what it says on the tin, right?
00:47:44.639 --> 00:47:46.239
This what do you mean by ones?
00:47:46.239 --> 00:47:51.280
It's ambiguous, but this is completely unambiguous, at least if you know that it's a monetic context.
00:47:51.280 --> 00:47:53.840
And the same thing here, like okay, the top right corner.
00:47:53.840 --> 00:47:56.320
I guess that that's works as a name for it.
00:47:56.320 --> 00:47:57.119
Although it calls it.
00:48:01.199 --> 00:48:02.719
It's a in this case, yeah.
00:48:02.719 --> 00:48:04.480
But that's uh, not ourselves, exactly.
00:48:04.480 --> 00:48:05.840
You want to name things differently.
00:48:07.760 --> 00:48:12.400
I can this sort of construct is so common that I'll instantly recognize it.
00:48:12.400 --> 00:48:16.719
I mean we maybe replace some of these with jots instead if you want, but it's it's the same thing.
00:48:16.719 --> 00:48:20.239
Right, but mod argues well again, I don't remember.
00:48:20.239 --> 00:48:21.199
And this one as well.
00:48:21.199 --> 00:48:23.039
This one is the is the tough one, right?
00:48:23.199 --> 00:48:24.960
Where we this one is slightly harder to read.
00:48:24.960 --> 00:48:32.960
I didn't even get to the finish uh describing in an audible way what all of the things look like.
00:48:32.960 --> 00:48:34.480
Is it even possible?
00:48:35.199 --> 00:48:54.480
Oh uh yeah, I mean so the the descriptions of them were and I guess well that's a good point, is that the I said the most explicit, but really that is Rich was correct to point out that technically the first four lines where you're assigning names to uh components of the full tacit expression, that's all tacit.
00:48:54.480 --> 00:48:56.400
It's actually it's just naming.
00:48:56.400 --> 00:48:57.760
What do you what do you technically call that?
00:48:57.840 --> 00:49:06.079
It's I mean that's very if you look at any of the D Funds workspace, defense.dialog.com, look at the code in there, it's very that flavor.
00:49:06.079 --> 00:49:21.119
It's name a line uh as a definition of a thing, and then compose all the definitions or put all the definitions together into the final answer, which is and it was very much inspired by uh functional programming, that way of writing stuff.
00:49:21.119 --> 00:49:26.079
The pure symbol thing is slightly more controversial, if anything.
00:49:26.320 --> 00:49:39.679
So we have a comment from the unpronounceable participant name in the chat saying that uh the tacit code is unambiguous if you know the aerity, but with hardware keeping track of all the atops here.
00:49:39.679 --> 00:49:40.559
That's what I'm saying.
00:49:40.559 --> 00:49:43.199
But actually, atops tell you what the arity is.
00:49:43.199 --> 00:49:47.199
If you have an atop, you know that whatever's on the left is called monetically.
00:49:47.199 --> 00:49:48.159
There's no other way.
00:49:48.159 --> 00:49:55.360
So if you go up and read I'm just you know that this plus is not a pairwise plus, right?
00:49:55.360 --> 00:50:02.000
It's and you know that this outer product here is monetic, and because of that atop, and you know that here yeah, yeah.
00:50:02.000 --> 00:50:04.000
So all the all of these, the same thing goes here.
00:50:04.079 --> 00:50:26.559
If you know that you have to read several of those to figure that out, and each piece, and it's not yeah, and it's like in the fork, you know, you've got some extra noise to detangle between the tops that are either side of the and, whereas the omega, like that's one omega, and then the rest just reads as and just passes as APL.
00:50:26.559 --> 00:50:27.360
Yeah.
00:50:27.360 --> 00:50:31.599
So you've got one indicator there saying this is uh monadic.
00:50:31.599 --> 00:50:36.079
Whereas in your like a top account, a top outer product.
00:50:36.400 --> 00:50:45.760
So maybe maybe some kind of um um compromise thing where we we'll just define the omnifix immediately.
00:50:45.760 --> 00:50:49.119
We say this is what the solution asks for, right?
00:50:49.119 --> 00:50:53.119
We we really it's trying it's defining this term of omnifix.
00:50:53.119 --> 00:50:58.239
So we're saying omnifix is space it out nicely.
00:50:58.239 --> 00:51:06.880
Uh this and what we want is then the rest of this.
00:51:06.880 --> 00:51:09.760
I mean these are some qualifications.
00:51:09.760 --> 00:51:13.920
How about that?
00:51:14.239 --> 00:51:17.920
Oh, I see that array box kind of link.
00:51:17.920 --> 00:51:20.000
Open my link, Adam.
00:51:20.000 --> 00:51:21.920
I wanted to see how crazy it looks.
00:51:21.920 --> 00:51:22.639
Uh okay.
00:51:22.639 --> 00:51:32.639
I mean, I'll say to that respelling that my problem wasn't with the the omnific side of it, it was the other side of it that I'm not a fan of.
00:51:32.639 --> 00:51:37.920
I do this is quite interesting that uh array box only you know can deconstruct.
00:51:37.920 --> 00:51:41.760
And the thing is the facet function, it can't do this with a defense.
00:51:42.079 --> 00:51:51.199
If you if you uh like if you go to the parenthesized component and you just select that and then you go shift enter, uh you know, it'll zoom in on that.
00:51:51.199 --> 00:51:52.719
And then I didn't add this feature.
00:51:52.719 --> 00:51:59.920
If you go and hover over each of the glyphs in in there, like uh a user went and added this, and so that's so nice.
00:51:59.920 --> 00:52:00.960
Yeah, love it.
00:52:00.960 --> 00:52:09.119
Anyways, like I'm not saying this is an argument for you know, one versus this is this is a tool to help you get over the deficiency, yeah.
00:52:09.360 --> 00:52:21.519
Uh you know, that it's um that you call it deficiency, but I'm saying uh a dictionary is a tool to help you get over the deficiency of the language that the words don't hold on.
00:52:21.519 --> 00:52:26.800
The words too many words the words in in English, for example, do not carry their own meaning, right?
00:52:26.800 --> 00:52:28.400
They only define the dictionary.
00:52:28.480 --> 00:52:32.079
So clearly every actually they're not they're not really even defined in the dictionary.
00:52:32.320 --> 00:52:39.440
No, no, I know, but in principle they define the dictionary, but it's all just circular definitions according to dictionary sellers that are defined in it.
00:52:39.440 --> 00:52:46.400
Okay, but but but so clearly we should include the dictionary entry for every word we say every time we say it.
00:52:46.400 --> 00:52:54.159
That's great for a language learner, but for somebody who gains proficiency in the language, you don't want to log a dictionary with you all the time.
00:52:54.159 --> 00:52:56.159
And I don't need this anymore.
00:52:56.159 --> 00:53:01.440
At some point, you have to stand on your own feet, you have to can't just define everything from basics all the time.
00:53:01.440 --> 00:53:03.920
Um, what was that that talk by Guy Steele?
00:53:03.920 --> 00:53:08.960
Um where he starts off his talk, yeah, growing a language, right?
00:53:08.960 --> 00:53:18.960
Yeah, it's it's painful if you were to start every talk, every paper, everything you do, every product growing things, everything from like some bare bones vocabulary.
00:53:18.960 --> 00:53:21.360
We make an assumption about the reader.
00:53:21.679 --> 00:53:33.199
It's a fair point, and it might be I'm just uh slightly I just haven't still haven't grown over my bias of uh against the maybe it's just the the glyph that's used for a top uh or something.
00:53:33.599 --> 00:53:38.320
That is an unfortunate pairing that makes it look noisy and and stuff.
00:53:38.480 --> 00:53:39.360
Uh yes.
00:53:42.559 --> 00:53:54.960
Well, you know, maybe I should maybe this is an experiment I should do is force myself to I th I think the the interesting thing is that like I also agree that like this is a bit noisy, but my thought is not that like tacit is the problem.
00:53:54.960 --> 00:54:05.039
My thought is that like wouldn't it be great if there was a glyph for uh you know the uh upper triangular matrix.
00:54:05.039 --> 00:54:17.599
Um, you know, so if you could just if there was a uh a higher order function or an operator that if you passed it less, it would give you that matrix, and then like it completely collapses like six glyphs into one.
00:54:17.599 --> 00:54:20.320
And and also two, we're technically repeating the prefix.
00:54:20.320 --> 00:54:31.920
So like I'm not saying there should be a glyph for is prefix, but like my my thought is is there a way to like contort this in order to only have those three glyphs once?
00:54:32.400 --> 00:54:41.599
Um uh Marshall's what is a primitive uh post, his document in BQN, because that's kind of what you're speaking to there.
00:54:41.760 --> 00:54:51.840
Is well, I mean, I I find myself liking Tiny Apple when I'm just like solving these trivial problems the most, because like whenever you want a glyph, it's usually there.
00:54:51.840 --> 00:54:57.599
And I don't actually think tiny apple has a upper triangular um matrix glyph.
00:54:57.679 --> 00:55:00.719
Um, but I was a notation had that if I remember right.
00:55:00.719 --> 00:55:01.440
Did it?
00:55:01.440 --> 00:55:03.599
Uh yeah we go, let's bring it back.
00:55:03.679 --> 00:55:05.599
Let's make APL great great again.
00:55:06.880 --> 00:55:08.800
Make APL glyph again.
00:55:08.800 --> 00:55:14.559
Um I if I remember right, it had like these I mean clearly, yeah.
00:55:14.559 --> 00:55:20.400
I mean symbols that was there were like little squares with dots in the corners and slashes.
00:55:20.719 --> 00:55:26.079
Um it's a fairly common technique, right?
00:55:26.079 --> 00:55:27.360
Uh in APL lands.
00:55:27.360 --> 00:55:29.440
Look at this over here.
00:55:29.599 --> 00:55:32.000
Maybe I should open up just this frame here.
00:55:32.000 --> 00:55:33.760
Oh, special indices.
00:55:33.760 --> 00:55:34.559
Yeah.
00:55:34.559 --> 00:55:35.760
Hell yeah.
00:55:35.760 --> 00:55:48.320
And we find that is the Unicode upper no, I'm not sure if they had that, but here uh I found the upper right.
00:55:48.320 --> 00:55:49.280
Look at this.
00:55:49.280 --> 00:55:53.199
So these upper left triangle, upper right triangle, lower left, lower right.
00:55:53.199 --> 00:56:02.400
And if I remember right, there are a bunch more that are uh defined that like if there's a slash going through them, then it includes the diagonal.
00:56:02.400 --> 00:56:03.280
That's amazing.
00:56:03.280 --> 00:56:04.480
Madeline, get on it.
00:56:04.480 --> 00:56:06.079
There's there's the glyphs.
00:56:06.400 --> 00:56:20.960
But that's the thing, is like I I think so often, like the you know, optimal or ideal solution in in array languages is so strongly informed by the glyphs that you have access to.
00:56:20.960 --> 00:56:45.199
Like, and like that sounds like an obvious statement, but when you're switching between array languages and you know it takes four or five glyphs to spell something versus a single glyph, like and then potentially there's a two-glyph way to spell it in uh the language where it was five or six to spell that uh thing that was a glyph, like that that affects like the way I want to spell something, especially if like performance is not a concern, right?
00:56:45.519 --> 00:56:55.840
Well, I was gonna ask Adam with the longest APL experience about the time before key, which is before I even joined dialogue or knew anything about APL.
00:56:55.840 --> 00:56:56.239
Yeah.
00:56:56.239 --> 00:57:07.280
But considering what it is and and what it does and how it's used, it is one of those things that boggles the mind a little bit that that people would do things before and else what before key.
00:57:07.280 --> 00:57:10.800
People did things before nested arrays, yeah.
00:57:10.960 --> 00:57:19.760
Yeah, so uh out of product, yes, but reluctantly because this performance would be obvious dangerous, right?
00:57:19.760 --> 00:57:21.920
So you want to do whatever you can to avoid that.
00:57:22.079 --> 00:57:30.400
But writing um and what everyone would just walk around with a little uh group bar operator or something they would use?
00:57:30.719 --> 00:57:37.119
Not necessarily, but I think there were for things that were that were critical, people would write some bespoke code, right?
00:57:37.119 --> 00:57:45.519
So even now key has performance issues in the general case, but in certain specific cases it's good, and that sort of comes back to the same thing.
00:57:45.519 --> 00:57:53.440
If you know what exactly your problem is, you can write some bespoke code that's really uh really good and fast and simpler than what it needs to be in general.
00:57:53.440 --> 00:57:58.719
Uh so I think people did that more, and the same thing goes to the the the Boolean techniques, right?
00:57:58.960 --> 00:58:18.320
You can now we have fancy things like pairwise application and uh and we can right that always gets me in the introductory APL tutorials uh in a in a good number of them, it introduces uh pairwise difference as a one drop minus the neg one drop.
00:58:18.320 --> 00:58:25.840
Even though for quite a while pairwise difference as a windowed reduction has existed.
00:58:25.840 --> 00:58:26.320
Yeah.
00:58:26.320 --> 00:58:29.119
And yet they always still seem to introduce it that way.
00:58:29.119 --> 00:58:31.440
I guess because that's what you see in real code.
00:58:31.440 --> 00:58:32.239
Yeah, yeah.
00:58:32.559 --> 00:58:33.679
I think that's true.
00:58:33.679 --> 00:58:40.800
Uh I think that's a lot of it's just legacy that and and the pairwise thing wasn't introduced until later, so people just get stuck with that.
00:58:40.800 --> 00:58:47.599
Um I mean dialogue has had tally since version 14, together with key.
00:58:47.599 --> 00:58:53.199
Nevertheless, people write the first of the shape all the time, or even one pick shape.
00:58:53.199 --> 00:58:54.559
Uh creatures.
00:58:54.559 --> 00:58:57.840
Yeah, people tend it works, right?
00:58:57.840 --> 00:59:01.440
It doesn't if mostly yeah, it doesn't even really cost.
00:59:01.440 --> 00:59:04.639
I think I think yeah, people wrote up more bespoke code like this.
00:59:04.639 --> 00:59:11.519
There's a comment here in the in the chat saying spelling things with more clips can give you insight into the implementation of algorithms.
00:59:11.519 --> 00:59:12.800
Yes, I think that's true.
00:59:12.800 --> 00:59:24.000
Like how we wrote earlier um each in terms of rank and open as a good disclose and and in-close, I think gives you more insight into what's actually happening.
00:59:24.000 --> 00:59:32.000
I think it's a good thing to try to model a model more complicated primitives in terms of simpler primitives to get insight into the case.
00:59:32.400 --> 00:59:51.840
There's a good post by Roger Huey about um the inner product and the rank operator, and doing a certain spelling of inner product using reductions and the rank operator uh gave him a a way to implement in C that was better than what they'd been doing before.
00:59:52.159 --> 00:59:52.960
Oh interesting.
00:59:53.199 --> 00:59:55.519
I wonder if I can dig that up somewhere.
00:59:57.039 --> 01:00:02.960
Yeah, I think you can also you can also understand some of the notation better.
01:00:02.960 --> 01:00:09.760
So a lot of these newer APLs have rationalized their the outer product to be a monetic operator.
01:00:09.760 --> 01:00:20.239
But there's a reason why it looks like it's a dyadic operator with some weird uh left operand, and that's because you can there's actually a relationship between outer product and inner product.
01:00:20.239 --> 01:00:31.840
Um if we if we took um one, two, three plus the times uh ten, twenty, thirty, you got 140.
01:00:31.840 --> 01:00:38.079
And so this is one times ten plus two times twenty, just three times thirty, and then add it together.
01:00:38.079 --> 01:00:44.000
But so the outer product, like this, you can actually see it here.
01:00:44.000 --> 01:00:47.280
So one times ten, two times twenty, three times thirty.
01:00:47.280 --> 01:00:54.960
So if we apply the diagonal, which we can do in this case it's not really important what the diagonal is, but this is the diagonal, and then we sum it.
01:00:54.960 --> 01:01:09.679
Okay, so the inner product plus the times is the plus function applied over the diagonal, uh is the the plus function reduced over the diagonals of this outer product.
01:01:09.679 --> 01:01:15.039
And if we don't do that part, then obviously we get the outer product.
01:01:15.039 --> 01:01:30.559
So let's let's write a model sort of for of the of the outer uh of not of the outer or inner product, but of the dot so we're going to write it so we can define later what actually the outer product does, but let's just say that that is a um a given thing.
01:01:30.559 --> 01:01:38.480
So we have the outer is alpha alpha alpha uh alpha alpha omega, right?
01:01:38.480 --> 01:01:44.480
And then we check, uh sorry, that's wrong, it's the right upper end.
01:01:44.480 --> 01:01:49.760
And then we check if um some null function is equal.
01:01:49.760 --> 01:01:51.760
So let's just use zero for now.
01:01:51.760 --> 01:01:58.159
So if zero and matches, or we can even say just look at the name class, right?
01:01:58.159 --> 01:02:01.440
So it's forward equal a tx of alpha alpha.
01:02:01.440 --> 01:02:12.079
So so this gives us the name class, which let's say is going to be three if it's a function, it's two if it's an array, so if uh if it's two, so if it's a zero or any other value actually, then we just return outer.
01:02:12.079 --> 01:02:16.719
Otherwise, we do, and this will only work on matrices, but it doesn't really matter.
01:02:16.719 --> 01:02:22.719
Uh we do the left function reduction over the uh diagonal of outer.
01:02:22.719 --> 01:02:31.039
Okay, so now we can write one, two, three, z and then zero uh yeah, that's fine actually.
01:02:31.039 --> 01:02:38.480
Dot times 10 20 30 is the outer product, and the inner product is this.
01:02:38.480 --> 01:02:57.119
So if we see the zero here as a sort of null function, meaning if you try to if you have an operation called the reduce over diagonal, so you do an alpha alpha reduce over diagonal, but alpha alpha is a null function, so we do a null reduce over diagonal, that means don't actually do any reducing over diagonal, then we just get the outer product.
01:02:57.119 --> 01:03:05.199
So we so originally jot wasn't used as bind and uh and the composition at all, it was only for this.
01:03:05.199 --> 01:03:08.400
So jot was it was even called nil, I think.
01:03:08.400 --> 01:03:10.400
So it was just a nil dot times.
01:03:10.400 --> 01:03:14.639
Meaning don't do that reduction over the diagonal thing, skip that step.
01:03:14.639 --> 01:03:18.400
It's a placeholder for a null function, and now they're consistent, right?
01:03:18.400 --> 01:03:19.360
Like now it makes sense.
01:03:19.360 --> 01:03:22.079
If you have a null null function, then you don't do it.
01:03:22.079 --> 01:03:33.840
And there were there were this concept would later um extend it to other operators as well, but never they never found them their way into uh mainstream APL, including dialogue APL.
01:03:33.840 --> 01:03:42.639
So, for example, we have the power operator, which keeps applying a function until something holds true, usually a fixed point, but it could be anything, right?
01:03:42.639 --> 01:03:50.559
It could be a greater than, could be something, something external, some custom tests on on the successive iterations.
01:03:50.559 --> 01:03:52.880
So until this condition holds true.
01:03:52.880 --> 01:03:56.480
And if you use the nil function, then it's forever.
01:03:56.480 --> 01:03:58.880
So that's the fixed point, I think.
01:03:58.880 --> 01:04:02.719
Or we could you say it's it's has a number, you do it five times, right?
01:04:02.719 --> 01:04:05.360
But nil means just keep going forever.
01:04:05.360 --> 01:04:12.000
Um that wasn't implemented because it has an option for fixed point, yeah.
01:04:12.000 --> 01:04:14.159
This yeah, this was how you you write it.
01:04:14.159 --> 01:04:20.800
Um I think it didn't even have a function, I think it was just originally a number and then and then fixed point.
01:04:20.800 --> 01:04:23.280
And that just means there's no particular number.
01:04:23.280 --> 01:04:25.360
It's not even infinity, isn't really true either.
01:04:25.360 --> 01:04:29.039
That's what J uses, but it's not infinite times, it's until it's stable.
01:04:29.039 --> 01:04:32.159
It's until until it doesn't make a difference anymore.
01:04:32.159 --> 01:04:45.360
And I think there were there were other ideas for very for operators having slots unoccupied in uh so I can't quite think of what they would be, but I think we could look them up.
01:04:45.360 --> 01:04:55.760
So sometimes I think comp decomposing things into simpler primitives could sort of give you insights about how things work, how they're connected to each other.
01:04:55.760 --> 01:05:03.039
And if you replace that out-of-product notation with some other notation, just another operator, then you lose the connection between inner and outer product.
01:05:03.039 --> 01:05:06.800
There's a reason why they're named like that, inner and outer product, because they're really related.
01:05:06.800 --> 01:05:09.199
They're both products of a sort.
01:05:09.199 --> 01:05:14.719
Anyway, we did we look we didn't even look at other ways of solving this.
01:05:14.719 --> 01:05:18.320
Because now we did the the the beginning and end thing.
01:05:18.320 --> 01:05:21.679
We another way we could we we did it with the find.
01:05:21.679 --> 01:05:28.559
Another way we could do it is uh taking a prefix of a length, but uh it still get pretty dirty.
01:05:28.559 --> 01:05:51.599
We still have a ray here, so we still need an an outer product, but then we still need the masking, all of that we still need uh in principle we could do something like we could get the we could we can save on the computation by by computing the the combinations uh combinations table um and then only applying those.
01:05:51.599 --> 01:05:55.280
So I think we have got um what's cmat?
01:05:55.280 --> 01:05:58.320
C mat three.
01:05:58.320 --> 01:05:59.599
Oh that's all right.
01:05:59.599 --> 01:06:02.079
Do you also have three isn't hanging out?
01:06:03.039 --> 01:06:03.920
No, you're right.
01:06:03.920 --> 01:06:04.719
It is a number.
01:06:04.719 --> 01:06:07.440
Oh, um, no, C mat's dyadic.
01:06:07.440 --> 01:06:10.000
P mat is the one addict one.
01:06:10.320 --> 01:06:15.920
Oh, because we want to we want to take okay, we want to do how many ways we can be two two two out of two out of three.
01:06:15.920 --> 01:06:16.559
Yeah, okay.
01:06:16.559 --> 01:06:19.840
So it's it's the same syntax as the exclamation part, right?
01:06:19.840 --> 01:06:24.239
That's yeah, that's counting how many they are, and this one is telling you what they are.
01:06:24.239 --> 01:06:25.119
Right.
01:06:25.119 --> 01:06:27.280
So these are all the ones we need to test.
01:06:27.280 --> 01:06:32.079
And so if we got array over here, there are only four, and we need to choose two at a time.
01:06:32.079 --> 01:06:35.519
So these are all the different combinations we need to test.
01:06:35.519 --> 01:06:41.679
But that's not really we do need the ordering as long as they're unique, right?
01:06:41.679 --> 01:06:43.199
Because it could be one or the other.
01:06:43.199 --> 01:06:46.719
So I think actually we need PMAT permutations.
01:06:47.280 --> 01:06:54.400
Uh but that only gives us Yeah, I think I was playing with something to generate combinations of things.
01:06:54.400 --> 01:06:56.079
And no, yeah, exactly.
01:06:56.079 --> 01:06:59.280
I only could basically need to do like a both.
01:06:59.280 --> 01:07:01.599
You want all the permutations.
01:07:02.000 --> 01:07:18.079
Yeah, this is where we need we need NARS 2000's uh double exclamation point uh operator that allows you to specify exactly yeah, it has like it has like a compound operand or something that allows you to say, like, do you put the balls back again after you use them?
01:07:18.079 --> 01:07:19.599
And does the ordering matter?
01:07:19.599 --> 01:07:27.280
And all those there's like the six-fold way or some uh of of doing things twelve fold, I can't remember how it is.
01:07:27.280 --> 01:07:31.440
Um but we I mean we could do this and it's reverse, right?
01:07:31.440 --> 01:07:32.480
That just makes sense.
01:07:32.639 --> 01:07:35.519
I mean, in the case of two and four, that is definitely sufficient.
01:07:35.519 --> 01:07:50.400
In general, you do uh you take your C Mat and then you get the P mat of that length, and then you do a uh basically a row wise out a product where you take all of the combinations, and then you're probably gonna do get a bunch of duplicates as a result of that.
01:07:50.400 --> 01:07:52.079
But why can't we just end?
01:07:52.079 --> 01:07:53.519
Why can't we just do this?
01:07:53.519 --> 01:07:56.480
No, in this case you can just do this because there's only two.
01:07:56.480 --> 01:07:59.199
But in general, oh that's what you mean.
01:07:59.199 --> 01:08:00.000
Yeah, the reverse.
01:08:00.400 --> 01:08:02.559
In our case, there will only ever be two, right?
01:08:02.559 --> 01:08:03.360
Exactly, yeah.
01:08:03.360 --> 01:08:13.679
So these these are all the different possibilities, and there can't be any uh any duplicates because cmet doesn't care about the ordering, so therefore they'll always be sorted, and then no they never know overlap with themselves.
01:08:13.679 --> 01:08:15.440
So these are all the ones we need to check.
01:08:15.440 --> 01:08:28.560
Okay, so now if we take array and do this, so these are all the uh the pairs that we need to check, and then we just need we we don't have our function anymore, but we can just define that, right?
01:08:28.560 --> 01:08:42.159
So we can say the the prefix and uh the suffix, and we just need to check whether that's the case for each one of them, and then we ask, are there any?
01:08:42.159 --> 01:08:45.039
You still with me, Connor?
01:08:45.359 --> 01:08:46.239
Yeah, yeah, I'm still here.
01:08:46.239 --> 01:08:47.760
Just watching and join, you know.
01:08:47.760 --> 01:08:54.479
So we can write this Monday night football except I don't watch football, I watch people coding APL.
01:08:54.880 --> 01:08:55.840
Here we go.
01:08:55.840 --> 01:08:59.680
So this uh we think we have the problem of the duplicates though.
01:08:59.680 --> 01:09:02.880
Like if we say ab and ab.
01:09:02.880 --> 01:09:04.560
Oh no.
01:09:05.199 --> 01:09:09.199
Uh no, because why?
01:09:09.199 --> 01:09:13.119
Because the C M doesn't give you with itself.
01:09:13.119 --> 01:09:16.640
Yeah, there's no duplicate indices in the in that matrix, is there?
01:09:16.640 --> 01:09:18.079
There's no one, two.
01:09:18.079 --> 01:09:20.399
This doesn't care, right?
01:09:20.399 --> 01:09:24.000
So yeah, it doesn't give you one, one, and two, two.
01:09:24.720 --> 01:09:28.560
No, but why doesn't this oh we don't know because we want to count them, that's the problem.
01:09:28.560 --> 01:09:29.520
That's my mistake here.
01:09:29.520 --> 01:09:30.079
Oh, right.
01:09:30.079 --> 01:09:31.119
I did an R.
01:09:31.119 --> 01:09:34.079
Yeah, so this will give us this will give us two.
01:09:34.079 --> 01:09:37.840
So we need to do uh unique first.
01:09:37.840 --> 01:09:39.039
Oh, sorry.
01:09:39.039 --> 01:09:40.640
Yeah, yeah, I'm catching up.
01:09:40.640 --> 01:09:50.159
Um which I guess we can do that on the well, there will never be any duplicates in here, and we don't know what there are.
01:09:50.159 --> 01:09:55.199
We need to sort of take away the you take the uniques before we even start, right?
01:09:55.199 --> 01:09:57.520
So I think we can just do that.
01:09:57.520 --> 01:10:00.319
Did I make a mistake here?
01:10:00.640 --> 01:10:06.319
Yeah, they don't have an example, do they, where it's there are different ones, but two of them are the same.
01:10:06.720 --> 01:10:08.560
What what mistake did I make here?
01:10:08.560 --> 01:10:14.000
F what you excuse two.
01:10:14.000 --> 01:10:19.600
And if I do this, we get a nonsense result.
01:10:19.600 --> 01:10:21.359
Uh let's look at that.
01:10:21.359 --> 01:10:22.720
What's actually happening here?
01:10:22.720 --> 01:10:27.279
Maybe maybe CMET is not happy when it's one, there's only one.
01:10:27.760 --> 01:10:30.159
Oh, it's not, it's yeah, it's a stranding.
01:10:30.159 --> 01:10:32.800
You gotta include simple as well, do you?
01:10:33.279 --> 01:10:35.359
No, that should be fine.
01:10:35.680 --> 01:10:37.359
Oh, that's the problem.
01:10:37.600 --> 01:10:38.960
How do you take two?
01:10:38.960 --> 01:10:39.920
From one.
01:10:39.920 --> 01:10:41.039
From one.
01:10:41.039 --> 01:10:42.319
Oh well.
01:10:42.319 --> 01:10:44.720
That's the problem.
01:10:44.720 --> 01:10:49.520
So I mean we could just throw in the unique here.
01:10:49.520 --> 01:10:53.680
It's slightly wasteful, but too bad.
01:10:53.680 --> 01:11:00.319
Which means we can also throw the unique in in so we don't have to compare the values themselves, we can compare in here.
01:11:00.319 --> 01:11:02.399
So what actually happens here?
01:11:02.399 --> 01:11:05.920
Two, one, and what's the problem is that they are the same.
01:11:05.920 --> 01:11:09.119
Yeah, but the indice, the CMAP doesn't tell you that.
01:11:09.359 --> 01:11:10.399
Yeah, the C no, they're not.
01:11:10.399 --> 01:11:11.359
It doesn't know.
01:11:11.359 --> 01:11:12.079
It doesn't know.
01:11:12.079 --> 01:11:15.119
Oh, so you do have to do it outside this actually.
01:11:15.119 --> 01:11:16.239
Yeah, I think so.
01:11:16.239 --> 01:11:18.479
Apply the unique to the indices, yeah.
01:11:18.720 --> 01:11:21.600
Okay, so this is another solution that's sort of sort of neat.
01:11:21.600 --> 01:11:23.600
Get rid of that here.
01:11:23.600 --> 01:11:26.239
But of course, it relies on a bunch of code in the CMAP.
01:11:26.239 --> 01:11:27.039
Yeah, yeah.
01:11:27.039 --> 01:11:33.760
I was gonna say it's kind of big fat dependency on a big fat loopy unless it's yeah, dependent.
01:11:33.760 --> 01:11:44.960
Looks like they're any loops, but they are because we'd actually taken this giant function and uh actually it's this one, I think, and reducing over a whole bunch of things.
01:11:44.960 --> 01:11:47.439
So that's actually just it, it's iterative.
01:11:47.439 --> 01:11:51.439
But it might still be I will still be faster, I believe.
01:11:51.439 --> 01:11:54.159
Well, it's because it's not doing an outer product.
01:11:54.640 --> 01:11:55.039
Yeah.
01:11:55.039 --> 01:11:58.880
Well, yeah, I think there's going to be a crossover.
01:11:58.880 --> 01:12:00.479
There'll be a point there.
01:12:00.479 --> 01:12:06.640
Early on, the outer product is probably gonna be just because that's optimized.
01:12:06.880 --> 01:12:15.039
Yeah, because we couldn't, by the way, if we go back all the way, uh it's a long way, it wouldn't matter here.
01:12:15.039 --> 01:12:23.279
But the omnifix, we did we did a single outer product with omnifix, but we could actually break out the outer product into these two.
01:12:23.279 --> 01:12:31.279
So if we take our whole solution here, uh it's not going to be shorter, but it might be slightly easier to understand if you do it like this.
01:12:31.279 --> 01:12:33.600
We gotta get a JX butt on here.
01:12:33.760 --> 01:12:34.800
Let me see the comment.
01:12:34.800 --> 01:12:36.560
Do you know about outfix?
01:12:37.119 --> 01:12:43.520
Yeah, Oracle's mentioning uh J's outfix is useful for this pattern where you want to ignore self-comparisons.
01:12:44.560 --> 01:12:46.560
Uh yeah, didn't we?
01:12:46.560 --> 01:12:53.920
We had such a problem once upon a time on the ray cast where we looked at uh the sum of the array except for every element.
01:12:53.920 --> 01:12:56.159
We also want to ignore itself.
01:12:56.159 --> 01:13:02.800
Anyway, so so this is another another formulation that's I can exactly fit.
01:13:02.800 --> 01:13:05.760
We sort of make smaller outer products.
01:13:05.760 --> 01:13:14.720
These are all the suffixes, and these are all the prefixes, and this is the top right uh triangle, and this is summation step by step.
01:13:14.720 --> 01:13:23.600
Also, here you said that writing things testedly requires greater discipline to keep your codes um digestible.
01:13:23.600 --> 01:13:27.199
So, what is Chase Chase outfix?
01:13:28.640 --> 01:13:35.760
And just a heads up, I have to leave it five minutes from now, so we gotta hard stop them.
01:13:35.760 --> 01:13:42.159
But yeah, maybe the last thing we can do is look at the well, like we mentioned at the beginning, we're looking to build out our panel.
01:13:42.159 --> 01:13:44.640
So hopefully we will be adding uh a J.
01:13:50.000 --> 01:13:51.520
Infix dependent X.
01:13:51.520 --> 01:14:02.720
So yeah, we want the outer the outer two, but I don't yeah, this sort of thing, but I'm not really sure how how you'd use it like this.
01:14:02.720 --> 01:14:06.560
It's not not really my word.
01:14:06.560 --> 01:14:15.920
So what was uh array we had over here?
01:14:15.920 --> 01:14:27.199
Uh well let's say an example full solution of sorts is it's J, so it won't win any brevity always in here.
01:14:27.199 --> 01:14:38.159
But I'm not sure I'm not sure what to write because like the okay, so we want two, but I'm not even sure what the negative thing is.
01:14:38.479 --> 01:14:43.520
Uh uh success representative one is for like sliding window and one is for chunks.
01:14:43.520 --> 01:14:44.720
Oh yeah.
01:14:45.039 --> 01:14:49.359
But how does that how does that help us here?
01:14:49.359 --> 01:14:53.279
I mean it no, this is infix.
01:14:53.279 --> 01:14:55.039
This is not outfix, right?
01:14:55.039 --> 01:14:59.439
There's all the okay, so we got something here in the chat.
01:14:59.439 --> 01:15:02.720
Let's do this in the array.
01:15:02.720 --> 01:15:05.359
Okay, I see.
01:15:05.359 --> 01:15:07.359
So it's just for the pairing, right?
01:15:07.359 --> 01:15:14.159
So it's using this thing that we had before with the outfix, all the all the means with single element removed, right?
01:15:14.159 --> 01:15:15.680
That's what it's using here.
01:15:15.680 --> 01:15:22.399
And then we are pairing them up, but we still need to go for each one of them and check whether they are prefixes and suffixes.
01:15:22.399 --> 01:15:28.560
This doesn't solve the even though it's called outfix, it doesn't actually solve solve the problem of prefixes and outfixes.
01:15:29.039 --> 01:15:31.840
This just sharing issue.
01:15:31.840 --> 01:15:36.319
Yeah, of getting the combinations without the self-combination.
01:15:36.319 --> 01:15:38.880
Oh, there's an array.
01:15:39.600 --> 01:15:41.119
No, that got eaten somehow.
01:15:41.119 --> 01:15:53.840
If you go post it on uh Yeah, I can't I can't see their butt the people that's the annoying thing in YouTube that it doesn't tell people when their message got rejected, it just silently eats them for you unless you see them, but nobody else can see it.
01:15:54.000 --> 01:15:58.079
So yeah, if you add the link here, Adam can go post it.
01:15:59.359 --> 01:16:02.000
Yeah, but it might take time to do that.
01:16:02.000 --> 01:16:03.680
You have to do a PR, no?
01:16:03.840 --> 01:16:05.359
No, no, it's just a comment.
01:16:05.680 --> 01:16:06.880
Oh, it's a comment there.
01:16:07.039 --> 01:16:07.279
Okay.
01:16:07.279 --> 01:16:08.880
No, you just have to see F5.
01:16:08.880 --> 01:16:10.960
Hopefully it happens in the next 120 seconds.
01:16:10.960 --> 01:16:13.439
Otherwise, I'm pulling the plug on the stream.
01:16:15.760 --> 01:16:17.199
I just had a lean on F5.
01:16:17.520 --> 01:16:20.000
Or if I if if I had a uh what do you call it?
01:16:20.000 --> 01:16:34.880
Uh uh if I was like Big Brother, I could I could uh have some dashboard that shows all the links being created on a Ray box, but unfortunately I I don't have that, so it's not there.
01:16:35.119 --> 01:16:40.960
I mean with uh I there might be clear I oh it has fine, so we can actually do the same thing.
01:16:40.960 --> 01:16:42.399
J has fine.
01:16:42.399 --> 01:16:44.079
Sure, can you do it in 30 seconds?
01:16:44.079 --> 01:16:46.560
No, but I can show the I can show the principle.
01:16:46.560 --> 01:16:48.000
I think it's called like E dot.
01:16:48.000 --> 01:16:54.880
So if we say uh AB and then they will find it there, right?
01:16:54.880 --> 01:16:56.239
That thing.
01:16:56.239 --> 01:16:58.960
And then we need the first of that, etc.
01:16:58.960 --> 01:17:06.079
Right, and so that will be the same thing, it's exactly like it's just translation character of a character, basically, of the of the APL code.
01:17:06.079 --> 01:17:11.680
So we'll leave it as an exercise to the viewer, uh, to figure out how that how to do that.
01:17:11.680 --> 01:17:12.880
Okay, Connor?
01:17:12.880 --> 01:17:14.000
All right.
01:17:15.439 --> 01:17:18.960
Yeah, uh, I I think someone did just post.
01:17:18.960 --> 01:17:29.439
I guess maybe there's a hack that if you uh there's this like what looks like a Mandarin symbol for when, which is language.
01:17:29.439 --> 01:17:36.000
Um if you put something like that, uh, it enables you to to like post the array language.
01:17:36.000 --> 01:17:41.039
I don't know what that hack is, but or or maybe maybe we can see it, but the other users can't see it.
01:17:41.039 --> 01:17:45.119
I'm not seeing it, so oh there we we got something.
01:17:45.119 --> 01:17:46.000
Oh, I see.
01:17:46.000 --> 01:17:52.239
So it says there's a J1 liner shows up afterwards if you choose show all messages in the chat filter.
01:17:52.239 --> 01:17:53.760
Uh all right.
01:17:53.760 --> 01:17:54.960
Well, we'll figure that out.
01:17:54.960 --> 01:18:03.760
Maybe there's a setting on these live streams where I can just say allow all spam and uh yeah, so depending on this okay.
01:18:03.840 --> 01:18:11.439
So here we have the the finding thing, and this is uh an or.
01:18:11.439 --> 01:18:15.359
Oh, yeah, I'm not sure whether we do a first there, but okay.
01:18:15.359 --> 01:18:20.319
Oh yeah, it's just finding if there's a I think I don't think this is right, but I'm not entirely sure.
01:18:20.319 --> 01:18:28.000
Because this looks to me like it's an an or reduction atop this, and I think it has to be a first of that instead.
01:18:28.000 --> 01:18:30.479
That's my my feeling at least.
01:18:30.880 --> 01:18:36.399
All right, well, in the future we'll have a J Pro, and so we'll never find ourselves in this J pickle.
01:18:36.399 --> 01:18:43.359
And uh as we mentioned at the top, reach out to us at uh contact at array c uh array cast.
01:18:43.359 --> 01:18:44.560
Boy, oh boy.
01:18:44.560 --> 01:18:48.399
Yeah, I guess you have to do it for a hundred episodes before you can nail it like Bob did every time.
01:18:48.399 --> 01:18:55.840
Contact at raycast.com and we'll be monitoring uh yeah, looking for your guys' emails.
01:18:56.000 --> 01:19:01.119
And with that, we will say crushed it.