C++ Concepts vs Rust Traits vs Haskell Typeclasses vs Swift Protocols - Conor Hoekstra - ACCU 2021

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

concepts are extremely powerful constructs, so powerful that you can use it to define algebraic kinds.cxx), see DataKinds.

I'm not sure if any of the other mechanisms here is this powerful, tho some languages (e.g. Haskell) might provide other mechanisms to do this kind of things

👍︎︎ 1 👤︎︎ u/geekfolk 📅︎︎ Jun 13 2021 🗫︎ replies
Captions
i am going to hop into things and if people are trickling in it's okay because the first bit is just introduction so welcome to my accu 2021 talk this is my first accu conference if you don't count the accu autumn that i went to back in 2019 i'm going to be presenting my talk on c concepts versus rust rates versus haskell type classes versus swift protocols which this was the initial title slide that i had and as a bonus i'm actually going to be including the d language which has a language facility similar to these which is called type constraints but my title was already long enough and the initial time that i submitted this i didn't include d so uh the working title is concepts versus type classes versus traits versus protocols my name is connor huckstra this is the about me slide or this is not the boat me slide um all of these slides can be found on the uh my github page under the talks repository so there's gonna be a 202103 accu folder that has both these slides to this talk and the lightning talk that i will be giving at uh 1 pm eastern standard time later today so this is the about me slide the visual graphic about me slide so i work for nvidia on the rapids team rapids is a suite of open source libraries that is focused on gpu accelerating data science so if you're familiar with libraries python libraries like pandas we are basically building up gpu analogs of these libraries that can be uh run on the gpu end to end so if you are working with data science libraries and you're looking to accelerate your work definitely check us out at rapids.ai i have a podcast that i co-host with bryce lelbach called adsp the podcast which is a acronym for algorithms plus data structures equals programs i will provide a link for that in a sec i also have a youtube channel i also run a programming languages virtual meetup that runs every mondays at 8pm eastern standard time we last year in 2020 worked through the structure and interpretation of computer programs and we wrapped that up in january of this year and now we've moved on and are working our way through category theory for category theory for programmers by bartaj malewski oh yeah i can try not to move the camera as much because i'm not using my clicker due to my limited number of usb ports on my workstation and uh last but not least or second from last but not least i am a c plus plus developer so on my day-to-day job we code in c plus 14 we'll be upgrading to c plus 17 but i also am a programming language enthusiast um i'm learning you know multiple languages at any given time haskell and closure are two of my top five languages um next to c plus plus and my favorite language by far is apl um i'm not going to say anything more about apl but expect to see more talks from me in the future talking about apl this is a three symbol expression for detecting whether a string or an array of numbers is a palindrome um so apl is known for being unreadable but that's just because folks don't know how to read it um but anyways like i said that's all i'll say about apl so all of the links that are corresponding to sort of the information about me can be found here podcast youtube channel rapids.ai and the programming languages virtual meetup it says toronto but it is a virtual meetup um now and forever so let's hop into this talk the first thing i want to say is that this is not a language war talk this is going to be a language comparisons talk which is different than a language war talk so if you've seen any of my tweets or lightning talks in the past you will know that i love all programming languages this is a tweet from back in october of 2019 that i highlighted in a lightning talk at meeting c plus 2019 where i basically am encouraging everyone to be kinder to our programming uh developers in other ecosystems in other languages i see on reddit a lot which is not the best place to go and look for sort of camaraderie but i see a lot of bashing of different programming languages and i think that every programming language whatever your view of it there is something to be learned from that programming language another tweet that i tweeted out once was a quote from guy steele who's one of my heroes and the people that i look up to he was giving an ama at the pldi which is the programming languages design and implementation conference back in 2020 and he said i love all programming languages when i was asking him about apl uh and yeah i just it's so awesome to see someone that i look up to so much saying this and i really encourage everyone to try and take this more point of view so the point is this is not a language board talk even though we're going to be comparing languages uh this is a language comparison talk and the second thing i want to highlight is that this is a part one of a two-part talk so i started preparing for this talk thinking that i was going to give a really really technical comparison of all the different you know compiled time runtime features of these language facilities but this is a super super super deep topic and this is the beginner introduction to the topic it is not going to be looking at the technical differences you know which uh of these language facilities support associated types stuff like that um look forward to that in part two this is basically an introduction to how do you build simple versions of you know a rush trade or a c plus 20 concept and what are the different categories that these sort of language facilities fit into um so set your expectations that this is sort of the beginner talk and if you enjoy this talk and are looking for a more technical in-depth version of this expect a part two at some point in the future so this is going to be the agenda for this talk there's gonna be five seconds five sections i will pause at the end of each section uh to try and answer any questions um depending on how many there are i might only answer you know two to three to four um but my goal is to leave you know five to ten minutes at the end so we can address any outstanding questions and i'll be in the hallway track afterwards if folks want to grab a table and talk about any of the stuff that's covered in this talk so the first section is going to be an introduction uh it'll be about 15 20 minutes we're going to try and burn through it pretty quickly of how i came to give this talk then there's going to be a short section highlighting generics and parametric polymorphism and sort of defining a couple different terms but then we're going to look at two different examples one is a super simple one and then the second one is a little bit more involved but still pretty simple and then the final section will be my final thoughts on these five programming languages so hopping into the introduction this story starts in 2018 when at my workplace we had a functional programming study group where we decided to work through a course that was an introduction to functional programming and this course was given by a very well-known individual in the programming language community eric meyer if you saw one of the lightning talks yesterday where it was c-sharp 9.0 or 5.0 records being introduced eric myers has been a um very involved in the development of features that have been added to c-sharp in the past and we worked through the first few chapters of the textbook that came with this course but then decided that it was a little bit out of date and that we wanted a more modern textbook so we switched to real world haskell and if any of you have read real world haskell you'll know that chapter six covers type classes and at the time i knew about c plus concepts that were slotted to show up in c plus plus 20. and this was the first dotted line connection that i had between uh these two programming language uh features or facilities um it seemed very similar that what sort of type classes were providing for haskell was similar to what concepts we're going to be providing for c plus so this was the first dotted line between c plus concepts and haskell type traits then roughly a year later i watched a talk by dave abrahams who i'm sure many of you are familiar with on protocol oriented programming in swift and we are going to look at a clip from this talk as you can see dave was gave himself the the title professor of blowing your mind it's an awesome talk i believe it's actually ranked number two of all time wwdc talks i could be wrong about that it might have been one of dave's other talks but it's a fantastic talk and let's take a look at a clip from this talk of course i'm talking about protocols all right this is not playing so we're going to try this again of course i'm talking about protocols protocols have all these advantages and that's why when we made swift we made the first protocol oriented programming language so question for the chat was there moving uh video there was not on my side so i assume it did not stream to your side um we will continue on but maybe i'll hop out and hop in again to see if we can get it moving um but yes you heard what dave said uh the first protocol-oriented programming language and this brings us then to the next point in this list so first was haskell in 2018 then just over a year later in 2019 i watched this talk in december and then just a a month later in 2020 in january i was listening to a podcast called magic read-along which is the inspiration for uh bryce in our podcast adsp and uh the two house say the following i just watched a video today on um swift and it's uh and like their protocol driven development or protocol orient oriented development and yeah i know it's pop i guess there was protocol oriented programming and uh they just basically introduced type classes and they're like we invented this this is amazing is it is it actual type glasses or is it just like uh interfaces it's it's interfaces that you can extend uh ad hoc on on the fly like it's a and basically you can have as many constraints as you want it's basically type classes um so i posted the like 1988 wadler paper so we're going to revisit this in a little bit um but uh basically as you heard just heard they're linking type classes now to swift protocols so at this point i now have this sort of mental model of c plus uh 20 concepts uh haskell type classes and then uh swift protocols so you can see once again that um they're linking type classes and uh protocols from swift and the paper that they mentioned was 1988's uh how to make ad hoc polymorphism less ad hoc by phillip wadler we're going to revisit this in a little bit so i just thought i'd highlight it now but this is basically the paper that introduced type classes and this brings us to our fourth and final point in this journey is that uh literally four days later after i listened to this podcast in 2020 i was on reddit and i saw a post that was linking c plus plus and swift um that talked about a core question and this is that uh question so the influence of c plus on swift which links to the uh core question uh which is going to bring us to our first digression of the talk so the question is what are the similarities and differences between c plus plus and swift any guesses to uh who asked or who answered this question who has the top answer on this question it is a person in the c plus plus community i'll wait five to ten seconds to see if anybody knows all right i don't have any responses herb sutter uh is incorrect streusep incorrect the individual you're close actually uh no not phil but not phil nash um strewstrap is on the uh design committee and this individual is also on the design committee for c plus plus and that individual is david van der vood um who as right as his byline states is on the c plus plus committee and the direction group member or sorry i meant to say direction group not uh committee but he is both a committee member iso c plus plus committee member and one one of the five individuals in the c plus direction group so um he's also the offer of the very well known c plus templates textbook and we're going to take a look at david's answer we're not going to read the whole thing because it's very lengthy but it's worth highlighting some points so the first thing he says is remember that the original designer of swift was chris lattner who started and led the llvm project llvm is written in c plus plus and the clang c plus plus compiler is one of the primary drivers for its continued development uh he then later on says when it came time to select a lead swift compiler engineer and a lead swift standard library designer who did apple turn to doug greger for the compiler and dave abrahams for the library both were some of the main contributors to the c plus 11 standard and widely recognized as world-class c plus experts so here david basically pointing out that two of the main compiler and library engineers on swift uh came directly from c plus plus which i think is just super fascinating and last but not least david mentions at the end all this to say that swift oh man i just spilled some tea which is not great but we're going to move on because it's not too bad i apologize for that all that to say that swift was tremendously influenced by c plus apple does not acknowledge this i've been told that it is because more senior apple decision makers dislike c plus at a personal level in part because of the bitter rivalry between c plus and objective c in the 1980s so uh david's pointing out that swift doesn't like to acknowledge that they're influenced by c plus but actually all of the people that work on developing c-plus plus um in all of the talks um widely refer to when they borrow from different languages so it's more management that doesn't like acknowledging it but the engineers especially chris lattner if you've listened to any of the podcasts that he's been on he is very quick to mention the influences that um other languages had on swift so uh to recap these three individuals worked on swift and that's chris latner on the left doug gregor in the middle and dave abrahams and um all three of them have some relationship to c plus so much so that uh the photo of dave abrahams on the right is actually a photo of him right next to john cobb for for those of you that don't know is the organizer of the cppcon c plus now conferences and the creator of cppchat um and yeah someone in the chat saying doug doug greger is the author of variatic templates which is a um very very useful feature uh that is utilized heavily in c plus so this brings us to an inner digression which i said we'd sort of come back to when i was referring to uh the dr boolean um magic read-along podcast and i saw this tweet at one point this was i believe april of 2020 which was the host john sundell of swift by sundell as a podcast saying that dave abrahams was going to come on and asking for any questions and sure enough i tweeted and said can you get a comment from uh the episode that mentioned that type classes was just copied from haskell um from uh brian lonsdorf aka dr boolean and this didn't get com but this didn't get brought up on the episode but dave abrahams responded on twitter saying that we never claimed to have invented proto golfs or swift after all even swift's predecessor objective c has a similar feature called protocols we were open about stealing great ideas from programming languages including haskell but swift's protocols are not type classes they were designed to be great for generic programming for which associated types turn out to be important and these papers are linked in the same github repository where you can find these slides but interesting to see that dave is basically pointing out that there are some material differences between haskell type classes and swift protocols and we're going to go into the most digressions within digressions that i've ever done in a talk because this is a longer talk that i'm able to and after the first time i gave this talk came out online uh both dr boolean from magic read-along and dave abraham's watched the talk um dr boolean responded uh just to point out that i i did acknowledge that we were totally wrong in what we said earlier so that's awesome just to see people being friendly um i pointed out that there was a longer version of this talk which was not the talk that i previously gave that has sort of the explanation of this dialogue back and forth and then dave abraham's followed up once again on this twitter thread saying that the the talk communicates the language flavors really well and that um you can see that something we're going to get to later the constrain versus consent approaches is highlighted at slide 14 uh which we are going to see in a bit at the 14 minute mark um which we haven't gotten to at this point um but the more important part that he says later is that said i think that rust traits circa 2012 provide all of these features except possibly the last composed copyable values and more accessible idiomatic in swift traits arrived in 2012 so i was wrong to claim the first without at least a mainstream and even that's arguable so saying basically that swift being the first protocol-oriented language you could argue that russ could have made the same statement and with this we are going to pop off our three digressions so digression number one digression number two and digression number three which brings us back to the initial uh post on reddit which is the influence influence of c plus on swift so very quickly the things i want to highlight from here because at this point you're sort of getting the idea swift protocols and rest traits are very similar and mr mobster goes on to say that this is why i'm saying that swift protocols are more similar to rust trades and that of course we have c plus plus context which concepts which are very interesting as well they are somewhat like traits and protocols so this is sort of the full circle now i have c plus concepts haskell type traits swift protocols and uh rust traits that are all sort of being dotted line linked to each other as very similar features so this is the sort of end of the story of how we got to giving this talk and then i started doing research into this talk and found a ton of other videos that are highlighting this relationship so we're quickly going to go through those the first is a video from contextfree which is one of my favorite youtubers online typescript structural interfaces nor on go interfaces nor unrushed traits nor on swift protocols nor on haskell type classes nor on standard ml modules instead i'm going to talk about c plus 20 concepts so the video is still not playing but uh i think it's okay because none of these are super meaningful to the talk um but yes the next video is going to be from the llvm 2017 uh talk uh by slava pastov and john mccall so swift has a very powerful generic system a very powerful system of constrained generics and those are expressed by what we call protocols protocols are a lot like features that you see in other languages with first class generic features such as signatures in santa mel or type classes in haskell the next time i saw this came up was during the c-plus plus uh london meet-up where they did this joint series between the c-plus plus meet-up and the russ meetup where two individuals pointed out this relationship the first was pi ass uh traits are closer to concepts but they are not exactly similar to they have close concepts but there are still differences and the second is hendrick who i believe also spoke at this conference and traits are similar to what we know as interfaces and languages like java or c sharp this generic functions work similar to templates in c plus plus and if you are experienced with the newest c plus plus standards or c plus 20 you might think of this so i have a generic functions function which i constrain to fulfill a certain interface this can be seen as something similar to concepts and constraints in c plus next up is from the same series james muns who refers to a talk by marin which we're going to take a look at after there's a really wonderful talk by marin um at rust fest in 2016 where he goes over the rust that could have been let's take a look at a highlight from that talk and then at some points we got more haskell people on the team and we all started agitating for a type class kind of implementation interface thing that we ended up now and this brings us to a digression of one of my favorite quotes from one of my favorite podcasts which is the following by i believe his name is jared roche who said i've been referring to rust as a love child between haskell and c plus plus so i'm not a rust expert by any means but i sort of think of rust as c plus uh plus haskell or maybe c plus plus haskell plus heart um and i just love these little dotted line relationships between languages um sort of knowing what are the primary influences that got um that influenced the language and why it was created so that brings us to the end of that digression and so this uh whole introduction section is wrapped up um with the following slide that's saying every single programming language i shouldn't say every single programming language but many programming languages have a language facility that is similar to what we're going to be covering in today's talk so the five that we're going to be covering are c plus plus concepts rush traits all right we are done with this t uh rust traits swift protocols haskell type classes and d type constraints but um we're only going to be focusing on those five but know that there are other language facilities um such as typescript structural interfaces go interfaces modules signatures etc that could be covered in like a full day class but we've only got 90 minutes today or 75 minutes so we're only going to be focusing on these five with this this brings us to the end of the introduction section so i'm going to click on the q a i currently don't see any questions so i'm going to continue to move on and if you do have questions feel free to put them in the chat and we will pause at the end of the generic and parametric polymorphism section as well to see if there are questions at that point so section number two generics and parametric polymorphism so we're going to revisit the 1988 paper by philip wadler called how to make ad-hoc polymorphism less ad hoc and the things that i want to highlight from this talk are two definitions one of ad-hoc polymorphism and one of parametric polymorphism so first up is ad-hoc polymorphism which the paper states ad-hoc polymorphism occurs when a function is defined over several different types acting in a different way for each type the paper then goes on to define a parametric polymorphism which occurs when a function is defined over a range of types acting in the same way for each type so the two examples that they give are for ad hoc polymorphism you can have multiplication for integer types which is three times three or uh floating point types which is 3.14 times 3.14 and you get um different behavior and then the example they give for parametric polymorphism is the length function so you can have an array or a string and a generic function length that is going to have the same behavior across different types so the way that you can kind of summarize this is the following you have ad hoc polymorphism versus parametric polymorphism both of them for function names when they have the same function name and the same or different types parametric polymorphism has the same behavior whereas ad hoc polymorphism has different behaviors so super superficially in c plus plus we have support for parametric polymorphism through our templates uh and we have support for ad hoc polymorphism through function overloading in c plus and i really really love parametric polymorphism and i didn't realize this until i learned go so go is a extremely interesting language and we're going to take a minute or a second to look at a quote or a video clip from kevin henney our keynote speaker from yesterday on what his thoughts on go are now here's an interesting one so this is go which has been described as a very opinionated language in terms of its style and its design decisions many which i find incredibly easy to disagree with so i think it's super funny that kevin's saying that that i completely agree go is a very very opinionated language they draw a circle and they want you to stand in that circle um and so uh that's just it's useful to know because we're gonna hop back to this example and this example does not compile and so i'm going to pause does anybody know in the chat why this example does not compile it is not uh well it could be bronec has said int um unused println requires a string nope none of those bronic might be correct when he's saying quote uh end quote um depending on what uh they mean by that but the reason is that math.min only works for float64s so if that's what broneck was trying to say with the int then uh they were correct so if you try and uh run this you're gonna get cannot use type int as a type float64 in arguments to math.min so the a and b here are expected to be float 64. so in order to get this to work you have to cast a and b first to float 64s then you get back a float64 and then if you want c to be an int you have to cast that float64 that you got back back to an end and this is because go famously does not have support for parametric polymorphism uh when we write a max function or a min function in c plus plus we can make it work on you know any number of types um but in go you would have to explicitly write like min and then min int or do something uh you know a little bit fancier because they don't have support for parametric polymorphism and this was highlighted in a talk by philip wadler the same individual that wrote the 1988 paper that we just looked at so let's take a look at this audio clip there's this programming language called go i knew absolutely nothing about it except that it's very widely used by some people and i knew that it didn't have parametric polymorphism as part of the language and i get a letter from rob pike who i know we used to work together at bell labs and he wrote to me said would you be interested in helping us get polymorphism right and or figuring out what right means for some future versions of go so this is super fascinating because the last time that i gave this talk this was sort of uh the end of this story so philip wather gave this talk i believe it was in june of 2020 and since then now that we are in march of 2020-21 um this i guess collaboration has turned into an actual proposal for uh generics for go so you can see this was released on january 12th of 2021 um literally two months ago to the day um from when i am presenting this talk currently uh i guess it'll be a bit later if you're watching this on youtube and i believe this proposal came out of this collaboration so i'm not sure if go for a long time it's been said that go 2.0 was going to have generic so i'm not sure if go is actually going to be coming out with a 2.0 version or what's going to happen with this proposal um but the whole point of this digression is that i realized my love for parametric polymorphism when i went and learned go and then realized that it had no support for parametric polymorphism and it it requires you to end up duplicating a lot of the code that you're writing uh which i find highly irritating so i think this will be awesome for go developers if this ends up getting into the language and the last thing that i want to highlight in this section on generics and parametric polymorphism is a super random paper that talks about lightweight parametric polymorphism for oberon and it's because when i was reading through this in preparing for this talk there was a really great quote that basically informs my mental model for type constraints versus types and types versus values so the quote says we introduce parametric polymorphism via our previous example a type may be parameterized on types in much the same way a procedure may be parameterized on values so the way that i think about this is the following type constraints are to types as types are to values so when you have a type like an integer it defines the values that that type can assume and the same thing can be said for type constraints a type constraint uh provides basically the set of types that the type constraint can assume and i've been told that this is technically incorrect but it's a mental model and i've also heard that all models are wrong but some are useful and i find this mental model very useful so yes this brings us to the end of section number two at which point i will pause again and check the q and a to see if there are any questions at this point i once again um do not see any questions so uh we will continue to move along but feel free to ask any questions uh actually no that one just came in from peter summerlad would one name a type system for types a meta type system uh i guess you could i mean you can name it whatever you want um i sort of like the name type constraints but a meta type system sort of fits and as you'll see and as we saw earlier every language sort of calls this something different they put a different label on it and so but yeah if you want to think of it that way as sort of a type constraints or types type system a meta type system uh definitely so uh i answered that one a question just came in are there a list of references at the end yes i will provide links um but it's the same link that you saw at the beginning um underneath my talks repository all of the links are in a file called links.md which i will show at the end of the talk all right that's all the questions at this point but like i said feel free to ask questions and we will take a break at the end of the third section and fourth section to answer those questions as well so let's move on to the more interesting part of this talk which is the examples so the first example is a super simple example but i find it extremely illustrative to show some of the differences between these language facilities and that example is adding two integers so very straightforward i assume all of you know how to do this in whichever language you consider your primary language on day to day um and c plus that's my primary language day to day it looks as follows so hopefully this is super familiar to all of the c plus developers either watching live or watching in the future on the internet and the only thing that might be a little bit surprising if you haven't been keeping up with the uh sort of c plus plus 11 14 17 is the trailing return type which is my preferred way to write functions because it's more similar to other more modern programming languages and functional languages but um this uh someone mentioned in the chat constexpr yes we could put const expert if we wanted but this is we're height we're trying to highlight just going from a simple uh adding function to a generic adding function um and so this is what it looks like in c plus plus two integers a and b and then we're just returning a plus b so let's put this at the top of our screen and we're now going to look at what this function looks like in d rust swift and haskell so d is up first it looks honestly identical and we could have written this the exact same way in c plus plus the only difference here is that there's no trailing return type in d so we can't uh use the trailing return type that we used in the c plus plus solution otherwise these two are identical uh for rust we have the following so note rust mandates trailing return type they don't call it trailing return type because that's just how functions look like in c plus and instead of int they have i-32 and they name their parameters uh before they list the type so it's a colon i32 and uh also very interestingly there is no return and there is no semicolon so in rust the last expression in a function if that is your return value you can omit the semicolon and the return which i think is quite nice especially for these super simple uh one line functions and yeah i saw a couple other folks uh mentioned no discard and no except for the c plus plus solution yes we could definitely add those and that is the best practice thing to do um swift we have the following so instead of the two letter fun we have the four letter funk and uh instead of inter i 32 we have a capital i int and note we have trailing return type as well and similar to rust we do not need a return or a semicolon for the last expression in our function body [Music] and then someone also just mentioned that yes you can make the parameters const at which point we're going to need a bigger slide but yes the c plus plus ad is just a very simple version of the add function not the best practice version and last but not least we have uh haskell which doesn't look anything like the other solutions and that's because it's an entirely different language it's a purely functional programming language the way you can think about this is that the first line is the function declaration they call them type signatures in haskell and everything but the last type is basically an input argument that's not actually what's happening here but coming from sort of imperative languages like c plus plus and rust that's the way you can think of this is that the first two ins are your input arguments and the last our type is your output argument and then here you're just declaring your definition of your function as a plus b um and yeah someone actually has pointed out a version of ad that we're going to see in just a second auto for all the languages i don't think yeah most of these languages don't have support for auto but many of them do have very good support for type inference which is an adjacent language facility so if we take all five of these uh function definitions we can put them at the top then we can reformat them so that we line up sort of the function bodies and the return types as best as possible and then we can do a summary of the comparisons between these languages so this is all just sort of syntax and doesn't mean much but as a programming language enthusiast and a potential programming language designer i find you know looking at this stuff side by side interesting so the key word before the function in all of the languages are followed c plus plus is auto uh d is just the type of your output rust is fun the two letters fn and then swift is funk haskell doesn't have anything note that i tweeted something out a couple months ago saying you know what what is the key word of every language before a function and then many people took me to task over auto being saying that auto does not declare a function that is true you can use auto in many many different cases but it is the key word if you want to have trailing return type that is going to become before your function declaration um so note auto can be used many places uh not just before a function declaration for our integers uh c plus plus says into or in 32 underscore t um and then d has int as well rust has i-32 and then swift and haskell have uh int with a capital i trailing return type the only language that doesn't support trailing return type is d and then is the return necessary only in c plus plus and d i can see we have a question so we can actually um answer it now which language would allow type deduction um aka auto ad paren int a int b return a b i don't actually know at the top of my head i know haskell and c plus plus do um i don't think d does and i'm pretty sure rust you have to be explicit about your return type and swift i'm not sure um but folks in the chat can correct me if i'm wrong or if you're watching this on youtube please feel free to add a comment of what i just said was incorrect moving on uh to a digression which is on the keyword that shows up before functions so like i said i tweeted this out a couple months ago and here was the tweet it is a very large graphic of sort of what functions use to indicate that we have a function declaration so if we zoom in on this um the most popular is def and um that's because languages like python and ruby use it and i think that influenced a bunch of other languages that were created later such as elixir scala and of these languages i think crystal is the most interesting crystal is basically uh statically typed ruby aimed at having the performance of c um so if you're familiar with ruby but you want more performance crystal is a language worth checking out and then 4chan at the bottom uses function which is the second most common i believe fortran also has a keyword uh subroutine if we scroll down you can see javascript julia and lua also all use function and then the third most common is func uh nim is uh extremely interesting because funk i believe is actually just a shortcut for no side effect proc so there are two keywords in nim for declaring a function proc proc and funk and funk is basically just a no side effecting proc which not many languages have language support for defining functions that don't have side effects so i think that's super cool and last but not least our uh russ zigg that have fun um closure which has defun which i think technically is a macro and then kotlin with fun and then just the one offs and uh i think i like fun the best from kotlin because it spells out fun and programming is fun which is probably what i would choose um yeah someone in the chat just said crystal uh hasn't hit 1.0 yet yeah i think it's a it's a very very young language that's still in development um and yeah someone said plus one for nim all right end of digression back to our examples of adding two integers so these are the non-generic uh implementations of adding two integers across these five languages now what we're gonna do is we're gonna take these five implementations and turn them in from non-generic functions into generic functions so first we're gonna do it for c plus plus and if you're a c plus plus developer you probably know the way to do this is with a template so we can replace our ins with uh template type name t and then everywhere we saw an int we can just replace that with a t and we're done um some of you might be thinking and i know someone in the chat earlier said this that in c plus 20 we can actually write this uh slightly differently um in a way that i actually prefer i'm not sure if this is going to be could be considered a non-best practice in the future but you can actually just use auto now and auto is basically the exact same thing it's just a different way of spelling what we just spelled using the template type name t um there are slight differences in that like you can't constrain um we we constrained previously that both a and b were of the same type t here i believe that's not the case um but still nice to note that you can use three autos in our function declaration now for our c plus plus function yeah someone uh mike in the chat just mentioned it's not because a and b can be different types so it is slightly different um and then peter says please do not define an edible concept we won't be doing that in this talk so i can't speak for the rest of the c plus community but not in this talk moving on to d d looks very similar to c plus but instead of using angle brackets it uses uh an extra set of parentheses plus the template uh name or in in front of our two parenthesis so we have now t add paren t paren and then we replace each of the ins that we had before with a t um so very similar to c plus plus just instead of angle brackets and having to spell a template type name um they use parentheses in rust um it looks as follows so uh very similar to d except instead of uh parentheses we're now using angle brackets um and once again we're replacing each of the i32s uh with the template type t so now it's angle bracket t angle bracket and then a colon t comma b colon t everything else stays the same for swift it uh is very very similar to what we saw in rust almost identical we're replacing our ins with t and then putting an angle bracket t in front of our argument list and last but not least is haskell and haskell replaces each of our ins just with a t or any letter for that matter it doesn't have to be a t but just to be consistent with the other generic implementations across rust d c plus bus and swift we're calling it t but i think more idiomatically you would call this a for any type in haskell all right i'm going to pause now and ask the audience which of these compile because we have five different generic implementations of the add function on our screen but not all of them compile so can anybody tell me which of these solutions do compile so peter said c plus which definitely compiles and then dema says it depends on how you use it um dimitrios says rust does not so that is correct rust doesn't compile c plus plus compiles and a couple people saying it depends um so yeah i guess maybe depending on the context that i compiled this in um but generally the point that i'm trying to get at is that uh only c plus and d compile and that's because we need to add something to the rust swift and haskell solutions in order to get these to compile and those are the following so for rust we need to add this trait stood colon colon ops colon colon add and then output equal to t for swift we have to also add a protocol which is the numeric protocol and for haskell we have to add a type class on t which is the num type class which you do with this num t and then a fat arrow with the same t angle t angle t and this is probably um the most important thing that i want folks to take away from this talk is that i consider there to be two categories of um this sort of parametric polymorphism language feature whether you're calling it concepts type constraints traits protocols or type classes these fit into two broad categories which i am calling the following type constraints versus type classes so note that you know each of these correspond you know type constraints corresponds to d and type classes corresponds to haskell but i'm using these as broad categories for the categories that each of these language facilities fits into and the main thing that differentiates these two categories is that type constraints constrain and type classes consent meaning that with c plus and d you start with the world and then when you add either a concept or a type constraint you are limiting what can be passed into your generic function whereas with type classes you are consenting when you declare a generic function and you don't say anything about that function you can do zero things with that and you need to add type classes or traits or protocols to that generic function in order to let the compiler know this function with uh the types that are provided is able to do the following is able to add is able to compare etc um and for me the best way to sort of uh look at an example of this is by looking at the simplest version of a generic function which is the following we're going to look at c plus plus and haskell and we're looking at a function that takes a generic type t and returns a generic type t and the difference between the c plus plus solution which is just template type name t auto f t t uh arrow t and then haskell's which is just f colon colon t arrow t c plus plus function theoretically can do anything because our generic is completely unconstrained whereas in haskell you can do exactly one thing because we haven't told the compiler what tea can do and the one thing that we can do is just return back the t that we gave the function f which seems very useless but this is actually a built-in function to the haskell prelude which i'm sure a few of you know which is the function id or id which is short for identity so it's the identity function it's a function that just returns uh the argument that was passed in and uh curiously enough in c plus 20 um we actually added this to our functional header so we now have a function object in c plus that is uh doing the exact same thing that we see on the screen here for haskell and c plus plus and you might think like the first time i think i heard of uh the identity function was on a podcast called lambdacast i thought that sounds incredibly useless uh what would you ever want a function for that just returns you back what you gave it but when you start doing a lot of functional programming things where you're working with higher order functions that uh expect functions as arguments especially multiple functions as arguments sometimes you'll want custom behavior for one of the functions that you're taking as an argument but for the other one you just want to do a no op you just want to return back what uh you are being given which is exactly what identity is for and uh so yeah i'm gonna hop back now um to one of the clips that we saw earlier from the llvm 2017 talk called implementing swift generics uh that was given by slava pestov and john mccall and it's interesting that they call their generics constrained generics even though that's sort of the opposite of what i just explained um they basically go on to say that the unconstrained generics are the ones that can't do anything um which seems completely counter-intuitive to me because if you're if you have something that's unconstrained like semantically to me that seems like you're saying that you can do whatever you want there's no constraints you're not there's no constraints do whatever you want but here they're saying when you have an unconstrained generic that's when your behavior is limited or what you can do with your function is limited and the second thing i want to highlight from this talk is that earlier when slava pestdog was presenting they had a slide which highlights what they call their parametric polymorphism aka protocols bounded parametric polymorphism and this is something that i'm going to talk a lot more about in the follow-up 2.0 version of this talk so in the literature they refer to this type of parametric polymorphism um as different things in like every single paper i've heard it referred to as bounded parametric polymorphism i've heard it referred to as constrained parametric polymorphism in one of the papers it seemed like they were inventing sort of new words and they were referring to the two different categories as nominal and structure structural i can't be 100 sure because a lot of these papers were 50 to 80 pages long and i did not read them through fully but in expect in part two of this talk for me to go through the full literature and really break down you know what are the different categories what are the names in both sort of industry and programming languages in and in the academic literature because this is sort of a point that i find very confusing is that there doesn't seem to be agreed upon terminology when it comes to this um sort of category of parametric polymorphism where you're bounding or constraining your types so once again just to recap we are going back to our two different categories type constraints where you're constraining uh what you can do with your function versus type classes where you are consenting you are starting off by only being able to do uh the the least amount and then by adding uh traits protocols or type classes you are enabling your function to do more and with this this brings us to the end of our first example so i can see that i have at least one question in the q a um broneck asks would you consider these both parametric as opposed to ad hoc um i am going to assume that the both is referring to the two different categories um although i could be incorrect there oh so yeah bronic followed up with a yes uh yes i would definitely consider these as uh different uh facilities either providing support for or superficial support for parametric polymorphism so um it's important to note or maybe not important to note but uh technically speaking c plus plus templates are not uh are not supporting parametric polymorphism they are not a parametric polymorphism language facility they they superficially give support for it because what templates are doing behind the scene is they were going and they're stamping out all of the different versions of that sort of template function that you need for each of the times that it's called uh so at the end of the day you don't have a single function you have a bunch of individual functions that have been customized for the types that you're calling that function with so it's technically not parametric polymorphism by the textbook definition but it is superficially giving you support for that language facility um so answer live done answer live done an anonymous anonymous attendee asks is there room in c plus for type classes um well so arguably concepts is our support for type classes um and i would encourage you to take a look at a paper that just came out in the most recent c plus mailing by barry revzin i believe it's called just search for um uh i can't remember if it's tag invoke in the title or um customization points but basically barry rebson in the most recent uh language evolution working group meeting gave a fantastic presentation comparing the different solutions uh for things that we are trying to solve with concepts and how basically we've really fallen short and at one point in the presentation he compared our current c plus concepts to rust traits and showed how um how much more flexible the rust traits are uh so i i can also find a paper if you find me after the talk i can link that paper to you um once the talk is over but uh i think we're gonna get closer to what is possible in other languages but i don't think ever we will have exactly type classes because haskell is just such a different language meg is asking does template specialization introduce ad hoc polymorphism does template specialization introduce ad-hoc polymorphism technically yes um i would say yes to that answer so i when i think of ad-hoc polymorphism in c plus the first thing i think of is function overloading but definitely specialization gives you the exact same thing a different behavior um based on types so yes that is that's definitely a correct way to think about things and yeah lucian is saying yes as well in the in the chat all right that is the end of the uh question queue so once again if you have questions feel free to ask them and we will revisit them both at the end of the talk and at the end of the next section so our final example is a bit more involved than the example that we just looked at looked at and it is going to be the following we are going to create two different shapes a circle and a rectangle and then we are going to define uh some functions on on the shape uh primarily area perimeter and name and then we're going to write a generic function that prints out the information of a object either a circle or a rectangle based on the different implementations of your sort of area and perimeter oh yeah and roger orr has linked the paper we need a language mechanism for customization points thanks roger that's awesome yeah and it's it's a fantastic read uh barry's papers are are marvelous um his ones on the pipeline operator is also fantastic um if you ever want like introductory sort of uh papers that are more digestible i can't recommend barry's papers enough but yes example number two uh shapes circle and rectangle so let's take a look at our c plus example first so we're just gonna declare our two classes uh circle and rectangle so if you're a c plus plus developer this should look quite familiar uh once again as we have in the past with our c plus plus examples we're using trailing return type so for name we have a function that's just returning a string for area and perimeter we're returning uh floats and you can see the uh implementations pretty straightforward for circle it's just pi r squared perimeter is 2 pi r and then for rectangle we have the equivalent formulas width times height and 2 times width times 2 times height for our area and perimeter note that it's not best practice to call your member variables single uh character names like r for radius and w and h for width and height use uh better names but because this is slideware and already there's quite a bit of code on the slide i abbreviated the member variable names to be single characters just for brevity um [Music] and yeah i don't think there's much else to say here um other than the fact that it's a bit irritating that we got the defaults wrong in c plus plus however many decades ago and that we have to add the const here in order to make this a non-modifying function it'd be nice that by default um it was non-modifying and if we wanted to have a mutating function we did something similar to rust la vie that ship is sailed um but otherwise i think this is it's quite nice for c plus plus uh moving on and explicit as well yes ricardo has mentioned that uh that's also a default that we got wrong but what can you do moving on to our d solutions so this looks very similar the constructor is um slightly different you have to use the this keyword but other than that we're also using pascal case because that's more idiomatic in the d language um other than that though it looks quite similar once again we have the const keyword to let the the reader and the compiler know that this is a non-modifying function oh yeah and i forgot to mention that uh maybe the coolest part of the c plus solution is that we're actually making use of c plus plus 20's math constants um with pi um which also d has uh through their constants um so yeah i think it was a mistake that dee didn't seize the opportunity to correct the default of having to add the cons to your function declarations um but rust and swift got it right so uh you know you win some you lose some other than this though these two look very similar the c plus plus and the d solution moving on to the rust solution so the rust is quite interesting this is starting to look slightly different one of the key things here that's different is that you can't just return a string literal here you have to use a conversion method called tostring which is interesting i learned that while putting these together and you'll also note that you don't see any const anywhere so by default functions in rust are non-modifying in that you have to add a mute to the self parameter in order to have a modifying function and i think this is definitely the correct default other difference is instead of float we have f32 and that we define our structs sort of upfront and then we do these uh impul which is stored for implementation uh down below um other than that i think it looks pretty similar um you know we should be getting used to seeing these uh uh we should be getting used to seeing these sort of implementations for our functions pi r squared and two pi r uh w times h which is with time height and two times width plus two times height moving on to the swift solution this probably is my favorite solution actually and one of the things i'll say about swift is i'm not a swift developer but when i was writing up these solutions for swift i basically just wrote the code and it always worked um swift is an incredibly nice language to transition to at least from a c plus plus coming from a c plus background um so many times i would just write the swift code and then that would be the correct code whereas rust a lot of the times i would get compiler errors the compiler errors are absolutely magnificent and we're going to have a digression about that in the future but it's really really nice it's a really nice experience coming to swift writing the code and then it just sort of works which is super super nice once again couple small differences that the constructor is using a knit here for swift and we're once again using pascal case because that's idiomatic in swift but other than that looks very similar to what we had in the other solutions and last but not least is going to be the solution that is most different a pattern that we are starting to see is haskell so here we are using record types at the top um with the data keyword in order to define our record our record circle and record rectangle and then we have a bunch of functions that are sort of free functions defining our name area and perimeter for both circle and rectangle note that this actually uh does not work because we don't have function overloading in haskell so here we have same named functions name area and perimeter for both circle and rectangle however this is not gonna compile um i'm i'm setting this up because it'll have a nicer transition uh later on in the slide deck but um if we want to get this to compile we actually have to make these uh functions have different names um and if you're if you're familiar with haskell you'll know that this sort of syntax is pattern matching a lot of the time so when we have this record type and then the parentheses plus our type and then under bar here we're basically ignoring uh the information that's stored in the record type and just returning circle and then for other ones where we're doing the uh you know area and the perimeter we're getting out the radius and the width and the height and then doing something with that so anytime you need to discard information you can just use the underbar and we might be getting something similar to that in c plus with pattern matching whenever that gets in to the standard so this takes us through the setup of each of our circles and rectangles for c plus plus d rust swift and haskell and so now what we're going to do is we're going to go back uh to our c plus solution and we are going to add a print information function and it's going to be called print shape info for each of our languages and we are going to try and print out the shape the the so the name uh the area and the perimeter for each of our objects and so for c plus plus um this is what it looks like we're using a snake case because that's idiomatic in c plus we're taking in a generic type at this point which is unconstrained s for shape and then we're using format print this technically i don't believe is supported by any of the standard libraries currently but it did get into c plus 20 and if you go to godbolt um or if you look at any of the salute like all of the code that shows up in this slide deck is also in the github repository with godbolt links um you can access uh victor's format library on godbolt which is what the standard format was based on and so i'm starting to use it just to get in the habit um and we get this a lot nicer than using c stood c out with the less than less than operator which i think is super nice um and this works in c plus because we are in the type constraint model where we're starting with the world we don't actually need to do anything extra here in order to get this code to work moving on to the d solution uh looks somewhat similar here we're using right lin uh we don't have the sort of nice uh formatting capabilities of uh the c plus uh format print so we have to do this sort of inline but it still looks pretty nice and once again we have our generic function that takes a shape t and that is sort of uh generic made by the parent t before the argument list and once again this works because we are in the type constraint model so um we don't have to do anything extra in order to get this to work mike says i think that only stood format made it into c plus 20 so you need to use the library in order to use format print so that is true but uh there is uh you know committee work being done to get um a lot more of the uh format uh library that victor's worked on into the standard it's the same with uh c plus plus 20 ranges um c plus plus 20 ranges is based on eric niebler's range v3 um and only i believe it was like 13 range adapters got into c plus 20 and there's you know way way more in range v3 um and there's currently a proposal for c plus 23 to add you know a bunch more so over time we're going to see more and more of these libraries get into standard functionality moving on to the rust solution so this is what it looks like in rust very similar to what it looked like in c plus plus instead of format colon colon print we have print line bang but other than that it actually looks almost identical except that we have our angle t angle instead of our auto in our argument list to make this a generic function but note because we are now in the type class world this no longer works if we try to compile this we get the following name area and perimeter are not found on the generic type t um and at this point uh i wanna highlight how amazing the rust compiler is if we take a look at the full message whenever you have a i shouldn't say whenever but a lot of the times when you have a compiler error in rust the compiler gives you these help messages and they read items from traips can only be used if the type parameter is bounded by the trait the following trait defines an item name perhaps you need to restrict type parameter t with it and then it suggests you uh that i should add uh colon shape to my uh generic type t here this is phenomenal so much so that i want to go on a digression here on how amazing the rust compiler is and if you're a c-plus plus developer and you haven't explored uh rust prepare to be a little bit sad um because of how amazing the rust compiler is uh so for instance these are just examples of things that over time while i've been while i've been exploring the rust language how the compiler has basically like spoken to me like talked to me like hey here's what you might want to do so when i was building up the circle example and i was defining the name function that just prints out a string note that i said you had to add the dot to string conversion method because you can't uh return a string literal what did the compiler tell me uh bam bam uh expected a struct uh of stood colin cohen's string colon colon string found a refstring help try using a conversion method uh quote unquote circle two uh two string paramparan um so like i didn't know what i was doing and i made this mistake and then the compiler immediately told me what i needed to do in order to get this to work that is such a wonderful experience as someone who is learning and exploring the language another example uh when i was building up the first exercise of uh creating a generic ad function when i did this uh the compiler basically just told me what i needed so like even though i said swift was a much nicer experience and then i just typed something and it worked in rest i would type something it wouldn't work and the compiler would tell me what i needed to do in order to get it to work which is just it's such an amazing experience i don't have to go to stack overflow it just it it won't always tell you what you need to do but a lot of the times it does and i think this is the last example where this is something i really really wish we had in c plus plus here i'm using the mute keyword to define a variable that is modifiable so here is a circle c that i'm saying i'm going to mutate this in the future however if i don't go on to mutate it the compiler will tell me um consider removing mute because you've you've declared this variable mutable but you have not mutated it so it could be immutable which is super super nice um i really wish in c plus that we had a static analyzer or a compiler warning that would let us know when we could make a variable const i believe actually in visual studio they do have a check for that but um currently for clang there's a proposed extension to clank tidy i believe that does this static analysis check but it has not been merged the last time i checked um so yeah this this is just for any future people that are watching this on youtube uh that are thinking about creating a language uh please try and build this kind of stuff into your compiler and i know c plus plus compiler today is like an order or two orders of magnitude better than it was two decades ago um but i think we're far from like our base basically our compiler like telling us what we need to do and this is this is some like super super uh nice functionality um peter's saying c vellup has a const checker that proposes quick fixes okay that's super nice so so there are a couple uh you know i think uh tools out there that give you this ability but i have not found any open source uh like free ones through clang tidy yet but i hope that in a decade we have those so this is the end of the digression i just want to highlight like how wonderful the rust programming language is when it comes to sort of assisting you because it is it does have a steep learning curve uh similar to c plus plus but i think their compiler does a much better job of like helping uh the new programmer um jonathan in the chat says in elm they refer to this idea as compiler driven development yeah i've heard the same thing of um i think uh no red ink they use elm quite a bit like they're the primary company and they've been on podcasts um talking about how yeah that's like a fundamental value for elm is that um if we're going to sort of uh be more constraining in what you can do we're going to let the compiler really really help you out so like half the time the compiler's just writing the code for you which is super nice and uh ricardo linked i highly recommend reading this elm lang.org news compiler errors for humans um so yeah thanks for sharing that that's super awesome but yeah this is the end of this digression let's get back to our generic print shape info functions so for swift we're switching to camelcase because that's idiomatic and this looks uh super similar to the d solution that we saw earlier we're printing each of the shapes and then inline doing this s dot name s dot area s dot perimeter once again this is not going to work in swift because uh we are in the type class world so uh for our type t here it's going to say has no member name and finally for haskell we're gonna skip this one technically we could get something working but really in haskell it either works or it doesn't work you can't really build up a solution and then uh get like a nice message so for for haskell we're gonna skip this and we're going to come back to it when we actually are setting up our type class so let's loop back to our c plus solution so this works but now we're going to define our concept so very simply this is all we need to do template type name s uh where s is our our our type our generic type t or s and then we have concept shape uh which is going to be the name of our concept and then we go requires with our generic type s and then we have two braces and basically we put all our constraints inside these braces so we're saying we want a function called name that returns us a string we want a and then two functions area and perimeter that return us floating points and then once we have this concept all we have to do is in front of our auto in our argument list is insert our shape concept and we're good to go and so now we've constrained our generic function print shape info and we're good to go note that there are like three different ways to spell this technically we could keep our template type name above our generic function and then replace the type name with the concept and i think there's another way to spell this as well this is my favorite but we're very early in the c plus 20 sort of concept era and i'm sure there will be best practice coming out on this in the future um so this is super cool like i said it worked before but now we've defined a simple concept that we can use on our generic functions that are supposed to work on shapes and anytime we pass it something that doesn't conform to this concept we're going to get a nice compiler error moving on to the d solution once again this worked before but now we're going to define a type constraint for d this is a little bit noisy it's definitely the least clean of the five solutions so here we go template shape with our generic type t uh const shape in order to name our type constraint and then we have to uh unfortunately go under our underbar traits uh paren compiles uh comma and then our generic type t and then once again inside the braces we set up all the requirements so here i left out the uh type constraints on the output type um but we're saying that we basically want a name an area and a perimeter so although the type constraint is a little bit messy to define using it is actually quite nice and we use it with what i think is a super nice way of declaring this is basically just an if statement before your braces before the declaration or the the definition of your function but after the signature of your function which i think is really nice because even if you don't know anything about you know concepts or type constraints if you read something like this you know here's a function if and then a concept you can almost guess that this is doing something to sort of constrain when this function is usable and that is that for our uh our d type constraint now moving on to the type class world of rust swift and haskell and um for rust we are going to have to do the following so we i have um impulse circle and impul rectangle omitting sort of the body of these because we're going to need to make changes to this and now we're going to define a trait uh so we define trait the same way that you might define like a class in c plus and then we're just basically uh defining the signatures that we want our trait to conform to so this is super nice name area perimeter that return us a string and two float32s and then note that if you saw the animation we're going for an impulse circle and imple rectangle to imple shape four circle and imple shape for rectangle and so uh similar to c plus plus all you have to do is set this up and then once we've done that we need to add to our generic type t a colon shape and now we have constrained our rust function and this will work at this point we will no longer get a compiler error so i think that's all i want to say about the rust solution moving on to the swift solution for the protocol once again i'm showing the class rectangle and class circle omitting the bodies because we're going to need to make changes uh to these two classes in order to use the protocol that we're about to define so we need to set up a protocol very similar to how we set up the trait in rust and the concept in c plus this is probably the cleanest and um the nicest in my opinion because it just looks so clean uh we have protocol the same way we use trace trait in rust and then we're defining the signatures of the functions that we want so we've got a function name that returns a string and then area and perimeter that return two floats and then once again the same way that we had to add uh to our class rectangle and class circle for the implement rus we have to now do something that looks like inheritance but is not really we are just saying that we have a class that uh conforms to this protocol shape and once we've done this that's all we need to do to set up this protocol in swift we just want to add the colon shape to our generic type t and the angle brackets and we're good to go and last but not least we have haskell so i've gone back to the original version where we called these both name and area because it's going to lead to a more beautiful code transition um but now what we're going to do is we're going to set up a type class and define the following so we're going to move things around here so here we have our type class class shape a where a is a generic type and then it has the following a name that goes from a generic type a to a string and then two functions area and perimeter that go from a generic type a to a float and once again we have our record type circle and rectangle and now we just have our um shape our shape type class that's being implemented for each of our circle and rectangle shape so for a circle we're basically just taking the definitions that were free functions before and slotting them into this uh instant shape circle where and then we're doing the exact same thing for instance uh shape rectangle note that this looks like a lot more code than we saw previously but that's because we're including more than we needed to we're including these definitions inside the uh instance shaped circles that we were not including in the previous examples so if we omit these this is actually closer to what we were showing for the previous examples and i think this is actually quite nice and note that there are a couple different ways to do this you could uh define like a sum type that is a you know a shape type that consists of either a circle or a rectangle and then do the type class implementation all at once using pattern matching which i think is more idiomatic but just in order to uh compare these to the four previous examples in c plus plus d rust and swift i was trying to keep it sort of as similar as possible and then uh of course at the bottom here we have a print shape info which we're seeing for the first time which is basically doing catnation of strings with the plus plus operator so yeah this is basically the end of our second example so at this point i'm going to pause before i get to my final thoughts and um let's take a look at the question so uh peter is i think he's actually just making a statement that c plus ox had concept maps which of the language of the languages allows something similar to map differently named functions to be considered as one of the concepts so yeah there was a paper that got highlighted in the clip from context free that also dave abrahams was referring to that i believe you can find in the resources linked in the github repo where all the code and the slide decks and the links are that basically goes over what we lost out we went from like concepts ox to concepts light and we lost a lot of stuff in that sort of transition to concepts light but yeah that's a great point thanks for pointing that out peter um and then tristan asks will i be talking about uh c plus plus ox concepts at all no i did not go into that rabbit hole um i will in the 2.0 version of this talk and there's actually i found a great clip at the end of a c plus now talk from i believe it was 2015 where um there were there was a presentation on concepts light and there was like 10 to 15 minutes of discussion at the end of that presentation on sort of the differences and the pros and cons between the two different um and then tristan followed up saying doug greger worked on them before swift they offered both consent and constraint options as i understand it um but that complexity was probably their downfall um so yeah look forward to the 2.0 version of this talk and then peter asks how can you map existing types that almost fit but that you cannot change to fit i do not know let's chat about that uh in the hallway afterwards um you yeah let's talk about that afterwards or if you have an answer someone in the chat feel free to answer in the chat so um once again we're gonna leave it looks like we've got uh 10 minutes left so the last section should take about five minutes where we'll have five minutes at the end for questions so yeah this is just my final thoughts on the different five languages in going through the exercise of writing up these two different examples and some of these are like fluffy comparisons so you know take it with a grain of salt it's all completely biased from my point of view um but yeah i think i think it's useful to look at these different sort of metrics so final thoughts um the first one we're going to look at is time to implement so uh i kept track of how long each of these took me to implement this one's focusing primarily on the second example uh swift was the fastest d was the second fastest then russ then haskell and then c plus um that might be a bit surprising seeing as i'm a c plus plus developer but i think part of the issue is that when i was developing these the compiler support for these is sort of uh it was coming out we're still getting support for c plus concepts across different compilers whereas every other language has these language facilities the tutorials the resources the documentation all built out entirely um and like i said going from swift uh to swift from c plus plus it just seemed like every time i coded something it ended up working um and then yeah rust and haskell i would definitely put on sort of the steeper learning curve languages so not surprising to see them uh at three and four the second metric is lines of code um so haskell not surprisingly is it number one with 25 lines of code uh then swift then russ then d which are all quite close and then c plus plus is a is a close fifth uh note that the initial time i presented this i actually had c plus plus at uh more lines of code than it needed to be and it dropped down about 12 or 13 lines to 47 and also like take this with a grain of salt because different languages have like imports uh that are necessary uh whereas other languages don't so this is all you know you could put like a plus or minus five probably on each of these in which case this is just a no op except haskell probably will always win in first place but then the other four uh depending on you know how you format your code um and whether you count like the white spaces and the imports you know this is gonna move around entirely and my favorite metric of all is the pleasantness which is what this happy face represents um so i found swift by far to be the nicest just due to the fact that every single time i wrote something it seemed to work rust was a close second in that even though i would write something and it wouldn't work the compiler would immediately tell me how to get something to work which is fantastic um d was d was okay i think that d unnecessarily added more complexity than they needed to to the language um you know for instance uh c plus plus has like the const keyword and d has like you know three or four more keywords they have const they have immutable they have i think pure um and i just i think that there's an unnecessary level of complexity that was added uh haskell um is super nice but definitely it's a steep learning curve and c plus plus a c plus plus so i think i have some bullet points that i just want to highlight half the time i just uh guessed right for swift um chris lattner the designer of the language has this value that uh was embedded deeply into the language called pdoc uh progressive disclosure of complexity which is also also known as being uh infinitely hackable um this is the idea that like you want the language to start out feeling like python but then if you want you can like lift the hood of the language and then get more down into like the c plus side of things if you want to and i think they did an amazing job at this and uh defaults are all correct in in switch which is nice rust as mentioned before compiler messages are amazing uh defaults are all correct uh d seems a bit too similar to c plus when you add that there's a lot of complexity in certain places haskell's got a steep learning curve and the compiler messages are bad which is something that i'm very thankful that russ did not adopt and c plus has 40 years of history which means there's going to be less elegance when you define when you design language features you know 40 years later which is just it's just the way it is um most of the defaults are wrong which is just unfortunate you know there's nothing we can do about that now unless if we decide to break abi in like a massive way which is never going to happen probably uh and then c plus plus 20 is still a work in progress as i mentioned before so last but not least um i just want to highlight some sort of programming language ranking sites so this is a site called languish that was um built by the same individual context free that we saw at clip 4 earlier in the talk it measures different statistics on github and this is like an average of them so c plus unsurprisingly is at the top swift is in second uh rust is in third haskell in fourth and then d is in fifth if you take a look across different programming language rankings um tiob uh pi apl redmonk and google trends you basically get the same pattern every single time except for tiob which ranks haskell below d in this case um and i was super surprised at how high swift ranked on some of these if you take a look at the number of reddit subscribers on the subreddits this is the way it looks at least as of a couple months ago c plus is in first place but rust and swift um considering that they've been around like for a fraction of the amount of time that uh c plus plus has been around um have got quite a few and i wouldn't actually be surprised if swift has more developers than russ does and that's because i don't think swift developers primarily go to reddit i think they go to the swift forums um so i think i don't have a mac i don't develop like i don't have an iphone i don't have a mac i'm not an apple um developer so i'm sort of removed from that community but i think the swift community is actually a lot larger than i would have expected so once again uh these are the final thoughts overall um i think it's awesome that all five of these languages have some sort of facility for a type class or type constraint facility and yeah all of the code as i mentioned before can be found at my github repository talks under the 202103 accu folder as well as the code examples and all the links so there's a file called links.md for all the podcast links the youtube video links and the papers and articles that i referenced um if i'm missing one that i reference which i don't think i am but if i am feel free to open a pr and i'll be happy to add it and yeah thank you and i'm happy to answer any remaining questions that people might have you
Info
Channel: ACCU Conference
Views: 3,122
Rating: 4.7307692 out of 5
Keywords: conor hoekstra, conor hoekstra youtube, conor hoekstra c++, c++ concepts, c++20 concepts, rust traits vs c++ concepts, haskell type classes, swift protocols, swift protocols explained, rust traits explained, d language vs c++, haskell vs c++, swift vs c++, rust vs c++, c++ programming, C++, meeting c++, c++ talk, c++ coding, c++ talk video, cpp talk, C++ teaching, modern c++, modern cpp, accu conference, accu 2021, accu conference 2021, c++ tutorial, coding talk video
Id: iPVoCTgvi8M
Channel Id: undefined
Length: 85min 23sec (5123 seconds)
Published: Fri Apr 09 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.