I mean it it kinda hurt hurts my soul a little bit though when you when you see the the rainbow end after like seven languages and then everything else is white because there's zero agreement on on the naming of uh one of them is is prior, a JSON transform, which we now have in C23. It's called prior and Q, uh zip with next in in Scholar or Kotlin, I can't remember which one. And and but like every language has a different name for that. Welcome to AD SP The Podcast, episode 230, recorded on April 9th, 2025. My name is Connor, and today with my co-host Ben, we chat about a new website, Hoogle Translate. Although I probably I'm not sure also because you don't spend much time on the socials anymore, or maybe this can be um part two now. We're now on episode 230. I have spun up my long-awaited uh Hoogle Translate um website. All right. In fact, maybe I'll I mean uh we try not to share screens here, but um maybe I'll do it for a sec. And honestly, say what you will about vibe coding, folks. Vive coding is I think the number one best thing about these AI-assisted stuff. It is a barrier remover. You know, the l- the you know the reason? You actually commented, I think it back on Twitter years ago, when I had I think you you commented something about like, oh, sss this like uh graphic that I had posted is kind of like a Hoogle Translate, um, referencing the Haskell website. Potentially. And then I replied to that. It was so many years ago, yeah.
BenYou probably probably it sounds vaguely familiar, but it may have been the first time you'd heard of Hoogle. Oh is that the case? I don't know.
ConorIt had not, I think I had heard of it before. Definitely I'd heard of it before because I had I you said Hoogle Translate, and I replied, I've owned the domain for like 12 days, um, hoogeltranslate.com. Okay. Uh and so like I was like floored when you had suggested that. I guess it's it's um a pretty uh common like if you know of Hoogle, this is basically that's why I called it that, right? It's a Google Translate for Hoogle. You type in one thing and you get it cross-language. And uh this was a site that I built in ClojuScript like uh in 2023, but the reason I didn't publish it was because I already had a website spun up, um, which was my program language rankings, plrank.com. Right. But the way that I would deploy that, I would like build the ClojuScript website, it generates a main.js, and then I would always manually push that main.js as and that's what basically the website was, which is like you should be able to, with uh CI recognize that there's some uh change and then basically get like uh CI to rebuild that JavaScript file and then push it for you. I spent half a day or a day or a couple days at one point trying to figure that out, but I'm not a CI engineer, and I'm also not like a front-end web developer, so like I'm already out of my depths uh dealing with JavaScript and stuff. And so I I just gave up and I put it on my list of things to do, and I wanted to get the automatic deployment of this main.js working before I built my second ClojuScript website so that I didn't have two different, you know, bad, badly, poorly deployed websites.
BenIt's it's funny, it's funny when you say and I I totally uh echo the sentiment like you know, um you're out of your depth with JavaScript. You know, um my wife is a front-end developer, and uh you know, she thinks what I do is arcane magic and the same the other way around, right?
ConorIt's like it is and that's the thing, is it's it's true, like how you know how how you can be an expert in one thing and then you move just slightly to the right, you know? It's just a different programming language, it's just a different stack, but you don't know the idioms, you don't know the libraries to reach for, and you may know how to spell it algorithmically in your head, but like potentially those algorithms you need that primer to translate. You need Hukle translate. And uh long story long is that I I vibe coded using Cloud 3.7, got like re-uh did like all of the plumbing of that first website, got the GitHub actions automatically deploying, and then I did that like one day, and then the next day I was like, well, now that I have this, I can just go spin up Google Translate, even though it's been sitting there for two years. And initially, like it was just this you know bareborne's website, and now I've got like a bunch of uh settings and uh light mode, etc.
BenLet me now interview you about this website for our listeners. So this is hoogletranslate.com uh h-o-g-le translate.com. And what does it do, Connor? So it the the front page here looks very much like just the sort of Google front page where you have just a search bar and a few settings off to the side, but we're expected to type something in. What what do we type in here?
ConorSo and and I've had uh I'll start off by I've got a lot of comments because I released a YouTube video on this saying it's a terrible name, change the name. And then a couple people being like, you realize there's already a tool out there called Hoogle. And I'm like, yes, that's where I borrowed the name from. That's right. There is an existing website. If you Google Haskell, Hoogle, it'll come up. And Hoogle is a type signature, aka like function declaration search engine. You type in the type signature of a function, and it'll return you all of the functions across Haskell libraries that match that type signature. So it's a great way for finding a function that you don't know the name of. Uh for instance, I did it one time when trying to find the Python in function. You're trying to check is there an element that exists in a uh a list of elements. That's called in in Python, it's called contains in many functions. In fact, uh if I now type in here, I'll get the Python in. And if I click on the in LM in Haskell, all right? One version of it is called LM. And now you get a uh a list across languages of the different names for algorithms that share the semantics. So behind the scenes, there's a couple different searching methods. When you just type in an algorithm name, that's called the by name search. But then when you click on a specific language's implementation, that switches to a by algo ID, which is basically an ID that maps to a specific semantics of an algorithm. So sometimes there's algorithms across languages that share the same name but have different semantics. Uh a great example of that is uh partition. So partition, when you type it in, has, I don't know, what this is 15 languages, and there's four different colors. And the colors in this by algo ID or like bi semantic search means that partition across languages has four different implementations. Some of the times it's the C partition where you are basically given a unary predicate and you're putting the ones that uh pass it at the front and the ones that uh fail it at the end. And the two other languages that share the same color are D and then CUDA, which is makes sense because CUDA is just basically a parallel version of the C one. And everything else is uh basically different implementation. Um so I think partition for Haskell and friends. Um I mean I actually have to go to the docs, but you can see that when I click on partition for Haskell, I now get partition copy and split with in Elixir. And my guess is that you're writing to two separate sequences here. So you're returning a tuple of two sequences, yes. Exactly. Instead of like mutating in place. And right now I play a little bit fast and loose. Um I'm going to be adding something called signature search, which is the exact same as Hoogle where you type in the signature. And like the worst offender uh right now is if I type in fold uh and then click on one of these, I get all the reduces, folds, inserts, aggregates. Right. And the semantics of some of these are different, and the best way to see that is if you compare the type signatures. A lot of these, there's a difference between one that takes an initial value and one that doesn't take an initial value. And that's typically like you'll see Kotlin shows up both for reduce and fold, Russ is the same thing. Many languages are like this, and the difference is whether it takes an initial value or not. This is going to get split, and there's currently an issue open to say, you know, build in signature search, and then while you do that, uh be more clear about what do I mean by you know same semantics. I've been playing a little bit fast and loose because technically the partition copy in C doesn't return a tuple of um lists, right? It writes to two different sequences, and there's always gonna be.
BenIt is the only standard algorithm that does that, in fact.
ConorIt is indeed, yeah. Um and uh there's some other cool things that like if you this was added after the fact because someone requested it. If you click on a language, it'll give you all the um algorithms.
BenSo if we go to C, which is And there are a lot of languages uh represented here, um many as as we might expect. Um of of different paradigms, you know. We've got we've got the C style, the the um the algol family, we might say. C sharp, C, C, Go, Python, Rust. We've got the array languages, uh, APL, we were uh we've got Excel at the bottom. And we've got functional languages. There was one language I didn't know how to pronounce in there. I didn't recognize it's the the crescent.
ConorYeah, this is I think I'm gonna ch I'm gonna change this to moon. You can see that half of these characters aren't recognized. This was uh uh a watcher of one of the live streams. Um I think their personal language. This is uh an array language, I take it. It's uh I'm not sure if it's an array language. It is a symbolic glyph language um that I it does have a lot of the same primitives transposed, so I I wouldn't be surprised if it's an array language. But the thing about this site is it uh this whole site operates basically on a markdown file that is just a table. And then thanks to Cloud 3.7 again, I basically built up a CI pipeline that whenever the markdown file gets changed, it kicks off uh a GitHub action that runs a Python script, parses the markdown file, and then generates a closure script dictionary, and that's what basically runs the site. So anyone that wants to can basically just go and open a PR and add any language or any missing algorithm. Um and even it's it's uh now that if you want to add like third-party, like technically range v3 is here, but that's hidden by default. And then also in array languages, a lot of the times they don't have explicit glyphs because it's just a combination of two or three to get that. So you can click show expressions and for certain array languages, it'll show you that you know, like any is just uh an and reduction in all the array languages. Currently, right now, we don't actually have those added, but in the future you'll see stuff like that. Um one of the coolest things that I've added because one of the like the motivation for this is one, it's a useful tool for finding algorithms. You know, Hoogle's very useful. A Hoogle Translate is also super useful. I've gotten a bunch of comments saying, like, oh, I was working in Python and I I knew this thing should exist, but didn't know to check in more iter tools, which is like a iter tool library extension. But the other motivation is I I love putting these graphics, especially if I'm at a non-C ⁇ conference, in talks where I'm talking about Python, and you know, I'll say, you know, I know this as this in C, but it's also known if I can just show this thing, uh, but manually creating these is a pain. You know, it takes like you know thirty minutes to go and and handle this. So now that it's online, people can submit PRs, but I've also wanted to be able to show the differences across multiple languages in like a nice table. And so my favorite one these days is if you type the name of a language, and then you can type a bunch of you know, multiple of these. So swap is the um the C combinator known as Flip and Haskell, uh, which I guess Haskell should be here as well. But then if you can continue to type, it'll build up. Oh, a multi-column table showing each algorithm in a different column. Exactly. And it adds a little sad face. Sad face for when the algorithm's missing in that language. Sometimes this is just because it hasn't been added, but specifically for what we're looking at, we're looking at the combinators in that match to BQN's uh swap over before, and I can I can add after. And then it's still, and I guess we haven't explained this, is that uh I have I don't actually have a name for the algorithm. It's it's kind of basically it it creates a frequency uh map. Enclosure is actually an algorithm called frequencies, where it's the equivalent of the counter data structure. In fact, if we copy and paste this and and we type in uh frequencies, you'll see that there's two you know two languages that have a function called frequencies, racket enclosure. And when we click on this This is this is histogram? Exactly. This is creating a histogram, yeah. And in Python, the idiomatic way to do this is actually not to use an algorithm, it's to use a container from collections called counter, which is why there's a little asterisk beside this because once again, yeah, it's it's um it's playing a little fast and loose. Um but it uses frequencies to basically figure out what's the most common. And then uh I've stolen the colors from Excel 2003, which has got one of the best color palettes out there, folks. And then it describes purple to the most common name, and then um I guess blue is the next most common, and then it goes down the rainbow. And so across this you can see that you know, over, aka the psi combinator, is the most consistently named across these array languages, but then some of them, like every single language chooses a different name for um it, and uh some of them don't actually have uh the glyphs. And so you can do this for anything, you know, you can you can go CE all, and then technically, you know, it should it should be any of and all of. But then this shows that like uh by a landslide, the most common names for this are any and all. And um if if you're actually using this to build up graphics for a presentation, I've added the feature that you can um control and click on any row. So if you don't want, you know, C sharp, elm, Julia, common list, whatever.
BenGet rid of ones you don't want to put in your graphic. Yeah.
ConorYou can build the graphic that that you um want. Uh so anyways, it's uh there's still lots of stuff that I'll be adding over time, but it's uh it's a neat tool.
BenUm, now the obvious thing for me to ask is for you to type in but last.
ConorOh yes, that's why we came here. So um I don't think it'll be here, but when I was doing my uh masters, um I was doing a lot of small talk work, and I know that small talk, the Pharaoh implementation specifically, does have the equivalent of but last and and so and so I guess init would be the one that so init's not even in here from Haskell, and but last won't show up either. But I shall, after the fact, go and get these. And if we go to Pharaoh Small Tattalk but last algorithm, it's very hard to search Pharaoh. And actually, I don't why are we doing this? Let's go to ChatGPT. Hello, uh good friend. I don't even know. I I got into the trip trap uh trap of uh Googling when I would never do that if I wasn't on this podcast. You were about to say something though.
BenWell, I was gonna say we want the right answer, so if ChatGPT will give us the right answer.
ConorOh, that's the thing, is if you give it a lot of context, if you say, um, I know uh in Pharaoh Smalltalk, there is an algorithm identical to Haskell's a knit and is it commonlisp? Yeah, common lisp calls it but last. Do you know the name? It nails stuff like this. It nails stuff like this. All but last. All but last, implemented on sequenceable collection, okay. And they even gave us a little snippet using the hash paren for uh a list. And um and so yes, uh I should I should add this. And and you can note that, you know, on the Hoogle Translate, uh the Pharaoh uh there's only four um algorithms uh from Pharaoh Smalltalk that I have here. And that's because the stuff that mostly, or half the stuff that exists in here was what I needed when I was interested in looking into something like two or two and a half years ago. And I think that was like roughly 300, but we've I think since a week or week and a half ago, it's doubled to like six hundred um algorithms across languages because people have been opening PRs. And so I imagine at some point it'll it'll get to like a thousand or two thousand. Um but yes, init, but last, all but last.
BenSo what is the correct name for well in common list, but last can take an optional integral parameter. So you can do but last n, right? But last is is but last one, but if you give it an integer, you can optionally chop off the last n.
ConorRight. And this is this is something that will also be built in, because right now, for the most part, things just map to one alg algorithm ID. But over time, things with optional parameters or default parameters, like closure, a lot of the times, their partition algorithm I think technically maps to a couple different algorithms. And uh with the type signature work, you'll be able to basically map a single algorithm to multiple semantics. So it'll show up in every place.
BenCommon Lisp also uh somewhat confuses you confusingly. Well, it has n but last because it uses n in the name of an algorithm to mean a destructive algorithm. N reduce is another one. I think n reduce or n I can't remember, but uh n append, I think, n concat. These are algorithms that change their data structures in place rather than returning a new one. So but last return to a new list with everything but the last element. N but last does not, as you might think, uh have anything to do with selecting n elements, but it it changes the list to chop off the last element. Interesting. That's what the prefix n stands for. In common list that is the um that is the conventional that is the convention, yes. N I think n concat is uh is another example. So you give it two lists. Concat just concatenates to this, returns the concatenation. N concat sets the uh tail of the first list to be the second list, so it effectively uh destroys the first list or or changes it in place.
ConorDo you know why? What the history but behind choosing prefix n? I don't know why n is used in that way.
BenUm certainly um th those variations exist for efficiency.
ConorRight, right. Yeah, that totally makes sense. And that is, I mean, that is the a part of the issue of like a site like this, is that you want there to be like a a clear, you know, almost strict how semantic how do you group you know algorithms by semantics. But when you get to a language like C ⁇ where you know we have a smattering of in-place versus non-in-place algorithms that are inconsistently named with the underscore copy suffix, is you know at a at a certain level, semantically they are the same. Um, but and it it's also like I've been thinking, I haven't added I think someone actually the other day added reverse and reversed from Python for the reverse algorithm. But you know, those are an in-place versus uh one that's returning a copy. And you know, how do you how do you deal with that? Do you split that? Because the type signature is different, right? One returns void and one returns a new copy. The new collection, yeah. And or do you come up with some way of I type sort and then it shows you two different columns of like in place or out of place? I haven't really figured that out yet. But I mean that's that's one of my um I mean I've complained about that in the past too, is that you know, sort is in place and transform is out of place. But like why did we not consistently name like have a naming convention where it was either underscore copy for anything, so it should really be transform copy. Um and we're kind of just inconsistent with that because you might think that like, oh right, this one doesn't have a copy, therefore it must be in place, and that's that's not always the case, right? Um yeah, interesting though. Common list calls it n and array languages don't care. I mean, I I think sometimes there's some internal optimizations based on they can reason that there's only one thing happening, so they do everything in place, but um that's not something the user necessarily is aware of.
BenUm yeah, nconcat is the interesting case, or an interesting case in Commodisp, because so regular concat uh so both nconcat and concat don't have to change the second argument, right? Um but in the case of concat, you need to create as many concells as are in the first list. You basically create a new first list with the second list as its tail. The second list remains unchecked. The second, you know, like the second list can be the tail of something and not know about it. So the second list, because a list is really just a pointer to a a con cell which is designated a head of a list, right? Uh and the rest just flow after it. So the the non-destructive version of concat allocates n new concells for the first list and then and then appends the second list just with a single operation. Um but the n concat doesn't need to allocate, it steps down the first list and when it hits the end, it just sets the tail to the second list. So it it turns the first list into the longer list while still leaving the second list alone.
ConorAnd is uh just to clarify, because concat can mean different things. I mean, sure enough, I'm sure if I type concat here, uh you can see there's multiple colors. Is it sounded like concat is just for two different lists appending to Lists. Gotcha. Okay. Yeah. Whereas my guess is across these languages, one of them is like a flatten where it can take any list of lists and flatten them all. Interesting. Yeah, that's that makes complete sense. Yeah.
BenCan cat might be able to take variatic arguments in some in some Lisps. But I, you know, for simplicity's sake, let's just consider the two argument version.
ConorYeah. Interesting. I'm trying to think, like in C basically, well, is there is no really equivalent. I mean, in ranges land, they do have join now, but if you're pre-ranges. You can't really do that, right? Like if you have like a a vector effect, like that stuff is statically typed, right? So you can't turn that into like a one-dimensional vector. So you're always going to be doing some kind of copy, out-of-place copy.
BenIt's like a splice. Splice is uh in unordered map or map. I'm gonna say one of those. There's an operation or is it called merge? I've heard of merge, and I definitely haven't heard of splice. Um, splice is an operation on std list. Yeah, okay, so splice is the list version.
ConorTransfer elements from one list to another.
BenNo elements are copied or moved, only the internal pointers of the list nodes are repointed. Yeah, that's the same. Okay.
ConorWhich makes sense, right? Because that's common lists. I assume implementation is some kind of point pointer chasing thing. Interesting.
BenAlright. Well, and and merge actually also exists, and I think it's similar. Merge exists on list and also on unorder map forward list. So it's a very similar sort of idea. And there's a freestanding, I think, merge algorithm as well, I think. Yeah, well, yeah, but that's something different. Right. The merge algorithm is taking two sorted sequences and that was zipping them together into a third. Again, zip is an overloaded term. Um but yeah.
ConorRight. Anyway, so yeah. This I guess this spun out of what to call the for each but last, and then that made me think, oh, I have a tool for this. Not fully not fully built out because it doesn't have any of the names. You have a tool that doesn't quite know this yet, but they will. Yeah, yeah, over time. And that's the thing, is that I h my my hope over time is that like languages that I have you know zero familiarity with that potentially have like extensive libraries, like D is one of those languages that has a lot of interesting names. Um and Swift actually the other day, uh I think I knew this and I had forgotten it, that um Clojure calls their scan, which is overwhelmingly the name chosen for uh the incremental fold that's outputting all the you know running results. Cotton calls it running reduce and running fold. Um Clojure calls it reduce for the reduction and reductions for the scan. Oh, okay. Okay. Which is kind of nice. It's one of the few algorithms or few languages that shows that they're um related in the naming of it. And Swift also, I don't know if they borrowed it from Clojure, but Swift and their algorithm library, which is an extension of what's provided in the standard library, uh they call it um reductions as well, which uh I only I thought Clojure was the only one. Um but yeah, it's neat when you when you stumble on different names but that are arguably better names. I mean it's right, right.
BenI'm reminded of um Tails. I think in Haskell it's called Tails. It might also be called Tails and Lisp. Although maybe not.
ConorWhich is like prefixes. Yeah, they have initlinits and tail and tails, yeah.
BenThat's um, like I forget exactly what it is, but it's something like all of the So the Tail is the Lisp minus the head and the or the the cudder in in Lisp and the cudder and the cuddr. Yeah.
ConorThe Lisp folks understand what what you just said. Uh yeah. Or anybody that's read uh SICP um probably understood as well. Uh yeah, I think actually BQN, you know, my my favorite language of the day, they have two versions of that, and I believe they're called prefixes and suffixes. Yeah, prefixes and suffixes, which uh arguably is a is a kind of nicer name in my head because scan a lot of the times they're known as prefix um prefix scans, or they involve the word prefix because it is you know different prefixes.
BenBecause you're computing the reductions of the prefixes, yeah.
ConorYeah. I mean it is it is very cool. I I I love when people add stuff to the site because then it it shows that, you know, sometimes like filter uh and even arguably filter. You know, there's there's been conversations about are you filtering in, are you filtering out? Um is that the the best like but some of them, you know, filter, map are almost unanimously, unfortunately not for C ⁇ , we called our transform, but almost unanimously are agreed upon. And then there's other ones where it's like there's maybe three languages, and two of them are like C and CUDA C ⁇ , which really should count as one. And then every language has a different name for it, which is uh this this is like the vocabulary that we use to write.
BenYeah, it's a great uh and the site is good for naming, uh you know, as well as As well as exploring languages, and by exploring languages we get the idea of what what is the common name if there is one, or what are some of the names, what are some of the ideas around this, you know, also because things called different names have slightly different uh signatures in different languages, right? So you get to explore the design space around the algorithm.
ConorYeah. I mean it it kind of hurts hurts my soul a little bit though when you when you see the the rainbow end after like seven languages and then everything else is white because there's zero agreement on the naming of it. One of them is is prior, a JSON transform, which we now have in C23. Uh it's called uh prior in Q, uh zip with next in in Scala or Kotlin, I can't remember which one. And and but like every language has a different name for that. And uh it to me that's like it's a fundamental algorithm. Like I don't know how many times I think in your talks in Ivan uh Kucix, I'm gonna pronounce that wrong. It's been a while since I I've met him, so I um but anyways, multiple talks, I've seen the zip tail trick. I think I've seen it in Odin Holmes, maybe uh give it talk as well. That's that's this pattern is uh you know, adjacent transform. And it it's a real shame, in my opinion, that it's it's not as like popular as as map and filter and reduce. Like it should be up there. Um anyways, we'll wrap up Google Translate. Be sure to check these show notes either in your podcast app or at adspthepodcast.com for links to anything we mentioned in today's episode, as well as a link to a GitHub discussion where you can leave thoughts, comments, and questions. Thanks for listening. We hope you enjoyed and have a great day. I am the anti price. Um