Algorithms + Data Structures = Programs - Episode 4: How Many Programming Languages?

Episode Date: December 18, 2020

In this episode, Bryce and Conor talk about how many programming languages you should learn, why Haskell and APL are worth learning, and how to get your "scan eyes".Date Recorded: 2020-12-13...Date Released: 2020-12-18Ben Deane's tweetBen Deane's blog post "Six languages worth knowing"Michael Park's Advent of Code 10A in AWKConor's Advent of Code 10A in SmalltalkConors' Advent of Code 11A in APLHaskell SectionsBoost hana::flipC++ P1371 Patten Matching ProposalConway's Game of Life in APL YouTube VideoHaskell's mapAdjacentpandas Series.ffillthrust::inclusive_scanBryce's CppCon 2019 - The C++20 Synchronization LibraryIntro Song InfoMiss You by Sarah Jansen https://soundcloud.com/sarahjansenmusicCreative Commons — Attribution 3.0 Unported — CC BY 3.0Free Download / Stream: http://bit.ly/l-miss-youMusic promoted by Audio Library https://youtu.be/iYYxnasvfx8

Transcript
Discussion (0)
Starting point is 00:00:00 is at least partially underwater. And so I'm biking, and at one point I realized that my pedals are like underwater. I haven't seen my friends in basically all year. What are you talking about? You're seeing one of your friends right now. What am I, chopped liver? I don't see any of my friends in person. Proctor's like, hmm, should I really let this kid who's completely soaked into a room full of computers?
Starting point is 00:00:38 Welcome to ADSP the podcast, episode four, recorded on December 13th, 2020. My name is Connor. And today with my co-host, Bryce, we're going to be talking about how many programming languages you should learn, why APL and Haskell are worth learning and how to get your scan eyes. We have to read. We don't have to, but I would like to read some feedback. So I sent you a DM saying – you sent me a DM saying we've got to read user feedback. And I sent a DM saying is it good feedback or bad feedback? And I almost like – I almost hope it's bad feedback because I think that's going to be a lot more funny. But, yeah, let's read the user feedback.
Starting point is 00:01:24 I'm not sure if i've read all of the feedback uh that we've received i think i have but i haven't come across any that's that's uh negative um but sure we'll highlight well i'm not come on internet up your game we're not asking for negative i'm not personally asking for negative feedback but bryce uh bryce would would appreciate some but anyways uh pablo from linkedin messaged us saying started listening to your podcast and i thoroughly enjoy it listening to you and bryce talk so passionately revitalize my tough love for algorithms with a smiley face emoji can't wait for more episodes so i'm not sure what tough love means, but we appreciate the feedback. Not sure if you have any thoughts on that that you'd like to share, Bryce. Tough love. Well, I think
Starting point is 00:02:12 he may have been referring to the fact that, you know, we're very passionate about algorithms, but we also, you know, pointed out some of the holes and problems with some of the, you know, names and designs of some of the algorithms in C++. So maybe he's sharing the same appreciation for the problems. And we've got two more pieces. We'll limit ourselves to one piece per episode, but we're at episode number four here, so we're catching up. Ahmad, and I apologize if I mispronounce any of these names Ahmad said can't wait for episode 3
Starting point is 00:02:47 episode 2 was quite interesting first time I heard about the unique pointer array specialization pretty cool amazing podcast so kudos to you for pointing that out educating the masses and then the last one that I was going to read which clearly
Starting point is 00:03:04 I have moved away from. Awkward pause. I had it all lined up and now it's gone. So I'll find it next time but maybe I'll cut this part out too anyways when we started this podcast Connor was like we're not going to do any editing
Starting point is 00:03:36 it'll be nice and lightweight and every episode except for episode one we've been like oh we're going to have to make all these edits although I think only episode what was last week, three? Only episode three actually required some edits because of our... There's been pretty lightweight. The last episode was quite heavy, but they've been pretty lightweight.
Starting point is 00:03:58 It's mostly the first section that needs to be edited. Anyways, today we're debating. Let me adjust my chair. Get in debate mode. Lock the back so that I'm not slouching. What are we debating? We are debating how many programming languages should you learn. How many? Or whether you should learn more than one. Right. I think it was that. Yes. Whether you should learn more than one programming language. And
Starting point is 00:04:31 I will be taking the position of that you should learn more than one. At least a little bit. Well, I think it's really what the debate is. Should you learn a lot of programming languages or should you just focus on a couple of programming languages? And I think I'm going to be team fewer programming languages and you're going to be team more programming languages.
Starting point is 00:05:00 Yes. I will be arguing one of my favorite tweets of all time from ben dean where he tweeted it'll be in the it'll be in the show notes but he says learn computational paradigms and then lists off c++ lisp haskell small talk prologue fourth apl and it's this is actually from a blog post that he wrote, and later in the blog post, he also mentions Erlang. But I think those eight, feel free to leave comments on either the Reddit where we post this or on Twitter or somewhere or LinkedIn if you think that there's another language that represents a paradigm outside of those eight. But I completely agree. He ends his tweet saying, if you know these, just about everything else is variations. And I completely agree that learning one language from each of those paradigms is a paradigm shift.
Starting point is 00:06:02 It's going to completely change the way that you think about problems and that you solve problems. So what do you say to that, Bryce? Nothing. Well, I mean, I should say I don't necessarily, like, as... I've already won. He agrees. As a programming language designer, it would be... It would kind of be hard for me to say
Starting point is 00:06:24 that you should only ever look at, you know, a small number of languages. Because when you're designing a programming language, of course, you want to look at other programming languages to draw inspiration. You want to look at what, you know, what's the existing best practice? What's the prior art? But that's sort of with my hat on is somebody that's involved in programming language evolution. As somebody that's, you know, just working on building, you know, software libraries or software frameworks, in that role, I'm not, I don't feel very motivated to go and learn a whole bunch of other languages,
Starting point is 00:07:07 except when I really need to. Like the languages that I work in right now are the, we talked about in a past episode how my mentor thought there were three acceptable programming languages, C++, JavaScript, and Python. So I kind of know all those languages. I like to joke I write really bad Python. I also read a lot of Bash. Bash is actually a language that I kind of love. And I'm sure we'll talk about that at length at some point. And then more recently, I've been spending a lot more time with Fortran because Fortran's a very important language to HPC and I work on an HPC compiler
Starting point is 00:07:47 here at NVIDIA. But I've just never felt the motivation to go and learn every, you know, cool new language or, you know, languages that I'm not going to be using in my day-to-day work. And I just, part of it's just a matter of time management. You know, I've got so much stuff I want to do and I don't necessarily have the spare time to go and learn a language that I'm not, like, that I don't actively have a reason to use. Like, I've recently been going and relearning Fortran, not because I'm particularly excited about, like, not because I personally have a need to learn Fortran, but because I need to use it in my work. And, like, I think Fortran is actually a pretty cool and exciting language. And modern Fortran, in particular, if you look at modern Fortran versus like older Fortran, like it's a whole different language.
Starting point is 00:08:50 But it's just like I learned it because I needed to use it for my job, not because I had some desire to explore it. And I feel like there's so many things to learn within, you know, each different language. I'd rather specialize in a few languages, you know? Like, there's so much to learn in C++. I'd rather focus my efforts on really mastering C++ instead of going off and learning, you know, Go or Ling, APL, etc. So I think part of part of it is just like how do you find the time um yeah yeah i mean i feel like honestly this is a bad debate because like we very quickly have taken our extreme positions and like centered on something like we agree on uh so i'm sure
Starting point is 00:09:42 people think that i know languages very well but the truth is is like at one point i heard some people referring uh to me at a conference as like oh he's the haskell guy um and i was like what uh because i guess in a couple of my talks i had just i brought up haskell quite a bit but like i i am not a haskell expert by any means. In fact, like I got six chapters into real world Haskell and then got distracted. And like, that's the extent of my Haskell knowledge. And I've spent a lot of time like studying the prelude and like all the different algorithms
Starting point is 00:10:15 in a couple of the most popular libraries. But that does not make someone a Haskell expert. And same thing with basically all the other languages that I learn or that I know, I have some knowledge of, like, I would say I have a very surface level understanding of many of the languages that I can write like a simple solution to some programming problem in. So your comment, you know, mastering one language and just sort of knowing a few that you can like write scripts in is actually probably what I would advocate for. But I would say, you know, follow the advice of the pragmatic programmer, which says, you know, attempt to learn a language every year, every couple of years so that you do get exposed to sort of different paradigms. And I wouldn't say it's definitely not worth it to become like an expert
Starting point is 00:11:08 in a language from every single one of those paradigms. It's worth it to become an expert in maybe one or two or three, and then just sort of have like no, have a surface level understanding of like in broad strokes like you know how does this language deal with polymorphism like how does this language what do they do for their type system you know um do they have like a dsl for insert this or insert that um well but so like for i think it also might be that you and I are like slightly different types of programmers. And that might also drive our different levels of interest in other languages. Like you're really very much an algorithms guy. You get very, you're very passionate about going out and solving algorithmic problems.
Starting point is 00:11:59 And like that's something that you can go and do in, you know, whatever language. Like I've noticed you've done some of the Advent of Codes. Okay, you should tell me what Advent of Code is. I've seen that you've done some of them on Twitter and APL. I have no idea what it is. So very quickly, and this is anyone that wants to can hop in and start solving them. I was talking to Michael Park at the Bay Area C++
Starting point is 00:12:24 virtual user group meeting on Wednesday, this past Wednesday, and was chatting with him and then somehow looped him into starting Advent of Code. He did his first solution in awk, I believe, which we should probably do an episode on at some point. But he's been like changing languages every day. I think the last one he did was in Rust. Anyways, Avent of Code, it's a little programming problem contest, sort of. If you're like in the top 100, it's a contest.
Starting point is 00:12:57 If you're not, then it's just something fun to do, which I am not in the top 100. It's just something fun. Where every day for 25 days from December 1st till Christmas, they release a problem at midnight Eastern Standard Time. And the problem comes in two parts. And I think the idea is that progressively it gets harder from day one till day 25. And a lot of people use it as sort of like,
Starting point is 00:13:27 they take it as an opportunity to get more familiar or to learn a new language. So they choose a language that they don't program in day to day. Not everyone, like I know Tristan Brindles, he's solving them in C++. Barry Revzin I've seen has been solving them in Rust. I've been solving them in a combination
Starting point is 00:13:45 of small talker apl depending on uh what what the problem is and this is the thing i will say about advent of code is that i typically don't get very far because a lot of the problems are super heavy on like parsing the input and i half the time can't be bothered to like just parse input like the problem itself is quite easy. It's just, you have to extract some information from like strings and especially like, you know, years past,
Starting point is 00:14:13 I'd never done it in any other language other than C++. C++ is infamously not a good language for like parsing strings. I've noticed a lot of like coding competitions, like some of the ones that I've seen at various conferences tend to be very, like, string-oriented. And, like, I have a theory that the reason for that is that it's easier to engineer sort of self-contained challenges where your inputs are all just strings. Like, there might be interesting algorithmic problems where the inputs aren't strings, but, like, that requires a little bit more setup. Like, if you've got more complex data types, et cetera. Whereas like strings are fairly easy to set up. But like, I agree with you, like if the problem just like boils down to like either parsing some input string or formatting
Starting point is 00:14:56 some output string in a certain way, that's just like not super exciting to me. Yeah. And that's the thing is some of them aren't like there was a really cool problem the other day that boiled down to basically like you have a list of numbers. If you sort them, you're guaranteed that all the differences will either be one or three. So like figure out how many differences of one there are, figure out how many differences of three there are, and then multiply those two numbers. And if you live in algorithm land, you can very, very nicely just go sort, pipe, adjacent difference, pipe frequencies, pipe values, pipe multiply, and you're done. And if you don't live in algorithms land, then you're gonna have a bunch of for loops, and it's gonna look super messy. So like problems like that, I think are awesome that like,
Starting point is 00:15:40 and all you're doing is parsing basically integers. So that's super fine. But other ones, they give you a sentence that's space and comma delimited, and you need to pull the last two words in three different partitions, and it's just irritating. Anyway, so Advent of Code. How did this come up? Or you said you saw me in APL. Why?
Starting point is 00:16:09 That's the question. Why? Why? Because, yeah, why do I love learning other languages? It starts with Haskell. When I learned Haskell, my mind was blown in that I had been learning the algorithms and seeing a little bit of functional programming and that you can pass, you know, function objects or lambdas to algorithms to customize the behavior. So you can take a simple accumulate and change how it works. And that's very powerful.
Starting point is 00:16:43 Okay, but you can do that in C++ too. So that's what I'm saying. You can do that in C++, but it's limited to what you're given a set of algorithms in the algorithm and numeric headers. And you can write your lambdas. But you're limited to the extent of how many algorithms you get. You get like whatever, 100 plus or minus.
Starting point is 00:17:03 And you can't do anything nice, like really nice. So like if I want to add, if I want to create a unary operator that just adds one to a number, the spelling of that in C++ is bracket, bracket, paren, auto, e, n, paren, brace, return, e, plus one, semicolon, brace, paren, you're done. That hurts my soul a little bit. C++ did an amazing job getting lambdas into C++11, but it hurts my soul a little bit. Then I went to Haskell. First, I learned the lambda syntax, which honestly isn't a lot better, but like the equivalent of that in Haskell
Starting point is 00:17:52 is paren slash e arrow e plus one n paren. So still not super elegant, but it's a lot shorter. And then I learned about something called sections in Haskell, which are basically terse lambdas. So if you take a binary operator like plus, and you just put parens around it, so three characters, paren, paren plus, and paren, that is a binary operator that adds two things together. If you insert a one on either side of the plus, so if you have paren plus one and paren,
Starting point is 00:18:32 you then change that binary operator that does plus to a unary operation that just adds one. So like in three characters, I defined a binary operation. And in four characters, just by binding a value to either side of the binary operation plus, I've created a unary operation. And, like, that's just syntax. Like, you really haven't learned anything at that point. Yeah, are you, like, being charged by the character or something?
Starting point is 00:18:54 You know, it makes me a lot happier. So that's the thing. It makes me happy. Like, when I learned about sections, like, I was just like, oh, my God, goodness. Like, this is amazing. But then, like, you start to learn about ways that like you can manipulate these things. So they have like, we technically in Boost HANA have a template metaprogramming function called flip, which they have the equivalent in Haskell.
Starting point is 00:19:17 So like if you need to flip a binary operation that's like not associative or commutative so that it applies the arguments in the reverse order you can just like compose a function in Haskell called flip with that binary operation and you're done like in C++ unless if you're like doing something in template metaprogramming land and you have access to boost hana there's there's no way to do that like the only way to do that is to wrap your function inside a lambda or there's a couple ways to do it but the simplest way is to wrap your binary function in a lambda and then like reverse the order that you're passing your arguments uh to that function which is irritating um but like in other languages you can just compose
Starting point is 00:19:58 a a function called flip with your other function and you're done um and like that's just that's just like the tip of the iceberg and so like as i started like going down the haskell path it just it just the way that they um you know the way that they had pattern matching like that was the first time i'd really seen like pattern matching in a language was when i learned haskell like i knew it was coming in c++ and later on i would read, you know, Michael's paper. But like seeing how Haskell dealt with pattern matching and guard statements is just extremely elegant. So it just changed the way that like I saw that problems could be solved. And then I stumbled across APL. And if like, if the difference from C++ to Haskell was an order of magnitude, the difference from C++ to APL
Starting point is 00:20:45 is like two or three orders of magnitude. Like the solution that I most recently solved for Advent of Code had to do with basically, they say picture a grid that represents an airport waiting area. So there is a sequence of chairs, which are represented by the character L. And then there's everything else in between that's a period.
Starting point is 00:21:07 It's just empty space that you can walk around. And it is, honestly, it's a spin on the Conway's Game of Life problem. I won't attempt to explain, or do you want to, well, let's stay on topic. Let's finish the problem, and then you can attempt to explain Conway's Game of Life if you want. I can attempt to explain it? If you want. Other than that, otherwise we'll just link a YouTube video. But anyways, Conway's Game of Life, famous problem.
Starting point is 00:21:30 This is sort of a variation of it where it says each iteration of people sitting down, if every adjacent possible seat to them is empty, then that seat becomes taken. And if there are four or more people sitting adjacent to you, then that person gets up and leaves. So those are the rules of like, if you start off completely empty, the second iteration, every seat will be filled. And then the third iteration, any seat that has four or more people sitting next to it will become empty. And then it just sort of repeats. The way that you solve this in APL is like, is mind blowing. Like modern APL actually has something called a stencil operator, which specifically takes like a N by M region of your two dimensional thing.
Starting point is 00:22:17 It's like a popular trick and like NumPy like libraries. But like the old school way of doing it, it's honestly going to be so hard to explain but it involves a bunch of rotates you know Sean Parent's favorite algorithm for the win where basically you're creating a 3x3 matrix of the original matrix so you have a matrix of matrices
Starting point is 00:22:41 where each of the 9 matrices that makes up the outer matrix is, has a one rotate applied in every direction to the original matrix. So like the top left has like a one rotate to the left, the top right has like a one rotate to the right, and then you can imagine like rotates in both directions so that, uh, you have the diagonals anyway. So you end up with like eight different, uh,
Starting point is 00:23:11 rotated versions of the initial one. And if you just do like a summation across all of those original, uh, or rotated matrices, you end up with like a matrix that represents the number of adjacent, uh, seats that are actively um being sat in and like i would never ever in a million years like think to solve it that way um and
Starting point is 00:23:35 unless if i was like learning apl and like learning the apl way to solve things anyways i will end my digression does it but do you do you does that knowledge like you don't you don't write apl code in your day job no um well so i will say uh what the one main thing that was so awesome about that story is when i got the code to work like i i literally like i let out like a yelp of excitement um when i got that code working like it felt it was amazing i i know that uh yelp i've heard that connor yelp before it was like because i honestly i had didn't know how to do conway's game of life and apl and i was working walking through a tutorial and i was like i honestly don't even know i was just typing in like one zero negative one rotate and i'm watching all these numbers pop on my screen. I did not understand it. By the end I did.
Starting point is 00:24:28 But your point is, you know, okay, that's great. You've learned to think differently. Like, but you're not writing an APL day to day. So like, what's the point? The point is that like, it has like, I thought I had good algorithm knowledge when I learned Haskell. Like I, it was pretty good when I was learning C++. Then I went to Haskell and then I had good algorithm knowledge when I learned Haskell. It was pretty good when I was learning C++. Then I went to Haskell, and then I had a bunch of insights. For instance, adjacent difference. It's a terrible name. It encodes the default operation of minus into the name of the algorithm. I had that realization because in Haskell, there's an algorithm called map adjacent. Our map is called transform. So the equivalent sort of translated back to C++ name is transform adjacent. And so then I thought like,
Starting point is 00:25:12 oh yeah, that makes sense. And the Haskell version doesn't come with the default binary operation. You have to specify it. And like when I saw that in Haskell, I realized, yeah, we messed that up in C++. We should have just called our adjacent difference adjacent transform and not encoded a default binary operation because you lose sight of the fact that you can do other things with adjacent difference. One of the things I highlighted in my very first talk is that you can calculate Fibonacci numbers with adjacent difference because it's really adjacent transform. And if you substitute the minus for plus, you have a Fibonacci generator. Based on if you feed the inputs incorrectly. And so like I learned things about C++ from Haskell.
Starting point is 00:25:56 And the exact same thing happened for APL. Like I've learned a ton about algorithms. Like really, arguably, APL should be I've learned a ton about algorithms, like really, arguably APL should be called the algorithm programming language, not a programming language. But I think that's what it actually stands for is a programming language. Yeah, it stands for a programming language based on a 1962 book that Ken Iverson, the guy that wrote the language wrote, honestly, they didn't know what to call it. It was originally called Iverson notation.
Starting point is 00:26:28 And then he wrote a book about it called A Programming Language. And then in the 60s, IBM was like, hey, we could probably implement this. And then they started implementing it in like 66 and 67. And then at that time, like they didn't have a name for it. And like they were trying to figure out a good name for this language. And then at some point, someone walked in and was just like, about we just call it apl after the book and then everyone sort of shrugged their shoulders and said okay um anyways this is supposed to be a debate now i've just started talking about i'm gonna maybe modify my answer to you should have at least one person on your squad like connor so that you have somebody that has all this knowledge that you can uh
Starting point is 00:27:05 you can extract for your purposes but uh see for me for me it's just like I mean again maybe it's just a difference in like what we do um I don't spend a lot of day-to-day time like writing algorithms anymore or even like writing code I'm doing more like architectural stuff. Um, and so maybe it's just because we're like, we do different things, uh, that it's, uh, it's more valuable for you than for me. Um, yeah, it's just like, I don't know, I don't know where I'd find the time. Um, and, uh, it's certainly, I, I could see it being very interesting and exciting to go and learn a language like APL. I'm just not sure that it would do anything useful for me. Plus, I've already got you who's learned it.
Starting point is 00:27:54 This is the thing. As I was going to say, you guys can all, or I apologize. I said guys. Everyone can just watch the future talks that I will give that will just be condensations of everything I learned in language X and skip the learning part, although it's probably not the same. But yeah, I mean, definitely it's job dependent. I happen to work on a library that is heavily built on top of algorithms, the thrust algorithms. And a lot of the times it's figuring out how do we implement another algorithm in terms of like the existing algorithms.
Starting point is 00:28:32 So like having a strong knowledge of algorithms is like very important for the work that I do day to day. Like for instance, the other day, I thought this was awesome. A colleague was implementing something called forward fill. So in a data frame, I'll use the pandas and our Python API terminology. So you have a series, which is basically just a column or a vector, if you will. And we have an algorithm called replace nulls. So you can have, it's basically like a vector of optional data.
Starting point is 00:29:05 So you can either have, you know, optionals that have the values or ones called replace nulls. So you can have, it's basically like a vector of optional data. So you can either have, you know, optionals that have the values or ones that are null opt. And so there's an algorithm that we have called replace nulls that goes through and you just specify a value and anything that's a null value, they replace with that value. There's a variant of that algorithm called forward fill, which instead of specifying a value, you just take the preceding value, the which instead of specifying a value, you just take
Starting point is 00:29:25 the preceding value, the preceding non-null value, and replace that with the null value. So for instance, if you have 1, null, 3, null, 5, a forward fill will replace the first null with the preceding 1 and the second null with the preceding 3. So you end up with 1, three three five so the question is for the listeners and for bryce do you know what algorithm that is not off the top of my head no so we'll give we'll give the listeners uh a couple more seconds well it's it's some sort of a JSON algorithm, obviously. Or I'm guessing it's some sort of a JSON algorithm because you've got to look at the last element.
Starting point is 00:30:13 So you need some sort of stencil where you're looking at multiple elements at the same time. Unless you've got some sort of stateful thing where you're storing what the last element was. But I don't like such things because they're harder to paralyze uh yeah so if you were guaranteed i think that um you only ever had uh nulls that were you didn't have like a sequence of nulls one one after another, that would definitely work. You could do an adjacent transform, a.k.a. what we call an adjacent difference,
Starting point is 00:30:51 and that would work. The problem is what happens if we take our original example and get rid of the middle three and you have one null, null, null, five. If you're doing it sequentially then you're still fine because you you know you you replace the the first null and then it becomes a number and then you by the time you get to the second null you know the thing on its left has been which was a null has been replaced with a with a one already yeah i think actually that would work. Is that defined behavior? Yeah, yeah, yeah.
Starting point is 00:31:28 If it's a sequential algorithm, yes. I mean, if we're talking parallel, then things get a little bit more complicated. In some ways, this reminds me of stream compactation, which is an algorithm where you want to go and find like runs of numbers of the same value and compact them to, or you want to go find runs of elements of the same value and compact
Starting point is 00:31:50 them to a single element. Yes, encoding is what that's classically referred to. Sorry to keep everybody hanging, but the answer to the question or problem is to use something that in Thrust is called an inclusive scan.
Starting point is 00:32:12 Yeah, that was actually my first intuitive thought was that kind of sounds like a scan. But then my second thought was that might be inefficient because you don't need the sum of everything, right? Well, so that's the thing is classically a scan, the default operation of the scan in C++ is partial sum. So basically a scan is a transform that just carries state with it. And classically in C++, the default operation is std plus, which that means that like at every point in time, the state that you are carrying is the rolling sum of all of the elements that you visited so far. But you don't actually need to carry like state that is the sum of everything. There is something called a scan max um or a scan min which all it does is
Starting point is 00:33:07 carries a single value that represents the minimum of the values you've seen so far and so in this example when you're scanning all you're doing is basically scanning with the previous element um and then you basically have a ternary operator where you check like uh is the current element null uh if it is just use the previous element that is the state that you're carrying return that otherwise just return the current value and the way that that works out is that if you end up with consecutive nulls it will always be returning the last previously non-null value yeah this also kind of reminds me of of group by algorithms.
Starting point is 00:33:46 But yes, I'm not surprised to hear you say scan because that was the first thing that jumped out at me. But the thing is, I initially thought scan and then I wasn't certain that it actually worked
Starting point is 00:33:56 due to the sort of case with the extra nulls and I couldn't see it. But what's beautiful is that I think this is like, I think identifying min scans, max scans, you know, plus scans, those are all pretty easy.
Starting point is 00:34:11 Like whenever you need to see those, like in my first algorithm intuition talk, when you have to calculate like the mountain range, which is basically identify the maximum and then do a plus scan from both sides. It's pretty easy to see that. But like this is a non-classical scan i would say like in my opinion that is it is definitely a scan um but unless if
Starting point is 00:34:33 you like spent if unless if you're mark harris and like you spend your your days thinking about like he he said like once you have your scan eyes this is mark harris uh the pick on my team um he was like once you have your scan eyes, you see it everywhere. And I thought that was like a great quote because I don't spend like a ton of my time thinking about like scans. So I wasn't convinced. But when I presented this in like a lightning talk meeting or more accurately, one of my colleagues, Michael Wang, presented it. And then like a couple people immediately when I was like, what's the algorithm? They were like scan, scan.
Starting point is 00:35:07 And because they just they have their scan eyes. If have your scan eyes you see them everywhere um yeah i think this is awesome i'm pretty sure that my adjacent uh transform approach works if you only care about doing this sequentially but if you if you care about doing this in parallel the problem is if you've got like if i've got like one no no five um and let's say that i i divide i divide that four element input sequence into two element chunks each one that's given to a separate thread that second right chunk is going to be null five. And I guess the more nefarious case would be what if you had one – no, no, no. That's the sufficiently nefarious case. In that case, the second thread doesn't know what to do. But I also think – no, I can't really do it with a transformer.
Starting point is 00:36:03 Yeah, I guess it's got to be a scan if you're doing it in parallel um but if you're doing it in in serial um i think uh just like an adjacent transform would work fine if you just if you know that you're always um marching serially from left to right yeah i i think we're getting close to the end but but I'll link what Bryce just said makes sense to me. But I'm guessing to a lot of the listeners, sort of the parallel versus serial when it comes to like adjacent transform versus scan. There's like a subtle thing that he's relying on. And we can try to explain it in a couple of sentences here. But there's a one of
Starting point is 00:36:46 your best talks i think i think it's called the c++ 20 synchronization library from cppcon 2019 i believe at the end of that talk that's where you give like a visualization of inclusive scan with like the upsweep and the downsweep yeah and that that is like i'm not sure if you recall, but the first time we went to, and this probably deserves a whole episode to its own. When you drove to San Francisco and we went to the Michael Park hosted, we were at Mesosphere, I believe. In that car ride on the way to San Francisco, I think previously at like a different time I had asked like I don't understand how a scan can be done in parallel like a reduction is pretty straightforward you can visualize the tree reduction and you know you just add the numbers that make sense but like a scan inherently when you visualize a scan it's carrying state and like anything that carries state it is not intuitive
Starting point is 00:37:40 like how you can make that work in parallel and And then you explained to me in that car ride and I was enlightened. And if you recall, we missed a certain turn that we had to take like three or four times while I was in the deep part of the explanation. But you had the aha moment in the car. Yeah, that was that was hilarious. Yeah, we were so we were talking about the the scan and then yeah a few minutes later wait did we take the wrong ah and then yes some uh colorful words were shared and then i was i was less concerned about us getting there on time than i was about you understanding the power of a parallel scan and i think too i i you were trying
Starting point is 00:38:23 to like get back on the right highway and I was still asking questions. And at one point you were just like, all right, we got to take a break. We got to pause the scan talk. Yeah. We've got to.
Starting point is 00:38:34 And, and that, that version of scan that I showed isn't even the most efficient scan algorithm. Cause that, that was still a two pass algorithm where you didn't upsweep in a downsweep. Whereas the, the modern state-of-the-art, the scan algorithm that we have in Thrust is a single-pass algorithm.
Starting point is 00:38:50 But it's much trickier to explain. There's a whole paper written on it that my colleague Dwayne Merrill wrote. We should link all that stuff. Yeah. Maybe we should leave. We'll leave the explanation of inclusive scan in parallel, maybe for the next episode, maybe that's what we can talk about. Implementing counter and less intuitive algorithms, parallel algorithms, we can try and explain
Starting point is 00:39:16 that stuff next episode. Spicy. All right, anything else we want to highlight before we hop off here? I think that's it. I think it's a good one. All right, everybody. Thanks for listening, and we'll catch you in the next one.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.