WEBVTT
00:00:13.439 --> 00:00:18.879
Welcome to episode 128 of Raycast.
00:00:18.879 --> 00:00:24.640
I hope I got that number right because I realized just as we went live that I didn't actually have it in front of me.
00:00:24.640 --> 00:00:29.519
But uh I think I did, and we have a very exciting episode today.
00:00:29.519 --> 00:00:34.000
We've got uh three guests with us who I will well, I guess I should mention them now.
00:00:34.000 --> 00:00:40.640
Actually, I'll mention them in a sec, but if you're watching this on YouTube, which I think is, I don't know what percentage of our listenership, but it's the minority.
00:00:40.640 --> 00:00:42.560
You can already see all three of their names.
00:00:42.560 --> 00:00:45.600
The audio listener, though, will have to wait a few more seconds.
00:00:45.600 --> 00:00:49.679
And uh I guess with that I'll do a brief infro introduction.
00:00:49.679 --> 00:00:51.679
Adam can go first, uh, then I can go.
00:00:51.679 --> 00:00:54.240
And actually, should we just change it so that we can all go around?
00:00:54.240 --> 00:00:56.719
Because I just realized that we're bringing back Steven.
00:00:56.719 --> 00:01:03.439
Spoiler for the audio listener, uh Stephen Taylor, longtime panelist, uh, has come back for this special episode.
00:01:03.439 --> 00:01:07.120
And so I was just thinking that I guess he should do the brief introduction.
00:01:07.120 --> 00:01:13.680
So maybe what we'll do is we'll we'll go around and we'll do brief introductions from everyone, and uh and we'll we'll go from there.
00:01:13.680 --> 00:01:20.879
So we'll start with Adam and we'll finish with me, and then we'll go uh Steven, Alex, and Jacob uh will do last for our guests.
00:01:20.879 --> 00:01:22.400
So uh kick us off, Adam.
00:01:22.400 --> 00:01:24.239
Yeah, I'm Adam Busewski.
00:01:24.480 --> 00:01:29.680
Uh I am head of language design and longtime APL at Luck Limited.
00:01:30.159 --> 00:01:37.359
I'm Steven Taylor and APL and Q enthusiast and uh one-time KX librarian.
00:01:37.680 --> 00:01:39.680
Hi, I'm Alexander Lontaner.
00:01:39.680 --> 00:01:44.959
I'm a Q enthusiast and the founder and blogger behind DEF CON Q.
00:01:45.599 --> 00:01:47.200
Yep, and I'm Jake Leblos.
00:01:47.200 --> 00:01:50.560
I'm a very longtime K and Q developer.
00:01:51.040 --> 00:01:51.519
Awesome.
00:01:51.519 --> 00:01:54.879
And as mentioned before, or actually, I'm not even sure if I mentioned it before.
00:01:54.879 --> 00:01:57.120
Uh my name's Connor, host of ArrayCast.
00:01:57.120 --> 00:02:01.840
Uh fan of all the array languages, I'm very excited to hear about uh the topic for today.
00:02:01.840 --> 00:02:08.000
But before we get to that, uh I'm gonna hand it over to Adam, who I believe has three announcements if I recall correctly.
00:02:08.479 --> 00:02:10.240
Well, we could call it four, maybe.
00:02:10.240 --> 00:02:11.360
Um, right.
00:02:11.360 --> 00:02:14.000
So uh first a couple of deadlines.
00:02:14.000 --> 00:02:22.000
On July 31st is the deadline for early bird 10% off special uh for the dialogue user meeting.
00:02:22.000 --> 00:02:27.039
You get that rebate because the schedule for what happens at the user meeting isn't quite settled yet.
00:02:27.039 --> 00:02:28.560
Only the workshops are settled.
00:02:28.560 --> 00:02:33.439
So if you're willing to sign up, even though you don't know exactly what the presentations will be, you get some money off.
00:02:33.439 --> 00:02:45.360
And also there's an the APL challenge, this uh introductory uh course slash competition where you can win some money for learning a little bit of APL and using it.
00:02:45.360 --> 00:02:49.360
Uh it has a round finishing that same day, July 31st.
00:02:49.360 --> 00:03:00.000
Um, then uh a couple of weeks ago we had a uh a workshop internally at uh at Dialog, and it was on using LLMs with APL.
00:03:00.000 --> 00:03:07.599
And uh so we're trying to educate our employees on uh on how to use LLMs uh effectively and safely.
00:03:07.599 --> 00:03:18.960
And there's an interesting blog post that we'll we'll put a link to as well on using APL with LLMs and how to make them do that, uh, then be able to write some sensible APL.
00:03:18.960 --> 00:03:40.240
But out of that came also an old project, something I started uh three and a half years ago, uh, when I was in parental leave and I was holding a baby with one hand, and then I was typing a little bit of JavaScript with uh with the other hand, and I made the bare bones a framework for a game that like a top-down dungeon crawler game that would teach you some APL.
00:03:40.240 --> 00:03:43.280
But I never had a chance to finish it because you know the baby grew up.
00:03:43.280 --> 00:03:52.560
Um and then I figured, well, as an experiment for there's a material for this workshop, I would throw the LLM at it and see if it could finish up the game.
00:03:52.560 --> 00:03:54.159
I think it turned out really well.
00:03:54.159 --> 00:03:58.080
Uh so uh this we'll leave a link to that as well.
00:03:58.400 --> 00:03:58.800
Awesome.
00:03:58.800 --> 00:04:08.240
So links for all four of those things uh will be both in the YouTube description and the podcast show notes uh after I up this update this later.
00:04:08.240 --> 00:04:11.039
And with those out of the way, we're gonna do something a little bit different today.
00:04:11.039 --> 00:04:25.360
So uh because we have our former panelist with us, uh he knows much more about the uh you know K space, and uh we're gonna throw it over to Steven, and Steven's gonna uh lay the groundwork for what we're gonna be talking about today.
00:04:25.360 --> 00:04:28.399
And uh so with that, uh we'll throw it over to you, Stephen.
00:04:29.040 --> 00:04:31.040
Well, let's thank thank you, Connor.
00:04:31.040 --> 00:04:34.639
And let's start by frankly admitting that Alex and I screwed up.
00:04:34.879 --> 00:04:35.279
Uh uh.
00:04:35.600 --> 00:04:40.639
He he and I are both uh romantics about the Q and K languages.
00:04:40.639 --> 00:04:58.079
And when the KX module manager appeared, we announced a meeting at Milden Hall in Suffolk for this September, uh, so that our people could get together and plan and start building uh open source Q packages.
00:04:58.079 --> 00:05:01.439
Uh yeah, that was a romantic vision.
00:05:01.439 --> 00:05:02.879
It was a wonderful idea.
00:05:02.879 --> 00:05:26.079
However, um KDB developers uh turn out to be actually rationalists, and they saw um what was actually quite obvious and what we didn't want to we we didn't really want to admit, which is that the price of KDB licenses restricts the language usage to some very deep corporate silos.
00:05:26.079 --> 00:05:50.399
And those corporate silos had no use for community code resources, and so we got very few registrations and wound up cancelling the meeting, and then something very significant happened, and um our guest today, Jake, did it, um, just I think the week before last, and it changes the landscape.
00:05:50.399 --> 00:06:05.920
And now there's still some kind of a meeting happening in Suffolk in September, it's emerging what it is in real time, but it's starting to look like ground zero for a QK Q open source community.
00:06:05.920 --> 00:06:08.399
Uh we're pretty excited about it.
00:06:08.399 --> 00:06:17.920
I'm not going to spoil I'm not going to um spoil uh what we're gonna learn from Jake, but um uh that's about it.
00:06:17.920 --> 00:06:20.639
Something's something really exciting is happening.
00:06:20.959 --> 00:06:29.360
All right, so with that, I guess we'll throw it over to to Jake, and you can tell us uh about everything you've been working on and uh what you released uh just in the last little bit.
00:06:29.759 --> 00:06:30.639
Oh sure.
00:06:30.639 --> 00:06:33.920
Um so yeah, so like I said, my name is Jake Lopas.
00:06:33.920 --> 00:06:46.319
Um I've been I've been a K programmer since um probably very early 2000s, maybe 2000, maybe 2000, 2001, at a company called Appian.
00:06:46.319 --> 00:07:04.079
And then I um did that, worked for DOD, then I went to Wall Street, was on Wall Street for a very long time, and then I left um a little more than 10 years ago, and I was on Garden Leave, which I think is a very kind of garden leave is fantastic.
00:07:04.399 --> 00:07:05.120
It is fantastic.
00:07:05.120 --> 00:07:09.040
I I've never been on it, but when I hear people are on it, I was like, the first time I heard about it, I was like, what?
00:07:09.120 --> 00:07:13.759
You're getting paid to do you're getting getting paid not to work anywhere else.
00:07:13.759 --> 00:07:15.920
You're actually getting paid to work in your garden.
00:07:15.920 --> 00:07:29.199
And um, and while while I was on garden leave, I was I started a project um to basically go rebuild um the kind of a K4 and a Q interpreter.
00:07:29.199 --> 00:07:31.920
And uh I called that L.
00:07:31.920 --> 00:07:46.879
And so um, and there had been kind of different versions of that all along the way, but about maybe a month ago, uh got to the point where I was like, hey, let's actually like post this out to the community, see if anybody else wants to play with it.
00:07:46.879 --> 00:07:52.480
Um so it's so L is a K4 compatible, Q compatible.
00:07:52.480 --> 00:08:02.399
Its goal is to be a drop-in replacement so that you can take kind of KDB style workloads and run it, you know, anywhere, right?
00:08:02.399 --> 00:08:14.639
You don't need uh all of the kind of as Stephen said, you know, can we can we kind of take this language and bring it to a larger community in a runtime that you know anybody can run?
00:08:14.639 --> 00:08:27.920
Um and so it was a really small group of people on uh basically a Discord server, and uh then we put up a website and then it got uh uh pretty pretty big pretty quickly.
00:08:27.920 --> 00:08:32.480
So I think we had like in the first two days, the website got discovered.
00:08:32.480 --> 00:08:36.399
Um it's like 48,000 people came to the website.
00:08:36.399 --> 00:08:45.360
We had over 300 downloads of the binary, so which is a good thing the binary is small, uh, because family small.
00:08:45.360 --> 00:08:57.600
So yeah, so that's that's the the thing that has kind of come out here, I'd say, in the last 30 days has been um people downloading the L interpreter, running K4 and Q code.
00:08:57.600 --> 00:09:10.320
Um for me it's really exciting to see not just you know everybody that that kind of I know in this community, but brand new people coming from completely different backgrounds.
00:09:10.320 --> 00:09:20.720
Um like I had somebody last week who emailed to the list group and they were working on telemetry data for um effectively cars.
00:09:20.720 --> 00:09:29.440
I had somebody who emailed that was working on um like biogenomics um and saying, hey, you know, can I use this for this?
00:09:29.440 --> 00:09:31.679
And I was like, yes, it'll be great for that.
00:09:31.679 --> 00:09:37.840
You know, let's talk about you know how do you restructure these kind of problems in an array-oriented thing.
00:09:37.840 --> 00:09:43.440
And um, by the way, it turns out that that KK and Q just absolutely crush for that kind of workload.
00:09:43.440 --> 00:09:49.600
Um at uh we built a rag, uh, which is one of these AI vector search things.
00:09:49.600 --> 00:09:54.960
It was like 20 lines, um, and really, really, really fast.
00:09:54.960 --> 00:09:57.600
So yeah, so that's that's what it is.
00:09:57.600 --> 00:10:06.960
And and it's got a public website, it's at lv1.sh uh because you needed a a short domain, um, and that's as short as I could get it.
00:10:06.960 --> 00:10:10.960
So yeah, that's that's the big big out there in the open.
00:10:11.200 --> 00:10:12.639
Yeah, so it's uh very exciting.
00:10:12.639 --> 00:10:18.080
I did see, I think I saw it first on uh the APL JK Reddit.
00:10:18.080 --> 00:10:19.679
It was posted there by someone.
00:10:19.679 --> 00:10:21.200
And uh very exciting.
00:10:21.200 --> 00:10:30.320
But I so I guess the I mean there's a number of things we could talk about first, but uh probably notable um is the differences, like the runtime differences.
00:10:30.320 --> 00:10:54.080
So do you want to talk about what L offers that uh you know the previous interpreters like because they're and they're not exactly like it's a drop-in replacement from like a what do you call it, language level point of view, but from a runtime point of view, uh there are some differences, which I'm sure uh people listeners of this podcast who are you know programmers, some are maybe not programmers and just curious, but uh I'm sure a lot of the listeners would be curious to hear those differences.
00:10:54.320 --> 00:11:02.559
Yeah, I mean I it it needed to be um language compatible because you know, frankly, I have 20 years of code.
00:11:02.559 --> 00:11:04.480
I didn't want to rewrite.
00:11:04.480 --> 00:11:11.840
Um that said, I I did want to go experiment with you know kind of new ideas under the cover.
00:11:11.840 --> 00:11:22.000
And I and I think the big ones are um, well, the first one, which is pretty straightforward, um, is just SIMD, right?
00:11:22.000 --> 00:11:26.879
You you you want to actually get every cycle out of the chip that you can.
00:11:26.879 --> 00:11:35.200
Um so take all of your primitives, um, you know, sit very quietly and make sure that you can implement SIMD versions of that.
00:11:35.200 --> 00:11:39.039
Uh then once you have that, I wanted auto threading.
00:11:39.039 --> 00:11:46.559
So uh K4 had a concept of uh peach, of parallel each, um, which is wonderful.
00:11:46.559 --> 00:11:49.919
But I you know, it kind of changes the code.
00:11:49.919 --> 00:12:05.440
So I wanted like um, you know, like a reduction like sum or something like that to actually automatically thread over the array and you know, kind of do that that map reduce concept, but do it completely transparently.
00:12:05.600 --> 00:12:11.600
Um does uh K not have any guarantees of stability of results like that?
00:12:11.759 --> 00:12:13.759
Or with regards to floating point?
00:12:14.240 --> 00:12:14.639
Of what?
00:12:14.639 --> 00:12:15.679
Yeah, floating point, yes.
00:12:16.320 --> 00:12:16.639
Yeah.
00:12:16.639 --> 00:12:20.399
Um I don't really know what Kd B has.
00:12:20.399 --> 00:12:29.279
Um L's floating point is there's effectively a like a comparison tolerance that that comes out.
00:12:29.279 --> 00:12:35.759
And yeah, if you sum them in different directions, obviously you would get different values.
00:12:35.759 --> 00:12:45.519
So um so the reductions are are taken in chunks, but the comparison tolerance is uh I think it's it's 18 to the negative 17.
00:12:45.519 --> 00:12:55.919
So it's yeah, as you get far enough out there, um, you can get different answers, but kind of the interpreter itself hides that comparative comparison tolerance at a at a certain level.
00:12:55.919 --> 00:12:57.519
Did that that answer your question?
00:12:57.519 --> 00:13:08.559
You get the same answer every time, um, but it because you are paralyzing and reducing reducers, right?
00:13:08.559 --> 00:13:12.399
You you can if you would get something different than if you were seriously just walking.
00:13:12.399 --> 00:13:13.120
Yeah, yeah.
00:13:13.120 --> 00:13:19.039
Yeah, just like you would get something different if you reversed it and walked through it.
00:13:19.200 --> 00:13:21.840
Yeah, and we I'm asking because we have this problem with dialogue.
00:13:21.840 --> 00:13:32.000
Our summation code and interpreter was written pre-SIMD, and uh and now we can't change it because we we our customers want stability.
00:13:32.000 --> 00:13:37.440
You don't want the amount of money in people's bank accounts to change because we changed the summation algorithm.
00:13:37.440 --> 00:13:42.799
And uh yeah, you might ask why people are using floats for money, they are like well.
00:13:42.960 --> 00:13:49.840
I I think well, if you use if you use floats for money, you should really think very carefully about where your life went wrong.
00:13:49.840 --> 00:13:55.679
But um that that is actually kind of a good segue to last thing.
00:13:55.679 --> 00:14:20.960
So the last thing was this idea of I mean, I call it compression because I can't think of another more elegant way to explain it, but can you take quantitization is maybe another way to say it, but basically, can you can you take this array and can you store it in a different format that allows you to work on smaller uh memory footprints?
00:14:20.960 --> 00:14:29.360
So can you can you change underneath the covers, can you change, can you compress that array into another format?
00:14:29.360 --> 00:14:32.720
And then most importantly, can you work on that compressed device?
00:14:32.720 --> 00:14:40.000
Can you can you make all of the array operators, can you make all of the verbs and adverbs work on what I call computer and compressor?
00:14:40.000 --> 00:14:42.159
Lots of people call it computer and compressed.
00:14:42.159 --> 00:14:52.559
Um and when you do that, you could do something like if you are storing money as floats, like behind the covers, L doesn't store that as a float.
00:14:52.559 --> 00:15:06.559
L actually goes ahead and promotes that into an int, um, and then kind of does this very clever little trick underneath the covers um to allow you to operate in the int space and then gives it back to you in in the floating point space, um, or the real space, depending on.
00:15:06.559 --> 00:15:22.240
So um so those three things, kind of the the SIM D, the auto-parallelization, which is different than SIM D, um, and the compression, those are probably the three giant pillars that are really fundamentally different.
00:15:22.240 --> 00:15:26.960
I mean, compression, compression, I started doing compression a couple years ago.
00:15:26.960 --> 00:15:34.399
And it was uh it was enough of a performance improvement that I actually had to delete everything and start over.
00:15:34.399 --> 00:15:39.919
Um, because you basically changed the entire uh representation of the object.
00:15:39.919 --> 00:15:44.639
But it turns out that that is the unlock from a performance standpoint.
00:15:44.639 --> 00:15:53.679
Um, you can really only make these things go so fast in SIMD, you can only make them go so fast, you know, across multiple cores.
00:15:53.679 --> 00:15:57.200
The I mean, bandwidth, memory bandwidth is the enemy.
00:15:57.200 --> 00:16:02.159
So you know, I say this all the time, but making things go faster is actually pretty simple.
00:16:02.159 --> 00:16:07.039
You just move less data over a shorter distance using a more efficient protocol.
00:16:07.039 --> 00:16:14.559
So um if you can take that array and move it into a smaller type, um, you can move less data.
00:16:14.559 --> 00:16:22.879
You know, you have to be very cognizant of making sure that where that array is relative to the core that it's going to operate on, that's your shorter distance.
00:16:22.879 --> 00:16:29.200
And you know, really the protocol you can think about as the actual operation, the CIMD operation underneath the covers.
00:16:29.200 --> 00:16:33.679
So those those are kind of the three crazy, crazy ideas.
00:16:33.840 --> 00:16:35.759
Um doesn't sound very crazy.
00:16:35.759 --> 00:16:37.519
I misunderstood when I was reading up on this.
00:16:37.519 --> 00:16:41.919
I thought by compression you actually like compressed data as in zipping it, but it's not.
00:16:41.919 --> 00:16:43.840
You're just talking about using data types.
00:16:44.159 --> 00:16:47.840
Yeah, dictionary compression is a really I I don't think really helpful.
00:16:47.840 --> 00:16:50.480
Um, because you can't really operate it on it.
00:16:50.480 --> 00:16:52.480
You can't really operate on it.
00:16:52.559 --> 00:17:07.279
I I think well you you could like let's say you had a matrix stored as as some vectors and it was fairly sparse, and you actually compressed each row separately, and then you want to reverse the order of the matrix, this you can do without decompressing the components, right?
00:17:07.279 --> 00:17:14.640
So I that's that was the idea I got when you when I heard about like compression, it's like, well, how in the world do you write algorithms to operate on the compressed data?
00:17:14.640 --> 00:17:23.920
But if you just mean data types that are more of more dense for the data that's actually there, then that's pretty regular fair for array languages.
00:17:23.920 --> 00:17:27.759
I I thought that every serious array language already did this.
00:17:27.759 --> 00:17:35.039
And if obviously you can't tell me about the source code at uh of of official KQ, KDB.
00:17:35.039 --> 00:17:40.559
Um I would I assume that that was happening underneath the cover there as well.
00:17:40.799 --> 00:17:51.920
Well, well, I think in a like like let's take a simple example, probably the the easiest codec that there is to kind of you can kind of almost see it in your mind is the the frame of reference, right?
00:17:51.920 --> 00:18:00.079
So imagine you've got um, you know, I don't know, 255 plus till a thousand, all right?
00:18:00.079 --> 00:18:02.640
Or 255 plus iota a thousand.
00:18:02.640 --> 00:18:06.960
Um so now you've got this big array of 32-bit integers.
00:18:06.960 --> 00:18:10.880
Um frame of reference basically says find a minimum, right?
00:18:10.880 --> 00:18:15.200
Store that offset as the base, remove that from everything else.
00:18:15.200 --> 00:18:20.720
And then the question is now you've got a base, and then you've got a payload, right?
00:18:20.720 --> 00:18:24.000
You've removed the base from the array, and now you've got a payload.
00:18:24.000 --> 00:18:30.240
Is there a bit width that can represent that payload smaller than the original bit width?
00:18:30.240 --> 00:18:36.160
And um, and it turns out that the answer is yes, that happens like all the time, right?
00:18:36.160 --> 00:18:43.599
You can, you know, you might have an array of 32-bit integers that you can represent as you know, as a short.
00:18:43.599 --> 00:18:54.799
Um or you know, if you kind of take frame of reference and apply delta on top of it, you might actually be able to get that down to four bits, right?
00:18:54.799 --> 00:19:15.039
So, and you know what's really nice about frame of reference, aside from the fact that it's kind of easy to see in your mind, is if you make everything do that from the beginning, then you kind of get these free little performance wins just by the structure of that.
00:19:15.039 --> 00:19:21.759
So, uh to give you an example, let's say you wanted to add an atom to that array, right?
00:19:21.759 --> 00:19:25.119
Well, obviously there's no reason to do that element-wise.
00:19:25.119 --> 00:19:29.519
If you're going to add the atom to every single value of the array, you would just add it to the base.
00:19:29.519 --> 00:19:33.680
Um so these kind of operations become faster.
00:19:33.680 --> 00:19:46.400
Um, also, when you when you kind of sweep to go do the bit width calculation, you're gonna get some pretty useful metadata that's gonna fall out for free that you might want to actually stamp on the object, right?
00:19:46.400 --> 00:19:50.400
So um you you know, certainly you're gonna get the range, right?
00:19:50.400 --> 00:20:01.519
Um, and again, as you kind of do this consistently, what you start to find is you know the performance wins stack up like a lot.
00:20:01.680 --> 00:20:03.039
Yeah, I understand a lot a lot.
00:20:03.039 --> 00:20:06.000
So it's it's I just I just remembered now.
00:20:06.000 --> 00:20:16.480
What I what I understand from you is uh is that you're doing this aggressively, you're doing every basically taking every data type that exists, uh, and and and trying to combine.
00:20:16.480 --> 00:20:23.759
So I I I know array languages traditionally do things like this, but they tend to restrict themselves to a few types rather than every possible type.
00:20:24.640 --> 00:20:27.039
Anything worth doing is worth overdoing.
00:20:27.039 --> 00:20:29.359
Um so yeah, it happens.
00:20:29.920 --> 00:20:41.680
There was a uh there was a talk by Simon Garland that spoke about differences in uh in how in the implementation of of KQ and APL.
00:20:41.680 --> 00:20:46.640
And he said that there were uh APL traditionally has bit booleans, right?
00:20:46.640 --> 00:21:03.759
But that requires a lot of fancy uh bit flipping work to to make all your algorithms work, but it does create a huge difference in in performance because I mean at worst, an eighth of the uh of the data going across.
00:21:05.440 --> 00:21:16.640
But then when you want to do something like you know, get the average of a Boolean array um to give you like a probability, then you know, then you have to kind of start going the other way.
00:21:16.960 --> 00:21:24.559
Well you don't have to put you uh explode it up to to bytes because you could in the inter the the processor has pop counts, right?
00:21:24.559 --> 00:21:24.960
Yep.
00:21:24.960 --> 00:21:35.279
So there so there are lots and lots of fancy tricks you can do, and then and then the processors have like APL functions like expand and compress and things like that.
00:21:35.279 --> 00:21:37.359
Uh and that that they can they can do.
00:21:37.359 --> 00:21:40.079
But remember, he spoke about that's where I want to get here.
00:21:40.079 --> 00:21:49.039
He spoke about the changes or the the differences in how you design the language based on how it's implemented.
00:21:49.039 --> 00:22:20.799
And I thought that was really interesting that because K doesn't have bit booleans, there's no point in having a primitive built in verb, whatever you want to call it, uh Of compress rather you just use indexing with a where right so you convert the Boolean to indices, and then at that point it it you lose a lot of uh of the length because all the zeros go away, and you're not you at least if it's shorter than 256, uh then then it's not going to blow up the type for the indices being there.
00:22:20.799 --> 00:22:24.559
Everything is every element, every Boolean is one byte, so it doesn't make a difference.
00:22:24.559 --> 00:22:30.400
And and so you don't need a compressed function, therefore k doesn't have a compressed function, it just uses indexing wheelware.
00:22:30.400 --> 00:22:40.559
Whereas APL that does have bit booleans, does have compressed, and it's a huge waste to blow up a Boolean that's already packed to uh integers before you do that.
00:22:40.559 --> 00:22:42.559
So now here's the kicker then.
00:22:42.559 --> 00:22:55.200
If you aggressively pursue all these internal representations, such that yeah, I'm sure you do have bit booleans, then and but isn't the language then like doesn't it fight you in that way?
00:22:55.200 --> 00:23:03.279
That it that you it for the the way people write the code forces you to blow up your your beautiful bit booleans to ugly big integers.
00:23:04.079 --> 00:23:15.200
Yeah, and so you are describing essentially the three-year nightmare of stepping back and saying, Okay, all right, this works.
00:23:15.200 --> 00:23:25.680
What of these what of these verbs and adverbs do I need basically result in um in materializing?
00:23:25.680 --> 00:23:35.359
And then you just sit there very quietly with a giant yellow notebook and um and you knock them all out.
00:23:35.359 --> 00:23:38.720
And um you can't knock all of them out.
00:23:38.720 --> 00:23:45.680
Um so like some of the transcendentals, obviously, you do just because of kind of the nature of that, you do need to materialize them.
00:23:45.680 --> 00:23:50.640
But then then you start thinking about well, do I need to materialize the whole array?
00:23:50.640 --> 00:24:00.880
Or do I only need to materialize, you know, so I can move the array in into the cache line, but then when I'm doing the operation, I have to do a small materialization.
00:24:00.880 --> 00:24:04.960
I can uh you know, maybe store that in a scratch offset.
00:24:04.960 --> 00:24:08.319
Can I can I still save some memory bandwidth moving over?
00:24:08.319 --> 00:24:14.960
So the ideal scenario is um, you know, kind of a closed form of computer compressed.
00:24:14.960 --> 00:24:17.200
You want to get all of those that you can.
00:24:17.200 --> 00:24:34.960
And then, you know, worst case scenario, you want to get to to kind of a partial form of computer compressed, where you're like, all right, well, at least I'm gonna move this small, this, this much smaller thing over the memory bandwidth, but then I I am actually gonna have to work, kind of uh, you know, allocate a little space on the stack.
00:24:34.960 --> 00:24:38.960
I'm gonna have to explode this thing up and do a little bit of work and take it chunk by chunk.
00:24:38.960 --> 00:24:58.079
But um, yeah, Adam, I actually have a like a grid of all of the verbs, and I can I don't I don't know if I have it in front of me, but I can send it to you where it's got all the verbs, and you can and you can see kind of over time where it goes from basically red where you had to materialize to green where it uh where it operates compute on compressed.
00:24:58.240 --> 00:25:06.720
Um so so you're saying okay, so you're also aggressively using things like arithmetic progression vectors for the for things like indices.
00:25:06.720 --> 00:25:08.240
So they stay small.
00:25:08.240 --> 00:25:11.920
Yeah, but do do you also I don't know if it's a universal term or something?
00:25:11.920 --> 00:25:29.759
There's something at least in the in some area, some people use the term thunks, where the where the language does not actually evaluate some code, but rather remembers that this verb needs to be uh applied to this noun, but doesn't do it until necessary.
00:25:29.759 --> 00:25:32.400
So for example, you you you could do that.
00:25:32.400 --> 00:25:37.839
Let if somebody does a where on a boolean in order to index, then you wouldn't do the where on the boolean.
00:25:37.839 --> 00:25:49.359
You would remember that this where needs to be applied on this array, and then when you get to the index indexing, then the interpreter goes, Oh, wait a minute, indexing on something where where needs to be applied on a Boolean.
00:25:49.359 --> 00:25:51.119
I know this, that's just a replicate.
00:25:51.119 --> 00:25:58.480
So then it goes in and directly takes the Booleans and does the filtering and skips the whole materialization of the indices.
00:25:58.799 --> 00:26:04.720
Yeah, there's no kind of delayed compute there, but or at least not in L.
00:26:04.720 --> 00:26:05.440
Yet.
00:26:05.440 --> 00:26:08.160
But it does have a concept of fusion.
00:26:08.160 --> 00:26:14.240
Um so fusion, uh, you know, fusion I think is a really loaded term.
00:26:14.240 --> 00:26:17.200
Um uh Rick Sony works with this on me.
00:26:17.200 --> 00:26:20.480
Is so fusion means different things with different people.
00:26:20.480 --> 00:26:25.920
So for the easy case, it basically means no intermediates, right?
00:26:25.920 --> 00:26:41.119
So if I um, you know, if I do whatever some square root x, right, can I can I do this without creating intermediates, or better yet, would be like a chain of functions where it's you know array uh where the output is array, array, array.
00:26:41.359 --> 00:26:44.799
If you if you do two plus three times times an array, right?
00:26:44.799 --> 00:26:51.279
So then then since you need to loop over the array to do the the three times, you might as well do two plus three on each one separately.
00:26:51.599 --> 00:26:55.119
Yeah, and then like then you just hate yourself.
00:26:55.359 --> 00:26:58.720
Um so but how do you do that without being lazy?
00:26:59.119 --> 00:27:10.640
Yeah, so essentially underneath the covers, um every array you can you can borrow basically you can think about it almost like copy on right.
00:27:10.640 --> 00:27:27.839
Um so when an input comes in, it it can be uh kind of borrowed, which means you can mutate it, or it's you know, it's effectively you're operating on a copy, and then you can just mutate the intermediates, and then you don't um then you don't really have those intermediates.
00:27:27.839 --> 00:27:28.720
You know what I'm saying?
00:27:28.720 --> 00:27:38.960
You're not you you're kind of working directly, you're literally mutating the the input comes in and it's like, hey, this is safe to mutate, you do square root on it, mutate it in place.
00:27:38.960 --> 00:27:40.160
Oh, right.
00:27:40.240 --> 00:27:43.279
You you mean you're having a you have a ref count on the arrays, right?
00:27:43.279 --> 00:27:46.000
If the ref count is one, you know you can do it in place with it.
00:27:46.240 --> 00:27:46.640
Yep.
00:27:46.640 --> 00:27:50.640
Um and you kind of have to do that way up in the beginning.
00:27:50.640 --> 00:28:07.279
And then that's the other concept of fusion is this idea of hey, we're going to, you know, if we detect, and there's the this is done in L, like I think it's done pretty much everywhere else, which is just basically with uh kind of a table of known operators.
00:28:07.279 --> 00:28:17.039
But um, if you see this, you know, kind of bytecode type, you this structure of bytecode, let's go ahead and replace it with this other function, right?
00:28:17.039 --> 00:28:22.559
So um and and L does that in its fuse.c implementation.
00:28:22.559 --> 00:28:28.079
So it it uses actually it looks very similar to LuaJet from uh Mike Paul's.
00:28:28.079 --> 00:28:38.400
So it kind of looks at the bytecode and goes, aha, you're doing um, you know, you're doing where, you know, where array greater than x.
00:28:38.400 --> 00:28:39.839
Um okay.
00:28:39.839 --> 00:28:46.480
Uh there's actually a different kernel for this that we're gonna we're just I'm just gonna like swap out that byte code and replace it with this other one.
00:28:46.480 --> 00:28:47.759
It's gonna be a lot faster.
00:28:47.839 --> 00:28:59.839
Uh but again, if you do where arrays greater than x, I mean if you're just naively executing this this code, then you see the the comparison, you do the comparison, then you get to the where.
00:28:59.839 --> 00:29:04.480
Surely there must be some amount of laziness for it to even recognize the pattern.
00:29:04.480 --> 00:29:06.799
There's there's no laziness.
00:29:06.880 --> 00:29:11.039
It will actually Rick and I talk about working vertically versus horizontally.
00:29:11.039 --> 00:29:27.759
So you might want to, under certain operations, instead of doing uh the whole vector A, then the whole vector B, then the whole vector C, you actually might want to flip it on its side and do, you know, operator, operator, operator, operator, operator, operator operator.
00:29:27.759 --> 00:29:28.480
Yeah, mate.
00:29:28.480 --> 00:29:29.519
That's the fusion meaning.
00:29:29.519 --> 00:29:30.160
Yep.
00:29:30.160 --> 00:29:32.960
And so um we'll swap that out.
00:29:33.039 --> 00:29:39.279
That that little bit will swap out um so the interpreter reads ahead of what's going, what's coming?
00:29:39.359 --> 00:29:41.440
That's how it's well it just looks at the bytecode.
00:29:41.440 --> 00:29:44.400
So um when you write when you write the function, right?
00:29:44.400 --> 00:29:46.160
You write foo, whatever.
00:29:46.480 --> 00:29:47.759
That gives you the bytecode.
00:29:48.079 --> 00:29:54.079
Yeah, and then when the thing goes to the generating the bytecode, it's like, okay, I've made this bytecode just the way you asked.
00:29:54.160 --> 00:29:56.240
And then people I think I think I think you get it.
00:29:56.400 --> 00:30:00.799
Okay, so you so there's a it's not as complex as as as as well.
00:30:00.799 --> 00:30:01.359
No, no, no.
00:30:01.359 --> 00:30:02.079
I think we get it there.
00:30:02.240 --> 00:30:05.839
So there's a it's sort of like halfway halfway compiled, right?
00:30:05.839 --> 00:30:08.960
Then the interpreter goes through, take, takes the code, converts it.
00:30:08.960 --> 00:30:18.480
I suppose it builds some some AST internally for the function that that these and then it recognizes parts that the branches on the tree, and then says, Oh, I know this tree, this tree branch.
00:30:18.480 --> 00:30:20.079
Let's change that to something else.
00:30:20.079 --> 00:30:22.640
There you have an advantage we can't do in a dialogue.
00:30:22.640 --> 00:30:25.359
Yeah, because we're not statically parsable.
00:30:26.000 --> 00:30:31.200
That's actually how I mean it unfortunately it does have to do it in a two past, but it doesn't really matter.
00:30:31.200 --> 00:30:45.200
Um but yeah, it's that's how my call does kind of legit in in a lot of ways, is kind of looking at the intermediate representation, and that's where the that that's where the swap out happens.
00:30:45.200 --> 00:30:49.599
So I, you know, and I think that's kind of the fun part.
00:30:49.599 --> 00:30:58.400
It's nice to have the restriction of this this code must run this language standard, and you're like, but I want to do this.
00:30:58.400 --> 00:31:04.799
And it's like, all right, well then you have to you have to do it without changing that code or changing that language, right?
00:31:04.799 --> 00:31:28.079
So um, so you know, fuse.c, which kind of does that walk over the over the interpreter, over the bytecode, or you know, the actual object storage, where it's like, I'm giving you an array of dates, and it's like, okay, I'm I'm gonna tell you it's an array of dates, but I'm definitely not gonna store it like that, and I'm not gonna operate on it like that.
00:31:28.079 --> 00:31:34.480
Um and so I think you know, these little things, they I mean, they stack up.
00:31:34.480 --> 00:31:37.279
Um, I've I've gotten reports in the field.
00:31:37.279 --> 00:31:45.920
I think the the worst report I have from the field is that it's six times faster, and some of the best reports are just insane.
00:31:45.920 --> 00:31:49.279
But um again, there's no magic trick here.
00:31:49.279 --> 00:31:58.559
It's just there are some there are some places where you would probably want to change the language, although I'm nowhere near smart enough to write a better language.
00:31:58.559 --> 00:32:05.039
So instead, you just go, okay, well, I know that this combination of operators is more efficiently done this other way.
00:32:05.039 --> 00:32:07.359
And so I'm gonna put that in my fusion table.
00:32:07.359 --> 00:32:10.400
And then if I see that bytecode, I'm just gonna swap it out with this one.
00:32:10.640 --> 00:32:15.279
Um so if I understand correct, this is super um, super fascinating.
00:32:15.279 --> 00:32:26.160
Uh and it was interesting too when you were listing off like the major three things, you left out the fusion, uh, which I was like, wow, like if fusion doesn't fusion doesn't even make the top three, like that's uh that's pretty crazy.
00:32:26.160 --> 00:32:28.880
Um go ahead.
00:32:28.880 --> 00:32:29.599
Yeah, yeah, four.
00:32:29.599 --> 00:32:41.599
Um if my understanding is correct, then so uh with the ref count um basically reference counting, you avoid like the unnecessary allocations, which is like the biggest win.
00:32:41.599 --> 00:32:53.680
So does but does that mean that the like the luogit, not that that's what we're calling it, but you know, the that kind of mechanism that's doing that fusion, if that doesn't have uh uh you know a pattern recognition for a certain thing, yeah.
00:32:53.680 --> 00:33:08.160
Is it is it then like so say in the example that Adam had where it was you know plus X, you know, times Y or whatever, if it if it didn't, I'm sure it does have uh you know uh uh recognizes that and then replaces the the bytecode.
00:33:08.160 --> 00:33:15.839
But if it didn't, does that mean that you'll avoid the allocations, but you might end up iterating still the number of times the operations?
00:33:15.839 --> 00:33:29.119
So but like you basically there's two pieces you can expect to avoid allocations because of the reference counting, and then the uh the bytecode uh pattern recognition or whatever you want to call it, um, that's the one that like fuses the operations.
00:33:29.119 --> 00:33:30.559
So it's kind of like two pieces.
00:33:30.559 --> 00:33:36.880
You can get you guaranteed like your reference counting if it's one, you'll get that piece, and then it's just a matter of uh it recognizing.
00:33:36.880 --> 00:33:57.200
I mean, that's very and on top of honestly, I had never not to switch completely topics while I'm talking, I'd never heard of this uh because Adam says, Oh, you know, I think most languages, I had never heard of this kind of like separating or like compressing uh data into a smaller bit width by like basically storing a component of it.
00:33:57.200 --> 00:34:06.880
And then like it's very it's I don't know, it sounds novel to me because I've never thought about this, but then when you were like, oh, you know, if you just add a number, you can just do it to the base, and I was like, that's crazy.
00:34:06.880 --> 00:34:11.440
Like you you turn what, even if you're gonna use fusion, like because that's typically the way I would solve that, right?
00:34:11.440 --> 00:34:16.880
Like there's a an array language called cap um that is implemented in Kotlin and it's a lazy APL.
00:34:16.880 --> 00:34:21.360
So if you do a plus one or a plus X, it just it'll defer, it won't do it.
00:34:21.360 --> 00:34:28.320
So you you know, you're you're not gonna pay like a linear time for that operation, it'll just bundle it with whatever it needs to down the road.
00:34:28.320 --> 00:34:32.000
But in your implementation, it's just an O one operation, like who cares?
00:34:32.000 --> 00:34:47.920
Um and like that then my my my my my brain is like how many different cases like are there like you know uh tricks like that where you can turn you don't even need to fuse anything, like you can turn what would be an ON operation into just like a constant time thing.
00:34:47.920 --> 00:34:53.280
Um and Adam, you said like like this is classic, like this is a lot of interpreters do this kind of thing.
00:34:53.280 --> 00:34:54.000
Like, I don't know.
00:34:54.239 --> 00:34:59.039
So in APL land, I it for commercial, like a real APL implementation.
00:34:59.039 --> 00:35:02.239
I think it's unheard of to not do um type.
00:35:02.239 --> 00:35:04.079
So this doesn't have a name though.
00:35:04.079 --> 00:35:05.199
That's the thing, like Jacob.
00:35:05.199 --> 00:35:10.400
You you were saying that we call it squeeze internally, but the APL never ex sees this, right?
00:35:10.400 --> 00:35:18.800
You don't you can't it's not directly observable unless the vendor puts something into the language that lets you observe under the covers.
00:35:18.800 --> 00:35:19.679
So we have something.
00:35:19.679 --> 00:35:20.719
Like we're at dialogue.
00:35:20.719 --> 00:35:35.599
I can show you that dialogue has something called quad dr data representation, and it will tell you uh the what the internal representation is, how many bits per element and what type uh it is.
00:35:35.599 --> 00:35:41.280
And you can see that if you uh if you give it a one, if you give it one Boolean, you will say it's a byte.
00:35:41.280 --> 00:35:44.639
It doesn't bother to make it a bit because you're not gonna save anything.
00:35:44.639 --> 00:35:49.920
If you then connect that, make a vector of two bits, then it will squeeze it down to a single byte.
00:35:49.920 --> 00:35:56.800
And it's just using it has a length field, so it just says, okay, only the first two bits of this byte are actually the data that we're using right away.
00:35:56.800 --> 00:35:58.800
You cannot really stop it from doing that.
00:35:58.800 --> 00:36:08.000
Uh I mean you can, you can you can tell the interpreter don't don't squeeze this array, but it's not gonna stay forever, it will only be as until it finds that it's convenient to do it anyway.
00:36:08.000 --> 00:36:11.360
Um, and it yeah, it's aggressive, it does it all the time.
00:36:11.360 --> 00:36:16.639
And even though there's so many checks for every operation, do another check, what can we now squeeze?
00:36:16.639 --> 00:36:18.239
It it sure saves time.
00:36:18.239 --> 00:36:20.800
It would be unbearably slow if if you didn't do this.
00:36:20.800 --> 00:36:26.320
And the bit bit Boolean algorithms are are super optimized for do all kinds of crazy things.
00:36:26.639 --> 00:36:27.119
Did you say Jake?
00:36:27.119 --> 00:36:31.119
That because you it sounds like you've well, I mean, I guess you didn't come up with this idea.
00:36:31.119 --> 00:36:36.239
I mean, I'm hearing about it for the first time today, but apparently lots of folks know about this you know for decades.
00:36:36.239 --> 00:36:40.239
But like you've taken this idea, pushed it to like you know 110%.
00:36:40.239 --> 00:36:48.000
And um would you say like of the four different things, this is what gets you the the largest percentage of the game?
00:36:48.000 --> 00:36:53.599
Like because you're saying you basically went back and rewrote you know most of the language, if not all of it, because of this.
00:36:53.840 --> 00:37:10.400
Um that's really interesting too that that that's the main thing because if we I can tell you in dialogue has bit booleans, and then it has got one, two, and four-byte integers, and then we've got uh 64-bit floats, and and we have a crazy uh decimal uh 128-bit flows.
00:37:10.400 --> 00:37:17.199
We've got some two times 64-bit uh float complex numbers, and and even for characters we do this.
00:37:17.199 --> 00:37:21.039
So even text data will be the one, two, or four-byte uh per character.
00:37:21.039 --> 00:37:25.599
If you're writing ancient Chinese text, you think you're gonna end up with four bytes per character.
00:37:25.599 --> 00:37:30.239
Um, I know that APL plus only has a single integer type.
00:37:30.239 --> 00:37:43.519
It does do bit booleans, I think every APL does, um but then it just goes up to a full uh I don't know if it's 64-bit or 32-bit integer type, and then uh and then they have floats.
00:37:43.519 --> 00:37:49.199
Um and yeah, I didn't know that being so aggressive about the types would make such a big difference.
00:37:49.199 --> 00:37:57.039
I knew that it does make a difference to have this sort of thing, but certainly we don't do uh two-bit integers and four-bit integers.
00:37:57.440 --> 00:38:00.639
Oh yeah, it makes all the difference in the world.
00:38:00.639 --> 00:38:16.480
Because the you know, I think the thing that is different today than you know, whatever, 20 years ago, more than 20 years ago when Arthur did uh K is the the CPUs are fast, but it's the memory that's slow.
00:38:16.719 --> 00:38:19.440
Yeah, yeah, that that's that's well recognized.
00:38:19.679 --> 00:38:26.880
Yeah, and it's it's I mean the memory bandwidth is just fighting you everywhere along the path.
00:38:26.880 --> 00:38:31.440
And so, you know, again, you just you gotta just move less data.
00:38:32.159 --> 00:38:44.239
So for all the mathematical verbs, yeah, they are there libraries out there for like four-bit integer multiplication things like that because it's it's going to be a crazy mess.
00:38:44.800 --> 00:38:45.760
Yeah, it's a mess.
00:38:46.159 --> 00:38:47.519
Yeah, it takes years, yeah.
00:38:47.519 --> 00:38:54.400
Like, yeah, because either either you blow up every time you do something, you blow up to then you might as well not store it like that if you're not changing up an hour.
00:38:54.400 --> 00:39:02.239
So you have to you have to do have to stay at your type and still do multiplications at every width and additions, and uh etc.
00:39:02.239 --> 00:39:02.800
etc.
00:39:02.800 --> 00:39:04.559
That's yeah, uh huh.
00:39:04.559 --> 00:39:13.199
No, you have to some people described uh array languages and ascribed it for AP described for APL but it would be the same across the mole, that they're sort of like code libraries.
00:39:13.199 --> 00:39:26.719
You have some people, very clever people, working for many, many years to write all kinds of extreme algorithms for doing things well, and then you just use a simple symbol, a glyph, and you get all that hard work.
00:39:26.960 --> 00:39:44.320
Yeah, and there, I mean, there are some libraries that do things like um kind of fixed point arithmetic, and um uh there's a there's a GNU library that's you know kind of really good about uh but I mean at the end of the day, uh none of that stuff really helped.
00:39:44.320 --> 00:39:50.159
Um papers help, but you know, eventually you gotta roll up your sleeves and just do the implementation.
00:39:50.159 --> 00:39:58.800
And the trick is since you can't change the language, um you have to think about making the codec uh standard, right?
00:39:58.800 --> 00:40:08.239
So even though there's a bunch of codec under the under the covers, they all effectively share this concept of like a base and a payload and then a patch.
00:40:08.239 --> 00:40:11.280
Um you don't need a patch for frame of reference.
00:40:11.280 --> 00:40:18.320
But um yeah, you can you can I I will get you the HDML document and you can see what's left.
00:40:18.320 --> 00:40:20.960
Uh I think the only ones that are really left are the transcendentals.
00:40:20.960 --> 00:40:28.480
You have to do them partially, but um but um you have to do them partially if you're not doing the fast math versions.
00:40:28.639 --> 00:40:44.000
Um also helps you that language has a small vocabulary and not so mathematics oriented for that for APL this would be a nightmare because of all the fancy built-ins, and for something like J, it would be well I it's funny.
00:40:44.079 --> 00:41:00.159
I I think I think if you I am not a language developer, I could never write a language, I do not have that much um creativity and elegance and foresight, and I don't have any of that.
00:41:00.159 --> 00:41:01.280
I'm a mechanic.
00:41:01.280 --> 00:41:06.800
Um, so but the simpler the language, the the more you can do with it, right?
00:41:06.800 --> 00:41:17.119
So, you know, again, I've mentioned him a couple of times, but like Mike Paul's Lua Jet is I still think one of the most underappreciated pieces of code.
00:41:17.119 --> 00:41:21.760
And the the reason why you can get away with it is because Lua is so simple.
00:41:21.760 --> 00:41:34.400
Um Q is actually very messy, but K itself, I mean Q is built in K, but K itself is actually very simple and super elegant, and it's not a giant surface.
00:41:34.400 --> 00:41:43.039
So if you can, you know, if you start with something simpler, you can you can actually squeeze a lot of performance and you can do a lot of these tricks.
00:41:43.039 --> 00:41:48.159
Um because it's a nice, well-bounded framework that you're gonna work inside.
00:41:48.159 --> 00:41:56.800
So um, and yeah, you can in L, you can, I mean it's not I mean it's not hidden, you can do it, but you can do negative 17 bang.
00:41:56.800 --> 00:42:05.440
Negative int bang is kind of the KQ world of I've got this function, but I don't know what to call it yet, or something.
00:42:05.440 --> 00:42:20.639
Um, and you can do negative 17 bang and you can see kind of what is the object stored um into like how many bytes is is the object compressed, which should always be yes, and then how many bytes is it actually storing versus how many bytes was it originally?
00:42:20.639 --> 00:42:32.639
And you know, the other thing is again, this is not a like K and Q and and L they are not show horses.
00:42:32.639 --> 00:42:53.199
They're workhorses, like they're not they're do to the you know, these languages are built to do very specific, very kind of distinct workloads, and you know, database style workloads and financial style workloads, and so you know, you don't you don't have to you have to be able to solve those problems.
00:42:53.199 --> 00:42:55.599
Um, you don't have to be able to solve all problems.
00:42:55.599 --> 00:43:06.400
So I I mean again, uh K always had a concept of a comparison tolerance, and that's like you know, I I don't know if that's how it works in a APL, right?
00:43:06.400 --> 00:43:17.039
If you've got two uh 64-bit floats and they're almost the same, but not exactly the same, like at what point do you say those are equal?
00:43:17.280 --> 00:43:27.920
Um APL is has at least for very long time has had has a configurable um comparison tolerance, that's what it's called, and as well.
00:43:27.920 --> 00:43:30.000
But I know J's is fixed.
00:43:30.000 --> 00:43:31.760
You can I don't think you can you can change it.
00:43:31.760 --> 00:43:33.599
I suppose case is also fixed.
00:43:33.599 --> 00:43:42.719
I case case is fixed, L's is fixed, um and it's it's a is it a multiplicative uh comparison tolerance?
00:43:42.719 --> 00:43:51.039
So it's like there has to be a factor of of one plus ten to the power of negative seventeen maximum ratio between them, right?
00:43:51.360 --> 00:43:51.920
Yep, yep.
00:43:51.920 --> 00:43:58.880
So which is almost a shame because then you can't really do the uh then you can't just do the mem compare to exactly.
00:43:58.960 --> 00:44:01.920
Yeah, that makes that makes Load operation is much, much slower.
00:44:01.920 --> 00:44:05.840
And you really it would be sort of nice to not do that.
00:44:06.480 --> 00:44:11.360
Unless you've got a compression codec that kind of knows that from the beginning, right?
00:44:11.360 --> 00:44:14.239
Um sorry, Steven has his hand up.
00:44:14.480 --> 00:44:15.679
Yeah, I was gonna say hop in here.
00:44:15.679 --> 00:44:18.960
And also, too, we've got two questions in the the chat.
00:44:18.960 --> 00:44:21.920
Um, so uh we'll probably ask those in a little bit.
00:44:21.920 --> 00:44:26.719
Uh but yeah, if you have questions, feel free to cue them up and we'll make sure to to get to go to those in a bit.
00:44:26.719 --> 00:44:28.000
But yeah, Steven, go ahead.
00:44:28.480 --> 00:44:35.199
Well, look, Jake, we've spent a little time exploring the implementation of how you manage to get ahead on performance.
00:44:35.199 --> 00:44:42.400
Uh and I'd like to ask you a version of the question I was asking you the other um the other day on our call.
00:44:42.400 --> 00:44:53.599
You've got an interpreter that has 100% coverage of the key language uh and at least as much speed to put it to put it um mildly.
00:44:53.599 --> 00:44:56.400
Um, what do you want for this language?
00:44:56.400 --> 00:44:58.719
Um, that's not I'm not asking for a price.
00:44:58.719 --> 00:45:02.639
I don't know what you want to happen first.
00:45:03.199 --> 00:45:11.440
No, I think you need um we need more K and Q developers.
00:45:11.440 --> 00:45:21.360
We need a giant army of people building great systems, great code, and it needs to be out there.
00:45:21.360 --> 00:45:31.440
Like I um, you know, recently we've been doing a lot of work with kind of AI folks, and you know, it's like, why did Python win data science?
00:45:31.440 --> 00:45:35.039
Um, this is pretty easy because everyone used Python.
00:45:35.039 --> 00:45:37.599
Um, and there's a million packages.
00:45:37.599 --> 00:45:39.920
Um, you know, sci fi is amazing.
00:45:39.920 --> 00:45:47.599
Like, I mean, it's it is, it is actually amazing, but boy, is it slow and boy is it verbose.
00:45:47.599 --> 00:45:52.320
Um, and I think, you know, I think there were really two problems here.
00:45:52.320 --> 00:46:00.960
One was, you know, unless you were kind of a member of the Illuminati, getting access to these interpreters was very difficult.
00:46:00.960 --> 00:46:04.800
Um, and that that that that obviously needed to go away.
00:46:04.800 --> 00:46:27.360
Um, and then I think the second one was, you know, even though you know people like the bro have done great work on documentation and books and implementations, uh there there wasn't if you came, even if you had the interpreter and you had some base knowledge like Q for Mortals or something, um, it it's still difficult.
00:46:27.360 --> 00:46:30.079
You kind of learn this thing, or at least I did.
00:46:30.079 --> 00:46:35.119
Uh, you know, this language was kind of passed down like a secret from one person to another.
00:46:35.119 --> 00:46:41.920
You would learn, you know, uh, and I think that LLMs are making that go away.
00:46:41.920 --> 00:46:54.800
You know, you can you can ask, whatever, sub your favorite LLM in, but you can ask your favorite LLM how to do something in an idiomatic way, and you you tend to get right answers.
00:46:54.800 --> 00:47:00.960
And I think, you know, I think of the LLM as like an infinitely patient teacher, right?
00:47:00.960 --> 00:47:10.960
So um now it's not perfect, but you know, as as I always say to people when you have new technology, it's like, hey, just remember, this is the worst it's ever gonna be.
00:47:10.960 --> 00:47:27.360
Um, so you know, and especially in the array languages, you I I don't know about you guys, but I I have always said it's like I will go think about something for hours, hours and hours.
00:47:27.360 --> 00:47:30.079
And then it might take me five minutes to code it.
00:47:30.079 --> 00:47:35.840
Like the actual act of writing the code is never the hard part.
00:47:35.840 --> 00:47:36.719
Like, never.
00:47:36.719 --> 00:47:44.239
Like the language is so simple, you learn to think in that structure, you know, you start to recognize patterns.
00:47:44.239 --> 00:48:00.559
Um and you know, whereas like you look at today and it's like, you know, oh, people aren't thinking at all, and this LM is just vomiting out this, you know, truckload of Python that's gonna slowly set the world on fire uh through its inefficiency.
00:48:00.559 --> 00:48:04.400
And it's like, hey, hey, hey, hey, can we get back to like a craft?
00:48:04.400 --> 00:48:10.079
Like, we actually some of us actually want to do this as as an actual craft.
00:48:10.079 --> 00:48:18.719
Can we get back to thinking about and then you know, writing less code, reading less code, debugging less code?
00:48:18.719 --> 00:48:21.360
Like, can can we get back to that to that world?
00:48:21.360 --> 00:48:22.480
I I don't know.
00:48:22.480 --> 00:48:29.280
I mean, L soup to nuts is I mean, and it's a lot, but it's maybe 12,000 lines of C.
00:48:29.280 --> 00:48:34.559
And you got to keep in mind that every line of C can only be 80 characters because I am absolutely crazy.
00:48:34.559 --> 00:48:41.840
So um the you know, how do people how do people debug million lines of code?
00:48:41.840 --> 00:48:42.800
I have no idea.
00:48:42.800 --> 00:48:47.199
I mean, debugging more than 500 is just like takes me all day.
00:48:47.199 --> 00:48:50.239
So uh I I like like small shortcuts.
00:48:50.239 --> 00:48:53.199
So can we can we get everybody an interpreter?
00:48:53.199 --> 00:49:01.760
There's I think there's a lot of great um education documents out there, and people, you know, you should start playing with all ones.
00:49:01.760 --> 00:49:06.880
Like they can you can ask it to write idiomatic cue, and you know, it'll do it'll do an okay job.
00:49:06.880 --> 00:49:10.480
Um, and again, today's the worst it's ever going to be.
00:49:10.480 --> 00:49:15.119
Um, and so you know, I I I'll give you a great example of this.
00:49:15.119 --> 00:49:22.719
Um I now that you have an interpreter and you can kind of run it anywhere you want, um you can make that a tool call.
00:49:22.719 --> 00:49:33.039
So you can take this very, you know, kind of maybe an LLM that doesn't write great code, and you can let it call the interpreter and just iterate, iterate, iterate, iterate.
00:49:33.039 --> 00:49:36.960
And then it, you know, you can fine-tune it till well till it learns how this works.
00:49:36.960 --> 00:49:41.920
So um, so yeah, I think those are kind of the the main goals.
00:49:41.920 --> 00:49:50.000
And also I think, you know, I I think it's awesome that everybody, it seems like every single person right now is like, I'm gonna go build a language.
00:49:50.000 --> 00:49:52.559
And like, man, do I honor that?
00:49:52.559 --> 00:49:58.880
Um, but there's something to taking a language that has a big footprint.
00:49:58.880 --> 00:50:05.199
I mean, it has a bigger footprint than I think people realize, um, and just making it faster.
00:50:05.199 --> 00:50:07.280
Like, you don't actually have to go build a new language.
00:50:07.280 --> 00:50:12.320
Like, why would somebody continue to do work in K and Q?
00:50:12.320 --> 00:50:16.320
That's like it's still got to be the bleeding edge of performance.
00:50:16.320 --> 00:50:24.079
Um, yeah, I mean, it's amazing to me how how fast K and Q is for the you know, the style of workload that it does.
00:50:24.079 --> 00:50:28.079
Um, and you know, we're talking about effectively almost 20-year code.
00:50:28.079 --> 00:50:34.880
Um, I mean, I'm sure there's lots of improvements that have happened, but fundamentally there's it's it's 20 year 20-year-old code.
00:50:34.880 --> 00:50:38.159
Um so can you get another order of magnitude?
00:50:38.159 --> 00:50:45.760
Um you know, and that's not just on the language side, but really, guys, the the database is what makes this thing live, right?
00:50:45.760 --> 00:50:50.960
It's the database workload that people buy it for, use it for, implement it for.
00:50:50.960 --> 00:50:59.519
Um and you know, can you do can you be an order of magnitude faster than other things?
00:50:59.519 --> 00:51:12.800
And it turns out, yeah, you you can, but you have to, you know, make it small and it's binary sizes matter, like iCash matters, like um, like these things all matter.
00:51:12.800 --> 00:51:17.599
These are all parts of the craft that I think somewhere along the way got lost.
00:51:17.599 --> 00:51:27.760
Um, maybe everybody should, you know, go back to having 256k dial-up to to force force a diet, like a GLP one for computer science.
00:51:27.760 --> 00:51:32.400
But um yeah, that that that that's kind of what my thoughts are there.
00:51:32.400 --> 00:51:35.920
So right now it's uh can you make it faster than everything?
00:51:35.920 --> 00:51:37.760
It's it's pretty far on its way.
00:51:37.760 --> 00:51:39.519
Um even on the database side.
00:51:39.519 --> 00:51:41.519
I don't know if you guys have ever used DuckDB.
00:51:41.519 --> 00:51:44.079
DuckDB is an amazing, great piece of code.
00:51:44.079 --> 00:51:51.679
And it by the way, uh Adam, it has some of these compression codec concepts built into it, but for database workloads.
00:51:51.679 --> 00:52:09.039
Um, so um I think Duck uses for its loading point, I think it uses uh um ALP, um, which is basically you take your uh, you know, take whatever ill-gotten youth handed you uh money in decimals.
00:52:09.039 --> 00:52:21.519
Um this basically takes that and says, okay, well, we're gonna write a compression codec that's gonna effectively raise things to the power, you know, raise things to different powers of 10 to see if we can um get this guy up in the integer space.
00:52:21.679 --> 00:52:23.760
And then of course that's that's really interesting.
00:52:23.760 --> 00:52:27.199
Yeah, and then of course that means you have to have some fuzz, right?
00:52:27.199 --> 00:52:31.519
Because a lot of things will be almost fit if you raise it to some power of 10.
00:52:31.840 --> 00:52:39.599
There's a really good paper, the ALP paper, which is out of, I think um the CWI group, CMI group.
00:52:39.599 --> 00:52:43.280
Um we could put it in the show notes, kind of describes this.
00:52:43.280 --> 00:52:53.840
But you know, I think I I don't I don't know about you, but like I'm I am a small small little things and then interlock them, right?
00:52:53.840 --> 00:52:56.079
So you could even think that concept, right?
00:52:56.079 --> 00:53:10.079
So say, so say, you know, Timmy hands you an array of of US dollar in floats, um, and you could just raise that to a power of 10, um, and and everything would be okay.
00:53:10.079 --> 00:53:17.440
But then if you were to interlock that with the frame of reference, right, and remove that base off um and now take that payload.
00:53:17.440 --> 00:53:26.960
Well, hey, those two codec interlocked together actually give you like an insanely efficient way to work in the integer space on a smaller bit.
00:53:26.960 --> 00:53:28.000
Well, you know what I'm saying?
00:53:28.000 --> 00:53:30.079
Like these things all get interlocked.
00:53:30.079 --> 00:53:41.840
People, I think people, you know, would look at um kind of especially if you if if you looked at like some of the stuff that that Arthur did make open, it was like, oh my god, this interlocking mess.
00:53:41.840 --> 00:53:45.440
And it's like, no, no, no, no, no, like that's exactly how you want to do it.
00:53:45.440 --> 00:53:51.280
Like, if you have one function that's not interlocked with something else, you gotta ask yourself, do I need that function?
00:53:51.280 --> 00:53:54.639
Um, or is there some other way to tie these guys together?
00:53:54.639 --> 00:54:02.159
I mean, there's literally uh on the on on the L kind of to build L takes a long time because it runs all these tests.
00:54:02.159 --> 00:54:08.239
And one of the tests is um essentially going through and looking at the assembly gets output for every function.
00:54:08.239 --> 00:54:14.000
Um, that can often be inline and other functions, but making sure that they all fit within the iCache, right?
00:54:14.000 --> 00:54:24.960
And if it isn't, then you got to go back and be like, all right, is there a way I can shave off you know a few bytes off of this thing because I know that this is gonna be interlocked into all these other places?
00:54:24.960 --> 00:54:27.280
So yeah, I don't know.
00:54:27.280 --> 00:54:31.920
I that I went on a little bit of a diatribe there, Stephen, but that's that's a goal, right?
00:54:31.920 --> 00:54:42.559
More people using this language, doing this craft, and like, please, for the love of God, stop handing me pages of code and then be like, Can you find my bug?
00:54:42.559 --> 00:54:46.639
Um, it's like my answer is always like, Yes, I found your bug right away.
00:54:46.639 --> 00:54:48.719
It's this entire page of code.
00:54:48.719 --> 00:54:51.039
Um, you know, give me give me 20.
00:54:51.039 --> 00:54:56.559
The rag engine that I that I built with, you know, for for these friends.
00:54:56.559 --> 00:54:58.880
Um I mean, it's 20 lines.
00:54:58.880 --> 00:55:06.480
It's 20 lines, and it's way faster than what they were using, which is this giant commercial product.
00:55:06.480 --> 00:55:08.880
And it's like, okay, it's 20 lines.
00:55:08.880 --> 00:55:10.639
Like, we can all read it.
00:55:10.639 --> 00:55:18.239
Yes, yes, there's some complexity here because they're dense 20 lines, but like we all can read and understand this.
00:55:18.239 --> 00:55:25.280
Like, you can actually map it in your head, versus the other thing, which was like, you know, I don't even know, tens of thousands of lines.
00:55:25.280 --> 00:55:28.079
I was like, dude, how will you ever find the bug here?
00:55:28.079 --> 00:55:37.360
Like, or or by the way, finding a bug and optimizing it are just whether or not you admit it's broken, or it, you know, you don't admit it's broken.
00:55:37.360 --> 00:55:39.280
Like if it's slow, it's still broken.
00:55:39.280 --> 00:55:40.880
So, you know.
00:55:41.440 --> 00:55:42.480
It's it's interesting.
00:55:42.480 --> 00:55:46.079
You say this about the amount of of code and and the problem.
00:55:46.079 --> 00:55:50.880
A problem with LM is that people are spitting out giant amounts of of code.
00:55:50.880 --> 00:56:08.559
Uh, what I found, uh, so I I had uh I'm going back to what I said right in the beginning when we before it introduced our our guests and this uh this game that I'd made, and that had written it in in JavaScript with one hand, um, because the other was on the baby.
00:56:08.559 --> 00:56:19.360
And uh so by necess by necessity, but also because that's how I like to do it, I wrote it in a in a special she was a variant of JavaScript that I like to call Arthur Whitney JavaScript.
00:56:19.360 --> 00:56:25.039
Um where uh I don't know if Arthur has ever actually ever written any JavaScript.
00:56:25.039 --> 00:56:28.719
Um I would ask him if I if I met him.
00:56:28.719 --> 00:56:33.519
Um but but in what I imagine it would look like if he wrote it after having seen some of the code.
00:56:33.519 --> 00:56:36.880
Mind you, I don't understand C, I don't read C.
00:56:36.880 --> 00:56:41.360
Um, but I've seen some of the things he has written, and I figured this is how we'd write it.
00:56:41.360 --> 00:56:55.119
So uh one letter variables, two letter variables when necessary, and no unnecessary white space, keeping as much as it's keeping the code visible on the screen at one any given time.
00:56:56.000 --> 00:57:00.400
Um you can actually Google Arthur's JavaScript.
00:57:00.400 --> 00:57:02.719
There's one called C dot JS.
00:57:02.719 --> 00:57:05.360
Yeah, it's the the connector.
00:57:05.360 --> 00:57:11.760
Um, it was the basically the IPC protocol uh parser in JavaScript.
00:57:11.760 --> 00:57:13.039
C.S.
00:57:13.039 --> 00:57:14.960
You said C dot JS.
00:57:15.199 --> 00:57:16.320
Oh JS, yeah.
00:57:16.480 --> 00:57:18.480
Yeah, I'll I'll see if I can find it.
00:57:18.639 --> 00:57:24.559
But um, so this is how I like to write my JavaScript in general.
00:57:24.559 --> 00:57:30.559
I also relied on every quirk available in the uh in the browser's JavaScript engine.
00:57:30.559 --> 00:57:35.760
That might not be the best idea uh to do that, but it makes my code shorter because I don't know.
00:57:35.760 --> 00:57:43.280
People people have told me that you need to use things like const and let and var and don't know what in in in JavaScript.
00:57:43.280 --> 00:57:44.400
I don't know what these words do.
00:57:44.400 --> 00:57:47.840
Apparently, my code does the same thing when I don't write it, so I don't write it.
00:57:47.840 --> 00:57:53.599
Um and um, but my variables only survive very short before they're anymore.
00:57:53.599 --> 00:57:56.000
So who cares if it's the global scope or whatever?
00:57:56.000 --> 00:57:58.320
Um so so so this is how I write it.
00:57:58.320 --> 00:58:05.840
And and the interesting thing is that I was able to get, I was using using Claude, I was able to get Claude to stick to this.
00:58:05.840 --> 00:58:13.679
So I did make it first got rid of all the quirks because apparently there are some features that need a JavaScript that are not available in quirks mode.
00:58:13.679 --> 00:58:30.239
Um, but other than not writing super quirky code, so everything is sort of best standards, it still looks the same, still makes actual JavaScript programmers go all uh white in the face when they see it and say, for first reaction, that's not JavaScript.
00:58:30.239 --> 00:58:33.360
Second reaction is oh wait, that is JavaScript, but what are you doing?
00:58:33.360 --> 00:58:35.760
You're not supposed to write code like that, and that's fine.
00:58:35.760 --> 00:58:44.320
Um, but I was able to make Claude keep doing that, and that means that my whole game is like I don't know, 250 lines of of JavaScript, something like that.
00:58:44.320 --> 00:58:59.760
Um and I think it's and then I can I can actually go through it, even though it it is it 100 lines to 250 lines with Claude's editions, uh more code than I can actually go through it and make sure that every I know what everything is doing.
00:58:59.760 --> 00:59:03.280
There are no unnecessar unnecessary bits, about bytes.
00:59:04.000 --> 00:59:09.199
I mean, everything's an abstraction anyway, like you're not handwriting the stuff in assembler.
00:59:09.199 --> 00:59:19.039
Um, so like the syntax, I don't think matters as much as people think it does, or the style doesn't matter as much as people think it does.
00:59:19.039 --> 00:59:21.599
It's can you comprehend this?
00:59:21.599 --> 00:59:23.280
Like, what is the entropy?
00:59:23.280 --> 00:59:27.199
Like when you literally look at something, can you comprehend it faster?
00:59:27.199 --> 00:59:38.880
And by the way, like I'm sure that there are people for whom you know basically reading a novel that kind of walks you through what's happening is more is better for them.
00:59:38.880 --> 00:59:43.119
But you know, for me, I'll I'll I'll take a poem over a novel anytime.
00:59:43.280 --> 00:59:56.880
So Stephen, you got your uh Yeah, Jake, for uh for years, Q was my kind of go-to language for when I when I had uh a license to use it uh for pretty much everything.
00:59:56.880 --> 01:00:04.800
And I would love to be one of the people you envisage for the future writing applications in Q or K.
01:00:04.800 --> 01:00:16.719
Um, but for commercial applications, uh I will be writing them from a customer who's gonna say, well, if anything goes wrong, who can I call who has to pick up the phone?
01:00:17.039 --> 01:00:21.599
Yeah, I yeah, I think you're asking kind of what is the long-term commercial plan for L?
01:00:21.599 --> 01:00:24.880
Um and I don't have one yet.
01:00:24.880 --> 01:00:30.800
So um, you know, I think it's good to put it at a time.
01:00:31.280 --> 01:00:44.000
It's definitely that making a choosing a brand name to keep support because that just I don't know if it's just me, but I can barely make out what Adam is saying.
01:00:44.000 --> 01:00:47.199
Uh your audio has gotten a little choppy.
01:00:48.880 --> 01:00:52.400
But yeah, I I don't know what the long-term commercial application is.
01:00:52.400 --> 01:00:57.920
I think, you know, Steven, right now is can you run all these workloads?
01:00:57.920 --> 01:01:01.360
Um and can you run them in order of magnitude faster?
01:01:01.360 --> 01:01:03.280
Let's let's try to get that first.
01:01:03.280 --> 01:01:06.559
And then, you know, then we'll deal with the next part next.
01:01:06.559 --> 01:01:14.800
Um again, I think the good news is right, if if if uh you know this is compatible, this is dropping compatible.
01:01:14.800 --> 01:01:16.320
So I mean, I think that works both ways.
01:01:16.320 --> 01:01:30.559
So you can mind have somebody who you know downloads L and builds something, and then is like, you know, I could, you know, maybe if there wasn't an L commercial entity, then you can just be like, oh, well, I you know, I have this code I can call KX, and that's that's great.
01:01:30.559 --> 01:01:45.519
Um but because it is, you know, like I said, some of the reports from the field are pretty nuts, not just in terms of performance, and I hadn't actually contemplated this, but I feel stupid for not having contemplated it, is storage.
01:01:45.519 --> 01:01:50.719
So the um, you know, the objects are compressed in memory on disk.
01:01:50.719 --> 01:01:52.960
I mean, it's all the same format.
01:01:52.960 --> 01:01:56.719
Um, again, do one thing and just do it everywhere.
01:01:56.719 --> 01:02:05.599
Um and somebody just basically moved over what is essentially a TAC database to see what the disk storage was.
01:02:05.599 --> 01:02:15.360
And um, and it turns out it's like eightx less disk, even then the dictionary compressed versions, um, which which I think makes sense, right?
01:02:15.360 --> 01:02:22.800
Because you know, dates and um timestamps, the base type is a 32-bit and a 64-bit.
01:02:22.800 --> 01:02:35.119
They're almost always monotonic in the database, so they're always gonna delta really well, and then they're gonna frame a reference really well, and they're gonna um, you know, there's kind of one more trick that I do on the patch.
01:02:35.119 --> 01:02:42.800
And so you actually do end up like, yeah, like a column of time is gonna be super, super small.
01:02:42.800 --> 01:02:46.079
Um, if it's a high fidelity, like high frequency set of time.
01:02:46.079 --> 01:02:51.679
Deltas are gonna be tiny, um, and that's gonna compress down a lot, like a lot, a lot.
01:02:51.679 --> 01:02:55.119
Dictionary compression just really isn't good for numbers.
01:02:55.119 --> 01:02:59.199
I I don't know why people love dictionary compression.
01:02:59.199 --> 01:03:02.719
It's I mean, it's good for text, but it's not not good for numbers.
01:03:02.719 --> 01:03:04.320
Um yeah.
01:03:04.320 --> 01:03:05.679
Sorry, Adam.
01:03:05.679 --> 01:03:08.320
I I I don't know if your audio worked now.
01:03:08.320 --> 01:03:11.440
I wanted to answer your question, but I couldn't quite make it out.
01:03:12.079 --> 01:03:12.719
I'm sorry.
01:03:12.719 --> 01:03:14.079
Uh I hope it's better now.
01:03:14.079 --> 01:03:17.199
Um okay, I just need to reload.
01:03:17.199 --> 01:03:20.159
Um, but let's see if I remember what it was.
01:03:20.719 --> 01:03:21.519
It was in the middle of the year.
01:03:21.679 --> 01:03:24.960
Right, no, no, I think it's a commercial plan.
01:03:24.960 --> 01:03:57.760
Because it's sort of sort of a joke, but uh these they're these uh companies that that uh and that sell knockoff products that brand it like uh like real big brands out there, and they for customer support, they just list uh the originals contact information because their products are so identical to to the real expensive thing that that the customer support for uh for the real deal is the same as and as for the cheap stuff that they're selling.
01:03:57.760 --> 01:04:18.320
Uh it's sort of a joke, of course, because it doesn't it it's not commercially viable in the in the long run to say who do you call for assistance if something's not right oh that your language is behaves identically to into KX product and ask them and look at their documentation and so on.
01:04:18.320 --> 01:04:20.480
But that's that of course that's a joke.
01:04:20.480 --> 01:04:21.280
That doesn't work.
01:04:21.280 --> 01:04:24.559
Uh but essentially that's the situation you're in right now, right?
01:04:24.880 --> 01:04:27.280
Well, and I think Steven's point's a good point, right?
01:04:27.280 --> 01:04:49.679
Even open source code, um, you know, you're not gonna take a piece of open source code, I mean, I guess except for the case of the operating system, and um, you know, go deploy that in a mission critical environment without somebody to call, which is why these kind of open source business models um I I think succeed.
01:04:49.679 --> 01:04:56.800
Um but but yeah, again, just step one, get it compatible, which we're we're past that point.
01:04:56.800 --> 01:04:59.519
Um get it, get it fast.
01:04:59.519 --> 01:05:02.159
Um it's pretty fast.
01:05:02.159 --> 01:05:07.039
So, you know, I'm sure that the that we're gonna discover more things that we can make faster.
01:05:07.039 --> 01:05:08.480
I'll give you a great example.
01:05:08.480 --> 01:05:24.079
So um K, and I don't know if APL has this concept, but K is a concept of a symbol, which is essentially a character string that gets mapped to uh essentially an enumeration, right?
01:05:24.079 --> 01:05:28.559
So if you have this, is this comes from its use, from its use case, right?
01:05:28.559 --> 01:05:34.079
So in Wall Street, you know, stocks have tickers, you know, like IBM and whatever.
01:05:34.079 --> 01:05:40.719
Um you obviously, you know, don't want to you don't want to store a bunch of strings in a table.
01:05:40.719 --> 01:05:43.840
Like, no, again, terrible like choice.
01:05:43.840 --> 01:05:44.960
Don't don't do that.
01:05:44.960 --> 01:05:59.599
Um so what you want to do is you want to, you know, you want to store those as a number, and then you've got a lookup that needs to happen, kind of an enumeration between this this uh array of characters and its numeric representation that sets in the database.
01:05:59.599 --> 01:06:02.000
And that's great.
01:06:02.000 --> 01:06:03.920
And that works wonderful.
01:06:03.920 --> 01:06:07.840
Except you need to have that enumeration stored somewhere.
01:06:07.840 --> 01:06:11.920
Like if you lose that enumeration, and in K it's called the SIM file.
01:06:11.920 --> 01:06:16.159
And if you lose that SIM file, like you're smoked.
01:06:16.159 --> 01:06:18.800
Like there, like you've just lost the map.
01:06:18.800 --> 01:06:20.559
Like the Torah is now gone.
01:06:20.559 --> 01:06:22.880
We have no idea what how how things work anymore.
01:06:22.880 --> 01:06:30.480
Um, and this is this is both a a kind of an operational problem, but it is also actually a performance problem.
01:06:30.480 --> 01:06:45.280
So in a scenario in which you want to run kind of parallel reads um, you know, across multiple uh partitions, that symbol file needs to effectively be shared, right?
01:06:45.280 --> 01:06:48.800
They all all those partitions need to be able to decode that symbol file.
01:06:48.800 --> 01:06:51.599
And so you've got to have a lock on that symbol file.
01:06:51.599 --> 01:07:02.320
And um, you know, to be completely honest, I didn't do any character codec because, you know, I don't know, I don't just don't use strings a lot.
01:07:02.320 --> 01:07:06.639
And the community was like, hey, this is great, but is there any way?
01:07:06.639 --> 01:07:09.920
Basically, they're asking, is there any way you can get rid of the SIM file?
01:07:09.920 --> 01:07:10.960
And it's like, okay.
01:07:10.960 --> 01:07:14.960
What we're talking about is we just need a new codec here that will fit this.
01:07:14.960 --> 01:07:16.960
So again, be practical.
01:07:16.960 --> 01:07:19.519
It's a workhorse, not a show horse, right?
01:07:19.519 --> 01:07:25.760
So most financial workloads, the character string is fairly short.
01:07:25.760 --> 01:07:32.800
Um, so it's, you know, uh generally four or less characters, but certainly eight or less characters most times.
01:07:32.800 --> 01:07:37.679
Those are holding the ticker, uh kind of the the name of the stock, right?
01:07:37.679 --> 01:07:48.239
Um, well, you can, I don't know if you guys are familiar with this concept of German strings, but you can just basically take that character, right, turn it into the numeric uh equivalent.
01:07:48.239 --> 01:07:51.199
And um that has two benefits.
01:07:51.199 --> 01:07:58.000
One, it's a number, so you know, God likes storing numbers, and two, um, it's like lexographically sortable, right?
01:07:58.000 --> 01:08:01.039
So sorting sorting that number is the same as sorting the character.
01:08:01.039 --> 01:08:02.639
Um, so that was the first one.
01:08:02.639 --> 01:08:14.719
I did that, and it was like, hey, now you have no symphile, every symbol vector is kind of self-describing, subject to you only using small, small character strings.
01:08:14.719 --> 01:08:24.399
And then um, and if you use a large character string, then underneath the covers, that codec is gonna have to switch to an enumeration, and like you're gonna, you know, now you're back in pain.
01:08:24.399 --> 01:08:30.479
And then somebody in the community was like, Yeah, but like these options ones, they're just a little bit longer.
01:08:30.479 --> 01:08:33.680
And I was like, well, then you know, tell them to make them shorter.
01:08:33.680 --> 01:08:36.479
And um, it was like, well, no, you can't do that.
01:08:36.479 --> 01:08:48.000
So um that was that was like the last, I don't know, two, three weeks was thinking of kind of what is a codec for for storing a string that still allows you to have those properties.
01:08:48.000 --> 01:08:52.800
Um, and so actually for a symbol and for a symbol, there is no enumeration anymore.
01:08:52.800 --> 01:08:57.359
They are all self-described, and each vector is kind of self-composed.
01:08:57.359 --> 01:09:01.680
Um, and it's like, okay, that's great from an operational standpoint.
01:09:01.680 --> 01:09:04.800
You don't have to worry about losing a sim file and losing all your data.
01:09:04.800 --> 01:09:15.920
But boy, does that turn out to be a massive performance improvement, like massive, like more than an order of magnitude, um, because all of these locks on the sim file go away.
01:09:15.920 --> 01:09:22.479
And because then each, if you have multiple SIMs in a in a in a table, you can now operate them on them independently.
01:09:22.479 --> 01:09:26.880
And of course, because all the codecs are uh sortable, you don't have to worry about this.
01:09:26.880 --> 01:09:38.880
You used to like have to go work on the you would go into the enumeration, find the symbols that matter, then go back into the table, and then find the match, and then ah no.
01:09:38.880 --> 01:09:40.640
So all of that just goes away.
01:09:40.960 --> 01:09:45.520
Yeah, the sim file bloating is going away as well because there's sim files.
01:09:45.520 --> 01:09:59.279
Like yeah, one one one problem uh with the sim file is like it it you know it makes your data on disk faster, but as soon as you start bloat the sim file, you're losing this performance.
01:09:59.279 --> 01:10:21.279
And you know, I've been teaching KDB developers and juniors, and often you know, one of the grads, one of their rookie mistakes is like, okay, I'm making a column that's not supposed to be a SIM symbolic column, a SIM, and then you store it to this and you load, you blow up the size of the SIM file, and now suddenly your HTB isn't fast anymore.
01:10:21.279 --> 01:10:31.760
And then you have to deal with basically recreating your data because there is no easy way to remove something that went into the SIM file.
01:10:31.760 --> 01:10:36.640
You have to de-numerate everything, re-enumerate it, and save it back down to disk.
01:10:36.640 --> 01:10:40.560
And that's like a massive pain and a very risky operation.
01:10:40.560 --> 01:10:45.119
So not having to deal with SIM files, that's pretty cool to think.
01:10:45.439 --> 01:10:49.119
Yeah, and again, it's just it's a massive performance unlock.
01:10:49.119 --> 01:10:54.720
Um, because now you can have each one of these kind of parallel readers operate independently.
01:10:54.720 --> 01:10:57.119
Um, and you you know, you don't have to worry about a lock.
01:10:57.119 --> 01:11:02.239
Um, and um, you know, God has a couple of designing principles.
01:11:02.239 --> 01:11:08.079
He doesn't like characters and he doesn't like locks, and he doesn't like branches, and the more you can get rid of those, the better life is.
01:11:08.079 --> 01:11:09.119
So yeah.
01:11:09.520 --> 01:11:15.920
Have you noticed other things at least when uh when using uh like uh L versus your experience in the past?
01:11:16.239 --> 01:11:18.640
Um I found it really easy to transition.
01:11:18.640 --> 01:11:24.000
It's pretty much like I, you know, I came across this two, three weeks ago.
01:11:24.000 --> 01:11:35.920
Um, and then you know, Jake gave me the binary, installed it, run it, and I thought like I I I have to learn something new or you know, at least read some documentation.
01:11:35.920 --> 01:11:46.000
But Jake was basically it's pretty much like cube, just start playing around with it, which I did, and I haven't seen much that you know I couldn't do.
01:11:46.000 --> 01:11:51.279
Um it's it's it's pretty good um from what I've seen so far.
01:11:51.279 --> 01:11:53.279
And yeah, I like it.
01:11:53.600 --> 01:12:01.359
Do you have any like uh workflows that you notice got way faster, or do you not really have that kind of thing where you're you're running something regularly enough to notice?
01:12:01.920 --> 01:12:03.279
No, I haven't, you know.
01:12:03.279 --> 01:12:06.319
I've for now I've just done basic stuff.
01:12:06.319 --> 01:12:09.680
Um I didn't went too crazy on it yet.
01:12:09.680 --> 01:12:16.720
Um but yeah, I know Jacob runs some some stats and and they look pretty promising.
01:12:16.720 --> 01:12:26.960
And one of my questions for Jacob was actually like we've we've talked a lot about what you've already done in in terms of you know to squeeze some performance out of it.
01:12:26.960 --> 01:12:28.880
Do you think you can push it even harder?
01:12:28.880 --> 01:12:32.319
Like is there do you have are you there yet with L?
01:12:32.319 --> 01:12:33.199
Are you finished?
01:12:33.199 --> 01:12:37.760
Do you think it's okay that's the maximum we can you know squeeze out of it?
01:12:37.760 --> 01:12:41.119
Or or do you have a few more tricks in in your sleeve?
01:12:41.520 --> 01:12:43.840
Oh no, there's definitely more to do.
01:12:43.840 --> 01:12:45.680
There's always gonna be more to do.
01:12:45.680 --> 01:12:50.560
I think um I think I'm out of ideas for now.
01:12:50.560 --> 01:12:56.000
So that's why it's like you want more people to have this, because you want to, you know, I'm out of ideas.
01:12:56.000 --> 01:12:58.800
So let's let's see if anybody else has got some new ideas.
01:12:58.800 --> 01:13:07.199
But I think um I actually think the fusion uh fuse.c where it actually goes and changes the bytecode.
01:13:07.199 --> 01:13:22.239
Um one of the things I want to do, and I just haven't figured out how to, is expose that up so that a developer can essentially write new fusion rules in the interpreter and save them down.
01:13:22.239 --> 01:13:32.319
Um because that's that's where there's just a lot of institutional knowledge that it gives you just huge performance wins.
01:13:32.319 --> 01:13:37.840
Like, I mean, the classic example is like Connor said, the the fuse multiply at, right?
01:13:37.840 --> 01:13:43.039
Um let's take this set of operators and let's just move it into a dot.
01:13:43.039 --> 01:13:54.239
But you know, there's a lot more of them, like working with matrices and you know, working with them in arrays and indexing into the matrices in in in kind of a straight linear fashion rather than the matrix.
01:13:54.239 --> 01:13:55.520
Um, I don't know.
01:13:55.520 --> 01:14:01.600
As I come into more workloads, I'm sure there'll be more opportunities to make things better.
01:14:01.600 --> 01:14:06.159
But yeah, I'm kind of out of ideas of how to make it faster.
01:14:06.159 --> 01:14:12.239
Um so and really it's like where where if anywhere is it slow, right?
01:14:12.239 --> 01:14:22.399
So if it's so for example, I didn't do like the uh string operations, like you know, again, strings, I just don't use them.
01:14:22.399 --> 01:14:29.119
So um, and then somebody in the community came in and they were like, Man, this string search and replace is really slow.
01:14:29.119 --> 01:14:32.560
I was like, Oh, okay, let's go back and fix that.
01:14:32.560 --> 01:14:35.039
So um went and fixed that.
01:14:35.039 --> 01:14:38.640
Um and uh, you know, stuff like that.
01:14:39.039 --> 01:14:46.399
Speaking of the the this is a good time to ask one of the two questions, or maybe both, but uh one of them was relevant to the the patterns that you uh mentioned.
01:14:46.399 --> 01:14:53.760
Um so the question is all of those fusion patterns and compressed representations uh must lead to a lot of combinations.
01:14:53.760 --> 01:15:04.079
Um, do you have special code for even uh, and I think it's EG, for example, uh arithmetic progression vector plus a number plus frame of reference vector.
01:15:04.319 --> 01:15:07.279
Um, that's a good question.
01:15:07.279 --> 01:15:18.159
Um no, because all the verbs have the compression operations built in, it really is just purely on the function itself.
01:15:18.159 --> 01:15:30.800
You do you actually don't um there isn't actually any way to in a fuse operator to say do this if that is compressed with this codec, do this if it's compressed with that codec.
01:15:30.800 --> 01:15:33.520
Um, but again, you don't really have to worry about that.
01:15:33.520 --> 01:15:41.840
Um, because all as long as you get all the verbs and adverbs working compute on compressed and closed form, that's really just an implementation detail.
01:15:41.840 --> 01:15:46.319
Um where fusion really matters is again kind of institutional knowledge.
01:15:46.319 --> 01:15:50.000
I see this, it's it's better to do that.
01:15:50.000 --> 01:15:54.800
Um and that really is just like you know, institutional knowledge.
01:15:55.039 --> 01:15:56.399
Um or tricks.
01:15:56.399 --> 01:15:59.119
All right, so we'll go to the second question too, and then we'll go to Steven.
01:15:59.119 --> 01:16:01.199
Uh so the first the first question was from Asher.
01:16:01.199 --> 01:16:04.479
I forgot to mention uh Asher's uh I believe a dial dialogue employee.
01:16:04.479 --> 01:16:05.840
So both of these are APLers.
01:16:05.840 --> 01:16:07.439
Uh the second one's from Max.
01:16:07.439 --> 01:16:12.479
Uh is scan, this is rather uh specific, is scan linear or quadratic in L?
01:16:12.479 --> 01:16:16.239
Uh because across languages, uh sometimes it's quadratic.
01:16:16.239 --> 01:16:19.199
It has the K does, right?
01:16:19.520 --> 01:16:22.079
Is scan linear or quadratic?
01:16:22.560 --> 01:16:35.520
What he means to say it is when you've got uh you've got a a verb followed by backslash, uh you're taking the partial sums, whatever to uh run it and running some.
01:16:35.520 --> 01:16:41.359
Do you start over every time going from the left or do you reuse the previous uh result?
01:16:41.359 --> 01:16:53.920
Because the the point is that uh a verb, b verb c uh by apl and k grammar, you need to start to compute from the right to left.
01:16:53.920 --> 01:17:07.520
And therefore, there's also the the idea that if you do a reduction, uh fold, insert, whatever you want to call it, uh then that's equivalent to just having all the elements spread out with a verb between them, so you need to go from right to left.
01:17:07.520 --> 01:17:09.039
Okay, that's all fine.
01:17:09.039 --> 01:17:17.199
Um, although we spoke about not worrying about uh just commutativity of uh and of mathematical functions.
01:17:17.199 --> 01:17:36.960
But when you get the scan and you create a cumulative sum, then you cannot do a single pass computation because you really need to go to the the last element of the of the running sum has to be the last element plus the second to last element plus the third last element and so on.
01:17:36.960 --> 01:17:41.600
But the second to last element, you have to start with the second to last element and go to the left.
01:17:41.600 --> 01:18:02.000
And if you're strict about this, if you're strict about the order of operations and strict that uh each partial sum must match the equivalent sum of that, and you're strict that the sum has to run in the uh element that element, so no CMD, then you end up with uh a terrible performance because you have to stud over for every element in the scan.
01:18:02.399 --> 01:18:02.800
Right.
01:18:02.800 --> 01:18:06.159
Okay, so this is gonna be a long answer.
01:18:06.159 --> 01:18:09.760
So the um, but this is a place where fusion plays.
01:18:09.920 --> 01:18:14.720
So um but hold on, before you answer that, I think I can sort of sidestep the question.
01:18:14.720 --> 01:18:16.000
There are two things played in.
01:18:16.000 --> 01:18:21.760
If I remember right, case definition of uh of a scan is strictly left to right.
01:18:21.760 --> 01:18:23.199
You just keep adding one more element.
01:18:23.199 --> 01:18:24.880
I mean, that's that's the first thing.
01:18:24.880 --> 01:18:26.479
So the question doesn't come in.
01:18:26.479 --> 01:18:34.640
Second thing that sidestep the question is you don't care about the order of uh of application of commutative functions.
01:18:34.640 --> 01:18:40.720
So this whole thing is only only comes in into that because of being strict about it.
01:18:40.720 --> 01:18:44.640
So it would seem to me that there's nothing even to answer here.
01:18:44.880 --> 01:18:46.159
Yeah, obviously not.
01:18:46.159 --> 01:18:56.239
There's nothing really I I think beautiful or magical about this, but I will say this that the fuse there in fuse.c, they're obviously operating.
01:18:56.239 --> 01:18:59.279
So prefix sums is something you use all the time, right?
01:18:59.279 --> 01:19:06.880
So um that actually calls very specific C code for that problem.
01:19:06.880 --> 01:19:19.439
Um that allows not only to use SIM, and actually there's a great write-up on that on parallel prefix sums on um algorithm algorithmica, I think.
01:19:19.439 --> 01:19:36.319
But um, but that one specifically, the sums, prods, mins, maxes, um, those all have custom C implementations because they are used uh specifically and they're SIMD implemented and parallel implemented.
01:19:36.319 --> 01:19:39.520
Um, and they're they're they're fairly bespoke.
01:19:39.520 --> 01:19:51.840
But if you were to do like F, you know, create a function F and do like um F scan, um, that will just operate like A, where it just goes, just kind of runs through it as fast as it can from left to right.
01:19:52.239 --> 01:19:54.239
All right, you waited patiently, uh Stephen.
01:19:54.239 --> 01:19:55.359
Now over to you.
01:19:56.239 --> 01:20:02.159
Yeah, I want to comment a bit on the implications of what we've been hearing over the last hour.
01:20:02.159 --> 01:20:20.800
Uh Romantic Alex Unterreiter and romantic Stephen Taylor called a meeting to uh work on shared community uh queue libraries, and cold-eyed KDB dev said there's no use case for those, and we're not coming.
01:20:20.800 --> 01:20:26.399
So we wound up canceling the meeting and feeling very sad and having a little weep.
01:20:26.399 --> 01:20:30.960
Um, and then Jake released his L interpreter.
01:20:30.960 --> 01:20:39.359
And now, I mean, I can't remember who I heard call the use this term first, um, but the language has got jailbroken.
01:20:39.359 --> 01:20:54.640
The first time we've been we've got um Q that you can use um in uh uh uh uh a commercially performant uh interpreter and can use it anywhere, or at any rate, the prospect of it.
01:20:54.640 --> 01:21:02.640
And um this seems to be the time for this because um there are other there are other projects working on the same thing.
01:21:02.640 --> 01:21:08.159
Jake's the first to come forward with a hundred percent coverage of the language.
01:21:08.159 --> 01:21:13.920
Uh I think Peach Q is reporting 43% coverage, peachq.org.
01:21:13.920 --> 01:21:21.359
Uh and uh John Estrada with his Courtsey uh interpreter uh reckons he's at about 80%.
01:21:21.359 --> 01:21:26.000
So this is a completely new landscape for the language.
01:21:26.000 --> 01:21:38.000
It's broken out, it's jailbroken, and there's clearly a need for some kind of community meeting to work out what community resources could be shared between them and so forth.
01:21:38.000 --> 01:21:43.520
What we need to do, and that will take some time to plan and organize.
01:21:43.520 --> 01:21:57.359
Meanwhile, at um Milden Hall in September, there's um the original failed meeting is coming back to life in some form, and neither Alex nor I quite know what's happening there.
01:21:57.359 --> 01:22:02.000
But John Estrada um will be there with Kortzi.
01:22:02.000 --> 01:22:06.720
Uh his collaborator Rob Hodgkinson will be there from Australia.
01:22:06.720 --> 01:22:11.359
We're expecting FinTan from States with Shack T.
01:22:11.359 --> 01:22:18.960
Uh, and uh we hear Dave Thomas is coming over to talk about uh what needs to be done for the community.
01:22:18.960 --> 01:22:26.640
So we don't even have an agenda for this, and we don't yet know who who's coming or who needs to be there.
01:22:26.640 --> 01:22:30.479
Um but our celebrated chef is back.
01:22:30.479 --> 01:22:56.560
And um so so I'm better uh I'm basically putting this out there that if you if you listening are someone who wants to be in on the very um the the very ground zero of what looks like a first actual community for K and Q, um get in touch with Alex or with me.
01:22:57.039 --> 01:23:06.159
Yeah, and I gotta say, man, as someone who grew up in this community, you know, when I came to New York, I didn't know anybody.
01:23:06.159 --> 01:23:12.079
I got this job in New York at this, you know, at this shop, this Kennerford show.
01:23:12.079 --> 01:23:18.159
And um I literally reached out to the K community and was like, I'm here.
01:23:18.159 --> 01:23:19.680
Is anybody else here?
01:23:19.680 --> 01:23:31.600
And like the first beer I had, the first dinner I had, you know, the first apartment I went over to, um, you know, the first group of friends that I ever made was, you know, KMQ programmers.
01:23:31.600 --> 01:23:36.079
And like, um, you know, what's a kooky, quirky community?
01:23:36.079 --> 01:23:43.439
And I I miss I've been gone for a long time, so it's nice to come back and be reminded, like, oh, there's a whole city under here.
01:23:43.439 --> 01:23:48.720
Like this Discord server was like four people, and then it was like 40 people in like a weekend.
01:23:48.720 --> 01:23:57.520
Like, um, and yeah, I think there's you know, I used to make jokes that when I was people, people uh people like, what is your preferred language?
01:23:57.520 --> 01:24:00.079
And I'm like, oh, I always prefer programming in K.
01:24:00.079 --> 01:24:01.199
And they're like, What is K?
01:24:01.199 --> 01:24:05.279
And I'm like, it's there's dozens of us, like dozens.
01:24:05.279 --> 01:24:07.600
Um, but that's not true.
01:24:07.600 --> 01:24:12.880
Like, there's actually hundreds of us, and and you know, maybe thousands of us soon.
01:24:12.880 --> 01:24:15.840
Uh, we just need to make sure people have access to it.
01:24:15.840 --> 01:24:21.680
Um, have access to it, can play with it, and like not play with it in just educational ways.
01:24:21.680 --> 01:24:28.239
Like, the only way you actually I I say this all the time: the only way I can actually learn something is to use it in anger.
01:24:28.239 --> 01:24:35.439
Um, like it needs to be put in these situations where you have to make it work because something depends on it.
01:24:35.439 --> 01:24:38.560
Using things in anger is how how you get good at things.
01:24:38.560 --> 01:24:44.560
So um yeah, man, go go download L and like go use her in anger.
01:24:44.560 --> 01:24:48.479
And if something's wrong or slow or you know, just send a note.
01:24:48.479 --> 01:24:50.159
Well, like I'll I'll take a look at it.
01:24:50.159 --> 01:24:50.880
We'll get it fixed.
01:24:50.880 --> 01:24:53.039
Like symbol file took two weeks.
01:24:53.039 --> 01:24:55.920
So, and you know, how hard could the rest of it?
01:24:56.159 --> 01:25:01.439
So the the downloads available obviously at the lv1.uhsh link.
01:25:01.439 --> 01:25:05.760
What's the best way if you run into issues or you just want to leave feedback?
01:25:05.760 --> 01:25:08.800
You you mentioned a Discord, but that sounded like a smaller private thing.
01:25:08.800 --> 01:25:12.720
Is there a a go-to space, GitHub issues or Twitter or something?
01:25:12.720 --> 01:25:13.520
What's the best way?
01:25:13.840 --> 01:25:26.960
There's there's actually when you go to uh when you go to that website, when you go to lv1.sh, there's a mailing list and you can join the mailing list, um, which is how it used to work in the old in the olden days.
01:25:26.960 --> 01:25:28.640
Um I like the mailing list.
01:25:28.640 --> 01:25:35.840
I I I mean the Discord's fun, but um I like the mailing list because it allows, you know, you can work a little more asynchronously.
01:25:35.840 --> 01:25:47.039
Um and Randy just, I think last night got a forum up so that you can go and you know search old uh see kind of the mailing list archives and be able to search it.
01:25:47.039 --> 01:25:51.199
So um if you want to get in touch with with me, that's certainly the best way.
01:25:51.199 --> 01:25:57.279
Just send, you know, join the mailing list and then send um send a message to the group and then I'll get it.
01:25:57.600 --> 01:26:03.359
One one one thing I want to add, and that comes from you know the early days when I started to learn Q.
01:26:03.359 --> 01:26:09.680
Um, the original mailing list, everyone could see who sent an email to the mailing list.
01:26:09.680 --> 01:26:28.159
Now it was, you know, with some veterans who have been doing Q for a long time, and it always felt intimidating to ask a question out in the wild, and then you know, the imposter syndrome, wondering whether everyone is gonna laugh about you and think you're stupid.
01:26:28.159 --> 01:26:32.720
So Jake actually made the mailing list anonymous.
01:26:32.720 --> 01:26:43.119
So whenever you send uh email to it, unless you have a signature in your Gmail address like I do, no one will actually see who sent it.
01:26:43.119 --> 01:26:55.199
So um that's a good way to ask your question without worrying whether you're gonna be exposed for asking something stupid, even though there are no stupid questions, only the ones not asked.
01:26:55.199 --> 01:27:10.560
And then for all the listeners who are not coming from a Q background or haven't learned the syntax yet, um, go check out my blogconq.tech where you can actually learn the language and the syntax.
01:27:10.560 --> 01:27:16.000
And I think I did a pretty good job in explaining it in a very easy, comprehensible way.
01:27:16.000 --> 01:27:22.399
Um, if anyone wants to chip in, Jacob, Steven, um, you can give your opinion about it.
01:27:23.439 --> 01:27:26.319
I just I just downloaded it and it runs.
01:27:26.319 --> 01:27:28.960
I was about to ask, wait, what if I'm on Windows?
01:27:29.199 --> 01:27:32.079
So you should think about your life choices, Adam.
01:27:32.239 --> 01:27:46.159
Like, that's like that's you've you've made some bad turns in life if you've ended up with well, Windows now has such a thing called as uh WSL that can run Linux things, so that's what I'm doing, and it works just does that work?
01:27:46.159 --> 01:27:47.520
Yeah, it works fine.
01:27:47.760 --> 01:27:48.399
There you go.
01:27:48.399 --> 01:27:50.000
New platform supported.
01:27:50.159 --> 01:27:52.079
Yeah, so that's fine.
01:27:52.079 --> 01:27:53.680
Um now you know.
01:27:53.680 --> 01:27:59.600
Um, but uh you one thing you might want to do is make it available to run in the browser.
01:28:00.159 --> 01:28:14.319
if you can if you can target web assembly or something like that with a C to WebAssembly thing or I I I don't think that does WebAssembly have SIMD built in it it is deeply SIMD specific.
01:28:15.439 --> 01:28:20.079
I know there are there are things out there that are able to compile C code.
01:28:20.079 --> 01:28:26.239
I don't know what happens if it has deep simd things I would imagine that it would work but I don't know.
01:28:26.239 --> 01:28:27.680
I don't know anything about these things.
01:28:27.680 --> 01:28:37.520
But it would be something that's very nice for a language like a small uh existing audience is to have something you can try right away in your browser.
01:28:37.520 --> 01:28:50.399
So by whatever means necessary like even if you need to run some kind of virtual machine thing that's um in the browser that can then run it that makes it very slow but just that people can get a feel for it that might be a nice thing.
01:28:50.399 --> 01:28:59.439
But then I then I found an interesting quirk uh of the L language we can call it an inconsistency but it sort of has to be the way it is it's just funny I think I wanted to mention this.
01:28:59.439 --> 01:29:40.000
That is I happen to know I don't really know KO Q but I happen to know that in that in Q if you apply uh a a string a character vector to the character uh k then it gets evaluated as k code so here's the fun thing if the language name is L uh it this still works it is implemented I just tried it yeah but that means the language sort of claims to to to evaluate K code I guess it does it does evaluate K code it does you can actually you can just hit the backlash and you actually drop into the game to I that that's the first thing I do I don't I don't need no Q.
01:29:40.000 --> 01:29:42.000
Give me K.
01:29:42.479 --> 01:29:46.560
Yeah Q is Q is uh complicated um K is a lot simpler.
01:29:46.560 --> 01:29:57.760
The um yeah the only thing that is still gated which I'll ungate soon um is the is the offload the GPU offload.
01:29:57.760 --> 01:30:00.800
Again it's just transparent.
01:30:00.800 --> 01:30:16.479
So um I'll ungate that on the Mac first because the hardware is consistent and it has unified memory but yeah that's GPU go burr is really good for like it's really good for sort at stupid large amounts.
01:30:16.479 --> 01:30:25.119
Actually I mean you have to have really really really big arrays for that thing to actually start to kick in but when it does it's pretty it's pretty amazing.
01:30:25.119 --> 01:30:52.880
So we've got a comment in the chat from uh Madeline who's mentioning that uh WASM has had simd for a while so I mean there it could uh be possible um there's there's maybe uh there's a there's a project there maybe I'm not um I'm not I don't really do uh web development but I'll I Randy Lebeau who built you know like the forum and the anonymous email list and all that stuff I'll ask him he if anybody could do it he could do it so see what we can do.
01:30:53.439 --> 01:31:03.920
Max meme god says says that yeah array box please well well I mean I once it runs in in wasm then you should be able to get to run it on the Raybux as well.
01:31:04.319 --> 01:31:31.520
Once someone implements the Wasm it should be pretty straightforward um but uh one last thing too because I know Steven you mentioned uh for people to get in touch is there uh uh what's the best people what's the best way if people are interested in um attending the upcoming uh event um is it to reach out to you is there uh an a another mailing list um just so that I'm I'm sure of the folks that are listening there's gonna be a handful of folks that are interested so I want to make sure I'm pointing them in the right direction.
01:31:31.520 --> 01:33:06.880
As we record this it's not there but on Iversoncollege.com um there'll be a notice about what's happening with the meeting or at any rate what we know about it uh and an invitation to reach out to anyone who thinks that they like to be at the potential ground zero of a new or what should we call ourselves Alex communards I like that all right so I mean uh if if you uh if you're listening now you can check uh Iversoncollege.com if it's not there yet uh we will uh Steven will let us know uh Adam and myself and when it is live probably uh by the next time we're releasing one of these array casts uh we'll be sure to announce it and point people in that direction um and with that I will say uh thank you so much uh to all of uh Jacob Alex and Steven this has been awesome I've learned a ton I mean it's super exciting I also I didn't realize that there are it's not just L out there I learned about Peach Q and you mentioned a couple other ones uh we'll be sure to link all of the different flavors of these uh I guess Q implementations that are out there and uh will be very exciting if if you are having uh a meeting and uh folks are getting together um because yeah it's it kind of feels like uh I don't know maybe Renaissance is a bit generous but uh it it feels like there's a a shift in the Q wins and uh the same way that there's you know a number of APL implementations, whether they're hobby projects or more serious um that yeah this is uh as an enthusiast of different array languages it's very exciting to to see this kind of development happening.
01:33:06.880 --> 01:33:24.640
So um yeah thank you so much for for coming on and we'll be sure to link to all the different uh things that we uh mentioned in both the YouTube description and the show notes so check those and uh with that we will say happy array programming uh
00:00:13.439 --> 00:00:18.879
Welcome to episode 128 of Raycast.
00:00:18.879 --> 00:00:24.640
I hope I got that number right because I realized just as we went live that I didn't actually have it in front of me.
00:00:24.640 --> 00:00:29.519
But uh I think I did, and we have a very exciting episode today.
00:00:29.519 --> 00:00:34.000
We've got uh three guests with us who I will well, I guess I should mention them now.
00:00:34.000 --> 00:00:40.640
Actually, I'll mention them in a sec, but if you're watching this on YouTube, which I think is, I don't know what percentage of our listenership, but it's the minority.
00:00:40.640 --> 00:00:42.560
You can already see all three of their names.
00:00:42.560 --> 00:00:45.600
The audio listener, though, will have to wait a few more seconds.
00:00:45.600 --> 00:00:49.679
And uh I guess with that I'll do a brief infro introduction.
00:00:49.679 --> 00:00:51.679
Adam can go first, uh, then I can go.
00:00:51.679 --> 00:00:54.240
And actually, should we just change it so that we can all go around?
00:00:54.240 --> 00:00:56.719
Because I just realized that we're bringing back Steven.
00:00:56.719 --> 00:01:03.439
Spoiler for the audio listener, uh Stephen Taylor, longtime panelist, uh, has come back for this special episode.
00:01:03.439 --> 00:01:07.120
And so I was just thinking that I guess he should do the brief introduction.
00:01:07.120 --> 00:01:13.680
So maybe what we'll do is we'll we'll go around and we'll do brief introductions from everyone, and uh and we'll we'll go from there.
00:01:13.680 --> 00:01:20.879
So we'll start with Adam and we'll finish with me, and then we'll go uh Steven, Alex, and Jacob uh will do last for our guests.
00:01:20.879 --> 00:01:22.400
So uh kick us off, Adam.
00:01:22.400 --> 00:01:24.239
Yeah, I'm Adam Busewski.
00:01:24.480 --> 00:01:29.680
Uh I am head of language design and longtime APL at Luck Limited.
00:01:30.159 --> 00:01:37.359
I'm Steven Taylor and APL and Q enthusiast and uh one-time KX librarian.
00:01:37.680 --> 00:01:39.680
Hi, I'm Alexander Lontaner.
00:01:39.680 --> 00:01:44.959
I'm a Q enthusiast and the founder and blogger behind DEF CON Q.
00:01:45.599 --> 00:01:47.200
Yep, and I'm Jake Leblos.
00:01:47.200 --> 00:01:50.560
I'm a very longtime K and Q developer.
00:01:51.040 --> 00:01:51.519
Awesome.
00:01:51.519 --> 00:01:54.879
And as mentioned before, or actually, I'm not even sure if I mentioned it before.
00:01:54.879 --> 00:01:57.120
Uh my name's Connor, host of ArrayCast.
00:01:57.120 --> 00:02:01.840
Uh fan of all the array languages, I'm very excited to hear about uh the topic for today.
00:02:01.840 --> 00:02:08.000
But before we get to that, uh I'm gonna hand it over to Adam, who I believe has three announcements if I recall correctly.
00:02:08.479 --> 00:02:10.240
Well, we could call it four, maybe.
00:02:10.240 --> 00:02:11.360
Um, right.
00:02:11.360 --> 00:02:14.000
So uh first a couple of deadlines.
00:02:14.000 --> 00:02:22.000
On July 31st is the deadline for early bird 10% off special uh for the dialogue user meeting.
00:02:22.000 --> 00:02:27.039
You get that rebate because the schedule for what happens at the user meeting isn't quite settled yet.
00:02:27.039 --> 00:02:28.560
Only the workshops are settled.
00:02:28.560 --> 00:02:33.439
So if you're willing to sign up, even though you don't know exactly what the presentations will be, you get some money off.
00:02:33.439 --> 00:02:45.360
And also there's an the APL challenge, this uh introductory uh course slash competition where you can win some money for learning a little bit of APL and using it.
00:02:45.360 --> 00:02:49.360
Uh it has a round finishing that same day, July 31st.
00:02:49.360 --> 00:03:00.000
Um, then uh a couple of weeks ago we had a uh a workshop internally at uh at Dialog, and it was on using LLMs with APL.
00:03:00.000 --> 00:03:07.599
And uh so we're trying to educate our employees on uh on how to use LLMs uh effectively and safely.
00:03:07.599 --> 00:03:18.960
And there's an interesting blog post that we'll we'll put a link to as well on using APL with LLMs and how to make them do that, uh, then be able to write some sensible APL.
00:03:18.960 --> 00:03:40.240
But out of that came also an old project, something I started uh three and a half years ago, uh, when I was in parental leave and I was holding a baby with one hand, and then I was typing a little bit of JavaScript with uh with the other hand, and I made the bare bones a framework for a game that like a top-down dungeon crawler game that would teach you some APL.
00:03:40.240 --> 00:03:43.280
But I never had a chance to finish it because you know the baby grew up.
00:03:43.280 --> 00:03:52.560
Um and then I figured, well, as an experiment for there's a material for this workshop, I would throw the LLM at it and see if it could finish up the game.
00:03:52.560 --> 00:03:54.159
I think it turned out really well.
00:03:54.159 --> 00:03:58.080
Uh so uh this we'll leave a link to that as well.
00:03:58.400 --> 00:03:58.800
Awesome.
00:03:58.800 --> 00:04:08.240
So links for all four of those things uh will be both in the YouTube description and the podcast show notes uh after I up this update this later.
00:04:08.240 --> 00:04:11.039
And with those out of the way, we're gonna do something a little bit different today.
00:04:11.039 --> 00:04:25.360
So uh because we have our former panelist with us, uh he knows much more about the uh you know K space, and uh we're gonna throw it over to Steven, and Steven's gonna uh lay the groundwork for what we're gonna be talking about today.
00:04:25.360 --> 00:04:28.399
And uh so with that, uh we'll throw it over to you, Stephen.
00:04:29.040 --> 00:04:31.040
Well, let's thank thank you, Connor.
00:04:31.040 --> 00:04:34.639
And let's start by frankly admitting that Alex and I screwed up.
00:04:34.879 --> 00:04:35.279
Uh uh.
00:04:35.600 --> 00:04:40.639
He he and I are both uh romantics about the Q and K languages.
00:04:40.639 --> 00:04:58.079
And when the KX module manager appeared, we announced a meeting at Milden Hall in Suffolk for this September, uh, so that our people could get together and plan and start building uh open source Q packages.
00:04:58.079 --> 00:05:01.439
Uh yeah, that was a romantic vision.
00:05:01.439 --> 00:05:02.879
It was a wonderful idea.
00:05:02.879 --> 00:05:26.079
However, um KDB developers uh turn out to be actually rationalists, and they saw um what was actually quite obvious and what we didn't want to we we didn't really want to admit, which is that the price of KDB licenses restricts the language usage to some very deep corporate silos.
00:05:26.079 --> 00:05:50.399
And those corporate silos had no use for community code resources, and so we got very few registrations and wound up cancelling the meeting, and then something very significant happened, and um our guest today, Jake, did it, um, just I think the week before last, and it changes the landscape.
00:05:50.399 --> 00:06:05.920
And now there's still some kind of a meeting happening in Suffolk in September, it's emerging what it is in real time, but it's starting to look like ground zero for a QK Q open source community.
00:06:05.920 --> 00:06:08.399
Uh we're pretty excited about it.
00:06:08.399 --> 00:06:17.920
I'm not going to spoil I'm not going to um spoil uh what we're gonna learn from Jake, but um uh that's about it.
00:06:17.920 --> 00:06:20.639
Something's something really exciting is happening.
00:06:20.959 --> 00:06:29.360
All right, so with that, I guess we'll throw it over to to Jake, and you can tell us uh about everything you've been working on and uh what you released uh just in the last little bit.
00:06:29.759 --> 00:06:30.639
Oh sure.
00:06:30.639 --> 00:06:33.920
Um so yeah, so like I said, my name is Jake Lopas.
00:06:33.920 --> 00:06:46.319
Um I've been I've been a K programmer since um probably very early 2000s, maybe 2000, maybe 2000, 2001, at a company called Appian.
00:06:46.319 --> 00:07:04.079
And then I um did that, worked for DOD, then I went to Wall Street, was on Wall Street for a very long time, and then I left um a little more than 10 years ago, and I was on Garden Leave, which I think is a very kind of garden leave is fantastic.
00:07:04.399 --> 00:07:05.120
It is fantastic.
00:07:05.120 --> 00:07:09.040
I I've never been on it, but when I hear people are on it, I was like, the first time I heard about it, I was like, what?
00:07:09.120 --> 00:07:13.759
You're getting paid to do you're getting getting paid not to work anywhere else.
00:07:13.759 --> 00:07:15.920
You're actually getting paid to work in your garden.
00:07:15.920 --> 00:07:29.199
And um, and while while I was on garden leave, I was I started a project um to basically go rebuild um the kind of a K4 and a Q interpreter.
00:07:29.199 --> 00:07:31.920
And uh I called that L.
00:07:31.920 --> 00:07:46.879
And so um, and there had been kind of different versions of that all along the way, but about maybe a month ago, uh got to the point where I was like, hey, let's actually like post this out to the community, see if anybody else wants to play with it.
00:07:46.879 --> 00:07:52.480
Um so it's so L is a K4 compatible, Q compatible.
00:07:52.480 --> 00:08:02.399
Its goal is to be a drop-in replacement so that you can take kind of KDB style workloads and run it, you know, anywhere, right?
00:08:02.399 --> 00:08:14.639
You don't need uh all of the kind of as Stephen said, you know, can we can we kind of take this language and bring it to a larger community in a runtime that you know anybody can run?
00:08:14.639 --> 00:08:27.920
Um and so it was a really small group of people on uh basically a Discord server, and uh then we put up a website and then it got uh uh pretty pretty big pretty quickly.
00:08:27.920 --> 00:08:32.480
So I think we had like in the first two days, the website got discovered.
00:08:32.480 --> 00:08:36.399
Um it's like 48,000 people came to the website.
00:08:36.399 --> 00:08:45.360
We had over 300 downloads of the binary, so which is a good thing the binary is small, uh, because family small.
00:08:45.360 --> 00:08:57.600
So yeah, so that's that's the the thing that has kind of come out here, I'd say, in the last 30 days has been um people downloading the L interpreter, running K4 and Q code.
00:08:57.600 --> 00:09:10.320
Um for me it's really exciting to see not just you know everybody that that kind of I know in this community, but brand new people coming from completely different backgrounds.
00:09:10.320 --> 00:09:20.720
Um like I had somebody last week who emailed to the list group and they were working on telemetry data for um effectively cars.
00:09:20.720 --> 00:09:29.440
I had somebody who emailed that was working on um like biogenomics um and saying, hey, you know, can I use this for this?
00:09:29.440 --> 00:09:31.679
And I was like, yes, it'll be great for that.
00:09:31.679 --> 00:09:37.840
You know, let's talk about you know how do you restructure these kind of problems in an array-oriented thing.
00:09:37.840 --> 00:09:43.440
And um, by the way, it turns out that that KK and Q just absolutely crush for that kind of workload.
00:09:43.440 --> 00:09:49.600
Um at uh we built a rag, uh, which is one of these AI vector search things.
00:09:49.600 --> 00:09:54.960
It was like 20 lines, um, and really, really, really fast.
00:09:54.960 --> 00:09:57.600
So yeah, so that's that's what it is.
00:09:57.600 --> 00:10:06.960
And and it's got a public website, it's at lv1.sh uh because you needed a a short domain, um, and that's as short as I could get it.
00:10:06.960 --> 00:10:10.960
So yeah, that's that's the big big out there in the open.
00:10:11.200 --> 00:10:12.639
Yeah, so it's uh very exciting.
00:10:12.639 --> 00:10:18.080
I did see, I think I saw it first on uh the APL JK Reddit.
00:10:18.080 --> 00:10:19.679
It was posted there by someone.
00:10:19.679 --> 00:10:21.200
And uh very exciting.
00:10:21.200 --> 00:10:30.320
But I so I guess the I mean there's a number of things we could talk about first, but uh probably notable um is the differences, like the runtime differences.
00:10:30.320 --> 00:10:54.080
So do you want to talk about what L offers that uh you know the previous interpreters like because they're and they're not exactly like it's a drop-in replacement from like a what do you call it, language level point of view, but from a runtime point of view, uh there are some differences, which I'm sure uh people listeners of this podcast who are you know programmers, some are maybe not programmers and just curious, but uh I'm sure a lot of the listeners would be curious to hear those differences.
00:10:54.320 --> 00:11:02.559
Yeah, I mean I it it needed to be um language compatible because you know, frankly, I have 20 years of code.
00:11:02.559 --> 00:11:04.480
I didn't want to rewrite.
00:11:04.480 --> 00:11:11.840
Um that said, I I did want to go experiment with you know kind of new ideas under the cover.
00:11:11.840 --> 00:11:22.000
And I and I think the big ones are um, well, the first one, which is pretty straightforward, um, is just SIMD, right?
00:11:22.000 --> 00:11:26.879
You you you want to actually get every cycle out of the chip that you can.
00:11:26.879 --> 00:11:35.200
Um so take all of your primitives, um, you know, sit very quietly and make sure that you can implement SIMD versions of that.
00:11:35.200 --> 00:11:39.039
Uh then once you have that, I wanted auto threading.
00:11:39.039 --> 00:11:46.559
So uh K4 had a concept of uh peach, of parallel each, um, which is wonderful.
00:11:46.559 --> 00:11:49.919
But I you know, it kind of changes the code.
00:11:49.919 --> 00:12:05.440
So I wanted like um, you know, like a reduction like sum or something like that to actually automatically thread over the array and you know, kind of do that that map reduce concept, but do it completely transparently.
00:12:05.600 --> 00:12:11.600
Um does uh K not have any guarantees of stability of results like that?
00:12:11.759 --> 00:12:13.759
Or with regards to floating point?
00:12:14.240 --> 00:12:14.639
Of what?
00:12:14.639 --> 00:12:15.679
Yeah, floating point, yes.
00:12:16.320 --> 00:12:16.639
Yeah.
00:12:16.639 --> 00:12:20.399
Um I don't really know what Kd B has.
00:12:20.399 --> 00:12:29.279
Um L's floating point is there's effectively a like a comparison tolerance that that comes out.
00:12:29.279 --> 00:12:35.759
And yeah, if you sum them in different directions, obviously you would get different values.
00:12:35.759 --> 00:12:45.519
So um so the reductions are are taken in chunks, but the comparison tolerance is uh I think it's it's 18 to the negative 17.
00:12:45.519 --> 00:12:55.919
So it's yeah, as you get far enough out there, um, you can get different answers, but kind of the interpreter itself hides that comparative comparison tolerance at a at a certain level.
00:12:55.919 --> 00:12:57.519
Did that that answer your question?
00:12:57.519 --> 00:13:08.559
You get the same answer every time, um, but it because you are paralyzing and reducing reducers, right?
00:13:08.559 --> 00:13:12.399
You you can if you would get something different than if you were seriously just walking.
00:13:12.399 --> 00:13:13.120
Yeah, yeah.
00:13:13.120 --> 00:13:19.039
Yeah, just like you would get something different if you reversed it and walked through it.
00:13:19.200 --> 00:13:21.840
Yeah, and we I'm asking because we have this problem with dialogue.
00:13:21.840 --> 00:13:32.000
Our summation code and interpreter was written pre-SIMD, and uh and now we can't change it because we we our customers want stability.
00:13:32.000 --> 00:13:37.440
You don't want the amount of money in people's bank accounts to change because we changed the summation algorithm.
00:13:37.440 --> 00:13:42.799
And uh yeah, you might ask why people are using floats for money, they are like well.
00:13:42.960 --> 00:13:49.840
I I think well, if you use if you use floats for money, you should really think very carefully about where your life went wrong.
00:13:49.840 --> 00:13:55.679
But um that that is actually kind of a good segue to last thing.
00:13:55.679 --> 00:14:20.960
So the last thing was this idea of I mean, I call it compression because I can't think of another more elegant way to explain it, but can you take quantitization is maybe another way to say it, but basically, can you can you take this array and can you store it in a different format that allows you to work on smaller uh memory footprints?
00:14:20.960 --> 00:14:29.360
So can you can you change underneath the covers, can you change, can you compress that array into another format?
00:14:29.360 --> 00:14:32.720
And then most importantly, can you work on that compressed device?
00:14:32.720 --> 00:14:40.000
Can you can you make all of the array operators, can you make all of the verbs and adverbs work on what I call computer and compressor?
00:14:40.000 --> 00:14:42.159
Lots of people call it computer and compressed.
00:14:42.159 --> 00:14:52.559
Um and when you do that, you could do something like if you are storing money as floats, like behind the covers, L doesn't store that as a float.
00:14:52.559 --> 00:15:06.559
L actually goes ahead and promotes that into an int, um, and then kind of does this very clever little trick underneath the covers um to allow you to operate in the int space and then gives it back to you in in the floating point space, um, or the real space, depending on.
00:15:06.559 --> 00:15:22.240
So um so those three things, kind of the the SIM D, the auto-parallelization, which is different than SIM D, um, and the compression, those are probably the three giant pillars that are really fundamentally different.
00:15:22.240 --> 00:15:26.960
I mean, compression, compression, I started doing compression a couple years ago.
00:15:26.960 --> 00:15:34.399
And it was uh it was enough of a performance improvement that I actually had to delete everything and start over.
00:15:34.399 --> 00:15:39.919
Um, because you basically changed the entire uh representation of the object.
00:15:39.919 --> 00:15:44.639
But it turns out that that is the unlock from a performance standpoint.
00:15:44.639 --> 00:15:53.679
Um, you can really only make these things go so fast in SIMD, you can only make them go so fast, you know, across multiple cores.
00:15:53.679 --> 00:15:57.200
The I mean, bandwidth, memory bandwidth is the enemy.
00:15:57.200 --> 00:16:02.159
So you know, I say this all the time, but making things go faster is actually pretty simple.
00:16:02.159 --> 00:16:07.039
You just move less data over a shorter distance using a more efficient protocol.
00:16:07.039 --> 00:16:14.559
So um if you can take that array and move it into a smaller type, um, you can move less data.
00:16:14.559 --> 00:16:22.879
You know, you have to be very cognizant of making sure that where that array is relative to the core that it's going to operate on, that's your shorter distance.
00:16:22.879 --> 00:16:29.200
And you know, really the protocol you can think about as the actual operation, the CIMD operation underneath the covers.
00:16:29.200 --> 00:16:33.679
So those those are kind of the three crazy, crazy ideas.
00:16:33.840 --> 00:16:35.759
Um doesn't sound very crazy.
00:16:35.759 --> 00:16:37.519
I misunderstood when I was reading up on this.
00:16:37.519 --> 00:16:41.919
I thought by compression you actually like compressed data as in zipping it, but it's not.
00:16:41.919 --> 00:16:43.840
You're just talking about using data types.
00:16:44.159 --> 00:16:47.840
Yeah, dictionary compression is a really I I don't think really helpful.
00:16:47.840 --> 00:16:50.480
Um, because you can't really operate it on it.
00:16:50.480 --> 00:16:52.480
You can't really operate on it.
00:16:52.559 --> 00:17:07.279
I I think well you you could like let's say you had a matrix stored as as some vectors and it was fairly sparse, and you actually compressed each row separately, and then you want to reverse the order of the matrix, this you can do without decompressing the components, right?
00:17:07.279 --> 00:17:14.640
So I that's that was the idea I got when you when I heard about like compression, it's like, well, how in the world do you write algorithms to operate on the compressed data?
00:17:14.640 --> 00:17:23.920
But if you just mean data types that are more of more dense for the data that's actually there, then that's pretty regular fair for array languages.
00:17:23.920 --> 00:17:27.759
I I thought that every serious array language already did this.
00:17:27.759 --> 00:17:35.039
And if obviously you can't tell me about the source code at uh of of official KQ, KDB.
00:17:35.039 --> 00:17:40.559
Um I would I assume that that was happening underneath the cover there as well.
00:17:40.799 --> 00:17:51.920
Well, well, I think in a like like let's take a simple example, probably the the easiest codec that there is to kind of you can kind of almost see it in your mind is the the frame of reference, right?
00:17:51.920 --> 00:18:00.079
So imagine you've got um, you know, I don't know, 255 plus till a thousand, all right?
00:18:00.079 --> 00:18:02.640
Or 255 plus iota a thousand.
00:18:02.640 --> 00:18:06.960
Um so now you've got this big array of 32-bit integers.
00:18:06.960 --> 00:18:10.880
Um frame of reference basically says find a minimum, right?
00:18:10.880 --> 00:18:15.200
Store that offset as the base, remove that from everything else.
00:18:15.200 --> 00:18:20.720
And then the question is now you've got a base, and then you've got a payload, right?
00:18:20.720 --> 00:18:24.000
You've removed the base from the array, and now you've got a payload.
00:18:24.000 --> 00:18:30.240
Is there a bit width that can represent that payload smaller than the original bit width?
00:18:30.240 --> 00:18:36.160
And um, and it turns out that the answer is yes, that happens like all the time, right?
00:18:36.160 --> 00:18:43.599
You can, you know, you might have an array of 32-bit integers that you can represent as you know, as a short.
00:18:43.599 --> 00:18:54.799
Um or you know, if you kind of take frame of reference and apply delta on top of it, you might actually be able to get that down to four bits, right?
00:18:54.799 --> 00:19:15.039
So, and you know what's really nice about frame of reference, aside from the fact that it's kind of easy to see in your mind, is if you make everything do that from the beginning, then you kind of get these free little performance wins just by the structure of that.
00:19:15.039 --> 00:19:21.759
So, uh to give you an example, let's say you wanted to add an atom to that array, right?
00:19:21.759 --> 00:19:25.119
Well, obviously there's no reason to do that element-wise.
00:19:25.119 --> 00:19:29.519
If you're going to add the atom to every single value of the array, you would just add it to the base.
00:19:29.519 --> 00:19:33.680
Um so these kind of operations become faster.
00:19:33.680 --> 00:19:46.400
Um, also, when you when you kind of sweep to go do the bit width calculation, you're gonna get some pretty useful metadata that's gonna fall out for free that you might want to actually stamp on the object, right?
00:19:46.400 --> 00:19:50.400
So um you you know, certainly you're gonna get the range, right?
00:19:50.400 --> 00:20:01.519
Um, and again, as you kind of do this consistently, what you start to find is you know the performance wins stack up like a lot.
00:20:01.680 --> 00:20:03.039
Yeah, I understand a lot a lot.
00:20:03.039 --> 00:20:06.000
So it's it's I just I just remembered now.
00:20:06.000 --> 00:20:16.480
What I what I understand from you is uh is that you're doing this aggressively, you're doing every basically taking every data type that exists, uh, and and and trying to combine.
00:20:16.480 --> 00:20:23.759
So I I I know array languages traditionally do things like this, but they tend to restrict themselves to a few types rather than every possible type.
00:20:24.640 --> 00:20:27.039
Anything worth doing is worth overdoing.
00:20:27.039 --> 00:20:29.359
Um so yeah, it happens.
00:20:29.920 --> 00:20:41.680
There was a uh there was a talk by Simon Garland that spoke about differences in uh in how in the implementation of of KQ and APL.
00:20:41.680 --> 00:20:46.640
And he said that there were uh APL traditionally has bit booleans, right?
00:20:46.640 --> 00:21:03.759
But that requires a lot of fancy uh bit flipping work to to make all your algorithms work, but it does create a huge difference in in performance because I mean at worst, an eighth of the uh of the data going across.
00:21:05.440 --> 00:21:16.640
But then when you want to do something like you know, get the average of a Boolean array um to give you like a probability, then you know, then you have to kind of start going the other way.
00:21:16.960 --> 00:21:24.559
Well you don't have to put you uh explode it up to to bytes because you could in the inter the the processor has pop counts, right?
00:21:24.559 --> 00:21:24.960
Yep.
00:21:24.960 --> 00:21:35.279
So there so there are lots and lots of fancy tricks you can do, and then and then the processors have like APL functions like expand and compress and things like that.
00:21:35.279 --> 00:21:37.359
Uh and that that they can they can do.
00:21:37.359 --> 00:21:40.079
But remember, he spoke about that's where I want to get here.
00:21:40.079 --> 00:21:49.039
He spoke about the changes or the the differences in how you design the language based on how it's implemented.
00:21:49.039 --> 00:22:20.799
And I thought that was really interesting that because K doesn't have bit booleans, there's no point in having a primitive built in verb, whatever you want to call it, uh Of compress rather you just use indexing with a where right so you convert the Boolean to indices, and then at that point it it you lose a lot of uh of the length because all the zeros go away, and you're not you at least if it's shorter than 256, uh then then it's not going to blow up the type for the indices being there.
00:22:20.799 --> 00:22:24.559
Everything is every element, every Boolean is one byte, so it doesn't make a difference.
00:22:24.559 --> 00:22:30.400
And and so you don't need a compressed function, therefore k doesn't have a compressed function, it just uses indexing wheelware.
00:22:30.400 --> 00:22:40.559
Whereas APL that does have bit booleans, does have compressed, and it's a huge waste to blow up a Boolean that's already packed to uh integers before you do that.
00:22:40.559 --> 00:22:42.559
So now here's the kicker then.
00:22:42.559 --> 00:22:55.200
If you aggressively pursue all these internal representations, such that yeah, I'm sure you do have bit booleans, then and but isn't the language then like doesn't it fight you in that way?
00:22:55.200 --> 00:23:03.279
That it that you it for the the way people write the code forces you to blow up your your beautiful bit booleans to ugly big integers.
00:23:04.079 --> 00:23:15.200
Yeah, and so you are describing essentially the three-year nightmare of stepping back and saying, Okay, all right, this works.
00:23:15.200 --> 00:23:25.680
What of these what of these verbs and adverbs do I need basically result in um in materializing?
00:23:25.680 --> 00:23:35.359
And then you just sit there very quietly with a giant yellow notebook and um and you knock them all out.
00:23:35.359 --> 00:23:38.720
And um you can't knock all of them out.
00:23:38.720 --> 00:23:45.680
Um so like some of the transcendentals, obviously, you do just because of kind of the nature of that, you do need to materialize them.
00:23:45.680 --> 00:23:50.640
But then then you start thinking about well, do I need to materialize the whole array?
00:23:50.640 --> 00:24:00.880
Or do I only need to materialize, you know, so I can move the array in into the cache line, but then when I'm doing the operation, I have to do a small materialization.
00:24:00.880 --> 00:24:04.960
I can uh you know, maybe store that in a scratch offset.
00:24:04.960 --> 00:24:08.319
Can I can I still save some memory bandwidth moving over?
00:24:08.319 --> 00:24:14.960
So the ideal scenario is um, you know, kind of a closed form of computer compressed.
00:24:14.960 --> 00:24:17.200
You want to get all of those that you can.
00:24:17.200 --> 00:24:34.960
And then, you know, worst case scenario, you want to get to to kind of a partial form of computer compressed, where you're like, all right, well, at least I'm gonna move this small, this, this much smaller thing over the memory bandwidth, but then I I am actually gonna have to work, kind of uh, you know, allocate a little space on the stack.
00:24:34.960 --> 00:24:38.960
I'm gonna have to explode this thing up and do a little bit of work and take it chunk by chunk.
00:24:38.960 --> 00:24:58.079
But um, yeah, Adam, I actually have a like a grid of all of the verbs, and I can I don't I don't know if I have it in front of me, but I can send it to you where it's got all the verbs, and you can and you can see kind of over time where it goes from basically red where you had to materialize to green where it uh where it operates compute on compressed.
00:24:58.240 --> 00:25:06.720
Um so so you're saying okay, so you're also aggressively using things like arithmetic progression vectors for the for things like indices.
00:25:06.720 --> 00:25:08.240
So they stay small.
00:25:08.240 --> 00:25:11.920
Yeah, but do do you also I don't know if it's a universal term or something?
00:25:11.920 --> 00:25:29.759
There's something at least in the in some area, some people use the term thunks, where the where the language does not actually evaluate some code, but rather remembers that this verb needs to be uh applied to this noun, but doesn't do it until necessary.
00:25:29.759 --> 00:25:32.400
So for example, you you you could do that.
00:25:32.400 --> 00:25:37.839
Let if somebody does a where on a boolean in order to index, then you wouldn't do the where on the boolean.
00:25:37.839 --> 00:25:49.359
You would remember that this where needs to be applied on this array, and then when you get to the index indexing, then the interpreter goes, Oh, wait a minute, indexing on something where where needs to be applied on a Boolean.
00:25:49.359 --> 00:25:51.119
I know this, that's just a replicate.
00:25:51.119 --> 00:25:58.480
So then it goes in and directly takes the Booleans and does the filtering and skips the whole materialization of the indices.
00:25:58.799 --> 00:26:04.720
Yeah, there's no kind of delayed compute there, but or at least not in L.
00:26:04.720 --> 00:26:05.440
Yet.
00:26:05.440 --> 00:26:08.160
But it does have a concept of fusion.
00:26:08.160 --> 00:26:14.240
Um so fusion, uh, you know, fusion I think is a really loaded term.
00:26:14.240 --> 00:26:17.200
Um uh Rick Sony works with this on me.
00:26:17.200 --> 00:26:20.480
Is so fusion means different things with different people.
00:26:20.480 --> 00:26:25.920
So for the easy case, it basically means no intermediates, right?
00:26:25.920 --> 00:26:41.119
So if I um, you know, if I do whatever some square root x, right, can I can I do this without creating intermediates, or better yet, would be like a chain of functions where it's you know array uh where the output is array, array, array.
00:26:41.359 --> 00:26:44.799
If you if you do two plus three times times an array, right?
00:26:44.799 --> 00:26:51.279
So then then since you need to loop over the array to do the the three times, you might as well do two plus three on each one separately.
00:26:51.599 --> 00:26:55.119
Yeah, and then like then you just hate yourself.
00:26:55.359 --> 00:26:58.720
Um so but how do you do that without being lazy?
00:26:59.119 --> 00:27:10.640
Yeah, so essentially underneath the covers, um every array you can you can borrow basically you can think about it almost like copy on right.
00:27:10.640 --> 00:27:27.839
Um so when an input comes in, it it can be uh kind of borrowed, which means you can mutate it, or it's you know, it's effectively you're operating on a copy, and then you can just mutate the intermediates, and then you don't um then you don't really have those intermediates.
00:27:27.839 --> 00:27:28.720
You know what I'm saying?
00:27:28.720 --> 00:27:38.960
You're not you you're kind of working directly, you're literally mutating the the input comes in and it's like, hey, this is safe to mutate, you do square root on it, mutate it in place.
00:27:38.960 --> 00:27:40.160
Oh, right.
00:27:40.240 --> 00:27:43.279
You you mean you're having a you have a ref count on the arrays, right?
00:27:43.279 --> 00:27:46.000
If the ref count is one, you know you can do it in place with it.
00:27:46.240 --> 00:27:46.640
Yep.
00:27:46.640 --> 00:27:50.640
Um and you kind of have to do that way up in the beginning.
00:27:50.640 --> 00:28:07.279
And then that's the other concept of fusion is this idea of hey, we're going to, you know, if we detect, and there's the this is done in L, like I think it's done pretty much everywhere else, which is just basically with uh kind of a table of known operators.
00:28:07.279 --> 00:28:17.039
But um, if you see this, you know, kind of bytecode type, you this structure of bytecode, let's go ahead and replace it with this other function, right?
00:28:17.039 --> 00:28:22.559
So um and and L does that in its fuse.c implementation.
00:28:22.559 --> 00:28:28.079
So it it uses actually it looks very similar to LuaJet from uh Mike Paul's.
00:28:28.079 --> 00:28:38.400
So it kind of looks at the bytecode and goes, aha, you're doing um, you know, you're doing where, you know, where array greater than x.
00:28:38.400 --> 00:28:39.839
Um okay.
00:28:39.839 --> 00:28:46.480
Uh there's actually a different kernel for this that we're gonna we're just I'm just gonna like swap out that byte code and replace it with this other one.
00:28:46.480 --> 00:28:47.759
It's gonna be a lot faster.
00:28:47.839 --> 00:28:59.839
Uh but again, if you do where arrays greater than x, I mean if you're just naively executing this this code, then you see the the comparison, you do the comparison, then you get to the where.
00:28:59.839 --> 00:29:04.480
Surely there must be some amount of laziness for it to even recognize the pattern.
00:29:04.480 --> 00:29:06.799
There's there's no laziness.
00:29:06.880 --> 00:29:11.039
It will actually Rick and I talk about working vertically versus horizontally.
00:29:11.039 --> 00:29:27.759
So you might want to, under certain operations, instead of doing uh the whole vector A, then the whole vector B, then the whole vector C, you actually might want to flip it on its side and do, you know, operator, operator, operator, operator, operator, operator operator.
00:29:27.759 --> 00:29:28.480
Yeah, mate.
00:29:28.480 --> 00:29:29.519
That's the fusion meaning.
00:29:29.519 --> 00:29:30.160
Yep.
00:29:30.160 --> 00:29:32.960
And so um we'll swap that out.
00:29:33.039 --> 00:29:39.279
That that little bit will swap out um so the interpreter reads ahead of what's going, what's coming?
00:29:39.359 --> 00:29:41.440
That's how it's well it just looks at the bytecode.
00:29:41.440 --> 00:29:44.400
So um when you write when you write the function, right?
00:29:44.400 --> 00:29:46.160
You write foo, whatever.
00:29:46.480 --> 00:29:47.759
That gives you the bytecode.
00:29:48.079 --> 00:29:54.079
Yeah, and then when the thing goes to the generating the bytecode, it's like, okay, I've made this bytecode just the way you asked.
00:29:54.160 --> 00:29:56.240
And then people I think I think I think you get it.
00:29:56.400 --> 00:30:00.799
Okay, so you so there's a it's not as complex as as as as well.
00:30:00.799 --> 00:30:01.359
No, no, no.
00:30:01.359 --> 00:30:02.079
I think we get it there.
00:30:02.240 --> 00:30:05.839
So there's a it's sort of like halfway halfway compiled, right?
00:30:05.839 --> 00:30:08.960
Then the interpreter goes through, take, takes the code, converts it.
00:30:08.960 --> 00:30:18.480
I suppose it builds some some AST internally for the function that that these and then it recognizes parts that the branches on the tree, and then says, Oh, I know this tree, this tree branch.
00:30:18.480 --> 00:30:20.079
Let's change that to something else.
00:30:20.079 --> 00:30:22.640
There you have an advantage we can't do in a dialogue.
00:30:22.640 --> 00:30:25.359
Yeah, because we're not statically parsable.
00:30:26.000 --> 00:30:31.200
That's actually how I mean it unfortunately it does have to do it in a two past, but it doesn't really matter.
00:30:31.200 --> 00:30:45.200
Um but yeah, it's that's how my call does kind of legit in in a lot of ways, is kind of looking at the intermediate representation, and that's where the that that's where the swap out happens.
00:30:45.200 --> 00:30:49.599
So I, you know, and I think that's kind of the fun part.
00:30:49.599 --> 00:30:58.400
It's nice to have the restriction of this this code must run this language standard, and you're like, but I want to do this.
00:30:58.400 --> 00:31:04.799
And it's like, all right, well then you have to you have to do it without changing that code or changing that language, right?
00:31:04.799 --> 00:31:28.079
So um, so you know, fuse.c, which kind of does that walk over the over the interpreter, over the bytecode, or you know, the actual object storage, where it's like, I'm giving you an array of dates, and it's like, okay, I'm I'm gonna tell you it's an array of dates, but I'm definitely not gonna store it like that, and I'm not gonna operate on it like that.
00:31:28.079 --> 00:31:34.480
Um and so I think you know, these little things, they I mean, they stack up.
00:31:34.480 --> 00:31:37.279
Um, I've I've gotten reports in the field.
00:31:37.279 --> 00:31:45.920
I think the the worst report I have from the field is that it's six times faster, and some of the best reports are just insane.
00:31:45.920 --> 00:31:49.279
But um again, there's no magic trick here.
00:31:49.279 --> 00:31:58.559
It's just there are some there are some places where you would probably want to change the language, although I'm nowhere near smart enough to write a better language.
00:31:58.559 --> 00:32:05.039
So instead, you just go, okay, well, I know that this combination of operators is more efficiently done this other way.
00:32:05.039 --> 00:32:07.359
And so I'm gonna put that in my fusion table.
00:32:07.359 --> 00:32:10.400
And then if I see that bytecode, I'm just gonna swap it out with this one.
00:32:10.640 --> 00:32:15.279
Um so if I understand correct, this is super um, super fascinating.
00:32:15.279 --> 00:32:26.160
Uh and it was interesting too when you were listing off like the major three things, you left out the fusion, uh, which I was like, wow, like if fusion doesn't fusion doesn't even make the top three, like that's uh that's pretty crazy.
00:32:26.160 --> 00:32:28.880
Um go ahead.
00:32:28.880 --> 00:32:29.599
Yeah, yeah, four.
00:32:29.599 --> 00:32:41.599
Um if my understanding is correct, then so uh with the ref count um basically reference counting, you avoid like the unnecessary allocations, which is like the biggest win.
00:32:41.599 --> 00:32:53.680
So does but does that mean that the like the luogit, not that that's what we're calling it, but you know, the that kind of mechanism that's doing that fusion, if that doesn't have uh uh you know a pattern recognition for a certain thing, yeah.
00:32:53.680 --> 00:33:08.160
Is it is it then like so say in the example that Adam had where it was you know plus X, you know, times Y or whatever, if it if it didn't, I'm sure it does have uh you know uh uh recognizes that and then replaces the the bytecode.
00:33:08.160 --> 00:33:15.839
But if it didn't, does that mean that you'll avoid the allocations, but you might end up iterating still the number of times the operations?
00:33:15.839 --> 00:33:29.119
So but like you basically there's two pieces you can expect to avoid allocations because of the reference counting, and then the uh the bytecode uh pattern recognition or whatever you want to call it, um, that's the one that like fuses the operations.
00:33:29.119 --> 00:33:30.559
So it's kind of like two pieces.
00:33:30.559 --> 00:33:36.880
You can get you guaranteed like your reference counting if it's one, you'll get that piece, and then it's just a matter of uh it recognizing.
00:33:36.880 --> 00:33:57.200
I mean, that's very and on top of honestly, I had never not to switch completely topics while I'm talking, I'd never heard of this uh because Adam says, Oh, you know, I think most languages, I had never heard of this kind of like separating or like compressing uh data into a smaller bit width by like basically storing a component of it.
00:33:57.200 --> 00:34:06.880
And then like it's very it's I don't know, it sounds novel to me because I've never thought about this, but then when you were like, oh, you know, if you just add a number, you can just do it to the base, and I was like, that's crazy.
00:34:06.880 --> 00:34:11.440
Like you you turn what, even if you're gonna use fusion, like because that's typically the way I would solve that, right?
00:34:11.440 --> 00:34:16.880
Like there's a an array language called cap um that is implemented in Kotlin and it's a lazy APL.
00:34:16.880 --> 00:34:21.360
So if you do a plus one or a plus X, it just it'll defer, it won't do it.
00:34:21.360 --> 00:34:28.320
So you you know, you're you're not gonna pay like a linear time for that operation, it'll just bundle it with whatever it needs to down the road.
00:34:28.320 --> 00:34:32.000
But in your implementation, it's just an O one operation, like who cares?
00:34:32.000 --> 00:34:47.920
Um and like that then my my my my my brain is like how many different cases like are there like you know uh tricks like that where you can turn you don't even need to fuse anything, like you can turn what would be an ON operation into just like a constant time thing.
00:34:47.920 --> 00:34:53.280
Um and Adam, you said like like this is classic, like this is a lot of interpreters do this kind of thing.
00:34:53.280 --> 00:34:54.000
Like, I don't know.
00:34:54.239 --> 00:34:59.039
So in APL land, I it for commercial, like a real APL implementation.
00:34:59.039 --> 00:35:02.239
I think it's unheard of to not do um type.
00:35:02.239 --> 00:35:04.079
So this doesn't have a name though.
00:35:04.079 --> 00:35:05.199
That's the thing, like Jacob.
00:35:05.199 --> 00:35:10.400
You you were saying that we call it squeeze internally, but the APL never ex sees this, right?
00:35:10.400 --> 00:35:18.800
You don't you can't it's not directly observable unless the vendor puts something into the language that lets you observe under the covers.
00:35:18.800 --> 00:35:19.679
So we have something.
00:35:19.679 --> 00:35:20.719
Like we're at dialogue.
00:35:20.719 --> 00:35:35.599
I can show you that dialogue has something called quad dr data representation, and it will tell you uh the what the internal representation is, how many bits per element and what type uh it is.
00:35:35.599 --> 00:35:41.280
And you can see that if you uh if you give it a one, if you give it one Boolean, you will say it's a byte.
00:35:41.280 --> 00:35:44.639
It doesn't bother to make it a bit because you're not gonna save anything.
00:35:44.639 --> 00:35:49.920
If you then connect that, make a vector of two bits, then it will squeeze it down to a single byte.
00:35:49.920 --> 00:35:56.800
And it's just using it has a length field, so it just says, okay, only the first two bits of this byte are actually the data that we're using right away.
00:35:56.800 --> 00:35:58.800
You cannot really stop it from doing that.
00:35:58.800 --> 00:36:08.000
Uh I mean you can, you can you can tell the interpreter don't don't squeeze this array, but it's not gonna stay forever, it will only be as until it finds that it's convenient to do it anyway.
00:36:08.000 --> 00:36:11.360
Um, and it yeah, it's aggressive, it does it all the time.
00:36:11.360 --> 00:36:16.639
And even though there's so many checks for every operation, do another check, what can we now squeeze?
00:36:16.639 --> 00:36:18.239
It it sure saves time.
00:36:18.239 --> 00:36:20.800
It would be unbearably slow if if you didn't do this.
00:36:20.800 --> 00:36:26.320
And the bit bit Boolean algorithms are are super optimized for do all kinds of crazy things.
00:36:26.639 --> 00:36:27.119
Did you say Jake?
00:36:27.119 --> 00:36:31.119
That because you it sounds like you've well, I mean, I guess you didn't come up with this idea.
00:36:31.119 --> 00:36:36.239
I mean, I'm hearing about it for the first time today, but apparently lots of folks know about this you know for decades.
00:36:36.239 --> 00:36:40.239
But like you've taken this idea, pushed it to like you know 110%.
00:36:40.239 --> 00:36:48.000
And um would you say like of the four different things, this is what gets you the the largest percentage of the game?
00:36:48.000 --> 00:36:53.599
Like because you're saying you basically went back and rewrote you know most of the language, if not all of it, because of this.
00:36:53.840 --> 00:37:10.400
Um that's really interesting too that that that's the main thing because if we I can tell you in dialogue has bit booleans, and then it has got one, two, and four-byte integers, and then we've got uh 64-bit floats, and and we have a crazy uh decimal uh 128-bit flows.
00:37:10.400 --> 00:37:17.199
We've got some two times 64-bit uh float complex numbers, and and even for characters we do this.
00:37:17.199 --> 00:37:21.039
So even text data will be the one, two, or four-byte uh per character.
00:37:21.039 --> 00:37:25.599
If you're writing ancient Chinese text, you think you're gonna end up with four bytes per character.
00:37:25.599 --> 00:37:30.239
Um, I know that APL plus only has a single integer type.
00:37:30.239 --> 00:37:43.519
It does do bit booleans, I think every APL does, um but then it just goes up to a full uh I don't know if it's 64-bit or 32-bit integer type, and then uh and then they have floats.
00:37:43.519 --> 00:37:49.199
Um and yeah, I didn't know that being so aggressive about the types would make such a big difference.
00:37:49.199 --> 00:37:57.039
I knew that it does make a difference to have this sort of thing, but certainly we don't do uh two-bit integers and four-bit integers.
00:37:57.440 --> 00:38:00.639
Oh yeah, it makes all the difference in the world.
00:38:00.639 --> 00:38:16.480
Because the you know, I think the thing that is different today than you know, whatever, 20 years ago, more than 20 years ago when Arthur did uh K is the the CPUs are fast, but it's the memory that's slow.
00:38:16.719 --> 00:38:19.440
Yeah, yeah, that that's that's well recognized.
00:38:19.679 --> 00:38:26.880
Yeah, and it's it's I mean the memory bandwidth is just fighting you everywhere along the path.
00:38:26.880 --> 00:38:31.440
And so, you know, again, you just you gotta just move less data.
00:38:32.159 --> 00:38:44.239
So for all the mathematical verbs, yeah, they are there libraries out there for like four-bit integer multiplication things like that because it's it's going to be a crazy mess.
00:38:44.800 --> 00:38:45.760
Yeah, it's a mess.
00:38:46.159 --> 00:38:47.519
Yeah, it takes years, yeah.
00:38:47.519 --> 00:38:54.400
Like, yeah, because either either you blow up every time you do something, you blow up to then you might as well not store it like that if you're not changing up an hour.
00:38:54.400 --> 00:39:02.239
So you have to you have to do have to stay at your type and still do multiplications at every width and additions, and uh etc.
00:39:02.239 --> 00:39:02.800
etc.
00:39:02.800 --> 00:39:04.559
That's yeah, uh huh.
00:39:04.559 --> 00:39:13.199
No, you have to some people described uh array languages and ascribed it for AP described for APL but it would be the same across the mole, that they're sort of like code libraries.
00:39:13.199 --> 00:39:26.719
You have some people, very clever people, working for many, many years to write all kinds of extreme algorithms for doing things well, and then you just use a simple symbol, a glyph, and you get all that hard work.
00:39:26.960 --> 00:39:44.320
Yeah, and there, I mean, there are some libraries that do things like um kind of fixed point arithmetic, and um uh there's a there's a GNU library that's you know kind of really good about uh but I mean at the end of the day, uh none of that stuff really helped.
00:39:44.320 --> 00:39:50.159
Um papers help, but you know, eventually you gotta roll up your sleeves and just do the implementation.
00:39:50.159 --> 00:39:58.800
And the trick is since you can't change the language, um you have to think about making the codec uh standard, right?
00:39:58.800 --> 00:40:08.239
So even though there's a bunch of codec under the under the covers, they all effectively share this concept of like a base and a payload and then a patch.
00:40:08.239 --> 00:40:11.280
Um you don't need a patch for frame of reference.
00:40:11.280 --> 00:40:18.320
But um yeah, you can you can I I will get you the HDML document and you can see what's left.
00:40:18.320 --> 00:40:20.960
Uh I think the only ones that are really left are the transcendentals.
00:40:20.960 --> 00:40:28.480
You have to do them partially, but um but um you have to do them partially if you're not doing the fast math versions.
00:40:28.639 --> 00:40:44.000
Um also helps you that language has a small vocabulary and not so mathematics oriented for that for APL this would be a nightmare because of all the fancy built-ins, and for something like J, it would be well I it's funny.
00:40:44.079 --> 00:41:00.159
I I think I think if you I am not a language developer, I could never write a language, I do not have that much um creativity and elegance and foresight, and I don't have any of that.
00:41:00.159 --> 00:41:01.280
I'm a mechanic.
00:41:01.280 --> 00:41:06.800
Um, so but the simpler the language, the the more you can do with it, right?
00:41:06.800 --> 00:41:17.119
So, you know, again, I've mentioned him a couple of times, but like Mike Paul's Lua Jet is I still think one of the most underappreciated pieces of code.
00:41:17.119 --> 00:41:21.760
And the the reason why you can get away with it is because Lua is so simple.
00:41:21.760 --> 00:41:34.400
Um Q is actually very messy, but K itself, I mean Q is built in K, but K itself is actually very simple and super elegant, and it's not a giant surface.
00:41:34.400 --> 00:41:43.039
So if you can, you know, if you start with something simpler, you can you can actually squeeze a lot of performance and you can do a lot of these tricks.
00:41:43.039 --> 00:41:48.159
Um because it's a nice, well-bounded framework that you're gonna work inside.
00:41:48.159 --> 00:41:56.800
So um, and yeah, you can in L, you can, I mean it's not I mean it's not hidden, you can do it, but you can do negative 17 bang.
00:41:56.800 --> 00:42:05.440
Negative int bang is kind of the KQ world of I've got this function, but I don't know what to call it yet, or something.
00:42:05.440 --> 00:42:20.639
Um, and you can do negative 17 bang and you can see kind of what is the object stored um into like how many bytes is is the object compressed, which should always be yes, and then how many bytes is it actually storing versus how many bytes was it originally?
00:42:20.639 --> 00:42:32.639
And you know, the other thing is again, this is not a like K and Q and and L they are not show horses.
00:42:32.639 --> 00:42:53.199
They're workhorses, like they're not they're do to the you know, these languages are built to do very specific, very kind of distinct workloads, and you know, database style workloads and financial style workloads, and so you know, you don't you don't have to you have to be able to solve those problems.
00:42:53.199 --> 00:42:55.599
Um, you don't have to be able to solve all problems.
00:42:55.599 --> 00:43:06.400
So I I mean again, uh K always had a concept of a comparison tolerance, and that's like you know, I I don't know if that's how it works in a APL, right?
00:43:06.400 --> 00:43:17.039
If you've got two uh 64-bit floats and they're almost the same, but not exactly the same, like at what point do you say those are equal?
00:43:17.280 --> 00:43:27.920
Um APL is has at least for very long time has had has a configurable um comparison tolerance, that's what it's called, and as well.
00:43:27.920 --> 00:43:30.000
But I know J's is fixed.
00:43:30.000 --> 00:43:31.760
You can I don't think you can you can change it.
00:43:31.760 --> 00:43:33.599
I suppose case is also fixed.
00:43:33.599 --> 00:43:42.719
I case case is fixed, L's is fixed, um and it's it's a is it a multiplicative uh comparison tolerance?
00:43:42.719 --> 00:43:51.039
So it's like there has to be a factor of of one plus ten to the power of negative seventeen maximum ratio between them, right?
00:43:51.360 --> 00:43:51.920
Yep, yep.
00:43:51.920 --> 00:43:58.880
So which is almost a shame because then you can't really do the uh then you can't just do the mem compare to exactly.
00:43:58.960 --> 00:44:01.920
Yeah, that makes that makes Load operation is much, much slower.
00:44:01.920 --> 00:44:05.840
And you really it would be sort of nice to not do that.
00:44:06.480 --> 00:44:11.360
Unless you've got a compression codec that kind of knows that from the beginning, right?
00:44:11.360 --> 00:44:14.239
Um sorry, Steven has his hand up.
00:44:14.480 --> 00:44:15.679
Yeah, I was gonna say hop in here.
00:44:15.679 --> 00:44:18.960
And also, too, we've got two questions in the the chat.
00:44:18.960 --> 00:44:21.920
Um, so uh we'll probably ask those in a little bit.
00:44:21.920 --> 00:44:26.719
Uh but yeah, if you have questions, feel free to cue them up and we'll make sure to to get to go to those in a bit.
00:44:26.719 --> 00:44:28.000
But yeah, Steven, go ahead.
00:44:28.480 --> 00:44:35.199
Well, look, Jake, we've spent a little time exploring the implementation of how you manage to get ahead on performance.
00:44:35.199 --> 00:44:42.400
Uh and I'd like to ask you a version of the question I was asking you the other um the other day on our call.
00:44:42.400 --> 00:44:53.599
You've got an interpreter that has 100% coverage of the key language uh and at least as much speed to put it to put it um mildly.
00:44:53.599 --> 00:44:56.400
Um, what do you want for this language?
00:44:56.400 --> 00:44:58.719
Um, that's not I'm not asking for a price.
00:44:58.719 --> 00:45:02.639
I don't know what you want to happen first.
00:45:03.199 --> 00:45:11.440
No, I think you need um we need more K and Q developers.
00:45:11.440 --> 00:45:21.360
We need a giant army of people building great systems, great code, and it needs to be out there.
00:45:21.360 --> 00:45:31.440
Like I um, you know, recently we've been doing a lot of work with kind of AI folks, and you know, it's like, why did Python win data science?
00:45:31.440 --> 00:45:35.039
Um, this is pretty easy because everyone used Python.
00:45:35.039 --> 00:45:37.599
Um, and there's a million packages.
00:45:37.599 --> 00:45:39.920
Um, you know, sci fi is amazing.
00:45:39.920 --> 00:45:47.599
Like, I mean, it's it is, it is actually amazing, but boy, is it slow and boy is it verbose.
00:45:47.599 --> 00:45:52.320
Um, and I think, you know, I think there were really two problems here.
00:45:52.320 --> 00:46:00.960
One was, you know, unless you were kind of a member of the Illuminati, getting access to these interpreters was very difficult.
00:46:00.960 --> 00:46:04.800
Um, and that that that that obviously needed to go away.
00:46:04.800 --> 00:46:27.360
Um, and then I think the second one was, you know, even though you know people like the bro have done great work on documentation and books and implementations, uh there there wasn't if you came, even if you had the interpreter and you had some base knowledge like Q for Mortals or something, um, it it's still difficult.
00:46:27.360 --> 00:46:30.079
You kind of learn this thing, or at least I did.
00:46:30.079 --> 00:46:35.119
Uh, you know, this language was kind of passed down like a secret from one person to another.
00:46:35.119 --> 00:46:41.920
You would learn, you know, uh, and I think that LLMs are making that go away.
00:46:41.920 --> 00:46:54.800
You know, you can you can ask, whatever, sub your favorite LLM in, but you can ask your favorite LLM how to do something in an idiomatic way, and you you tend to get right answers.
00:46:54.800 --> 00:47:00.960
And I think, you know, I think of the LLM as like an infinitely patient teacher, right?
00:47:00.960 --> 00:47:10.960
So um now it's not perfect, but you know, as as I always say to people when you have new technology, it's like, hey, just remember, this is the worst it's ever gonna be.
00:47:10.960 --> 00:47:27.360
Um, so you know, and especially in the array languages, you I I don't know about you guys, but I I have always said it's like I will go think about something for hours, hours and hours.
00:47:27.360 --> 00:47:30.079
And then it might take me five minutes to code it.
00:47:30.079 --> 00:47:35.840
Like the actual act of writing the code is never the hard part.
00:47:35.840 --> 00:47:36.719
Like, never.
00:47:36.719 --> 00:47:44.239
Like the language is so simple, you learn to think in that structure, you know, you start to recognize patterns.
00:47:44.239 --> 00:48:00.559
Um and you know, whereas like you look at today and it's like, you know, oh, people aren't thinking at all, and this LM is just vomiting out this, you know, truckload of Python that's gonna slowly set the world on fire uh through its inefficiency.
00:48:00.559 --> 00:48:04.400
And it's like, hey, hey, hey, hey, can we get back to like a craft?
00:48:04.400 --> 00:48:10.079
Like, we actually some of us actually want to do this as as an actual craft.
00:48:10.079 --> 00:48:18.719
Can we get back to thinking about and then you know, writing less code, reading less code, debugging less code?
00:48:18.719 --> 00:48:21.360
Like, can can we get back to that to that world?
00:48:21.360 --> 00:48:22.480
I I don't know.
00:48:22.480 --> 00:48:29.280
I mean, L soup to nuts is I mean, and it's a lot, but it's maybe 12,000 lines of C.
00:48:29.280 --> 00:48:34.559
And you got to keep in mind that every line of C can only be 80 characters because I am absolutely crazy.
00:48:34.559 --> 00:48:41.840
So um the you know, how do people how do people debug million lines of code?
00:48:41.840 --> 00:48:42.800
I have no idea.
00:48:42.800 --> 00:48:47.199
I mean, debugging more than 500 is just like takes me all day.
00:48:47.199 --> 00:48:50.239
So uh I I like like small shortcuts.
00:48:50.239 --> 00:48:53.199
So can we can we get everybody an interpreter?
00:48:53.199 --> 00:49:01.760
There's I think there's a lot of great um education documents out there, and people, you know, you should start playing with all ones.
00:49:01.760 --> 00:49:06.880
Like they can you can ask it to write idiomatic cue, and you know, it'll do it'll do an okay job.
00:49:06.880 --> 00:49:10.480
Um, and again, today's the worst it's ever going to be.
00:49:10.480 --> 00:49:15.119
Um, and so you know, I I I'll give you a great example of this.
00:49:15.119 --> 00:49:22.719
Um I now that you have an interpreter and you can kind of run it anywhere you want, um you can make that a tool call.
00:49:22.719 --> 00:49:33.039
So you can take this very, you know, kind of maybe an LLM that doesn't write great code, and you can let it call the interpreter and just iterate, iterate, iterate, iterate.
00:49:33.039 --> 00:49:36.960
And then it, you know, you can fine-tune it till well till it learns how this works.
00:49:36.960 --> 00:49:41.920
So um, so yeah, I think those are kind of the the main goals.
00:49:41.920 --> 00:49:50.000
And also I think, you know, I I think it's awesome that everybody, it seems like every single person right now is like, I'm gonna go build a language.
00:49:50.000 --> 00:49:52.559
And like, man, do I honor that?
00:49:52.559 --> 00:49:58.880
Um, but there's something to taking a language that has a big footprint.
00:49:58.880 --> 00:50:05.199
I mean, it has a bigger footprint than I think people realize, um, and just making it faster.
00:50:05.199 --> 00:50:07.280
Like, you don't actually have to go build a new language.
00:50:07.280 --> 00:50:12.320
Like, why would somebody continue to do work in K and Q?
00:50:12.320 --> 00:50:16.320
That's like it's still got to be the bleeding edge of performance.
00:50:16.320 --> 00:50:24.079
Um, yeah, I mean, it's amazing to me how how fast K and Q is for the you know, the style of workload that it does.
00:50:24.079 --> 00:50:28.079
Um, and you know, we're talking about effectively almost 20-year code.
00:50:28.079 --> 00:50:34.880
Um, I mean, I'm sure there's lots of improvements that have happened, but fundamentally there's it's it's 20 year 20-year-old code.
00:50:34.880 --> 00:50:38.159
Um so can you get another order of magnitude?
00:50:38.159 --> 00:50:45.760
Um you know, and that's not just on the language side, but really, guys, the the database is what makes this thing live, right?
00:50:45.760 --> 00:50:50.960
It's the database workload that people buy it for, use it for, implement it for.
00:50:50.960 --> 00:50:59.519
Um and you know, can you do can you be an order of magnitude faster than other things?
00:50:59.519 --> 00:51:12.800
And it turns out, yeah, you you can, but you have to, you know, make it small and it's binary sizes matter, like iCash matters, like um, like these things all matter.
00:51:12.800 --> 00:51:17.599
These are all parts of the craft that I think somewhere along the way got lost.
00:51:17.599 --> 00:51:27.760
Um, maybe everybody should, you know, go back to having 256k dial-up to to force force a diet, like a GLP one for computer science.
00:51:27.760 --> 00:51:32.400
But um yeah, that that that that's kind of what my thoughts are there.
00:51:32.400 --> 00:51:35.920
So right now it's uh can you make it faster than everything?
00:51:35.920 --> 00:51:37.760
It's it's pretty far on its way.
00:51:37.760 --> 00:51:39.519
Um even on the database side.
00:51:39.519 --> 00:51:41.519
I don't know if you guys have ever used DuckDB.
00:51:41.519 --> 00:51:44.079
DuckDB is an amazing, great piece of code.
00:51:44.079 --> 00:51:51.679
And it by the way, uh Adam, it has some of these compression codec concepts built into it, but for database workloads.
00:51:51.679 --> 00:52:09.039
Um, so um I think Duck uses for its loading point, I think it uses uh um ALP, um, which is basically you take your uh, you know, take whatever ill-gotten youth handed you uh money in decimals.
00:52:09.039 --> 00:52:21.519
Um this basically takes that and says, okay, well, we're gonna write a compression codec that's gonna effectively raise things to the power, you know, raise things to different powers of 10 to see if we can um get this guy up in the integer space.
00:52:21.679 --> 00:52:23.760
And then of course that's that's really interesting.
00:52:23.760 --> 00:52:27.199
Yeah, and then of course that means you have to have some fuzz, right?
00:52:27.199 --> 00:52:31.519
Because a lot of things will be almost fit if you raise it to some power of 10.
00:52:31.840 --> 00:52:39.599
There's a really good paper, the ALP paper, which is out of, I think um the CWI group, CMI group.
00:52:39.599 --> 00:52:43.280
Um we could put it in the show notes, kind of describes this.
00:52:43.280 --> 00:52:53.840
But you know, I think I I don't I don't know about you, but like I'm I am a small small little things and then interlock them, right?
00:52:53.840 --> 00:52:56.079
So you could even think that concept, right?
00:52:56.079 --> 00:53:10.079
So say, so say, you know, Timmy hands you an array of of US dollar in floats, um, and you could just raise that to a power of 10, um, and and everything would be okay.
00:53:10.079 --> 00:53:17.440
But then if you were to interlock that with the frame of reference, right, and remove that base off um and now take that payload.
00:53:17.440 --> 00:53:26.960
Well, hey, those two codec interlocked together actually give you like an insanely efficient way to work in the integer space on a smaller bit.
00:53:26.960 --> 00:53:28.000
Well, you know what I'm saying?
00:53:28.000 --> 00:53:30.079
Like these things all get interlocked.
00:53:30.079 --> 00:53:41.840
People, I think people, you know, would look at um kind of especially if you if if you looked at like some of the stuff that that Arthur did make open, it was like, oh my god, this interlocking mess.
00:53:41.840 --> 00:53:45.440
And it's like, no, no, no, no, no, like that's exactly how you want to do it.
00:53:45.440 --> 00:53:51.280
Like, if you have one function that's not interlocked with something else, you gotta ask yourself, do I need that function?
00:53:51.280 --> 00:53:54.639
Um, or is there some other way to tie these guys together?
00:53:54.639 --> 00:54:02.159
I mean, there's literally uh on the on on the L kind of to build L takes a long time because it runs all these tests.
00:54:02.159 --> 00:54:08.239
And one of the tests is um essentially going through and looking at the assembly gets output for every function.
00:54:08.239 --> 00:54:14.000
Um, that can often be inline and other functions, but making sure that they all fit within the iCache, right?
00:54:14.000 --> 00:54:24.960
And if it isn't, then you got to go back and be like, all right, is there a way I can shave off you know a few bytes off of this thing because I know that this is gonna be interlocked into all these other places?
00:54:24.960 --> 00:54:27.280
So yeah, I don't know.
00:54:27.280 --> 00:54:31.920
I that I went on a little bit of a diatribe there, Stephen, but that's that's a goal, right?
00:54:31.920 --> 00:54:42.559
More people using this language, doing this craft, and like, please, for the love of God, stop handing me pages of code and then be like, Can you find my bug?
00:54:42.559 --> 00:54:46.639
Um, it's like my answer is always like, Yes, I found your bug right away.
00:54:46.639 --> 00:54:48.719
It's this entire page of code.
00:54:48.719 --> 00:54:51.039
Um, you know, give me give me 20.
00:54:51.039 --> 00:54:56.559
The rag engine that I that I built with, you know, for for these friends.
00:54:56.559 --> 00:54:58.880
Um I mean, it's 20 lines.
00:54:58.880 --> 00:55:06.480
It's 20 lines, and it's way faster than what they were using, which is this giant commercial product.
00:55:06.480 --> 00:55:08.880
And it's like, okay, it's 20 lines.
00:55:08.880 --> 00:55:10.639
Like, we can all read it.
00:55:10.639 --> 00:55:18.239
Yes, yes, there's some complexity here because they're dense 20 lines, but like we all can read and understand this.
00:55:18.239 --> 00:55:25.280
Like, you can actually map it in your head, versus the other thing, which was like, you know, I don't even know, tens of thousands of lines.
00:55:25.280 --> 00:55:28.079
I was like, dude, how will you ever find the bug here?
00:55:28.079 --> 00:55:37.360
Like, or or by the way, finding a bug and optimizing it are just whether or not you admit it's broken, or it, you know, you don't admit it's broken.
00:55:37.360 --> 00:55:39.280
Like if it's slow, it's still broken.
00:55:39.280 --> 00:55:40.880
So, you know.
00:55:41.440 --> 00:55:42.480
It's it's interesting.
00:55:42.480 --> 00:55:46.079
You say this about the amount of of code and and the problem.
00:55:46.079 --> 00:55:50.880
A problem with LM is that people are spitting out giant amounts of of code.
00:55:50.880 --> 00:56:08.559
Uh, what I found, uh, so I I had uh I'm going back to what I said right in the beginning when we before it introduced our our guests and this uh this game that I'd made, and that had written it in in JavaScript with one hand, um, because the other was on the baby.
00:56:08.559 --> 00:56:19.360
And uh so by necess by necessity, but also because that's how I like to do it, I wrote it in a in a special she was a variant of JavaScript that I like to call Arthur Whitney JavaScript.
00:56:19.360 --> 00:56:25.039
Um where uh I don't know if Arthur has ever actually ever written any JavaScript.
00:56:25.039 --> 00:56:28.719
Um I would ask him if I if I met him.
00:56:28.719 --> 00:56:33.519
Um but but in what I imagine it would look like if he wrote it after having seen some of the code.
00:56:33.519 --> 00:56:36.880
Mind you, I don't understand C, I don't read C.
00:56:36.880 --> 00:56:41.360
Um, but I've seen some of the things he has written, and I figured this is how we'd write it.
00:56:41.360 --> 00:56:55.119
So uh one letter variables, two letter variables when necessary, and no unnecessary white space, keeping as much as it's keeping the code visible on the screen at one any given time.
00:56:56.000 --> 00:57:00.400
Um you can actually Google Arthur's JavaScript.
00:57:00.400 --> 00:57:02.719
There's one called C dot JS.
00:57:02.719 --> 00:57:05.360
Yeah, it's the the connector.
00:57:05.360 --> 00:57:11.760
Um, it was the basically the IPC protocol uh parser in JavaScript.
00:57:11.760 --> 00:57:13.039
C.S.
00:57:13.039 --> 00:57:14.960
You said C dot JS.
00:57:15.199 --> 00:57:16.320
Oh JS, yeah.
00:57:16.480 --> 00:57:18.480
Yeah, I'll I'll see if I can find it.
00:57:18.639 --> 00:57:24.559
But um, so this is how I like to write my JavaScript in general.
00:57:24.559 --> 00:57:30.559
I also relied on every quirk available in the uh in the browser's JavaScript engine.
00:57:30.559 --> 00:57:35.760
That might not be the best idea uh to do that, but it makes my code shorter because I don't know.
00:57:35.760 --> 00:57:43.280
People people have told me that you need to use things like const and let and var and don't know what in in in JavaScript.
00:57:43.280 --> 00:57:44.400
I don't know what these words do.
00:57:44.400 --> 00:57:47.840
Apparently, my code does the same thing when I don't write it, so I don't write it.
00:57:47.840 --> 00:57:53.599
Um and um, but my variables only survive very short before they're anymore.
00:57:53.599 --> 00:57:56.000
So who cares if it's the global scope or whatever?
00:57:56.000 --> 00:57:58.320
Um so so so this is how I write it.
00:57:58.320 --> 00:58:05.840
And and the interesting thing is that I was able to get, I was using using Claude, I was able to get Claude to stick to this.
00:58:05.840 --> 00:58:13.679
So I did make it first got rid of all the quirks because apparently there are some features that need a JavaScript that are not available in quirks mode.
00:58:13.679 --> 00:58:30.239
Um, but other than not writing super quirky code, so everything is sort of best standards, it still looks the same, still makes actual JavaScript programmers go all uh white in the face when they see it and say, for first reaction, that's not JavaScript.
00:58:30.239 --> 00:58:33.360
Second reaction is oh wait, that is JavaScript, but what are you doing?
00:58:33.360 --> 00:58:35.760
You're not supposed to write code like that, and that's fine.
00:58:35.760 --> 00:58:44.320
Um, but I was able to make Claude keep doing that, and that means that my whole game is like I don't know, 250 lines of of JavaScript, something like that.
00:58:44.320 --> 00:58:59.760
Um and I think it's and then I can I can actually go through it, even though it it is it 100 lines to 250 lines with Claude's editions, uh more code than I can actually go through it and make sure that every I know what everything is doing.
00:58:59.760 --> 00:59:03.280
There are no unnecessar unnecessary bits, about bytes.
00:59:04.000 --> 00:59:09.199
I mean, everything's an abstraction anyway, like you're not handwriting the stuff in assembler.
00:59:09.199 --> 00:59:19.039
Um, so like the syntax, I don't think matters as much as people think it does, or the style doesn't matter as much as people think it does.
00:59:19.039 --> 00:59:21.599
It's can you comprehend this?
00:59:21.599 --> 00:59:23.280
Like, what is the entropy?
00:59:23.280 --> 00:59:27.199
Like when you literally look at something, can you comprehend it faster?
00:59:27.199 --> 00:59:38.880
And by the way, like I'm sure that there are people for whom you know basically reading a novel that kind of walks you through what's happening is more is better for them.
00:59:38.880 --> 00:59:43.119
But you know, for me, I'll I'll I'll take a poem over a novel anytime.
00:59:43.280 --> 00:59:56.880
So Stephen, you got your uh Yeah, Jake, for uh for years, Q was my kind of go-to language for when I when I had uh a license to use it uh for pretty much everything.
00:59:56.880 --> 01:00:04.800
And I would love to be one of the people you envisage for the future writing applications in Q or K.
01:00:04.800 --> 01:00:16.719
Um, but for commercial applications, uh I will be writing them from a customer who's gonna say, well, if anything goes wrong, who can I call who has to pick up the phone?
01:00:17.039 --> 01:00:21.599
Yeah, I yeah, I think you're asking kind of what is the long-term commercial plan for L?
01:00:21.599 --> 01:00:24.880
Um and I don't have one yet.
01:00:24.880 --> 01:00:30.800
So um, you know, I think it's good to put it at a time.
01:00:31.280 --> 01:00:44.000
It's definitely that making a choosing a brand name to keep support because that just I don't know if it's just me, but I can barely make out what Adam is saying.
01:00:44.000 --> 01:00:47.199
Uh your audio has gotten a little choppy.
01:00:48.880 --> 01:00:52.400
But yeah, I I don't know what the long-term commercial application is.
01:00:52.400 --> 01:00:57.920
I think, you know, Steven, right now is can you run all these workloads?
01:00:57.920 --> 01:01:01.360
Um and can you run them in order of magnitude faster?
01:01:01.360 --> 01:01:03.280
Let's let's try to get that first.
01:01:03.280 --> 01:01:06.559
And then, you know, then we'll deal with the next part next.
01:01:06.559 --> 01:01:14.800
Um again, I think the good news is right, if if if uh you know this is compatible, this is dropping compatible.
01:01:14.800 --> 01:01:16.320
So I mean, I think that works both ways.
01:01:16.320 --> 01:01:30.559
So you can mind have somebody who you know downloads L and builds something, and then is like, you know, I could, you know, maybe if there wasn't an L commercial entity, then you can just be like, oh, well, I you know, I have this code I can call KX, and that's that's great.
01:01:30.559 --> 01:01:45.519
Um but because it is, you know, like I said, some of the reports from the field are pretty nuts, not just in terms of performance, and I hadn't actually contemplated this, but I feel stupid for not having contemplated it, is storage.
01:01:45.519 --> 01:01:50.719
So the um, you know, the objects are compressed in memory on disk.
01:01:50.719 --> 01:01:52.960
I mean, it's all the same format.
01:01:52.960 --> 01:01:56.719
Um, again, do one thing and just do it everywhere.
01:01:56.719 --> 01:02:05.599
Um and somebody just basically moved over what is essentially a TAC database to see what the disk storage was.
01:02:05.599 --> 01:02:15.360
And um, and it turns out it's like eightx less disk, even then the dictionary compressed versions, um, which which I think makes sense, right?
01:02:15.360 --> 01:02:22.800
Because you know, dates and um timestamps, the base type is a 32-bit and a 64-bit.
01:02:22.800 --> 01:02:35.119
They're almost always monotonic in the database, so they're always gonna delta really well, and then they're gonna frame a reference really well, and they're gonna um, you know, there's kind of one more trick that I do on the patch.
01:02:35.119 --> 01:02:42.800
And so you actually do end up like, yeah, like a column of time is gonna be super, super small.
01:02:42.800 --> 01:02:46.079
Um, if it's a high fidelity, like high frequency set of time.
01:02:46.079 --> 01:02:51.679
Deltas are gonna be tiny, um, and that's gonna compress down a lot, like a lot, a lot.
01:02:51.679 --> 01:02:55.119
Dictionary compression just really isn't good for numbers.
01:02:55.119 --> 01:02:59.199
I I don't know why people love dictionary compression.
01:02:59.199 --> 01:03:02.719
It's I mean, it's good for text, but it's not not good for numbers.
01:03:02.719 --> 01:03:04.320
Um yeah.
01:03:04.320 --> 01:03:05.679
Sorry, Adam.
01:03:05.679 --> 01:03:08.320
I I I don't know if your audio worked now.
01:03:08.320 --> 01:03:11.440
I wanted to answer your question, but I couldn't quite make it out.
01:03:12.079 --> 01:03:12.719
I'm sorry.
01:03:12.719 --> 01:03:14.079
Uh I hope it's better now.
01:03:14.079 --> 01:03:17.199
Um okay, I just need to reload.
01:03:17.199 --> 01:03:20.159
Um, but let's see if I remember what it was.
01:03:20.719 --> 01:03:21.519
It was in the middle of the year.
01:03:21.679 --> 01:03:24.960
Right, no, no, I think it's a commercial plan.
01:03:24.960 --> 01:03:57.760
Because it's sort of sort of a joke, but uh these they're these uh companies that that uh and that sell knockoff products that brand it like uh like real big brands out there, and they for customer support, they just list uh the originals contact information because their products are so identical to to the real expensive thing that that the customer support for uh for the real deal is the same as and as for the cheap stuff that they're selling.
01:03:57.760 --> 01:04:18.320
Uh it's sort of a joke, of course, because it doesn't it it's not commercially viable in the in the long run to say who do you call for assistance if something's not right oh that your language is behaves identically to into KX product and ask them and look at their documentation and so on.
01:04:18.320 --> 01:04:20.480
But that's that of course that's a joke.
01:04:20.480 --> 01:04:21.280
That doesn't work.
01:04:21.280 --> 01:04:24.559
Uh but essentially that's the situation you're in right now, right?
01:04:24.880 --> 01:04:27.280
Well, and I think Steven's point's a good point, right?
01:04:27.280 --> 01:04:49.679
Even open source code, um, you know, you're not gonna take a piece of open source code, I mean, I guess except for the case of the operating system, and um, you know, go deploy that in a mission critical environment without somebody to call, which is why these kind of open source business models um I I think succeed.
01:04:49.679 --> 01:04:56.800
Um but but yeah, again, just step one, get it compatible, which we're we're past that point.
01:04:56.800 --> 01:04:59.519
Um get it, get it fast.
01:04:59.519 --> 01:05:02.159
Um it's pretty fast.
01:05:02.159 --> 01:05:07.039
So, you know, I'm sure that the that we're gonna discover more things that we can make faster.
01:05:07.039 --> 01:05:08.480
I'll give you a great example.
01:05:08.480 --> 01:05:24.079
So um K, and I don't know if APL has this concept, but K is a concept of a symbol, which is essentially a character string that gets mapped to uh essentially an enumeration, right?
01:05:24.079 --> 01:05:28.559
So if you have this, is this comes from its use, from its use case, right?
01:05:28.559 --> 01:05:34.079
So in Wall Street, you know, stocks have tickers, you know, like IBM and whatever.
01:05:34.079 --> 01:05:40.719
Um you obviously, you know, don't want to you don't want to store a bunch of strings in a table.
01:05:40.719 --> 01:05:43.840
Like, no, again, terrible like choice.
01:05:43.840 --> 01:05:44.960
Don't don't do that.
01:05:44.960 --> 01:05:59.599
Um so what you want to do is you want to, you know, you want to store those as a number, and then you've got a lookup that needs to happen, kind of an enumeration between this this uh array of characters and its numeric representation that sets in the database.
01:05:59.599 --> 01:06:02.000
And that's great.
01:06:02.000 --> 01:06:03.920
And that works wonderful.
01:06:03.920 --> 01:06:07.840
Except you need to have that enumeration stored somewhere.
01:06:07.840 --> 01:06:11.920
Like if you lose that enumeration, and in K it's called the SIM file.
01:06:11.920 --> 01:06:16.159
And if you lose that SIM file, like you're smoked.
01:06:16.159 --> 01:06:18.800
Like there, like you've just lost the map.
01:06:18.800 --> 01:06:20.559
Like the Torah is now gone.
01:06:20.559 --> 01:06:22.880
We have no idea what how how things work anymore.
01:06:22.880 --> 01:06:30.480
Um, and this is this is both a a kind of an operational problem, but it is also actually a performance problem.
01:06:30.480 --> 01:06:45.280
So in a scenario in which you want to run kind of parallel reads um, you know, across multiple uh partitions, that symbol file needs to effectively be shared, right?
01:06:45.280 --> 01:06:48.800
They all all those partitions need to be able to decode that symbol file.
01:06:48.800 --> 01:06:51.599
And so you've got to have a lock on that symbol file.
01:06:51.599 --> 01:07:02.320
And um, you know, to be completely honest, I didn't do any character codec because, you know, I don't know, I don't just don't use strings a lot.
01:07:02.320 --> 01:07:06.639
And the community was like, hey, this is great, but is there any way?
01:07:06.639 --> 01:07:09.920
Basically, they're asking, is there any way you can get rid of the SIM file?
01:07:09.920 --> 01:07:10.960
And it's like, okay.
01:07:10.960 --> 01:07:14.960
What we're talking about is we just need a new codec here that will fit this.
01:07:14.960 --> 01:07:16.960
So again, be practical.
01:07:16.960 --> 01:07:19.519
It's a workhorse, not a show horse, right?
01:07:19.519 --> 01:07:25.760
So most financial workloads, the character string is fairly short.
01:07:25.760 --> 01:07:32.800
Um, so it's, you know, uh generally four or less characters, but certainly eight or less characters most times.
01:07:32.800 --> 01:07:37.679
Those are holding the ticker, uh kind of the the name of the stock, right?
01:07:37.679 --> 01:07:48.239
Um, well, you can, I don't know if you guys are familiar with this concept of German strings, but you can just basically take that character, right, turn it into the numeric uh equivalent.
01:07:48.239 --> 01:07:51.199
And um that has two benefits.
01:07:51.199 --> 01:07:58.000
One, it's a number, so you know, God likes storing numbers, and two, um, it's like lexographically sortable, right?
01:07:58.000 --> 01:08:01.039
So sorting sorting that number is the same as sorting the character.
01:08:01.039 --> 01:08:02.639
Um, so that was the first one.
01:08:02.639 --> 01:08:14.719
I did that, and it was like, hey, now you have no symphile, every symbol vector is kind of self-describing, subject to you only using small, small character strings.
01:08:14.719 --> 01:08:24.399
And then um, and if you use a large character string, then underneath the covers, that codec is gonna have to switch to an enumeration, and like you're gonna, you know, now you're back in pain.
01:08:24.399 --> 01:08:30.479
And then somebody in the community was like, Yeah, but like these options ones, they're just a little bit longer.
01:08:30.479 --> 01:08:33.680
And I was like, well, then you know, tell them to make them shorter.
01:08:33.680 --> 01:08:36.479
And um, it was like, well, no, you can't do that.
01:08:36.479 --> 01:08:48.000
So um that was that was like the last, I don't know, two, three weeks was thinking of kind of what is a codec for for storing a string that still allows you to have those properties.
01:08:48.000 --> 01:08:52.800
Um, and so actually for a symbol and for a symbol, there is no enumeration anymore.
01:08:52.800 --> 01:08:57.359
They are all self-described, and each vector is kind of self-composed.
01:08:57.359 --> 01:09:01.680
Um, and it's like, okay, that's great from an operational standpoint.
01:09:01.680 --> 01:09:04.800
You don't have to worry about losing a sim file and losing all your data.
01:09:04.800 --> 01:09:15.920
But boy, does that turn out to be a massive performance improvement, like massive, like more than an order of magnitude, um, because all of these locks on the sim file go away.
01:09:15.920 --> 01:09:22.479
And because then each, if you have multiple SIMs in a in a in a table, you can now operate them on them independently.
01:09:22.479 --> 01:09:26.880
And of course, because all the codecs are uh sortable, you don't have to worry about this.
01:09:26.880 --> 01:09:38.880
You used to like have to go work on the you would go into the enumeration, find the symbols that matter, then go back into the table, and then find the match, and then ah no.
01:09:38.880 --> 01:09:40.640
So all of that just goes away.
01:09:40.960 --> 01:09:45.520
Yeah, the sim file bloating is going away as well because there's sim files.
01:09:45.520 --> 01:09:59.279
Like yeah, one one one problem uh with the sim file is like it it you know it makes your data on disk faster, but as soon as you start bloat the sim file, you're losing this performance.
01:09:59.279 --> 01:10:21.279
And you know, I've been teaching KDB developers and juniors, and often you know, one of the grads, one of their rookie mistakes is like, okay, I'm making a column that's not supposed to be a SIM symbolic column, a SIM, and then you store it to this and you load, you blow up the size of the SIM file, and now suddenly your HTB isn't fast anymore.
01:10:21.279 --> 01:10:31.760
And then you have to deal with basically recreating your data because there is no easy way to remove something that went into the SIM file.
01:10:31.760 --> 01:10:36.640
You have to de-numerate everything, re-enumerate it, and save it back down to disk.
01:10:36.640 --> 01:10:40.560
And that's like a massive pain and a very risky operation.
01:10:40.560 --> 01:10:45.119
So not having to deal with SIM files, that's pretty cool to think.
01:10:45.439 --> 01:10:49.119
Yeah, and again, it's just it's a massive performance unlock.
01:10:49.119 --> 01:10:54.720
Um, because now you can have each one of these kind of parallel readers operate independently.
01:10:54.720 --> 01:10:57.119
Um, and you you know, you don't have to worry about a lock.
01:10:57.119 --> 01:11:02.239
Um, and um, you know, God has a couple of designing principles.
01:11:02.239 --> 01:11:08.079
He doesn't like characters and he doesn't like locks, and he doesn't like branches, and the more you can get rid of those, the better life is.
01:11:08.079 --> 01:11:09.119
So yeah.
01:11:09.520 --> 01:11:15.920
Have you noticed other things at least when uh when using uh like uh L versus your experience in the past?
01:11:16.239 --> 01:11:18.640
Um I found it really easy to transition.
01:11:18.640 --> 01:11:24.000
It's pretty much like I, you know, I came across this two, three weeks ago.
01:11:24.000 --> 01:11:35.920
Um, and then you know, Jake gave me the binary, installed it, run it, and I thought like I I I have to learn something new or you know, at least read some documentation.
01:11:35.920 --> 01:11:46.000
But Jake was basically it's pretty much like cube, just start playing around with it, which I did, and I haven't seen much that you know I couldn't do.
01:11:46.000 --> 01:11:51.279
Um it's it's it's pretty good um from what I've seen so far.
01:11:51.279 --> 01:11:53.279
And yeah, I like it.
01:11:53.600 --> 01:12:01.359
Do you have any like uh workflows that you notice got way faster, or do you not really have that kind of thing where you're you're running something regularly enough to notice?
01:12:01.920 --> 01:12:03.279
No, I haven't, you know.
01:12:03.279 --> 01:12:06.319
I've for now I've just done basic stuff.
01:12:06.319 --> 01:12:09.680
Um I didn't went too crazy on it yet.
01:12:09.680 --> 01:12:16.720
Um but yeah, I know Jacob runs some some stats and and they look pretty promising.
01:12:16.720 --> 01:12:26.960
And one of my questions for Jacob was actually like we've we've talked a lot about what you've already done in in terms of you know to squeeze some performance out of it.
01:12:26.960 --> 01:12:28.880
Do you think you can push it even harder?
01:12:28.880 --> 01:12:32.319
Like is there do you have are you there yet with L?
01:12:32.319 --> 01:12:33.199
Are you finished?
01:12:33.199 --> 01:12:37.760
Do you think it's okay that's the maximum we can you know squeeze out of it?
01:12:37.760 --> 01:12:41.119
Or or do you have a few more tricks in in your sleeve?
01:12:41.520 --> 01:12:43.840
Oh no, there's definitely more to do.
01:12:43.840 --> 01:12:45.680
There's always gonna be more to do.
01:12:45.680 --> 01:12:50.560
I think um I think I'm out of ideas for now.
01:12:50.560 --> 01:12:56.000
So that's why it's like you want more people to have this, because you want to, you know, I'm out of ideas.
01:12:56.000 --> 01:12:58.800
So let's let's see if anybody else has got some new ideas.
01:12:58.800 --> 01:13:07.199
But I think um I actually think the fusion uh fuse.c where it actually goes and changes the bytecode.
01:13:07.199 --> 01:13:22.239
Um one of the things I want to do, and I just haven't figured out how to, is expose that up so that a developer can essentially write new fusion rules in the interpreter and save them down.
01:13:22.239 --> 01:13:32.319
Um because that's that's where there's just a lot of institutional knowledge that it gives you just huge performance wins.
01:13:32.319 --> 01:13:37.840
Like, I mean, the classic example is like Connor said, the the fuse multiply at, right?
01:13:37.840 --> 01:13:43.039
Um let's take this set of operators and let's just move it into a dot.
01:13:43.039 --> 01:13:54.239
But you know, there's a lot more of them, like working with matrices and you know, working with them in arrays and indexing into the matrices in in in kind of a straight linear fashion rather than the matrix.
01:13:54.239 --> 01:13:55.520
Um, I don't know.
01:13:55.520 --> 01:14:01.600
As I come into more workloads, I'm sure there'll be more opportunities to make things better.
01:14:01.600 --> 01:14:06.159
But yeah, I'm kind of out of ideas of how to make it faster.
01:14:06.159 --> 01:14:12.239
Um so and really it's like where where if anywhere is it slow, right?
01:14:12.239 --> 01:14:22.399
So if it's so for example, I didn't do like the uh string operations, like you know, again, strings, I just don't use them.
01:14:22.399 --> 01:14:29.119
So um, and then somebody in the community came in and they were like, Man, this string search and replace is really slow.
01:14:29.119 --> 01:14:32.560
I was like, Oh, okay, let's go back and fix that.
01:14:32.560 --> 01:14:35.039
So um went and fixed that.
01:14:35.039 --> 01:14:38.640
Um and uh, you know, stuff like that.
01:14:39.039 --> 01:14:46.399
Speaking of the the this is a good time to ask one of the two questions, or maybe both, but uh one of them was relevant to the the patterns that you uh mentioned.
01:14:46.399 --> 01:14:53.760
Um so the question is all of those fusion patterns and compressed representations uh must lead to a lot of combinations.
01:14:53.760 --> 01:15:04.079
Um, do you have special code for even uh, and I think it's EG, for example, uh arithmetic progression vector plus a number plus frame of reference vector.
01:15:04.319 --> 01:15:07.279
Um, that's a good question.
01:15:07.279 --> 01:15:18.159
Um no, because all the verbs have the compression operations built in, it really is just purely on the function itself.
01:15:18.159 --> 01:15:30.800
You do you actually don't um there isn't actually any way to in a fuse operator to say do this if that is compressed with this codec, do this if it's compressed with that codec.
01:15:30.800 --> 01:15:33.520
Um, but again, you don't really have to worry about that.
01:15:33.520 --> 01:15:41.840
Um, because all as long as you get all the verbs and adverbs working compute on compressed and closed form, that's really just an implementation detail.
01:15:41.840 --> 01:15:46.319
Um where fusion really matters is again kind of institutional knowledge.
01:15:46.319 --> 01:15:50.000
I see this, it's it's better to do that.
01:15:50.000 --> 01:15:54.800
Um and that really is just like you know, institutional knowledge.
01:15:55.039 --> 01:15:56.399
Um or tricks.
01:15:56.399 --> 01:15:59.119
All right, so we'll go to the second question too, and then we'll go to Steven.
01:15:59.119 --> 01:16:01.199
Uh so the first the first question was from Asher.
01:16:01.199 --> 01:16:04.479
I forgot to mention uh Asher's uh I believe a dial dialogue employee.
01:16:04.479 --> 01:16:05.840
So both of these are APLers.
01:16:05.840 --> 01:16:07.439
Uh the second one's from Max.
01:16:07.439 --> 01:16:12.479
Uh is scan, this is rather uh specific, is scan linear or quadratic in L?
01:16:12.479 --> 01:16:16.239
Uh because across languages, uh sometimes it's quadratic.
01:16:16.239 --> 01:16:19.199
It has the K does, right?
01:16:19.520 --> 01:16:22.079
Is scan linear or quadratic?
01:16:22.560 --> 01:16:35.520
What he means to say it is when you've got uh you've got a a verb followed by backslash, uh you're taking the partial sums, whatever to uh run it and running some.
01:16:35.520 --> 01:16:41.359
Do you start over every time going from the left or do you reuse the previous uh result?
01:16:41.359 --> 01:16:53.920
Because the the point is that uh a verb, b verb c uh by apl and k grammar, you need to start to compute from the right to left.
01:16:53.920 --> 01:17:07.520
And therefore, there's also the the idea that if you do a reduction, uh fold, insert, whatever you want to call it, uh then that's equivalent to just having all the elements spread out with a verb between them, so you need to go from right to left.
01:17:07.520 --> 01:17:09.039
Okay, that's all fine.
01:17:09.039 --> 01:17:17.199
Um, although we spoke about not worrying about uh just commutativity of uh and of mathematical functions.
01:17:17.199 --> 01:17:36.960
But when you get the scan and you create a cumulative sum, then you cannot do a single pass computation because you really need to go to the the last element of the of the running sum has to be the last element plus the second to last element plus the third last element and so on.
01:17:36.960 --> 01:17:41.600
But the second to last element, you have to start with the second to last element and go to the left.
01:17:41.600 --> 01:18:02.000
And if you're strict about this, if you're strict about the order of operations and strict that uh each partial sum must match the equivalent sum of that, and you're strict that the sum has to run in the uh element that element, so no CMD, then you end up with uh a terrible performance because you have to stud over for every element in the scan.
01:18:02.399 --> 01:18:02.800
Right.
01:18:02.800 --> 01:18:06.159
Okay, so this is gonna be a long answer.
01:18:06.159 --> 01:18:09.760
So the um, but this is a place where fusion plays.
01:18:09.920 --> 01:18:14.720
So um but hold on, before you answer that, I think I can sort of sidestep the question.
01:18:14.720 --> 01:18:16.000
There are two things played in.
01:18:16.000 --> 01:18:21.760
If I remember right, case definition of uh of a scan is strictly left to right.
01:18:21.760 --> 01:18:23.199
You just keep adding one more element.
01:18:23.199 --> 01:18:24.880
I mean, that's that's the first thing.
01:18:24.880 --> 01:18:26.479
So the question doesn't come in.
01:18:26.479 --> 01:18:34.640
Second thing that sidestep the question is you don't care about the order of uh of application of commutative functions.
01:18:34.640 --> 01:18:40.720
So this whole thing is only only comes in into that because of being strict about it.
01:18:40.720 --> 01:18:44.640
So it would seem to me that there's nothing even to answer here.
01:18:44.880 --> 01:18:46.159
Yeah, obviously not.
01:18:46.159 --> 01:18:56.239
There's nothing really I I think beautiful or magical about this, but I will say this that the fuse there in fuse.c, they're obviously operating.
01:18:56.239 --> 01:18:59.279
So prefix sums is something you use all the time, right?
01:18:59.279 --> 01:19:06.880
So um that actually calls very specific C code for that problem.
01:19:06.880 --> 01:19:19.439
Um that allows not only to use SIM, and actually there's a great write-up on that on parallel prefix sums on um algorithm algorithmica, I think.
01:19:19.439 --> 01:19:36.319
But um, but that one specifically, the sums, prods, mins, maxes, um, those all have custom C implementations because they are used uh specifically and they're SIMD implemented and parallel implemented.
01:19:36.319 --> 01:19:39.520
Um, and they're they're they're fairly bespoke.
01:19:39.520 --> 01:19:51.840
But if you were to do like F, you know, create a function F and do like um F scan, um, that will just operate like A, where it just goes, just kind of runs through it as fast as it can from left to right.
01:19:52.239 --> 01:19:54.239
All right, you waited patiently, uh Stephen.
01:19:54.239 --> 01:19:55.359
Now over to you.
01:19:56.239 --> 01:20:02.159
Yeah, I want to comment a bit on the implications of what we've been hearing over the last hour.
01:20:02.159 --> 01:20:20.800
Uh Romantic Alex Unterreiter and romantic Stephen Taylor called a meeting to uh work on shared community uh queue libraries, and cold-eyed KDB dev said there's no use case for those, and we're not coming.
01:20:20.800 --> 01:20:26.399
So we wound up canceling the meeting and feeling very sad and having a little weep.
01:20:26.399 --> 01:20:30.960
Um, and then Jake released his L interpreter.
01:20:30.960 --> 01:20:39.359
And now, I mean, I can't remember who I heard call the use this term first, um, but the language has got jailbroken.
01:20:39.359 --> 01:20:54.640
The first time we've been we've got um Q that you can use um in uh uh uh uh a commercially performant uh interpreter and can use it anywhere, or at any rate, the prospect of it.
01:20:54.640 --> 01:21:02.640
And um this seems to be the time for this because um there are other there are other projects working on the same thing.
01:21:02.640 --> 01:21:08.159
Jake's the first to come forward with a hundred percent coverage of the language.
01:21:08.159 --> 01:21:13.920
Uh I think Peach Q is reporting 43% coverage, peachq.org.
01:21:13.920 --> 01:21:21.359
Uh and uh John Estrada with his Courtsey uh interpreter uh reckons he's at about 80%.
01:21:21.359 --> 01:21:26.000
So this is a completely new landscape for the language.
01:21:26.000 --> 01:21:38.000
It's broken out, it's jailbroken, and there's clearly a need for some kind of community meeting to work out what community resources could be shared between them and so forth.
01:21:38.000 --> 01:21:43.520
What we need to do, and that will take some time to plan and organize.
01:21:43.520 --> 01:21:57.359
Meanwhile, at um Milden Hall in September, there's um the original failed meeting is coming back to life in some form, and neither Alex nor I quite know what's happening there.
01:21:57.359 --> 01:22:02.000
But John Estrada um will be there with Kortzi.
01:22:02.000 --> 01:22:06.720
Uh his collaborator Rob Hodgkinson will be there from Australia.
01:22:06.720 --> 01:22:11.359
We're expecting FinTan from States with Shack T.
01:22:11.359 --> 01:22:18.960
Uh, and uh we hear Dave Thomas is coming over to talk about uh what needs to be done for the community.
01:22:18.960 --> 01:22:26.640
So we don't even have an agenda for this, and we don't yet know who who's coming or who needs to be there.
01:22:26.640 --> 01:22:30.479
Um but our celebrated chef is back.
01:22:30.479 --> 01:22:56.560
And um so so I'm better uh I'm basically putting this out there that if you if you listening are someone who wants to be in on the very um the the very ground zero of what looks like a first actual community for K and Q, um get in touch with Alex or with me.
01:22:57.039 --> 01:23:06.159
Yeah, and I gotta say, man, as someone who grew up in this community, you know, when I came to New York, I didn't know anybody.
01:23:06.159 --> 01:23:12.079
I got this job in New York at this, you know, at this shop, this Kennerford show.
01:23:12.079 --> 01:23:18.159
And um I literally reached out to the K community and was like, I'm here.
01:23:18.159 --> 01:23:19.680
Is anybody else here?
01:23:19.680 --> 01:23:31.600
And like the first beer I had, the first dinner I had, you know, the first apartment I went over to, um, you know, the first group of friends that I ever made was, you know, KMQ programmers.
01:23:31.600 --> 01:23:36.079
And like, um, you know, what's a kooky, quirky community?
01:23:36.079 --> 01:23:43.439
And I I miss I've been gone for a long time, so it's nice to come back and be reminded, like, oh, there's a whole city under here.
01:23:43.439 --> 01:23:48.720
Like this Discord server was like four people, and then it was like 40 people in like a weekend.
01:23:48.720 --> 01:23:57.520
Like, um, and yeah, I think there's you know, I used to make jokes that when I was people, people uh people like, what is your preferred language?
01:23:57.520 --> 01:24:00.079
And I'm like, oh, I always prefer programming in K.
01:24:00.079 --> 01:24:01.199
And they're like, What is K?
01:24:01.199 --> 01:24:05.279
And I'm like, it's there's dozens of us, like dozens.
01:24:05.279 --> 01:24:07.600
Um, but that's not true.
01:24:07.600 --> 01:24:12.880
Like, there's actually hundreds of us, and and you know, maybe thousands of us soon.
01:24:12.880 --> 01:24:15.840
Uh, we just need to make sure people have access to it.
01:24:15.840 --> 01:24:21.680
Um, have access to it, can play with it, and like not play with it in just educational ways.
01:24:21.680 --> 01:24:28.239
Like, the only way you actually I I say this all the time: the only way I can actually learn something is to use it in anger.
01:24:28.239 --> 01:24:35.439
Um, like it needs to be put in these situations where you have to make it work because something depends on it.
01:24:35.439 --> 01:24:38.560
Using things in anger is how how you get good at things.
01:24:38.560 --> 01:24:44.560
So um yeah, man, go go download L and like go use her in anger.
01:24:44.560 --> 01:24:48.479
And if something's wrong or slow or you know, just send a note.
01:24:48.479 --> 01:24:50.159
Well, like I'll I'll take a look at it.
01:24:50.159 --> 01:24:50.880
We'll get it fixed.
01:24:50.880 --> 01:24:53.039
Like symbol file took two weeks.
01:24:53.039 --> 01:24:55.920
So, and you know, how hard could the rest of it?
01:24:56.159 --> 01:25:01.439
So the the downloads available obviously at the lv1.uhsh link.
01:25:01.439 --> 01:25:05.760
What's the best way if you run into issues or you just want to leave feedback?
01:25:05.760 --> 01:25:08.800
You you mentioned a Discord, but that sounded like a smaller private thing.
01:25:08.800 --> 01:25:12.720
Is there a a go-to space, GitHub issues or Twitter or something?
01:25:12.720 --> 01:25:13.520
What's the best way?
01:25:13.840 --> 01:25:26.960
There's there's actually when you go to uh when you go to that website, when you go to lv1.sh, there's a mailing list and you can join the mailing list, um, which is how it used to work in the old in the olden days.
01:25:26.960 --> 01:25:28.640
Um I like the mailing list.
01:25:28.640 --> 01:25:35.840
I I I mean the Discord's fun, but um I like the mailing list because it allows, you know, you can work a little more asynchronously.
01:25:35.840 --> 01:25:47.039
Um and Randy just, I think last night got a forum up so that you can go and you know search old uh see kind of the mailing list archives and be able to search it.
01:25:47.039 --> 01:25:51.199
So um if you want to get in touch with with me, that's certainly the best way.
01:25:51.199 --> 01:25:57.279
Just send, you know, join the mailing list and then send um send a message to the group and then I'll get it.
01:25:57.600 --> 01:26:03.359
One one one thing I want to add, and that comes from you know the early days when I started to learn Q.
01:26:03.359 --> 01:26:09.680
Um, the original mailing list, everyone could see who sent an email to the mailing list.
01:26:09.680 --> 01:26:28.159
Now it was, you know, with some veterans who have been doing Q for a long time, and it always felt intimidating to ask a question out in the wild, and then you know, the imposter syndrome, wondering whether everyone is gonna laugh about you and think you're stupid.
01:26:28.159 --> 01:26:32.720
So Jake actually made the mailing list anonymous.
01:26:32.720 --> 01:26:43.119
So whenever you send uh email to it, unless you have a signature in your Gmail address like I do, no one will actually see who sent it.
01:26:43.119 --> 01:26:55.199
So um that's a good way to ask your question without worrying whether you're gonna be exposed for asking something stupid, even though there are no stupid questions, only the ones not asked.
01:26:55.199 --> 01:27:10.560
And then for all the listeners who are not coming from a Q background or haven't learned the syntax yet, um, go check out my blogconq.tech where you can actually learn the language and the syntax.
01:27:10.560 --> 01:27:16.000
And I think I did a pretty good job in explaining it in a very easy, comprehensible way.
01:27:16.000 --> 01:27:22.399
Um, if anyone wants to chip in, Jacob, Steven, um, you can give your opinion about it.
01:27:23.439 --> 01:27:26.319
I just I just downloaded it and it runs.
01:27:26.319 --> 01:27:28.960
I was about to ask, wait, what if I'm on Windows?
01:27:29.199 --> 01:27:32.079
So you should think about your life choices, Adam.
01:27:32.239 --> 01:27:46.159
Like, that's like that's you've you've made some bad turns in life if you've ended up with well, Windows now has such a thing called as uh WSL that can run Linux things, so that's what I'm doing, and it works just does that work?
01:27:46.159 --> 01:27:47.520
Yeah, it works fine.
01:27:47.760 --> 01:27:48.399
There you go.
01:27:48.399 --> 01:27:50.000
New platform supported.
01:27:50.159 --> 01:27:52.079
Yeah, so that's fine.
01:27:52.079 --> 01:27:53.680
Um now you know.
01:27:53.680 --> 01:27:59.600
Um, but uh you one thing you might want to do is make it available to run in the browser.
01:28:00.159 --> 01:28:14.319
if you can if you can target web assembly or something like that with a C to WebAssembly thing or I I I don't think that does WebAssembly have SIMD built in it it is deeply SIMD specific.
01:28:15.439 --> 01:28:20.079
I know there are there are things out there that are able to compile C code.
01:28:20.079 --> 01:28:26.239
I don't know what happens if it has deep simd things I would imagine that it would work but I don't know.
01:28:26.239 --> 01:28:27.680
I don't know anything about these things.
01:28:27.680 --> 01:28:37.520
But it would be something that's very nice for a language like a small uh existing audience is to have something you can try right away in your browser.
01:28:37.520 --> 01:28:50.399
So by whatever means necessary like even if you need to run some kind of virtual machine thing that's um in the browser that can then run it that makes it very slow but just that people can get a feel for it that might be a nice thing.
01:28:50.399 --> 01:28:59.439
But then I then I found an interesting quirk uh of the L language we can call it an inconsistency but it sort of has to be the way it is it's just funny I think I wanted to mention this.
01:28:59.439 --> 01:29:40.000
That is I happen to know I don't really know KO Q but I happen to know that in that in Q if you apply uh a a string a character vector to the character uh k then it gets evaluated as k code so here's the fun thing if the language name is L uh it this still works it is implemented I just tried it yeah but that means the language sort of claims to to to evaluate K code I guess it does it does evaluate K code it does you can actually you can just hit the backlash and you actually drop into the game to I that that's the first thing I do I don't I don't need no Q.
01:29:40.000 --> 01:29:42.000
Give me K.
01:29:42.479 --> 01:29:46.560
Yeah Q is Q is uh complicated um K is a lot simpler.
01:29:46.560 --> 01:29:57.760
The um yeah the only thing that is still gated which I'll ungate soon um is the is the offload the GPU offload.
01:29:57.760 --> 01:30:00.800
Again it's just transparent.
01:30:00.800 --> 01:30:16.479
So um I'll ungate that on the Mac first because the hardware is consistent and it has unified memory but yeah that's GPU go burr is really good for like it's really good for sort at stupid large amounts.
01:30:16.479 --> 01:30:25.119
Actually I mean you have to have really really really big arrays for that thing to actually start to kick in but when it does it's pretty it's pretty amazing.
01:30:25.119 --> 01:30:52.880
So we've got a comment in the chat from uh Madeline who's mentioning that uh WASM has had simd for a while so I mean there it could uh be possible um there's there's maybe uh there's a there's a project there maybe I'm not um I'm not I don't really do uh web development but I'll I Randy Lebeau who built you know like the forum and the anonymous email list and all that stuff I'll ask him he if anybody could do it he could do it so see what we can do.
01:30:53.439 --> 01:31:03.920
Max meme god says says that yeah array box please well well I mean I once it runs in in wasm then you should be able to get to run it on the Raybux as well.
01:31:04.319 --> 01:31:31.520
Once someone implements the Wasm it should be pretty straightforward um but uh one last thing too because I know Steven you mentioned uh for people to get in touch is there uh uh what's the best people what's the best way if people are interested in um attending the upcoming uh event um is it to reach out to you is there uh an a another mailing list um just so that I'm I'm sure of the folks that are listening there's gonna be a handful of folks that are interested so I want to make sure I'm pointing them in the right direction.
01:31:31.520 --> 01:33:06.880
As we record this it's not there but on Iversoncollege.com um there'll be a notice about what's happening with the meeting or at any rate what we know about it uh and an invitation to reach out to anyone who thinks that they like to be at the potential ground zero of a new or what should we call ourselves Alex communards I like that all right so I mean uh if if you uh if you're listening now you can check uh Iversoncollege.com if it's not there yet uh we will uh Steven will let us know uh Adam and myself and when it is live probably uh by the next time we're releasing one of these array casts uh we'll be sure to announce it and point people in that direction um and with that I will say uh thank you so much uh to all of uh Jacob Alex and Steven this has been awesome I've learned a ton I mean it's super exciting I also I didn't realize that there are it's not just L out there I learned about Peach Q and you mentioned a couple other ones uh we'll be sure to link all of the different flavors of these uh I guess Q implementations that are out there and uh will be very exciting if if you are having uh a meeting and uh folks are getting together um because yeah it's it kind of feels like uh I don't know maybe Renaissance is a bit generous but uh it it feels like there's a a shift in the Q wins and uh the same way that there's you know a number of APL implementations, whether they're hobby projects or more serious um that yeah this is uh as an enthusiast of different array languages it's very exciting to to see this kind of development happening.
01:33:06.880 --> 01:33:24.640
So um yeah thank you so much for for coming on and we'll be sure to link to all the different uh things that we uh mentioned in both the YouTube description and the show notes so check those and uh with that we will say happy array programming uh