Clojure in a nutshell by James Trunk

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

This is an excellent introduction to Clojure. Short and to the point. It clearly articulated the philosophy of Clojure, demonstrated the method of writing Clojure code with the help of a REPL.

👍︎︎ 4 👤︎︎ u/huahaiy 📅︎︎ Mar 25 2021 🗫︎ replies

That was one of the better Clojure talks I have seen in a while.

👍︎︎ 5 👤︎︎ u/fingertoe11 📅︎︎ Mar 25 2021 🗫︎ replies

Anyone know what editor they're using?

👍︎︎ 1 👤︎︎ u/[deleted] 📅︎︎ Mar 25 2021 🗫︎ replies

It really is a great and succinct introduction video.

👍︎︎ 1 👤︎︎ u/servingwater 📅︎︎ Mar 26 2021 🗫︎ replies
Captions
hello all and welcome to the fifth funk pro sweden we're so happy that this time we are live from a tv studio actually in stockholm so we don't have any audience we just have the speakers and some studio people here so welcome all on the youtube so the agenda today i'll do a short intro that's what we're doing now and then we'll do a presentation on closure by enclosure in a nutshell by james trunk and then we do a second presentation polyliff the last architecture you will ever need by joakim and ferkin and then the last guy up is he's going to talk a little bit about rust and what rust borrowed from functional yes so why did i start this community funk prog sweden because we love functional programming we're open and inclusive we want to spread functional so everyone will do functional programming in the end we also like to share hence we are here and hence we're streaming to you over youtube so let's have fun and spread functional programming and speakers and sponsors if you have anything to present around functional it doesn't need to be in a functional language we had harold from the c plus plus community coming over and talking about c plus plus and how what it does in functional programming so please come also if you have a venue you could share once the corona madness is over please come to us so just contact me and reach out to me magnus or the other organizers tienen matias and last but not least how to to to today as we live stream please ask any questions in the youtube chat that you have and we'll send it over to the presenters so let's start so i will introduce closure in a nutshell by james trunk welcome thank you very much magnus you're warm welcome i'll take that from you yep see if the technology works hi everyone hopefully you can see the slides now my name is james and i'm here to give you a brief introduction to closure and we're going to start by exploring closure through the lens of the design philosophy that is behind the language and that's because i found that understanding why something is the way it is often gives a lot more value than just understanding what it is or how that it works and then once we've done a little bit of that philosophical discussion we'll finish with a little bit of live coding i'm a bit nervous about that but we'll see how it goes and the idea there is to put some of the theory that hopefully you've been learning into practice and give you a little bit of an impression of what it feels like to create solutions with closure okay so let's dive in so design is separating into things that can be composed rich hickey he's the creator of closure and i i think this quote is perhaps the perfect place for us to start in our journey of trying to understand rich and how he thinks and especially his creation and what i think this quote tells us is that rich really values separating ideas that should be untangled but giving us tools that allow us to combine them back together into simple solutions so let's have a look at how he puts that into practice and the first idea we're going to cover the closure has a base philosophy is that it separates data from functionality it does this by elevating data to a first-class citizenship within the language and it encourages you to build your solutions using pure functions that work on that data you could say in a way that closure is the antithesis or the opposite of object-oriented programming where the fundamental idea there is to tangle up those two concepts of data and functionality into objects whereas clojure wants to split those apart but why is that when you combine two pieces of data you get data when you combine two machines you get trouble if you only remember one thing from my talk i really want it to be this quote write it down take a screenshot ask siri to take a note for you and then promise me that you're going to come back later and reread this and just give it a couple of minutes to ruminate on it to ponder it and think about why rich is is right here and why this is quite a profound way of thinking differently about writing programs when you understand this idea then you'll understand the brilliance of promoting data up to the syntax level of your language and then why giving a huge toolkit of functions to work with that data is the right way to do things and that's exactly what closure does so let's have a little look at how does data or syntax look like so here are the four core data structures that closure offers lists vectors maps and sets and as you can see lists have the the syntax of using parentheses vectors square brackets maps curly braces and sets have a hash in front of the curly brace and you might also notice that there are no commas separating the elements that's because enclosure a comma is treated as white space so that means it's fully optional if you put it there or not most coding standards or guidelines would recommend not to put it for lists but to use them just as a visual separator when you have key value pairs in maps as you see here on the third line so what does this mean when we have data a syntax it means that we visualize our data we bring it to the forefront and it makes it easier to think about to talk about to communicate to each other and to work with not only that but it also makes it easier to construct nested data which is of course the main kind of data that we work with with our systems here we have an example a vector that contains three maps and each map contains three key value pairs and one of those values is a vector itself and what i want you to notice is how clearly we see the shape of the data and think about how hard it is to see the shape of data when you're using the program when you're using code to construct rather than syntax you just don't see it right it's it's lost in the code i think there's a reason why json has taken over the world in terms of communicating data and you can think of closure's data syntax as json with super powers one of those superpowers is that clojure's code itself is data so closure doesn't stop with making the system data easy to visualize and to reason about and to work with it takes the perhaps heretical but i believe inspired next step to represent the code itself as data as the data structure that's because closure is a lisp list stands lisp stands for list processor so you can probably guess which data structure it uses to represent its code that's right it uses lists and here's how a function call is represented as a list enclosure where the function is always the first element in the list and the arguments are the rest of the elements in the list and this is called prefix notation and what's good about it is it simplifies the syntax because you can it means that the language is 100 consistent in the order of precedence there's no book that you need to learn that in this case you put them the operator or the function here in this other case it goes there it's always at the front of the list so let's see some examples of how that looks like so when we want to add numbers together you put the function at the front of the list when we want to find the max of a group of numbers you put the function at the front of the list and the arguments follow and of course you can have as many arguments passed to these as you want when we're filtering a collection here we use a predicate function called odd that filters out the odd numbers from the vector again filter goes at the front and then you pass in this case a um a function as the first argument and then when we're doing conditionals it's the same if goes at the front then we have a nested list that's that's the important thing to notice about this piece of code so the way it works with closure is when you have nested data structures in the code so nested lists you always evaluate from the deepest nest nested list first so he would evaluate that one is less than two so it's true that predicate and therefore we this conditional will return a rather than b okay here's another quote nobody wants to program with mutable strings anymore why do you want to program with mutable collections you've probably noticed already that i like quotes that's because i think at their best they have an almost magical ability to distill a lifetime's worth of wisdom and knowledge into a bite-sized piece of clarity and i think the particular insight with this quote is that rich is saying we've already solved how to make our programs stable to build upon and the answer is building on immutable data an enclosure all the collections are immutable by default and i think this is something that our industry has started to wake up to of course you you get immutable data structures in most languages now but where i think closure is different is that it did that right from the beginning it's a core part of the language and it's not been added as an afterthought or as a library so that changes how those data structures are and how people code by default enclosure in a good way so let's get a feeling for what it's like to work with these immutable collections starting with strings so here what we're doing is we're defining a string with the name first name and we're giving it the value dave and as you see it's in the list and def is how you define and that goes first and then you pass the arguments just as before so you already understand closure right that's kind of cool and then if we're going to manipulate that string so in this case we're concatenating it with another string i'm sorry and that output i'm sorry dave as expected but we haven't changed first name the value of first name is and always will be dave and that's pretty common in most languages that's that's how we do strings now mutable strings aren't really a thing but where closure is different is all of the other collections work in just the same way so here's an example where we've constructed a vector with three elements we've called it ages it has three integers in the vector and then we when we conjoin a new element onto the end 21 that outputs a vector but it's a new vector just like we had a new string and if we look at what's in ages it hasn't changed and that gives us this stable base to build upon it means that there's not a shifting sand of mutability underneath everything that we're building so what does rich think the problem with mutability is so eventually with mutable objects you create an intractable mess an encapsulation does not get rid of that encapsulation only means well i am in charge of this mess so what have we learned so far closure separates data from functionality closure visualizes our data it brings it to the front it makes it a first class citizen when we're working with our code closure code itself is data and closure collections are immutable by default and all of these four properties combined and normally what people mean when they say that closure is data oriented what it means is closure puts data front and center when we're building our systems when we're writing our code when we're talking about it with our fellow developers and it changes the way you think about building systems and it enables us to build fundamentally simpler solutions okay so that's the basics of closure's design philosophy but before we hop over into the live coding part of this i wanted to teach you a couple of pieces of syntax just so it's easier for you to follow along if you haven't seen closure before so here we're defining a function called greetings which takes a single argument called name and it concatenates it in after the the string hello and you'll see that this looks very similar to when we were defining values you define functions in essentially the same way however because creating functions is so common when you're writing code right that's what we do for the most part when we're writing functional approach closure actually has some syntactic sugar to simplify and shorten and reduce the the nesting for when we're making our functions so this is the exact same definition but here we're using def n instead of def and you can think about reading that as define function instead of define so it's different greetings name and then the same implementation so what we've essentially done is shortened how much we need to read and understand each time that we define a function so that's good to know because we'll be defining some functions later and then using that you already know the rule right you put it in a list the function call goes first then you follow it with the arguments in this case a single argument and it would output hello dave so our custom functions are treated in just the same way as the core functions in the language i think one of the things that can be a little bit upsetting when you're first reading a lisp code and closure is no different is a lisp is when you get quite a lot of nesting going on in the code so this is has three nested function calls and how you would read this is like i said from the inside out so we'd start by evaluating range five which would give us the sequence zero one two three four then we apply the increment function with map so we map it across each of the elements in the sequence giving us one two three four five and then we filter using the odd predicate so only letting the odd numbers through in the end which gives us the output one three and five but it feels a little bit unnatural especially when you're getting used to reading code that way it feels a bit oh and i think that's because in english at least that's not how we think and read and write we tend to read left to right not right to left and we tend to read top to bottom but closure has a tricky big sleeve a trick that is called threadlast and threadlast is is a macro that changes the order of the code essentially and lets you flip it and it's an arrow with two heads you'd see it here it's this is a ligature version but it's just a dash with two chevrons and what happens here is we can put range five first we see the output like i said zero one two three four then that gets piped or threaded into the next function call in the last position that's why this is thread last and then finally it gets threaded into the filter at the end and if you haven't seen this before it might be a bit confusing but if you've ever used unix you might know the pipe when you pipe the output of one command into the input of the next and that's essentially what we're doing here it's called thread but it's essentially the same and like i said commas are treated as white space but the output of executing range five gets placed into where those commas are on mapping into the last position and the output of mapping into the last on filter i hope that makes sense because we're going to use this quite a bit great one last quote systems are dynamic and data driven it might be a nice idea to use a language that is also dynamic and data driven so i want to show you what it feels like of course we're not going to build a whole system we're just going to do a bit of naughty examples really but it still hopefully will give you a feeling of those properties that we talked about the design philosophy behind closure how does that impact when you're working with code and shaping algorithms so let's jump over and do that let me just flip into mirror mode excuse me one second okay live coding not terrifying at all right so let's see if we have the repel up and running so we will send plus one two to the ripple and we get three back should i zoom in a tiny bit more maybe just so it's even easier for you guys to see that hopefully is big enough and if you're watching on a mobile phone then i'm afraid you only have yourself to blame wait until you get home and watch it on the big screen okay so what's happened here like i said it's a list the first element is the function then we pass the arguments and we're returning three right that's nice and simple but what i'm going to show you in this example is some textual analysis so what we're going to do is we're going to define a book and we're going to read in a file and one of my favorite names functions is a function called slurp i just think it sounds so delicious and we're going to slurp in a book from the project gutenberg and it's quite a big book so we'll see how long this takes to load and what slurp does is it reads a file either from the local file system or remotely as you see here and it converts it into a string so we've now set the value of the book symbol to be a string of the book if we're going to do some analysis on it we're going to want to break that out into the words in the book as a separate sequence there are a couple of ways we could do this one way is to use like string functions and split them based on spaces in fact we're going to do a regular expression there's a function called reseek that does a matching pattern and an output it's a sequence that matches that regular expression and i don't if you've ever heard the phrase but if you have a problem and you solve it with a regular expression now you have two problems so that's basically what we're doing here so what we're going to match it on is word characters or quotes so any time we see an a b c all the way to z or a 0 to 9 or i think underscore that's a word character and any quote or apostrophe so that we get possessives and let's run that across the whole book hopefully that will work okay and let's count how many words we have and that might give us an idea about what book we're looking at 220 391 words if someone knows what the book is just based on the word count i'll be impressed but let's take the first 20 of those words and that might tell us what the title is so it's moby dick or the whale by herman melville so let's do some analysis on moby dick so the first thing we're going to try and find out are what are the 20 most frequently used words in this book and we're going to use the thread last macro the one i just explained to you what it is and how it works so hopefully you can follow along so we're going to take the words and there's another really useful core function that's called frequencies enclosure and if we read the text it's a bit small here but it says returns a map from distinct items in collection to the number of times they appear which sounds almost exactly like what we want so let's run that that might take a while because it's a big book so here we've got a map and it's the the word and then the frequency that it appears in the book and i already see a problem here because lower is ironically not lowercase it's uppercase so what we're probably going to want to do is use closure dot string slash lowercase so this function takes a string and outputs the lowercase version of that string but of course with words we have a sequence of 220 000 strings so we can't just run this once we have to map that function across all of the entries in the sequence let's see if that fixed our problem with uppercase yeah that looks good and like i said when i briefly introduced functions but this is what's called a higher order function so what happens is as well that functions as well can take data or they can take functions so this is the higher order one that takes the lower case okay so now what we want to do is we want to sort this so that we can figure out which of the most frequently used ones and if we just do a standard sort it's going to sort them alphabetically so we want to give it another function to sort by and because we had a map we know we have keys and values so if we sort by keys it's going to sort alphabetically but what we're going to do is sort by the value because the value was the frequency so hopefully this will give us in order yes so these are the the words that only appear once and then the last ones of this list should hopefully be the most frequently used one so let's take the last say 20 because that's what we were aiming for and here are the 20 most commonly used words in moby dick however these are very very boring because these would be the 20 most commonly used words in most english works especially at this length so what we're actually going to do is try and make this a bit more interesting we're going to define a value called common words and it's going to be the set of common words in the english language and i have prepared that one earlier so we paste that in and here you start to get a feeling for what it's like when you bring the the data and the data structures up to the front to be first class because we see the shape of this data right okay so now we have those common words so what we want to do now is after we've done lowercase we want to remove those words out of the the collection common words so let's run that and hopefully we'll get a different result yes this looks promising and what's happening here maybe this is interesting how did it work that we could pass a set into the remove function so let me just take a quick detour to explain what's happening there when we have a set so let's say we have a set that contains one two and three closure can treat that as a function itself so if we say and pass that the argument one what it's going to do is return one if that's in the set and if we pass four which is not in the set it will return nil an enclosure one or any value is a truthy value so that means that if we're filtering or removing on it it will um exist and nil is a false or full c value so in this case when the common words are in this list they get removed so that's how that works so let's have one more look at what these were then okay so drum roll the number one used word in uh moby dick is whale perhaps unsurprisingly we have yi and ahab and ship oh thank you how kind and see a man and perhaps this isn't too surprising but what i want you to start to see here is just how close the the solution that i've described is to maybe how you would start to think about describing this to someone else in words if you're doing some kind of pseudo code description of what we're doing so let's just read it out so we take the words we map them to lower case we remove the common words we calculate the frequencies we sort those by the frequency or the val in this case and then we take the last 20. and i also want you to notice how much it feels like playing with lego what we're doing is just combining different functions that all know how to work on these sequences these data structures that have this first class citizenship within closure and it becomes that that uh that act of molding the software and and you see how using a repo gives you this instant feedback as you're working on it so you spot things as you go and you can improve and tweak your algorithms as you build them great so let's see how that would be slightly different if instead of doing the 20 most frequently used words let's find the longest words and what we probably want to do here to start with is reduce the the problem space a little bit so instead of doing this over all 220 000 words let's find the set of words so distinct returns a lazy sequence of the elements of the collection with duplicates removed so that's exactly what we want to do and then once we have the set or the distinct then we can sort them by the count so let me just show you why this is working so if we use the count function on a string it's going to return the number of characters in the string because internally you can think of closure as representing a string as a sequence of characters so when we sort by the count here it's going to count each one and then sort them by that which should be exactly what we want yes so these are all single letters so let's then take the last 20 of these and these should be the 20 longest words in the book oh there's some good words here supernaturalness the longest word is uninterpenetratingly that's a very good word uh and let's do one more thing so let's see exactly how many characters each one of these have so we'll use the group by function and we'll group by the count this time and that way what it's going to do is count each of these and then put them in in a vector for all of the ones that have that number of characters so these are all the ones with 16 and we see that the longest word in moby dick has 20 letters or 20 characters pretty cool okay one last little thing that we're going to do then is find the longest palindrome in moby dick so hopefully you all know what a palindrome is but if you don't i can teach you now one of my favorite palindromes is the word race car so a palindrome is a word that's the same backwards and forwards so what we're going to do is create a little helper function called palindrome question mark and this is going to take any collection and return true if it's a palindrome and false if it isn't so as a palindrome is the the same thing forwards and backwards the easiest way to do this enclosure i think is if we compare the collection to the reverse of the collection so let's execute that and do some tests again the great thing about using a reply is that we can test as we go so if we pass in a vector one two three three two one that should be a palindrome it is and then let's try with a string race car should also be a palindrome and it isn't and that's interesting so why is that not a palindrome the secret here is how the reverse function works with the string enclosure so if we pass in race car to reverse what we see is we get a sequence of characters back not them concatenated together into a string so when you compare this string to the sequence closure says ah those two things aren't the same however there's a little trick we can use here there's a core function called seek which forces a collection to be turned into a sequence so what that will do is turn racecar the string into the sequence of characters so we'll turn that into this and if it's already a sequence it won't touch it so then if we execute this hopefully this is still true now this should be true and then let's just double check that this works that isn't the palindrome so good this feels like it's working so let's let's use this then to do some analysis and find the longest palindrome in moby dick so we take the words should we do lowercase now i don't think it makes any difference this time but we should do distinct again let's just care about the oops the set of words rather than every single word and then what we're going to do is we're going to filter before we did a remove up here so we remove the common words this time we're going to do the opposite of that so what filter does is it keeps all of the ones that match that match the the function that you pass in whereas before remove got rid of the ones that match if that makes sense so hopefully this should give us all of the palindromes in the book yeah these single of course single letter words are technically a palindrome but those aren't really that interesting and these don't look like they're sorted so let's sort them by count like we did before yep that looks like it's working and then let's take the last say ten so these should be the longest palindromes in moby dick dude is in there apparently poop we're learning things here and the longest word is deified that's a nice word and i didn't know that that was a palindrome so that was cool but we're actually trying to find the longest palindrome so instead of taking the last 10 we could just take the last one or there's also a function that's even simpler than that that's just called last which will give us the same result okay and what we've been doing here is just creating these it's not really a function because we haven't named it we've not defined anything here so we can't call these bits of code from anywhere else so just to show you what it feels like to do that let's define a function called longest palindrome that takes words then we tab this in oops not that one so it takes the words finds the distinct set of words in that list of words filters out the palindromes sorts them by the count and grabs the last again you get a feeling for how close this is to how we would talk about it how few characters were using i know there are some languages that really try to be extremely terse and really concise and i think there is a lot of value in that of course if you're getting down to just having you know characters to describe things you start to lose some of the clarity so i think there's probably a balance there between clarity and conciseness and for my taste at least i feel like closure gets really close to perfect there so let's run that so now we have a custom defined function that we can call longest palindrome and if we pass in the words there it should give us the same result which it does and because we have a repo we can test so let's just test with a few other words that we know are palindromes let's put race car in again and hopefully it will return race car and it does so this was pretty much everything i wanted to show you like i said fairly basic functions you know we're not building a system here but again it's it's more to give you a feeling for what does it feel like to shape your solutions to build them as you go with this toolkit this uh this bucket of bricks that you get with closure and with bringing out the data structures to this top level so hopefully if you haven't seen this before you've learned something hopefully even if you'd seen closure before some of the stuff we talked about before about the philosophy was a little bit interesting and thank you very much for your attention
Info
Channel: Func Prog Sweden
Views: 21,708
Rating: undefined out of 5
Keywords: fps, functional, programming, clojure, func prog sweden, rich hickey
Id: C-kF25fWTO8
Channel Id: undefined
Length: 32min 44sec (1964 seconds)
Published: Wed Dec 09 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.