Clojure for Rubyists

   For Montreal.rb on September 21st 2010
                 By Jeff Heon
Clojure in a nutshell



   ●Functional
   ●Concurrency

   ●JVM

   ●Lisp
Similarities

       Interactive development


Ruby      Clojure

irb       REPL (read eval loop print)
          java -cp clojure.jar clojure.main
Similarities

Ruby symbols are Clojure keywords.



Ruby             Clojure

:symbol          :keyword
Similarities

           In a conditional, nil and false evalute
           to false and everything else to true.

Ruby                              Clojure

if 0 then true end                (if 0 true)
=> true                           => true

if nil then true else false end   (if nil true false)
=> false                          => false
Similarities

             Last expression in a method is the
                       return value.

Ruby                                  Clojure

def convert_farenheit_to_celcius(f)   (defn convert-farenheit-to-celcius [f]
  (f - 32) * 5.0 / 9                    (* (- f 32)
end                                        (/ 5.0 0)))
Basic types

Ruby                                Clojure
letter_digit = /^[a-zA-Z][0-9]$/    (def letter-digit #"^[a-zA-Z][0-9]$")

[0, 'Ruby', 42]                     [0 "Ruby" 42]

my_array[0]                         (my-vector 0)
{ :r => 'Ruby', :c => 'Clojure' }   { :r "Ruby" :c "Clojure" }

#Accessing                          ;Accessing
my_hash[:r]                         (my-hash :c)
Functional

Ruby                               Clojure


def odd?(n) (n % 2) == 1 end       (defn odd? [n] (= 1 (mod n 2)))

#Sum of odd numbers from 0 to 99   ;Sum of odd numbers from 0 to 99
(0..99).                           (reduce
select { |n| odd? n }.                +
inject(0) { |acc, n| acc + n }        (filter odd? (range 100)))

=> 2500                            => 2500
Functional, but lazy

Ruby                              Clojure


def odd_trace?(n)                 (defn odd-trace? [n]
  puts n                            (print n)
  (n % 2) == 1                      (= 1 (mod n 2)))
end

#Sum of odd numbers from 0 to 9   ;Sum of odd numbers from 0 to 9

(0..99).                          (reduce +
select { |n| odd_trace? n }.        (take 10
first(10).                            (filter odd-trace? (range 100))))
inject(0) { |acc, n| acc + n }

=> prints 0 to 99, returns 100    => prints 0 to 31, returns 100
Immutable data structure


Data structure are always immutable.
Adding or removing an element to an array,
vector, hash or set will always return a new
collection.

But, they are efficient because they are persistant
(in the sense that they share structure.)
Concurrency


Software transactional memory
Or having multiple threads access the same
reference using transactions instead of locks.

STMs are not all the same (like GC)
Readers are never blocked.
Works hand in hand with persistant data structure.
Ref

           1




@A    A    2




@A         3
Where did my books go?
(def book1
 { :author "David Flanagan" :title "The Ruby Programming language" })

(def book2
 { :author "Gregory Brown" :title "Ruby Best Practices"})

(def home-books (ref #{book1 book2}))

(def lent-books (ref #{}))

(alter home-books disj book1) => No transaction running

(dosync
    (alter home-books disj book1)
    (alter lent-books conj book1))

@home-books => #{{:author "Gregory Brown", :title "Ruby Best Practices"}}

@lent-books => #{{:author "David Flanagan", :title "The Ruby Programming
language"}}
Further exploration
If nothing else: Are we there yet?

Main site: Clojure.org

News & getting started: Disclojure

Books (a comparison)
●Programming Clojure

●Clojure in Action

●The Joy of Clojure

●Practical Clojure

●And one upcoming from O'Reilly

Clojure for Rubyists

  • 1.
    Clojure for Rubyists For Montreal.rb on September 21st 2010 By Jeff Heon
  • 2.
    Clojure in anutshell ●Functional ●Concurrency ●JVM ●Lisp
  • 3.
    Similarities Interactive development Ruby Clojure irb REPL (read eval loop print) java -cp clojure.jar clojure.main
  • 4.
    Similarities Ruby symbols areClojure keywords. Ruby Clojure :symbol :keyword
  • 5.
    Similarities In a conditional, nil and false evalute to false and everything else to true. Ruby Clojure if 0 then true end (if 0 true) => true => true if nil then true else false end (if nil true false) => false => false
  • 6.
    Similarities Last expression in a method is the return value. Ruby Clojure def convert_farenheit_to_celcius(f) (defn convert-farenheit-to-celcius [f] (f - 32) * 5.0 / 9 (* (- f 32) end (/ 5.0 0)))
  • 7.
    Basic types Ruby Clojure letter_digit = /^[a-zA-Z][0-9]$/ (def letter-digit #"^[a-zA-Z][0-9]$") [0, 'Ruby', 42] [0 "Ruby" 42] my_array[0] (my-vector 0) { :r => 'Ruby', :c => 'Clojure' } { :r "Ruby" :c "Clojure" } #Accessing ;Accessing my_hash[:r] (my-hash :c)
  • 8.
    Functional Ruby Clojure def odd?(n) (n % 2) == 1 end (defn odd? [n] (= 1 (mod n 2))) #Sum of odd numbers from 0 to 99 ;Sum of odd numbers from 0 to 99 (0..99). (reduce select { |n| odd? n }. + inject(0) { |acc, n| acc + n } (filter odd? (range 100))) => 2500 => 2500
  • 9.
    Functional, but lazy Ruby Clojure def odd_trace?(n) (defn odd-trace? [n] puts n (print n) (n % 2) == 1 (= 1 (mod n 2))) end #Sum of odd numbers from 0 to 9 ;Sum of odd numbers from 0 to 9 (0..99). (reduce + select { |n| odd_trace? n }. (take 10 first(10). (filter odd-trace? (range 100)))) inject(0) { |acc, n| acc + n } => prints 0 to 99, returns 100 => prints 0 to 31, returns 100
  • 10.
    Immutable data structure Datastructure are always immutable. Adding or removing an element to an array, vector, hash or set will always return a new collection. But, they are efficient because they are persistant (in the sense that they share structure.)
  • 11.
    Concurrency Software transactional memory Orhaving multiple threads access the same reference using transactions instead of locks. STMs are not all the same (like GC) Readers are never blocked. Works hand in hand with persistant data structure.
  • 12.
    Ref 1 @A A 2 @A 3
  • 13.
    Where did mybooks go? (def book1 { :author "David Flanagan" :title "The Ruby Programming language" }) (def book2 { :author "Gregory Brown" :title "Ruby Best Practices"}) (def home-books (ref #{book1 book2})) (def lent-books (ref #{})) (alter home-books disj book1) => No transaction running (dosync (alter home-books disj book1) (alter lent-books conj book1)) @home-books => #{{:author "Gregory Brown", :title "Ruby Best Practices"}} @lent-books => #{{:author "David Flanagan", :title "The Ruby Programming language"}}
  • 14.
    Further exploration If nothingelse: Are we there yet? Main site: Clojure.org News & getting started: Disclojure Books (a comparison) ●Programming Clojure ●Clojure in Action ●The Joy of Clojure ●Practical Clojure ●And one upcoming from O'Reilly