SlideShare ist ein Scribd-Unternehmen logo
1 von 34
Downloaden Sie, um offline zu lesen
Clojure
A Dynamic Programming Language for the JVM

                 Rich Hickey
Clojure Fundamentals
• 3 years in development, released 10/2007
• A new Lisp, not Common Lisp or Scheme
• Functional
 • emphasis on immutability
• Supporting Concurrency
 • language-level coordination of state
• Designed for the JVM
 • exposes and embraces platform
Clojure is a Lisp
• Dynamically typed, dynamically compiled
• Interactive - REPL
• Load/change code in running program
• Code as data - Reader
• Small core
• Sequences
• Syntactic abstraction - macros
• Not Object-oriented
Atomic Data Types
• Arbitrary precision integers -12345678987654


• Doubles , BigDecimals
           1.234              1.234M


• Ratios -22/7


• Strings -“fred”, Characters -a b c


• Symbols - fred ethel , Keywords -   :fred :ethel


• Booleans - true false  , Null -
                               nil


• Regex patterns    #“a*b”
Data Structures
• Lists - singly linked, grow at front
  •   (1 2 3 4 5), (fred ethel lucy), (list 1 2 3)


• Vectors - indexed access, grow at end
  •   [1 2 3 4 5], [fred ethel lucy]


• Maps - key/value associations
  •   {:a 1, :b 2, :c 3}, {1 “ethel” 2 “fred”}


• Sets  #{fred ethel lucy}


• Everything Nests
Syntax
• You’ve just seen it
• Data structures are the code
• Not text-based syntax
 • Syntax is in the interpretation of data
    structures
• Things that would be declarations, control
  structures, function calls, operators, are all
  just lists with op at front
• Everything is an expression
# Norvig’s Spelling Corrector in Python
# http://norvig.com/spell-correct.html

def words(text): return re.findall('[a-z]+', text.lower())

def train(features):
    model = collections.defaultdict(lambda: 1)
    for f in features:
        model[f] += 1
    return model

NWORDS = train(words(file('big.txt').read()))
alphabet = 'abcdefghijklmnopqrstuvwxyz'

def edits1(word):
    n = len(word)
    return set([word[0:i]+word[i+1:] for i in range(n)] +
               [word[0:i]+word[i+1]+word[i]+word[i+2:] for i in range(n-1)] +
               [word[0:i]+c+word[i+1:] for i in range(n) for c in alphabet] +
               [word[0:i]+c+word[i:] for i in range(n+1) for c in alphabet])

def known_edits2(word):
    return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)

def known(words): return set(w for w in words if w in NWORDS)

def correct(word):
    candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]
    return max(candidates, key=lambda w: NWORDS[w])
; Norvig’s Spelling Corrector in Clojure
; http://en.wikibooks.org/wiki/Clojure_Programming#Examples

(defn words [text] (re-seq #"[a-z]+" (.toLowerCase text)))

(defn train [features]
  (reduce (fn [model f] (assoc model f (inc (get model f 1))))
          {} features))

(def *nwords* (train (words (slurp "big.txt"))))

(defn edits1 [word]
  (let [alphabet "abcdefghijklmnopqrstuvwxyz", n (count word)]
    (distinct (concat
      (for [i (range n)] (str (subs word 0 i) (subs word (inc i))))
      (for [i (range (dec n))]
        (str (subs word 0 i) (nth word (inc i)) (nth word i) (subs word (+ 2 i))))
      (for [i (range n) c alphabet] (str (subs word 0 i) c (subs word (inc i))))
      (for [i (range (inc n)) c alphabet] (str (subs word 0 i) c (subs word i)))))))

(defn known [words nwords] (for [w words :when (nwords w)]    w))

(defn known-edits2 [word nwords]
  (for [e1 (edits1 word) e2 (edits1 e1) :when (nwords e2)]    e2))

(defn correct [word nwords]
  (let [candidates (or (known [word] nwords) (known (edits1 word) nwords)
                       (known-edits2 word nwords) [word])]
    (apply max-key #(get nwords % 1) candidates)))
Java Interop
Math/PI
3.141592653589793

(.. System getProperties (get "java.version"))
"1.5.0_13"

(new java.util.Date)
Thu Jun 05 12:37:32 EDT 2008

(doto (JFrame.) (add (JLabel. "Hello World")) pack show)

;expands into:
(let [x (JFrame.)]
   (do (. x (add (JLabel. "Hello World")))
       (. x pack)
       (. x show))
   x)
Clojure is Functional
• All data structures immutable
• Core library functions have no side effects
 • Easier to reason about, test
 • Essential for concurrency
    • Functional by convention insufficient
• let-bound locals are immutable
• loop/recur functional looping construct
• Higher-order functions
Sequences
(drop 2 [1 2 3 4 5]) -> (3 4 5)

(take 9 (cycle [1 2 3 4]))
-> (1 2 3 4 1 2 3 4 1)

(interleave [:a :b :c :d :e] [1 2 3 4 5])
-> (:a 1 :b 2 :c 3 :d 4 :e 5)

(partition 3 [1 2 3 4 5 6 7 8 9])
-> ((1 2 3) (4 5 6) (7 8 9))

(map vector [:a :b :c :d :e] [1 2 3 4 5])
-> ([:a 1] [:b 2] [:c 3] [:d 4] [:e 5])

(apply str (interpose , "asdf"))
-> "a,s,d,f"

(reduce + (range 100)) -> 4950
Maps and Sets
(def m {:a 1 :b 2 :c 3})

(m :b) -> 2 ;also (:b m)

(keys m) -> (:a :b :c)

(assoc m :d 4 :c 42) -> {:d 4, :a 1, :b 2, :c 42}

(merge-with + m {:a 2 :b 3}) -> {:a 3, :b 5, :c 3}

(union #{:a :b :c} #{:c :d :e}) -> #{:d :a :b :c :e}

(join #{{:a 1 :b 2 :c 3} {:a 1 :b 21 :c 42}}
      #{{:a 1 :b 2 :e 5} {:a 1 :b 21 :d 4}})

-> #{{:d 4, :a 1, :b 21, :c 42}
     {:a 1, :b 2, :c 3, :e 5}}
Persistent Data Structures
• Immutable, + old version of the collection is still
  available after 'changes'
• Collection maintains its performance guarantees
  • Therefore new versions are not full copies
• Structural sharing - thread safe, iteration safe
• All Clojure data structures are persistent
  • Hash map/set and vector based upon array
     mapped hash tries (Bagwell)
  • Practical - much faster than O(logN)
Bit-partitioned hash tries
Concurrency
•   Conventional way:
    •   Direct references to mutable objects
    •   Lock and worry (manual/convention)
•   Clojure way:
    •   Indirect references to immutable persistent
        data structures (inspired by SML’s ref)

    •   Concurrency semantics for references
        •   Automatic/enforced
        •   No locks in user code!
Typical OO - Direct
references to Mutable Objects
                             foo

                        :a          ?
                        :b          ?
                        :c         42
                        :d          ?
                        :e          6




 • Unifies identity and value
 • Anything can change at any time
 • Consistency is a user problem
Clojure - Indirect references
   to Immutable Objects
              foo                      :a    "fred"
                                       :b   "ethel"
                       @foo            :c      42
                                       :d      17
                                       :e       6




• Separates identity and value
 • Obtaining value requires explicit
   dereference
• Values can never change
 • Never an inconsistent value
Persistent ‘Edit’
                 foo               :a          "fred"
                                   :b         "ethel"
                          @foo     :c            42
                                   :d            17
                                   :e             6


                                        Structural sharing
                                   :a          "lucy"
                                   :b         "ethel"


•
                                   :c            42
    New value is function of old   :d            17


•
                                   :e             6
    Shares immutable structure
•   Doesn’t impede readers
•   Not impeded by readers
Atomic Update
              foo                   :a          "fred"
                                    :b         "ethel"
                                    :c            42
                                    :d            17
                                    :e             6

                       @foo
                                         Structural sharing
                                    :a          "lucy"
                                    :b         "ethel"


• Always coordinated
                                    :c            42
                                    :d            17


 • Multiple semantics
                                    :e             6



• Next dereference sees new value
• Consumers of values unaffected
Clojure References
• The only things that mutate are references
  themselves, in a controlled way
• 3 types of mutable references, with different
  semantics:
  • Refs - Share synchronous coordinated
    changes between threads
  • Agents - Share asynchronous autonomous
    changes between threads
  • Vars - Isolate changes within threads
Refs and Transactions
• Software transactional memory system (STM)
• Refs can only be changed within a transaction
• All changes are Atomic, Consistent and Isolated
 • Every change to Refs made within a
    transaction occurs or none do
  • No transaction sees the effects of any other
    transaction while it is running
• Transactions are speculative
 • Will be retried automatically if conflict
 • User must avoid side-effects!
The Clojure STM
•   Surround code with (dosync ...)

•   Uses Multiversion Concurrency Control (MVCC)

•   All reads of Refs will see a consistent snapshot of
    the 'Ref world' as of the starting point of the
    transaction, + any changes it has made.

•   All changes made to Refs during a transaction
    will appear to occur at a single point in the
    timeline.

•   Readers never impede writers/readers, writers
    never impede readers, supports commute
Refs in action
(def foo (ref {:a "fred" :b "ethel" :c 42 :d 17 :e 6}))

@foo -> {:d 17, :a "fred", :b "ethel", :c 42, :e 6}

(assoc @foo :a "lucy")
-> {:d 17, :a "lucy", :b "ethel", :c 42, :e 6}

@foo -> {:d 17, :a "fred", :b "ethel", :c 42, :e 6}

(commute foo assoc :a "lucy")
-> IllegalStateException: No transaction running

(dosync (commute foo assoc :a "lucy"))
@foo -> {:d 17, :a "lucy", :b "ethel", :c 42, :e 6}
Agents
• Manage independent state
• State changes through actions, which are
  ordinary functions (state=>new-state)
• Actions are dispatched using send or send-off,
  which return immediately
• Actions occur asynchronously on thread-pool
  threads
• Only one action per agent happens at a time
Agents
• Agent state always accessible, via deref/@, but
  may not reflect all actions
• Can coordinate with actions using await
• Any dispatches made during an action are held
  until after the state of the agent has changed
• Agents coordinate with transactions - any
  dispatches made during a transaction are held
  until it commits
• Agents are not Actors (Erlang/Scala)
Agents in Action
(def foo (agent {:a "fred" :b "ethel" :c 42 :d 17 :e 6}))

@foo -> {:d 17, :a "fred", :b "ethel", :c 42, :e 6}

(send foo assoc :a "lucy")

@foo -> {:d 17, :a "fred", :b "ethel", :c 42, :e 6}

(await foo)

@foo -> {:d 17, :a "lucy", :b "ethel", :c 42, :e 6}
Java Integration
• Clojure strings are Java Strings, numbers are
  Numbers, collections implement Collection,
  fns implement Callable and Runnable etc.
• Core abstractions, like seq, are Java interfaces
• Clojure seq library works on Java Iterables,
  Strings and arrays.
• Implement and extend Java interfaces and
  classes
• Primitive arithmetic support equals Java’s
  speed.
Implementation - Functions
 • Dynamically compiles to bytecode in memory
   • Uses ASM
   • No AOT compilation at present
 • Every function is new Class
   • Implements IFn interface
   • Set of invoke methods, overloaded on arity
   • All signatures take/return Objects
   • Variadics based on sequences
Implementation - Calls
• Function calls are straight Java method calls
  • No alternate type system, thunks etc
  • No special extra args
• Calls to Java are either direct or via reflection
  • No wrappers, caches or dynamic thunks
  • Type hints + inference allow direct calls
  • Very few hints needed to avoid reflection
    • compiler flag can generate warnings
Implementation - Primitives
• Locals can be primitives, arrays of primitives
• Math calls inlined to primitive-arg static methods
• HotSpot finishes inlining to primitive math
• Result is same speed as Java
(defn foo [n]                  (defn foo2 [n]
  (loop [i 1]                   (let [n (int n)]
    (if (< i n)                   (loop [i (int 0)]
      (recur (inc i))               (if (< i n)
      i)))                            (recur (inc i))
                                      i)))))
(time (foo 100000))
"Elapsed time: 1.428 msecs"   (time (foo2 100000))
100000                        "Elapsed time: 0.032 msecs"
                              100000
Implementation - STM
• Not a lock-free spinning optimistic design
• Uses locks, wait/notify to avoid churn
• Deadlock detection + barging
• One timestamp CAS is only global resource
• No read tracking
• Coarse-grained orientation
  • Refs + persistent data structures
• java.util.concurrent is still right tool for
  caches/queues
Pain Points
• No tail call optimization
  • Important for some functional idioms
  • Major point of criticism for choice of JVM
    from functional circles
• Use Java’s boxed Numbers + own Ratio
  • Integer, Long, BigInteger etc
  • Slow generic math, numbers on heap
  • Would love tagged fixnums and/or standard
    high performance boxed math lib
Conclusion
• Very happy with the JVM
  • Good performance, facilities, tools, libraries
• Clojure fills a niche
  • Dynamic + functional + JVM
• Lots of interest in first 11 months:
  • 500+ user mailing list, 500+ messages/month
  • 10,000+ SVN reads/month
  • Active community
Thanks for listening!




      http://clojure.org

Weitere ähnliche Inhalte

Was ist angesagt?

An Introduction to Scala - Blending OO and Functional Paradigms
An Introduction to Scala - Blending OO and Functional ParadigmsAn Introduction to Scala - Blending OO and Functional Paradigms
An Introduction to Scala - Blending OO and Functional Paradigms
Miles Sabin
 
Java 8 selected updates
Java 8 selected updatesJava 8 selected updates
Java 8 selected updates
Vinay H G
 
Ppl for students unit 4 and 5
Ppl for students unit 4 and 5Ppl for students unit 4 and 5
Ppl for students unit 4 and 5
Akshay Nagpurkar
 
Java jdk-update-nov10-sde-v3m
Java jdk-update-nov10-sde-v3mJava jdk-update-nov10-sde-v3m
Java jdk-update-nov10-sde-v3m
Steve Elliott
 
Clojure and The Robot Apocalypse
Clojure and The Robot ApocalypseClojure and The Robot Apocalypse
Clojure and The Robot Apocalypse
elliando dias
 

Was ist angesagt? (19)

New Features Of JDK 7
New Features Of JDK 7New Features Of JDK 7
New Features Of JDK 7
 
camel-scala.pdf
camel-scala.pdfcamel-scala.pdf
camel-scala.pdf
 
An Introduction to Scala - Blending OO and Functional Paradigms
An Introduction to Scala - Blending OO and Functional ParadigmsAn Introduction to Scala - Blending OO and Functional Paradigms
An Introduction to Scala - Blending OO and Functional Paradigms
 
Java 8 selected updates
Java 8 selected updatesJava 8 selected updates
Java 8 selected updates
 
Ppl for students unit 4 and 5
Ppl for students unit 4 and 5Ppl for students unit 4 and 5
Ppl for students unit 4 and 5
 
Java jdk-update-nov10-sde-v3m
Java jdk-update-nov10-sde-v3mJava jdk-update-nov10-sde-v3m
Java jdk-update-nov10-sde-v3m
 
Clojure and The Robot Apocalypse
Clojure and The Robot ApocalypseClojure and The Robot Apocalypse
Clojure and The Robot Apocalypse
 
The Evolution of Scala / Scala進化論
The Evolution of Scala / Scala進化論The Evolution of Scala / Scala進化論
The Evolution of Scala / Scala進化論
 
Java tutorials
Java tutorialsJava tutorials
Java tutorials
 
Java SE 8 best practices
Java SE 8 best practicesJava SE 8 best practices
Java SE 8 best practices
 
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and StreamsIntroduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
 
A Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to ScalaA Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to Scala
 
Core java
Core javaCore java
Core java
 
Core java
Core javaCore java
Core java
 
Domain-Specific Languages
Domain-Specific LanguagesDomain-Specific Languages
Domain-Specific Languages
 
Lambda: A Peek Under The Hood - Brian Goetz
Lambda: A Peek Under The Hood - Brian GoetzLambda: A Peek Under The Hood - Brian Goetz
Lambda: A Peek Under The Hood - Brian Goetz
 
Scalax
ScalaxScalax
Scalax
 
JavaOne 2012 - CON11234 - Multi device Content Display and a Smart Use of Ann...
JavaOne 2012 - CON11234 - Multi device Content Display and a Smart Use of Ann...JavaOne 2012 - CON11234 - Multi device Content Display and a Smart Use of Ann...
JavaOne 2012 - CON11234 - Multi device Content Display and a Smart Use of Ann...
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
 

Ähnlich wie Clojure A Dynamic Programming Language for the JVM

FP Days: Down the Clojure Rabbit Hole
FP Days: Down the Clojure Rabbit HoleFP Days: Down the Clojure Rabbit Hole
FP Days: Down the Clojure Rabbit Hole
Christophe Grand
 
Fosdem 2011 - A Common Graph Database Access Layer for .Net and Mono
Fosdem 2011 - A Common Graph Database Access Layer for .Net and MonoFosdem 2011 - A Common Graph Database Access Layer for .Net and Mono
Fosdem 2011 - A Common Graph Database Access Layer for .Net and Mono
Achim Friedland
 
GR8Conf 2011: STS DSL Support
GR8Conf 2011: STS DSL SupportGR8Conf 2011: STS DSL Support
GR8Conf 2011: STS DSL Support
GR8Conf
 
Charles nutter star techconf 2011 - jvm languages
Charles nutter   star techconf 2011 - jvm languagesCharles nutter   star techconf 2011 - jvm languages
Charles nutter star techconf 2011 - jvm languages
StarTech Conference
 
SDEC2011 NoSQL concepts and models
SDEC2011 NoSQL concepts and modelsSDEC2011 NoSQL concepts and models
SDEC2011 NoSQL concepts and models
Korea Sdec
 

Ähnlich wie Clojure A Dynamic Programming Language for the JVM (20)

Persistent Data Structures And Managed References
Persistent Data Structures And Managed ReferencesPersistent Data Structures And Managed References
Persistent Data Structures And Managed References
 
C# for beginners
C# for beginnersC# for beginners
C# for beginners
 
FP Days: Down the Clojure Rabbit Hole
FP Days: Down the Clojure Rabbit HoleFP Days: Down the Clojure Rabbit Hole
FP Days: Down the Clojure Rabbit Hole
 
The DBnary ecosystem - presentation to SD-LLOD 2015 datathon, Cercedilla
The DBnary ecosystem - presentation to SD-LLOD 2015 datathon, CercedillaThe DBnary ecosystem - presentation to SD-LLOD 2015 datathon, Cercedilla
The DBnary ecosystem - presentation to SD-LLOD 2015 datathon, Cercedilla
 
Cassandra drivers and libraries
Cassandra drivers and librariesCassandra drivers and libraries
Cassandra drivers and libraries
 
Kernel Recipes 2018 - 10 years of automated evolution in the Linux kernel - J...
Kernel Recipes 2018 - 10 years of automated evolution in the Linux kernel - J...Kernel Recipes 2018 - 10 years of automated evolution in the Linux kernel - J...
Kernel Recipes 2018 - 10 years of automated evolution in the Linux kernel - J...
 
Fosdem 2011 - A Common Graph Database Access Layer for .Net and Mono
Fosdem 2011 - A Common Graph Database Access Layer for .Net and MonoFosdem 2011 - A Common Graph Database Access Layer for .Net and Mono
Fosdem 2011 - A Common Graph Database Access Layer for .Net and Mono
 
GR8Conf 2011: STS DSL Support
GR8Conf 2011: STS DSL SupportGR8Conf 2011: STS DSL Support
GR8Conf 2011: STS DSL Support
 
Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-Eclipse
 
What the C?
What the C?What the C?
What the C?
 
JSR 335 / java 8 - update reference
JSR 335 / java 8 - update referenceJSR 335 / java 8 - update reference
JSR 335 / java 8 - update reference
 
Charles nutter star techconf 2011 - jvm languages
Charles nutter   star techconf 2011 - jvm languagesCharles nutter   star techconf 2011 - jvm languages
Charles nutter star techconf 2011 - jvm languages
 
SDEC2011 NoSQL concepts and models
SDEC2011 NoSQL concepts and modelsSDEC2011 NoSQL concepts and models
SDEC2011 NoSQL concepts and models
 
Functional Programming with Immutable Data Structures
Functional Programming with Immutable Data StructuresFunctional Programming with Immutable Data Structures
Functional Programming with Immutable Data Structures
 
I know Java, why should I consider Clojure?
I know Java, why should I consider Clojure?I know Java, why should I consider Clojure?
I know Java, why should I consider Clojure?
 
Ruby1_full
Ruby1_fullRuby1_full
Ruby1_full
 
Ruby1_full
Ruby1_fullRuby1_full
Ruby1_full
 
Concurrency and Multithreading Demistified - Reversim Summit 2014
Concurrency and Multithreading Demistified - Reversim Summit 2014Concurrency and Multithreading Demistified - Reversim Summit 2014
Concurrency and Multithreading Demistified - Reversim Summit 2014
 
JDD2015: Twenty-one years of "Design Patterns" - Ralph Johnson
JDD2015: Twenty-one years of "Design Patterns" - Ralph JohnsonJDD2015: Twenty-one years of "Design Patterns" - Ralph Johnson
JDD2015: Twenty-one years of "Design Patterns" - Ralph Johnson
 
Eurydike: Schemaless Object Relational SQL Mapper
Eurydike: Schemaless Object Relational SQL MapperEurydike: Schemaless Object Relational SQL Mapper
Eurydike: Schemaless Object Relational SQL Mapper
 

Mehr von elliando dias

Why you should be excited about ClojureScript
Why you should be excited about ClojureScriptWhy you should be excited about ClojureScript
Why you should be excited about ClojureScript
elliando dias
 
Nomenclatura e peças de container
Nomenclatura  e peças de containerNomenclatura  e peças de container
Nomenclatura e peças de container
elliando dias
 
Polyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better AgilityPolyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better Agility
elliando dias
 
Javascript Libraries
Javascript LibrariesJavascript Libraries
Javascript Libraries
elliando dias
 
How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!
elliando dias
 
A Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the WebA Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the Web
elliando dias
 
Introdução ao Arduino
Introdução ao ArduinoIntrodução ao Arduino
Introdução ao Arduino
elliando dias
 
Incanter Data Sorcery
Incanter Data SorceryIncanter Data Sorcery
Incanter Data Sorcery
elliando dias
 
Fab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine DesignFab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine Design
elliando dias
 
Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.
elliando dias
 
Hadoop and Hive Development at Facebook
Hadoop and Hive Development at FacebookHadoop and Hive Development at Facebook
Hadoop and Hive Development at Facebook
elliando dias
 
Multi-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case StudyMulti-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case Study
elliando dias
 
From Lisp to Clojure/Incanter and RAn Introduction
From Lisp to Clojure/Incanter and RAn IntroductionFrom Lisp to Clojure/Incanter and RAn Introduction
From Lisp to Clojure/Incanter and RAn Introduction
elliando dias
 

Mehr von elliando dias (20)

Clojurescript slides
Clojurescript slidesClojurescript slides
Clojurescript slides
 
Why you should be excited about ClojureScript
Why you should be excited about ClojureScriptWhy you should be excited about ClojureScript
Why you should be excited about ClojureScript
 
Nomenclatura e peças de container
Nomenclatura  e peças de containerNomenclatura  e peças de container
Nomenclatura e peças de container
 
Geometria Projetiva
Geometria ProjetivaGeometria Projetiva
Geometria Projetiva
 
Polyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better AgilityPolyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better Agility
 
Javascript Libraries
Javascript LibrariesJavascript Libraries
Javascript Libraries
 
How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!
 
Ragel talk
Ragel talkRagel talk
Ragel talk
 
A Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the WebA Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the Web
 
Introdução ao Arduino
Introdução ao ArduinoIntrodução ao Arduino
Introdução ao Arduino
 
Minicurso arduino
Minicurso arduinoMinicurso arduino
Minicurso arduino
 
Incanter Data Sorcery
Incanter Data SorceryIncanter Data Sorcery
Incanter Data Sorcery
 
Rango
RangoRango
Rango
 
Fab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine DesignFab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine Design
 
The Digital Revolution: Machines that makes
The Digital Revolution: Machines that makesThe Digital Revolution: Machines that makes
The Digital Revolution: Machines that makes
 
Hadoop + Clojure
Hadoop + ClojureHadoop + Clojure
Hadoop + Clojure
 
Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.
 
Hadoop and Hive Development at Facebook
Hadoop and Hive Development at FacebookHadoop and Hive Development at Facebook
Hadoop and Hive Development at Facebook
 
Multi-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case StudyMulti-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case Study
 
From Lisp to Clojure/Incanter and RAn Introduction
From Lisp to Clojure/Incanter and RAn IntroductionFrom Lisp to Clojure/Incanter and RAn Introduction
From Lisp to Clojure/Incanter and RAn Introduction
 

Kürzlich hochgeladen

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Kürzlich hochgeladen (20)

Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

Clojure A Dynamic Programming Language for the JVM

  • 1. Clojure A Dynamic Programming Language for the JVM Rich Hickey
  • 2. Clojure Fundamentals • 3 years in development, released 10/2007 • A new Lisp, not Common Lisp or Scheme • Functional • emphasis on immutability • Supporting Concurrency • language-level coordination of state • Designed for the JVM • exposes and embraces platform
  • 3. Clojure is a Lisp • Dynamically typed, dynamically compiled • Interactive - REPL • Load/change code in running program • Code as data - Reader • Small core • Sequences • Syntactic abstraction - macros • Not Object-oriented
  • 4. Atomic Data Types • Arbitrary precision integers -12345678987654 • Doubles , BigDecimals 1.234 1.234M • Ratios -22/7 • Strings -“fred”, Characters -a b c • Symbols - fred ethel , Keywords - :fred :ethel • Booleans - true false , Null - nil • Regex patterns #“a*b”
  • 5. Data Structures • Lists - singly linked, grow at front • (1 2 3 4 5), (fred ethel lucy), (list 1 2 3) • Vectors - indexed access, grow at end • [1 2 3 4 5], [fred ethel lucy] • Maps - key/value associations • {:a 1, :b 2, :c 3}, {1 “ethel” 2 “fred”} • Sets #{fred ethel lucy} • Everything Nests
  • 6. Syntax • You’ve just seen it • Data structures are the code • Not text-based syntax • Syntax is in the interpretation of data structures • Things that would be declarations, control structures, function calls, operators, are all just lists with op at front • Everything is an expression
  • 7. # Norvig’s Spelling Corrector in Python # http://norvig.com/spell-correct.html def words(text): return re.findall('[a-z]+', text.lower()) def train(features): model = collections.defaultdict(lambda: 1) for f in features: model[f] += 1 return model NWORDS = train(words(file('big.txt').read())) alphabet = 'abcdefghijklmnopqrstuvwxyz' def edits1(word): n = len(word) return set([word[0:i]+word[i+1:] for i in range(n)] + [word[0:i]+word[i+1]+word[i]+word[i+2:] for i in range(n-1)] + [word[0:i]+c+word[i+1:] for i in range(n) for c in alphabet] + [word[0:i]+c+word[i:] for i in range(n+1) for c in alphabet]) def known_edits2(word): return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS) def known(words): return set(w for w in words if w in NWORDS) def correct(word): candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word] return max(candidates, key=lambda w: NWORDS[w])
  • 8. ; Norvig’s Spelling Corrector in Clojure ; http://en.wikibooks.org/wiki/Clojure_Programming#Examples (defn words [text] (re-seq #"[a-z]+" (.toLowerCase text))) (defn train [features] (reduce (fn [model f] (assoc model f (inc (get model f 1)))) {} features)) (def *nwords* (train (words (slurp "big.txt")))) (defn edits1 [word] (let [alphabet "abcdefghijklmnopqrstuvwxyz", n (count word)] (distinct (concat (for [i (range n)] (str (subs word 0 i) (subs word (inc i)))) (for [i (range (dec n))] (str (subs word 0 i) (nth word (inc i)) (nth word i) (subs word (+ 2 i)))) (for [i (range n) c alphabet] (str (subs word 0 i) c (subs word (inc i)))) (for [i (range (inc n)) c alphabet] (str (subs word 0 i) c (subs word i))))))) (defn known [words nwords] (for [w words :when (nwords w)] w)) (defn known-edits2 [word nwords] (for [e1 (edits1 word) e2 (edits1 e1) :when (nwords e2)] e2)) (defn correct [word nwords] (let [candidates (or (known [word] nwords) (known (edits1 word) nwords) (known-edits2 word nwords) [word])] (apply max-key #(get nwords % 1) candidates)))
  • 9. Java Interop Math/PI 3.141592653589793 (.. System getProperties (get "java.version")) "1.5.0_13" (new java.util.Date) Thu Jun 05 12:37:32 EDT 2008 (doto (JFrame.) (add (JLabel. "Hello World")) pack show) ;expands into: (let [x (JFrame.)] (do (. x (add (JLabel. "Hello World"))) (. x pack) (. x show)) x)
  • 10. Clojure is Functional • All data structures immutable • Core library functions have no side effects • Easier to reason about, test • Essential for concurrency • Functional by convention insufficient • let-bound locals are immutable • loop/recur functional looping construct • Higher-order functions
  • 11. Sequences (drop 2 [1 2 3 4 5]) -> (3 4 5) (take 9 (cycle [1 2 3 4])) -> (1 2 3 4 1 2 3 4 1) (interleave [:a :b :c :d :e] [1 2 3 4 5]) -> (:a 1 :b 2 :c 3 :d 4 :e 5) (partition 3 [1 2 3 4 5 6 7 8 9]) -> ((1 2 3) (4 5 6) (7 8 9)) (map vector [:a :b :c :d :e] [1 2 3 4 5]) -> ([:a 1] [:b 2] [:c 3] [:d 4] [:e 5]) (apply str (interpose , "asdf")) -> "a,s,d,f" (reduce + (range 100)) -> 4950
  • 12. Maps and Sets (def m {:a 1 :b 2 :c 3}) (m :b) -> 2 ;also (:b m) (keys m) -> (:a :b :c) (assoc m :d 4 :c 42) -> {:d 4, :a 1, :b 2, :c 42} (merge-with + m {:a 2 :b 3}) -> {:a 3, :b 5, :c 3} (union #{:a :b :c} #{:c :d :e}) -> #{:d :a :b :c :e} (join #{{:a 1 :b 2 :c 3} {:a 1 :b 21 :c 42}} #{{:a 1 :b 2 :e 5} {:a 1 :b 21 :d 4}}) -> #{{:d 4, :a 1, :b 21, :c 42} {:a 1, :b 2, :c 3, :e 5}}
  • 13. Persistent Data Structures • Immutable, + old version of the collection is still available after 'changes' • Collection maintains its performance guarantees • Therefore new versions are not full copies • Structural sharing - thread safe, iteration safe • All Clojure data structures are persistent • Hash map/set and vector based upon array mapped hash tries (Bagwell) • Practical - much faster than O(logN)
  • 15. Concurrency • Conventional way: • Direct references to mutable objects • Lock and worry (manual/convention) • Clojure way: • Indirect references to immutable persistent data structures (inspired by SML’s ref) • Concurrency semantics for references • Automatic/enforced • No locks in user code!
  • 16. Typical OO - Direct references to Mutable Objects foo :a ? :b ? :c 42 :d ? :e 6 • Unifies identity and value • Anything can change at any time • Consistency is a user problem
  • 17. Clojure - Indirect references to Immutable Objects foo :a "fred" :b "ethel" @foo :c 42 :d 17 :e 6 • Separates identity and value • Obtaining value requires explicit dereference • Values can never change • Never an inconsistent value
  • 18. Persistent ‘Edit’ foo :a "fred" :b "ethel" @foo :c 42 :d 17 :e 6 Structural sharing :a "lucy" :b "ethel" • :c 42 New value is function of old :d 17 • :e 6 Shares immutable structure • Doesn’t impede readers • Not impeded by readers
  • 19. Atomic Update foo :a "fred" :b "ethel" :c 42 :d 17 :e 6 @foo Structural sharing :a "lucy" :b "ethel" • Always coordinated :c 42 :d 17 • Multiple semantics :e 6 • Next dereference sees new value • Consumers of values unaffected
  • 20. Clojure References • The only things that mutate are references themselves, in a controlled way • 3 types of mutable references, with different semantics: • Refs - Share synchronous coordinated changes between threads • Agents - Share asynchronous autonomous changes between threads • Vars - Isolate changes within threads
  • 21. Refs and Transactions • Software transactional memory system (STM) • Refs can only be changed within a transaction • All changes are Atomic, Consistent and Isolated • Every change to Refs made within a transaction occurs or none do • No transaction sees the effects of any other transaction while it is running • Transactions are speculative • Will be retried automatically if conflict • User must avoid side-effects!
  • 22. The Clojure STM • Surround code with (dosync ...) • Uses Multiversion Concurrency Control (MVCC) • All reads of Refs will see a consistent snapshot of the 'Ref world' as of the starting point of the transaction, + any changes it has made. • All changes made to Refs during a transaction will appear to occur at a single point in the timeline. • Readers never impede writers/readers, writers never impede readers, supports commute
  • 23. Refs in action (def foo (ref {:a "fred" :b "ethel" :c 42 :d 17 :e 6})) @foo -> {:d 17, :a "fred", :b "ethel", :c 42, :e 6} (assoc @foo :a "lucy") -> {:d 17, :a "lucy", :b "ethel", :c 42, :e 6} @foo -> {:d 17, :a "fred", :b "ethel", :c 42, :e 6} (commute foo assoc :a "lucy") -> IllegalStateException: No transaction running (dosync (commute foo assoc :a "lucy")) @foo -> {:d 17, :a "lucy", :b "ethel", :c 42, :e 6}
  • 24. Agents • Manage independent state • State changes through actions, which are ordinary functions (state=>new-state) • Actions are dispatched using send or send-off, which return immediately • Actions occur asynchronously on thread-pool threads • Only one action per agent happens at a time
  • 25. Agents • Agent state always accessible, via deref/@, but may not reflect all actions • Can coordinate with actions using await • Any dispatches made during an action are held until after the state of the agent has changed • Agents coordinate with transactions - any dispatches made during a transaction are held until it commits • Agents are not Actors (Erlang/Scala)
  • 26. Agents in Action (def foo (agent {:a "fred" :b "ethel" :c 42 :d 17 :e 6})) @foo -> {:d 17, :a "fred", :b "ethel", :c 42, :e 6} (send foo assoc :a "lucy") @foo -> {:d 17, :a "fred", :b "ethel", :c 42, :e 6} (await foo) @foo -> {:d 17, :a "lucy", :b "ethel", :c 42, :e 6}
  • 27. Java Integration • Clojure strings are Java Strings, numbers are Numbers, collections implement Collection, fns implement Callable and Runnable etc. • Core abstractions, like seq, are Java interfaces • Clojure seq library works on Java Iterables, Strings and arrays. • Implement and extend Java interfaces and classes • Primitive arithmetic support equals Java’s speed.
  • 28. Implementation - Functions • Dynamically compiles to bytecode in memory • Uses ASM • No AOT compilation at present • Every function is new Class • Implements IFn interface • Set of invoke methods, overloaded on arity • All signatures take/return Objects • Variadics based on sequences
  • 29. Implementation - Calls • Function calls are straight Java method calls • No alternate type system, thunks etc • No special extra args • Calls to Java are either direct or via reflection • No wrappers, caches or dynamic thunks • Type hints + inference allow direct calls • Very few hints needed to avoid reflection • compiler flag can generate warnings
  • 30. Implementation - Primitives • Locals can be primitives, arrays of primitives • Math calls inlined to primitive-arg static methods • HotSpot finishes inlining to primitive math • Result is same speed as Java (defn foo [n] (defn foo2 [n] (loop [i 1] (let [n (int n)] (if (< i n) (loop [i (int 0)] (recur (inc i)) (if (< i n) i))) (recur (inc i)) i))))) (time (foo 100000)) "Elapsed time: 1.428 msecs" (time (foo2 100000)) 100000 "Elapsed time: 0.032 msecs" 100000
  • 31. Implementation - STM • Not a lock-free spinning optimistic design • Uses locks, wait/notify to avoid churn • Deadlock detection + barging • One timestamp CAS is only global resource • No read tracking • Coarse-grained orientation • Refs + persistent data structures • java.util.concurrent is still right tool for caches/queues
  • 32. Pain Points • No tail call optimization • Important for some functional idioms • Major point of criticism for choice of JVM from functional circles • Use Java’s boxed Numbers + own Ratio • Integer, Long, BigInteger etc • Slow generic math, numbers on heap • Would love tagged fixnums and/or standard high performance boxed math lib
  • 33. Conclusion • Very happy with the JVM • Good performance, facilities, tools, libraries • Clojure fills a niche • Dynamic + functional + JVM • Lots of interest in first 11 months: • 500+ user mailing list, 500+ messages/month • 10,000+ SVN reads/month • Active community
  • 34. Thanks for listening! http://clojure.org