Introduction To Clojure BBC lunch & learn, July 18th 2012 Renzo Borgatti, Developer in Test, A/V TeamWelcome to this introduction to the Clojure language. Clojure had a lot of attraction lately aswell other well known languages based on the functional paradigm like Erlang or inspiredfrom the functional paradigm like Scala. There is deﬁnitely a reason for the return of thefunctional paradigm nowadays that we are going to explain brieﬂy in this talk.My name is Renzo Borgatti, blah blah
the functional re-emergence roots in λ-calculus 1930 re-discovered with Lisp 1958The functional paradigm has its root in the Lambda calculus, a method for notations andmanipulation of mathematical functions introduced by Alonso Church around 1930.Lambda calculus was then rediscovered as a versatile programming tool by McCarthy in 1958when Lisp was introduced as a programming language able to deal with mathematicalnotation.
Moore’s failure for cpu clock but cpu density growing fast software is the new bottleneck need to design for concurrencyMoore’s law recently failed on one of its axis. CPU speed is not doubling or tripling every yearanymore. It used to be the case in the late ’90. But the demand of computing power isgrowing as usual.Hardware manufacturer resorted to other means to increase power, such as transistordensity. Right now is not uncommon to see cheap laptops sold with 4 cpu cores out of thebox. Change on chip density requires a change in software scalability. Software must bewritten for concurrency to take advantage of multi-core architectures.
OOP encapsulates state changes overwrite state state has multiple observers concurrency requires locking locking is complicatedObject Oriented Programming conﬁnes state using speciﬁc language constructs like classes.The Program ﬂows as a series of state changes.When state needs concurrent access it must be protected using locks because there could bemultiple computations going on at the same time.A change on the state delete previous values and the history is lostThe problem is that “identity” and “values” are overlappingA clear example is a date object. A date is created to hold a value, maybe the the hottest dayof the year. If there is a new record this year, that is the new hottest day. But what about theprevious one? Why it should be completely replaced by changing the date and removing theinformation from the system? What about all the threads that were observing the valueproducing metrics for the old date? Should that information being lost by changing the dateinstance or should each thread just keep going observing the old value until they decideotherwise?State based languages are hard to understand and to debug. Looking at some method,chances are you can’t be sure until runtime about what that method is supposed to behave incertain condition. Sometimes even at runtime the portion of state inﬂuencing thecomputation is so big that is impossible to handle correctly.Concurrency based on locks is complicated, generating deadlock conditions and all sort ofsynchronisation issues.
Clojure, Scala, F#, Erlang... focus on immutability semantic for changing values “new” model for concurrencyHence why the resurgence of the “old” and “academic” functional model.Why not Lisp or Haskell?Clojure Scala and F# all have in common the fact that they are hosted, so interoperability withknown languages it’s easy. Erlang is a special case of non-hosted functional language thatbecame popular. Erlang is very focused on high availability and performs great in that kind ofenvironments.
A dynamically-typed jvm-based Lisp dialect Rich Hickey 2007 now 1.4What about Clojure in speciﬁc? Clojure is a relatively young programming language based onLisp but running on the JVM.It comes out from the frustration of Rich Hickey developing highly concurrent systems as aJava and .NET consultant.Rich Hickey developed dotLisp for the .NET environment before Clojure.He spent then 2.5 years designing and implementing Clojure. Clojure was officiallyannounced in 2007.
interactive hosted dynamic it’s a Lisp functional concurrentThese are the main Clojure design principles. Clojure is a “consenting adults” language. It sitssomeway between the functional pureness of Haskell and the lazy-evaluate-everything ofScheme. Checking for functions that aren’t pure in Clojure is technically possible, but thatwill make more than half of the JDK or CLR unusable.
interactive REPL read-eval-print loop suitable for exploration introspection capabilities fast development loop demoShow off REPL in action:- repl special variables *1 *2 *3 etc- the content of (pst) after an exception- doc searching and print sources- (ﬁnd-doc “some”)- (use ‘clojure.repl) (source func)
hosted built with Java interop in mind use Java directly no wrappers lots of syntatic sugar demo- java interop demo- (ﬁlter #(re-seq #"pper" (.getName %)) (seq (.getMethods String)))- (import java.util.Date) (def now (Date.))- (.. "" getClass getMethods)
dynamic less ceremony: speed concise: where’s my code ~1:1 ratio sudocode real codeClojure is dynamic in two ways. It’s dynamically typed, so it doesn’t specify types. Explicittyping would be more useful for a language that at compile time can check if the currentfunctions are producing side effects and issue warnings. For Clojure dynamic typing means tobe more concise and more ﬂexible.Second, Clojure it’s dynamic in the way programmers can approach development with it:ﬁring up a REPL, test live code that gets automatically re-evaluated (when needed) and tweakthe main program on the go. Less ceremony means speed: less code to type, less potentialbugs, code is more readable.Conciseness measures the quantity of code needed to express a “task” in the language. Whenthe language is concise it’s easier for the programmer to focus on business logic. Potentiallya 1:1 ratio between sudocode and the actual code would be ideal.
dynamic by the way, not this kind... ...of expressiveness!That’s the APL one liner for the game of life.http://catpad.net/michael/apl/
dynamic but instead of something likeThis is the isBlank static method in StringUtils from Apache commons. I have a quiz for you. Iremoved the name of the method. By reading the java and the clojure version of the samebehaviour, could you tell what the method is actually doing? If yes, was the Java or theClojure version more helpful?
It’s a Lisp homoiconic data as code powerful macro programming deﬁne new syntax demoIn Clojure everything that the compiler sees are just data structure although there is somesyntactic sugar to make it easier to program.But before the compiler there is a Reader in Clojure which transforms the textual input intodata structures.Homoiconic means just that, that everything is a data structure. Why this is important?Because the syntax is much simpler and more abstract constructs can be built in term of abunch of primitives. It also make it easier for macro programming.Macros are special constructs which are interpreted by the reader and will inﬂuence the ﬁnaloutput which is going to the compiler. With Macros you can effectively extend the language.Clojure “when”, “for” or syntax like the arrow operator “->” are effectively macros.(macroexpand (when (= "a" "a") (def renzo ", renzo") (str "this is also true" renzo)))(macroexpand (for [x (range 10)] (str x)))
functional focus on immutability side-effects free functions caching and laziness “consenting adults” purenessFinally, Clojure is functional. It should be already clear at this point of the presentation.Clojure main data structures are immutable, requiring a speciﬁc semantic to be altered. Beingfunctional means that the output of a function can only be inﬂuenced by its inputs. Theparameters must hence be immutable. If they were mutable then the function would have achance to be impure by altering them.When a function is pure there are no side effects so it is producing repeatable results whichare independent from the state of the system. Repeatable means caching can beimplemented easily. Laziness follows because there is no need to “render” the result of afunction until it’s actually needed. Laziness means more optimisation opportunities for thecompiler.Clojure always allows you to skip all of that and introduce side effects all around. It does nothave the assignment operator though.
concurrent immutable core data structures constrained change semantic atom, ref, agent, var demoClojure has been built with a focus on concurrency. Main data structures are immutablerequiring special semantic to be altered. There are four types of clojure construct to alterimmutable structures.Atoms are simple CAS (compare and swap) semantic. You create an atom and then you canchange it by just calling swap! on it passing the function that should alter the content of theatom. The swap! will succeed or not, based on a comparison with the current value in theatom. If the value is changed by another thread in the middle, the swap! will be attemptedagain over the new value. Needless to say, the altering function needs to be side effects free.Atoms cannot coordinate over multiple values. You need Refs for that. A ref is similar to adatabase transaction. You need to open a transaction before attempting to change any of theRefs. Transactions can be attempt an arbitrary number of times.Agents are similar to Atoms in the sense that they are uncoordinated. But an action sent to anAgent will be executed at some later point in time, on a thread pool.Vars is thread-local state that can be altered by using the (binding) form. They can be usedwhere too many repeating parameters are unpractical (like Java).
Clojure is not a replacement not just for list comprehension radical approach steeper learning curve what about all those parenthesis?Clojure has not been built to be a replacement for Java as other languages. It was built withimperative and state based languages drawbacks to solve the problem entirely.Another thing that is valid for all functionally inspired languages is that the functionalparadigm is not about having functions as variables that can be sent around and used oncollections. Ruby and Python aren’t certainly functional but they are heavily based on closures(aka lambdas). Scala is more functional in this respect but it allows assignment and supportobject orientation with instance variables that are clearly used to obtain side effects.If you come from another paradigm and usually programming in Java the Clojure learningcurve will be probably steeper than Groovy or Scala.Java people tend to try to match parenthesis as soon as they see them. Brackets mostlydelimit scope and give structure to the code. Lispers don’t need to match parenthesis.
Who is using Clojure?The always evolving lists:http://dev.clojure.org/display/community/Clojure+Success+Storieshttp://www.quora.com/Whos-using-Clojure-in-production
Clojure is a good hiring tool attract smart people diversify company mindsetThere is an higher probability to attract the Lisp community with Clojure than Scala.The Lisp community includes a very ﬁne selected crowd of people who must have been indeeply love with their language if they remained outside the mainstream languages forsomething like half a century! Apart from jokes, the average mathematical and algorithmicbackground of the Lisp community is very high and a nice addition for you team.An useful link: the london clojurians jobs page (requires to join the mailing list):- https://groups.google.com/forum/?fromgroups#!forum/london-clojurian-jobs
Scala Clojure type system change semantic models complicated type system clever sequences actor concurrency no objects good java interops harder to recruit friendly java syntax top-notch java interops object/functional steeper learning curve Lisp communityThe not-deﬁnitive Scala to Clojure comparison chart in no speciﬁc order of priority.The two languages have completely different philosophies but the impression is that at theend they have more in common than expected.There are hiring and people factors to consider when choosing one or the other. Clojure is aradical approach that refuses objects as the main tool to model the world, especially aconcurrent world. Scala embraces both styles and let object oriented developers depart fromthe paradigm when needed.The choice between the two language is almost impossible to make outside a speciﬁccontext. They both have pro and cons that compensate each other on an absolute scale. Whatshould not happen in both cases is that you choose the language because you can “sendmethods to collections and around”. There is much more about the functional paradigm thathas nothing to do with closures.
General resourcesthe main clojure website:http://www.clojure.orgeasily browsable documentation:http://clojuredocs.orgthe london clojure dojo and group:http://londonclojurians.orgwho is using Clojure?http://dev.clojure.org/display/community/Clojure+Success+Storiespaper introducing lamda calculus to programmers:http://www.cs.bham.ac.uk/~axj/pub/papers/lambda-calculus.pdfintroducing clojure in the organization:http://blog.jayﬁelds.com/2012/01/lessons-learned-while-introducing-new.html
BBC resourcesThe BBC clojure weekly dojo, every Thu 12:30 van gogh:https://conﬂuence.email@example.com/clojure-ugBBC Clojure forge mailing list:https://lists.forge.bbc.co.uk/mailman/listinfo/clojureBBC Clojure forge IRC channel:#clojure
TalkSlides PDF available here:https://conﬂuence.firstname.lastname@example.org/clojure-ugPlease rate my talk:sdfdfdVideo will be available soon