Abhijeet Lele
Vladimir Zakharov
Goldman Sachs
21/04/2011
Goals




                 Our Guarantee:
        You won’t become knowledgeable,
           but you will become aware




                                          2
Java




       3
Interview With Josh Bloch

Can you give us an example of code that you are most
proud of creating and explain why?

The Collections framework. It's far from perfect, but it's
proven itself maintainable and pleasant over the years.
Doug Lea built many parts of java.util.concurrent atop it.
And I still get letters from programmers telling me how
much more pleasant it makes their jobs. It lets you write
stuff like this little program, which computes all the
anagrams in the file on standard input.

From “2008 JavaOne Conference - Rock Star Joshua Bloch”
http://java.sun.com/javaone/sf/2008/articles/rockstar_joshuabloch.jsp



                                                                        4
Anagram Algorithm: How It Works




                                  5
Java Example
import java.util.*;
public class Anagram {
  public static void main(String[] args)
  {
    int minGroupSize = Integer.parseInt(args[0]);
    // Read words from input and put into simulated multimap
    Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
    for (Scanner s = new Scanner(System.in); s.hasNext();) {
      String word = s.next();
      String alphagram = alphagram(word);
      List<String> group = anagrams.get(alphagram);
      if (group == null)
        anagrams.put(alphagram, group = new ArrayList<String>());
      group.add(word);
    }
    // Print all permutation groups above size threshold
    for (List<String> group : anagrams.values())
      if (group.size() >= minGroupSize)
        System.out.println(group.size() + ": " + group);
  }
  private static String alphagram(String s)
  {
    char[] chars = s.toCharArray();
    Arrays.sort(chars);
    return String.valueOf(chars);
  }
}                 From “2008 JavaOne Conference - Rock Star Joshua Bloch”
                 http://java.sun.com/javaone/sf/2008/articles/rockstar_joshuabloch.jsp   6
Java Example With Deluxe Features
import java.util.*;
public class Anagram {
  public static void main(String[] args) {
    int minGroupSize = Integer.parseInt(args[0]);
    Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
    for (Scanner s = new Scanner(System.in); s.hasNext();) {
      String word = s.next();
      String alphagram = alphagram(word);
      List<String> group = anagrams.get(alphagram);                                            Multimap
      if (group == null)
        anagrams.put(alphagram, group = new ArrayList<String>());
      group.add(word);
    }
    List<List<String>> winners = new ArrayList<List<String>>();
    for (List<String> group : anagrams.values())
      if (group.size() >= minGroupSize)                                                        Filter
        winners.add(group);
    Collections.sort(winners, new Comparator<List<String>>() {
      public int compare(List<String> o1, List<String> o2) {
        return o2.size()-o1.size();                                                            Sort
      }
    });
    for (List<String> winner: winners)
      System.out.println(winner.size() + ": " + winner);
  }
                                                                                               Print

    private static String alphagram(String s) {
      char[] chars = s.toCharArray();
      Arrays.sort(chars);                                                                      Alphagram
      return String.valueOf(chars);
    }
}                     Additional code from “The Java™ Tutorial > Collections”
                      http://download.oracle.com/javase/tutorial/collections/algorithms/index.html         7
Groovy




         8
What is Groovy?
• Definition
   – A lightweight, low-ceremony, dynamic, object-oriented language
   – Open sourced under Apache License, version 2.0
   – “marvelous, wonderful, excellent, hip, trendy.” (Merriam-
     Webster)
• Like Java
   –   Follows Java semantics
   –   Seamlessly integrates with Java
   –   Compiles into Java bytecode
   –   Extends the Java API and libraries
   –   Groovy scripts can be injected into Java
• Not like Java
   –   Dynamic Language
   –   Closures
   –   Properties
   –   Native syntax for lists, maps, and regular expressions
                                                                      9
Groovy: Alphagram
 Java
private static String alphagram(String s) {
  char[] chars = s.toCharArray();
  Arrays.sort(chars);
  return String.valueOf(chars);
}

 Groovy
String.metaClass.alphagram = {
  char[] chars = delegate.toCharArray()
  Arrays.sort(chars)
  return String.valueOf(chars)
}

 Groovy - er
String.metaClass.alphagram = {
  return delegate.toList().sort().join()
}
                                              10
Groovy: Building Multimap
 Java
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
for (Scanner s = new Scanner(System.in); s.hasNext();) {
  String word = s.next();
  String alphagram = alphagram(word);
  List<String> group = anagrams.get(alphagram);
  if (group == null)
    anagrams.put(alphagram, group = new ArrayList<String>());
  group.add(word);
}




 Groovy
anagrams = (new Scanner(System.in)).toList().groupBy {it.alphagram()}




                                                                        11
Groovy: Filtering, Sorting, Printing
 Java
List<List<String>> winners = new ArrayList<List<String>>();
for (List<String> group : anagrams.values())
  if (group.size() >= minGroupSize)
    winners.add(group);
Collections.sort(winners, new Comparator<List<String>>() {
  public int compare(List<String> o1, List<String> o2) {
    return o2.size()-o1.size();
  }
});
for (List<String> winner: winners)
  System.out.println(winner.size() + ": " + winner);

 Groovy
winners = anagrams.values().findAll { it.size > minWordCount }
winners = winners.sort { -it.size }
winners.each { println "${it.size} : $it" }

                                                                 12
Groovy: Putting It All Together
String.metaClass.alphagram = {
  return delegate.toList().sort().join()
}

minWordCount = args[0].toInteger();

(new Scanner(System.in)).toList()
  .groupBy { it.alphagram() }
  .values()
  .findAll { it.size > minWordCount }
  .sort { -it.size }
  .each { println "${it.size} : $it" }




                                           13
Java Reminder
import java.util.*;
public class Anagram {
  public static void main(String[] args) {
    int minGroupSize = Integer.parseInt(args[0]);
    Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
    for (Scanner s = new Scanner(System.in); s.hasNext();) {
      String word = s.next();
      String alphagram = alphagram(word);
      List<String> group = anagrams.get(alphagram);
      if (group == null)
        anagrams.put(alphagram, group = new ArrayList<String>());
      group.add(word);
    }
    List<List<String>> winners = new ArrayList<List<String>>();
    for (List<String> group : anagrams.values())
      if (group.size() >= minGroupSize)
        winners.add(group);
    Collections.sort(winners, new Comparator<List<String>>() {
      public int compare(List<String> o1, List<String> o2) {        String.metaClass.alphagram = {
        return o2.size()-o1.size();                                   return delegate.toList().sort().join()
      }                                                             }
    });
    for (List<String> winner: winners)                              minWordCount = args[0].toInteger();
      System.out.println(winner.size() + ": " + winner);
  }                                                                 (new Scanner(System.in)).toList()
                                                                      .groupBy { it.alphagram() }
  private static String alphagram(String s) {                         .values()
    char[] chars = s.toCharArray();                                   .findAll { it.size > minWordCount }
    Arrays.sort(chars);                                               .sort { -it.size }
    return String.valueOf(chars);                                     .each { println "${it.size} : $it" }
  }
}

                                                                                                       14
Scala




        15
What is Scala?
• Like Java
   – Bytecode looks very similar to javac output
   – Familiar object-oriented concepts
   – Static types, only better (better type inference, better generics,
     implicit parameters)
   – Performance equivalent to Java
   – Java code can depend on Scala code
• Not like Java
   –   Functional principles
   –   Closures
   –   Everything is an object
   –   No such thing as static
   –   Greatly improved type inference and generics
   –   Traits (mixins)
   –   Pattern Matching

                                                                          16
Scala: Alphagram
 Java
private static String alphagram(String s) {
  char[] chars = s.toCharArray();
  Arrays.sort(chars);
  return String.valueOf(chars);
}


 Scala

word => word.sorted

 Scala With Underbar

_.sorted



                                              17
Scala: Building Multimap
 Java
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
for (Scanner s = new Scanner(System.in); s.hasNext();) {
  String word = s.next();
  String alphagram = alphagram(word);
  List<String> group = anagrams.get(alphagram);
  if (group == null)
    anagrams.put(alphagram, group = new ArrayList<String>());
  group.add(word);
}


 Scala

val map =
  new BufferedReader(new InputStreamReader(System.in))
  .readLine().split(" ").groupBy( _.sorted)



                                                                      18
Scala: Filtering And Sorting
 Java
List<List<String>> winners = new ArrayList<List<String>>();
for (List<String> group : anagrams.values())
  if (group.size() >= minGroupSize)
    winners.add(group);
Collections.sort(winners, new Comparator<List<String>>() {
  public int compare(List<String> o1, List<String> o2) {
    return o2.size()-o1.size();
  }
});


 Scala

val winners = map.values.filter(_.size > Integer.parseInt(args(0))).toList
val sorted = winners.sortBy(-_.size)




                                                                      19
Scala: Printing
 Java
for (List<String> winner: winners)
  System.out.println(winner.size() + ": " + winner);




 Scala

for (winner <- sorted.view)
  println(winner.size + ": " + winner)


 Scala – Another Way

sorted.view.map(list => list.size + ": " + list).foreach(println)




                                                                    20
Scala: Putting It Together
new BufferedReader(new InputStreamReader(System.in))
  .readLine()
  .split(" ")
  .groupBy(_.sorted)
  .values
  .filter(_.length > Integer.parseInt(args(0)))
  .toList
  .sortBy( - _.size )
  .elements
  .foreach(winner => println(winner.size + ": " + winner.toList))




                                                             21
Java Reminder
import java.util.*;
public class Anagram {
  public static void main(String[] args) {
    int minGroupSize = Integer.parseInt(args[0]);
    Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
    for (Scanner s = new Scanner(System.in); s.hasNext();) {
      String word = s.next();
      String alphagram = alphagram(word);
      List<String> group = anagrams.get(alphagram);
      if (group == null)
        anagrams.put(alphagram, group = new ArrayList<String>());
      group.add(word);
    }
    List<List<String>> winners = new ArrayList<List<String>>();
    for (List<String> group : anagrams.values())
      if (group.size() >= minGroupSize)
        winners.add(group);
    Collections.sort(winners, new Comparator<List<String>>() {
      public int compare(List<String> o1, List<String> o2) {
        return o2.size()-o1.size();
      }                                               new BufferedReader(new InputStreamReader(System.in))
    });                                                  .readLine()
    for (List<String> winner: winners)                   .split(" ")
      System.out.println(winner.size() + ": " + winner); .groupBy(_.sorted)
  }                                                      .values
                                                         .filter(_.length > Integer.parseInt(args(0)))
  private static String alphagram(String s) {            .toList
    char[] chars = s.toCharArray();                      .sortBy( - _.size)
    Arrays.sort(chars);                                  .elements
    return String.valueOf(chars);                        .foreach(
  }                                                       winner => println(winner.size+": "+ winner.toList))
}

                                                                                                       22
Jython




         23
What is Jython?

• Like Java
   – Have access to Java standard libraries and third party libraries
• Not like Java
   – Language is Python; latest release conforms to Python 2.5
   – Dynamically typed
   – Choice of using procedural, object oriented, or functional
     programming constructs, or a mixture of the three
   – Have access to the Python standard libraries and any pure
     Python third party library
• Not like Python
   – No access to compiled Python libraries
   – Some library features are not available (like fork) due to the
     restrictions of the JVM


                                                                        24
Jython: Alphagram
 Java

private static String alphagram(String s) {
  char[] chars = s.toCharArray();
  Arrays.sort(chars);
  return String.valueOf(chars);
}


 Jython
alpha = lambda l : ''.join(sorted(l))




                                              25
Jython: Building Multimap
 Java

Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
for (Scanner s = new Scanner(System.in); s.hasNext();) {
  String word = s.next();
  String alphagram = alphagram(word);
  List<String> group = anagrams.get(alphagram);
  if (group == null)
    anagrams.put(alphagram, group = new ArrayList<String>());
  group.add(word);
}


 Jython

anagrams = [list(g) for k, g in
 itertools.groupby(
   sorted(sys.stdin.readline().split(), key =alpha),
   alpha)]



                                                                      26
Jython: Filtering
 Java
List<List<String>> winners = new ArrayList<List<String>>();
for (List<String> group : anagrams.values())
  if (group.size() >= minGroupSize)
    winners.add(group);




 Jython

winners = (f for f in anagrams if len(f) > int(sys.argv[1]))


                            List comprehension:
          <output> for <variables> in <collection> if <filter>
             {<output>|<variables>       <collection>, <filter>}
                                     э


                                                                   27
Jython: Sorting
 Java
Collections.sort(winners, new Comparator<List<String>>() {
  public int compare(List<String> o1, List<String> o2) {
    return o2.size()-o1.size();
  }
});




 Jython

winners = sorted(winners, key = lambda t: -len(t))




                                                             28
Jython: Printing
 Java
for (List<String> winner: winners)
  System.out.println(winner.size() + ": " + winner);




 Jython

for winner in winners:
   print '%i: %s '%(len(winner), winner)




                                                       29
Jython: Complete Example
import itertools
alpha = lambda l : ''.join(sorted(l))

winners = [
  f for f in
    sorted (
      [list(g) for k, g in
        itertools.groupby(
          sorted(sys.stdin.readline().split(), key = alpha),
          alpha)],
      key = lambda t: -len(t) )
  if(len(f) > int(sys.argv[1]))]

for winner in winners:
   print '%i: %s '%(len(winner), winner)


                                                               30
Java Reminder
import java.util.*;
public class Anagram {
  public static void main(String[] args) {
    int minGroupSize = Integer.parseInt(args[0]);
    Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
    for (Scanner s = new Scanner(System.in); s.hasNext();) {
      String word = s.next();
      String alphagram = alphagram(word);
      List<String> group = anagrams.get(alphagram);
      if (group == null)
        anagrams.put(alphagram, group = new ArrayList<String>());
      group.add(word);
    }
    List<List<String>> winners = new ArrayList<List<String>>();
    for (List<String> group : anagrams.values())
      if (group.size() >= minGroupSize)                import itertools
        winners.add(group);                            alpha = lambda l : ''.join(sorted(l))
    Collections.sort(winners, new Comparator<List<String>>() {
      public int compare(List<String> o1, List<String> o2) {
                                                       winners = [
        return o2.size()-o1.size();                      f for f in
      }                                                    sorted (
    });                                                      [list(g) for k, g in
    for (List<String> winner: winners)                          itertools.groupby(
      System.out.println(winner.size() + ": " + winner);          sorted(
  }                                                                 sys.stdin.readline().split(),   key=alpha),
                                                                  alpha)],
  private static String alphagram(String s) {                key = lambda t: -len(t) )
    char[] chars = s.toCharArray();                      if(len(f) > int(sys.argv[1]))]
    Arrays.sort(chars);
    return String.valueOf(chars);                      for winner in winners:
  }                                                                 print '%i: %s '%(len(winner),   winner)
}

                                                                                                          31
Jython: A “Simple” Example
import java.util.*;
def sort_string(buf):
     l class Anagram {
public = list(buf)
  public static void main(String[] args) {
     l.sort()
    int minGroupSize = Integer.parseInt(args[0]);
     return ''.join(l)
    Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
    for (Scanner s = new Scanner(System.in); s.hasNext();) {
def get_words():
      String word = s.next();
     fp = open('dictionary', 'r')
      String alphagram = alphagram(word);
     words = [ l.strip() for l in fp.readlines() ]
      List<String> group = anagrams.get(alphagram);
     words.sort() null)
      if (group ==
     return words
        anagrams.put(alphagram, group = new ArrayList<String>());
      group.add(word);
def }
    get_lists_of_size(list_lists, min_size):
    List<List<String>> winners = new ArrayList<List<String>>();
     return [ l for l in list_lists if len(l) >= min_size ]
    for (List<String> group : anagrams.values())
      if (group.size() >= minGroupSize)
def main():
        winners.add(group);
     all_anagrams = {}
    Collections.sort(winners, new Comparator<List<String>>() {
     for word int get_words():
      public in compare(List<String> o1, List<String> o2) {
            key = sort_string(word)
        return o2.size()-o1.size();    a
                                    av
            if all_anagrams.has_key(key):
                                 e J ge!
      }

                              rit a
    });                  all_anagrams[key].append(word)
            else:
    for (List<String> winner: winners)
                             w u
                          an lang
      System.out.println(winner.size() + ": " + winner);
                         all_anagrams[key] = [word]
  }
                      u c ny
                    Yo alphagram(String s)8){
      list_lists = all_anagrams.values()
    private static String a
                       in
      winners = get_lists_of_size(anagrams,
      char[] chars = s.toCharArray();
      winners.sort(cmp=lambda x,y: cmp(-len(x), -len(y)))
      Arrays.sort(chars);
      for winner in winners:
      return String.valueOf(chars);
    }         print "%d : %s" % (len(winner), winner)
}

                                                                                32
Clojure




          33
What is Clojure?
• Like Java
   – Not much, really
   – Data structures implement the read-only portion of Collection
   – Functions implement Runnable & Callable
• Not like Java
   –   Dynamic, functional language
   –   Not object-oriented (!)
   –   Persistent, immutable data structures
   –   Lazy sequence abstraction
   –   Software transactional memory
   –   Multimethods and ad-hoc hierarchies
   –   Macros
• Compared to Common Lisp/Scheme
   –   Persistent, immutable data structures
   –   First-class Vectors, Sets, and Maps
   –   Focus on concurrency
   –   No tail call optimization; explicit calls to recur and trampoline required



                                                                                    34
Clojure: Alphagram
 Java

private static String alphagram(String s) {
  char[] chars = s.toCharArray();
  Arrays.sort(chars);
  return String.valueOf(chars);
}


 Clojure

(defn alphagram [word] (apply str (sort word)))

 Clojure anonymous function

(fn [word] (apply str (sort word)))

 Clojure with placeholder syntax

#(apply str (sort %))
                                                  35
Clojure: Multimap
 Java
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
for (Scanner s = new Scanner(System.in); s.hasNext();) {
  String word = s.next();
  String alphagram = alphagram(word);
  List<String> group = anagrams.get(alphagram);
  if (group == null)
    anagrams.put(alphagram, group = new ArrayList<String>());
  group.add(word);
}


 Clojure

(group-by alphagram (iterator-seq (java.util.Scanner. System/in)))

 Clojure with placeholder syntax

(group-by #(apply str (sort %))
  (iterator-seq (java.util.Scanner. System/in)))
                                                                      36
Clojure: Filtering And Sorting
 Java
List<List<String>> winners = new ArrayList<List<String>>();
  for (List<String> group : anagrams.values())
    if (group.size() >= minGroupSize)
      winners.add(group);
Collections.sort(winners, new Comparator<List<String>>() {
  public int compare(List<String> o1, List<String> o2) {
    return o2.size()-o1.size();
  }
});

 Clojure
(def words-in (iterator-seq (java.util.Scanner. System/in)))
(defn select-anagrams [words]
  (sort-by #(- (count %))
    (filter #(> (count %) min-group-size)
      (vals
        (group-by alphagram words)))))
                                                               37
Clojure: Printing
 Java

for (List<String> winner: winners)
  System.out.println(winner.size() + ": " + winner);
}




 Clojure

(doseq [winner (select-anagrams words-in)]
  (println (count winner) ": " winner))




                                                       38
Clojure: Complete Example
 Keeping it functional

(defn alphagram [word] (apply str (sort word)))
(def min-group-size (Integer/valueOf (first *command-line-args*)))
(def words-in (iterator-seq (java.util.Scanner. System/in)))
(defn select-anagrams [words]
  (sort-by #(- (count %))
    (filter #(> (count %) min-group-size)
      (vals
        (group-by alphagram words)))))

(doseq [winner (select-anagrams words-in)]
  (println (count winner) ":" winner))
 Let there be bindings!

(let [alphagram #(apply str (sort %))
      map (group-by alphagram words-in)
      filtered (filter #(> (count %) min-group-size) (vals map))
      winners (sort-by #(- (count %)) filtered)]
  (doseq [winner winners] (println (count winner) ": " winner)))
                                                                     39
Java Reminder
import java.util.*;
public class Anagram {
  public static void main(String[] args) {
    int minGroupSize = Integer.parseInt(args[0]);
    Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
    for (Scanner s = new Scanner(System.in); s.hasNext();) {
      String word = s.next();
      String alphagram = alphagram(word);
      List<String> group = anagrams.get(alphagram);
      if (group == null)
        anagrams.put(alphagram, group = new ArrayList<String>());
      group.add(word);
    }
    List<List<String>> winners = new ArrayList<List<String>>();
    for (List<String> group : anagrams.values())
      if (group.size() >= minGroupSize)
        winners.add(group);
    Collections.sort(winners, new Comparator<List<String>>() {
      public int compare(List<String> o1, List<String> o2) {
        return o2.size()-o1.size();                        (defn alphagram [word] (apply str (sort word)))
      }                                                    (def min-group-size
    });                                                      (Integer/valueOf (first *command-line-args*)))
    for (List<String> winner: winners)                     (def words-in
      System.out.println(winner.size() + ": " + winner);     (iterator-seq (java.util.Scanner. System/in)))
  }                                                        (defn select-anagrams [words]
                                                             (sort-by #(- (count %))
  private static String alphagram(String s) {                   (filter #(> (count %) min-group-size)
    char[] chars = s.toCharArray();                               (vals
    Arrays.sort(chars);                                             (group-by alphagram words)))))
    return String.valueOf(chars);
  }                                                        (doseq [winner (select-anagrams words-in)]
}                                                            (println (count winner) ":" winner))

                                                                                                       40
JRuby




        41
What is JRuby?
• Like Java
   – Have access to Java standard libraries and third party
     libraries
   – Runs in a JVM
• Not like Java
   –   Language is Ruby; latest release conforms to Ruby 1.8.7
   –   Dynamically typed
   –   Can compile to class files
   –   Have access to the Ruby standard libraries and any pure
       Ruby third party library
• Not like Ruby
   – No access to Ruby native-C API
   – No access to Ruby continuations


                                                                 42
JRuby Example: Alphagram
 Java
private static String alphagram(String s) {
  char[] chars = s.toCharArray();
  Arrays.sort(chars);
  return String.valueOf(chars);
}


 JRuby
word.chars.sort.join




                                              43
JRuby: Multimap
 Java
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
for (Scanner s = new Scanner(System.in); s.hasNext();) {
  String word = s.next();
  String alphagram = alphagram(word);
  List<String> group = anagrams.get(alphagram);
  if (group == null)
    anagrams.put(alphagram, group = new ArrayList<String>());
  group.add(word);
}


 JRuby
anagrams = words.group_by { |word| word.chars.sort.join }




                                                                      44
JRuby: Filtering, Sorting, Printing
 Java
List<List<String>> winners = new ArrayList<List<String>>();
for (List<String> group : anagrams.values())
  if (group.size() >= minGroupSize)
    winners.add(group);
Collections.sort(winners, new Comparator<List<String>>() {
  public int compare(List<String> o1, List<String> o2) {
    return o2.size()-o1.size();
  }
});
for (List<String> winner: winners)
  System.out.println(winner.size() + ": " + winner);


 JRuby

filtered = anagrams.values.select {|array| array.length > 4 } winners =
filtered.sort_by { |array| array.length }
winners.each {|each| puts “#{each.size} : #{each.join(‘, ‘)}"}



                                                                      45
JRuby: Complete Example

anagrams = words.group_by {|word| word.chars.sort.join}
filtered = anagrams.values.select {|array| array.length > 4}
winners = filtered.sort_by { |array| array.length }
winners.each {|each| puts “#{each.size} : #{each.join(‘, ‘)}"}




                                                                 46
JRuby: Complete Example – Let’s Make It Better
class String
  def collation
    self.chars.sort.join
  end
end

class Symbol
  def to_proc
    proc { |*args| args[0].send(self, *args[1...args.size]) }
  end
end

module Enumerable

 def partitioned_with(&transformer)
   group_by(&transformer).values
 end

 def longer_than(size)
   self.select {|e| e.length > size}
 end

 def sorted_by_size
   self.sort_by(&:length)
 end

end
                                                                47
JRuby: Better Complete Example

groups = words.partitioned_with(&:collation)
winners = groups.longer_than(4).sorted_by_size
winners.each{|each| puts "#{each.size}: #{each.join(', ')}"}




                                                               48
Takeaways
• JVM provides a robust, industrial strength, scalable
  platform
• You can take advantage of JVM and the rest of the
  Java ecosystem without the complexity of Java the
  language
• Don’t have to wait for Java to adopt the features
  already available in other languages: closures, dynamic
  capabilities, rich, humane interfaces
• Not all languages are enterprise ready
   – These languages are still worth looking into
• Pragmatic Programmer advice:
  Learn a new language every year. When you learn a
  new language, you learn a new way to think.


                                                        49
The End




          50

Alternate JVM Languages

  • 1.
  • 2.
    Goals Our Guarantee: You won’t become knowledgeable, but you will become aware 2
  • 3.
  • 4.
    Interview With JoshBloch Can you give us an example of code that you are most proud of creating and explain why? The Collections framework. It's far from perfect, but it's proven itself maintainable and pleasant over the years. Doug Lea built many parts of java.util.concurrent atop it. And I still get letters from programmers telling me how much more pleasant it makes their jobs. It lets you write stuff like this little program, which computes all the anagrams in the file on standard input. From “2008 JavaOne Conference - Rock Star Joshua Bloch” http://java.sun.com/javaone/sf/2008/articles/rockstar_joshuabloch.jsp 4
  • 5.
  • 6.
    Java Example import java.util.*; publicclass Anagram { public static void main(String[] args) { int minGroupSize = Integer.parseInt(args[0]); // Read words from input and put into simulated multimap Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } // Print all permutation groups above size threshold for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) System.out.println(group.size() + ": " + group); } private static String alphagram(String s) { char[] chars = s.toCharArray(); Arrays.sort(chars); return String.valueOf(chars); } } From “2008 JavaOne Conference - Rock Star Joshua Bloch” http://java.sun.com/javaone/sf/2008/articles/rockstar_joshuabloch.jsp 6
  • 7.
    Java Example WithDeluxe Features import java.util.*; public class Anagram { public static void main(String[] args) { int minGroupSize = Integer.parseInt(args[0]); Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); Multimap if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } List<List<String>> winners = new ArrayList<List<String>>(); for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) Filter winners.add(group); Collections.sort(winners, new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { return o2.size()-o1.size(); Sort } }); for (List<String> winner: winners) System.out.println(winner.size() + ": " + winner); } Print private static String alphagram(String s) { char[] chars = s.toCharArray(); Arrays.sort(chars); Alphagram return String.valueOf(chars); } } Additional code from “The Java™ Tutorial > Collections” http://download.oracle.com/javase/tutorial/collections/algorithms/index.html 7
  • 8.
  • 9.
    What is Groovy? •Definition – A lightweight, low-ceremony, dynamic, object-oriented language – Open sourced under Apache License, version 2.0 – “marvelous, wonderful, excellent, hip, trendy.” (Merriam- Webster) • Like Java – Follows Java semantics – Seamlessly integrates with Java – Compiles into Java bytecode – Extends the Java API and libraries – Groovy scripts can be injected into Java • Not like Java – Dynamic Language – Closures – Properties – Native syntax for lists, maps, and regular expressions 9
  • 10.
    Groovy: Alphagram Java privatestatic String alphagram(String s) { char[] chars = s.toCharArray(); Arrays.sort(chars); return String.valueOf(chars); } Groovy String.metaClass.alphagram = { char[] chars = delegate.toCharArray() Arrays.sort(chars) return String.valueOf(chars) } Groovy - er String.metaClass.alphagram = { return delegate.toList().sort().join() } 10
  • 11.
    Groovy: Building Multimap Java Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } Groovy anagrams = (new Scanner(System.in)).toList().groupBy {it.alphagram()} 11
  • 12.
    Groovy: Filtering, Sorting,Printing Java List<List<String>> winners = new ArrayList<List<String>>(); for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) winners.add(group); Collections.sort(winners, new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { return o2.size()-o1.size(); } }); for (List<String> winner: winners) System.out.println(winner.size() + ": " + winner); Groovy winners = anagrams.values().findAll { it.size > minWordCount } winners = winners.sort { -it.size } winners.each { println "${it.size} : $it" } 12
  • 13.
    Groovy: Putting ItAll Together String.metaClass.alphagram = { return delegate.toList().sort().join() } minWordCount = args[0].toInteger(); (new Scanner(System.in)).toList() .groupBy { it.alphagram() } .values() .findAll { it.size > minWordCount } .sort { -it.size } .each { println "${it.size} : $it" } 13
  • 14.
    Java Reminder import java.util.*; publicclass Anagram { public static void main(String[] args) { int minGroupSize = Integer.parseInt(args[0]); Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } List<List<String>> winners = new ArrayList<List<String>>(); for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) winners.add(group); Collections.sort(winners, new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { String.metaClass.alphagram = { return o2.size()-o1.size(); return delegate.toList().sort().join() } } }); for (List<String> winner: winners) minWordCount = args[0].toInteger(); System.out.println(winner.size() + ": " + winner); } (new Scanner(System.in)).toList() .groupBy { it.alphagram() } private static String alphagram(String s) { .values() char[] chars = s.toCharArray(); .findAll { it.size > minWordCount } Arrays.sort(chars); .sort { -it.size } return String.valueOf(chars); .each { println "${it.size} : $it" } } } 14
  • 15.
  • 16.
    What is Scala? •Like Java – Bytecode looks very similar to javac output – Familiar object-oriented concepts – Static types, only better (better type inference, better generics, implicit parameters) – Performance equivalent to Java – Java code can depend on Scala code • Not like Java – Functional principles – Closures – Everything is an object – No such thing as static – Greatly improved type inference and generics – Traits (mixins) – Pattern Matching 16
  • 17.
    Scala: Alphagram Java privatestatic String alphagram(String s) { char[] chars = s.toCharArray(); Arrays.sort(chars); return String.valueOf(chars); } Scala word => word.sorted Scala With Underbar _.sorted 17
  • 18.
    Scala: Building Multimap Java Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } Scala val map = new BufferedReader(new InputStreamReader(System.in)) .readLine().split(" ").groupBy( _.sorted) 18
  • 19.
    Scala: Filtering AndSorting Java List<List<String>> winners = new ArrayList<List<String>>(); for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) winners.add(group); Collections.sort(winners, new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { return o2.size()-o1.size(); } }); Scala val winners = map.values.filter(_.size > Integer.parseInt(args(0))).toList val sorted = winners.sortBy(-_.size) 19
  • 20.
    Scala: Printing Java for(List<String> winner: winners) System.out.println(winner.size() + ": " + winner); Scala for (winner <- sorted.view) println(winner.size + ": " + winner) Scala – Another Way sorted.view.map(list => list.size + ": " + list).foreach(println) 20
  • 21.
    Scala: Putting ItTogether new BufferedReader(new InputStreamReader(System.in)) .readLine() .split(" ") .groupBy(_.sorted) .values .filter(_.length > Integer.parseInt(args(0))) .toList .sortBy( - _.size ) .elements .foreach(winner => println(winner.size + ": " + winner.toList)) 21
  • 22.
    Java Reminder import java.util.*; publicclass Anagram { public static void main(String[] args) { int minGroupSize = Integer.parseInt(args[0]); Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } List<List<String>> winners = new ArrayList<List<String>>(); for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) winners.add(group); Collections.sort(winners, new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { return o2.size()-o1.size(); } new BufferedReader(new InputStreamReader(System.in)) }); .readLine() for (List<String> winner: winners) .split(" ") System.out.println(winner.size() + ": " + winner); .groupBy(_.sorted) } .values .filter(_.length > Integer.parseInt(args(0))) private static String alphagram(String s) { .toList char[] chars = s.toCharArray(); .sortBy( - _.size) Arrays.sort(chars); .elements return String.valueOf(chars); .foreach( } winner => println(winner.size+": "+ winner.toList)) } 22
  • 23.
  • 24.
    What is Jython? •Like Java – Have access to Java standard libraries and third party libraries • Not like Java – Language is Python; latest release conforms to Python 2.5 – Dynamically typed – Choice of using procedural, object oriented, or functional programming constructs, or a mixture of the three – Have access to the Python standard libraries and any pure Python third party library • Not like Python – No access to compiled Python libraries – Some library features are not available (like fork) due to the restrictions of the JVM 24
  • 25.
    Jython: Alphagram Java privatestatic String alphagram(String s) { char[] chars = s.toCharArray(); Arrays.sort(chars); return String.valueOf(chars); } Jython alpha = lambda l : ''.join(sorted(l)) 25
  • 26.
    Jython: Building Multimap Java Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } Jython anagrams = [list(g) for k, g in itertools.groupby( sorted(sys.stdin.readline().split(), key =alpha), alpha)] 26
  • 27.
    Jython: Filtering Java List<List<String>>winners = new ArrayList<List<String>>(); for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) winners.add(group); Jython winners = (f for f in anagrams if len(f) > int(sys.argv[1])) List comprehension: <output> for <variables> in <collection> if <filter> {<output>|<variables> <collection>, <filter>} э 27
  • 28.
    Jython: Sorting Java Collections.sort(winners,new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { return o2.size()-o1.size(); } }); Jython winners = sorted(winners, key = lambda t: -len(t)) 28
  • 29.
    Jython: Printing Java for(List<String> winner: winners) System.out.println(winner.size() + ": " + winner); Jython for winner in winners: print '%i: %s '%(len(winner), winner) 29
  • 30.
    Jython: Complete Example importitertools alpha = lambda l : ''.join(sorted(l)) winners = [ f for f in sorted ( [list(g) for k, g in itertools.groupby( sorted(sys.stdin.readline().split(), key = alpha), alpha)], key = lambda t: -len(t) ) if(len(f) > int(sys.argv[1]))] for winner in winners: print '%i: %s '%(len(winner), winner) 30
  • 31.
    Java Reminder import java.util.*; publicclass Anagram { public static void main(String[] args) { int minGroupSize = Integer.parseInt(args[0]); Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } List<List<String>> winners = new ArrayList<List<String>>(); for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) import itertools winners.add(group); alpha = lambda l : ''.join(sorted(l)) Collections.sort(winners, new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { winners = [ return o2.size()-o1.size(); f for f in } sorted ( }); [list(g) for k, g in for (List<String> winner: winners) itertools.groupby( System.out.println(winner.size() + ": " + winner); sorted( } sys.stdin.readline().split(), key=alpha), alpha)], private static String alphagram(String s) { key = lambda t: -len(t) ) char[] chars = s.toCharArray(); if(len(f) > int(sys.argv[1]))] Arrays.sort(chars); return String.valueOf(chars); for winner in winners: } print '%i: %s '%(len(winner), winner) } 31
  • 32.
    Jython: A “Simple”Example import java.util.*; def sort_string(buf): l class Anagram { public = list(buf) public static void main(String[] args) { l.sort() int minGroupSize = Integer.parseInt(args[0]); return ''.join(l) Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { def get_words(): String word = s.next(); fp = open('dictionary', 'r') String alphagram = alphagram(word); words = [ l.strip() for l in fp.readlines() ] List<String> group = anagrams.get(alphagram); words.sort() null) if (group == return words anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); def } get_lists_of_size(list_lists, min_size): List<List<String>> winners = new ArrayList<List<String>>(); return [ l for l in list_lists if len(l) >= min_size ] for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) def main(): winners.add(group); all_anagrams = {} Collections.sort(winners, new Comparator<List<String>>() { for word int get_words(): public in compare(List<String> o1, List<String> o2) { key = sort_string(word) return o2.size()-o1.size(); a av if all_anagrams.has_key(key): e J ge! } rit a }); all_anagrams[key].append(word) else: for (List<String> winner: winners) w u an lang System.out.println(winner.size() + ": " + winner); all_anagrams[key] = [word] } u c ny Yo alphagram(String s)8){ list_lists = all_anagrams.values() private static String a in winners = get_lists_of_size(anagrams, char[] chars = s.toCharArray(); winners.sort(cmp=lambda x,y: cmp(-len(x), -len(y))) Arrays.sort(chars); for winner in winners: return String.valueOf(chars); } print "%d : %s" % (len(winner), winner) } 32
  • 33.
  • 34.
    What is Clojure? •Like Java – Not much, really – Data structures implement the read-only portion of Collection – Functions implement Runnable & Callable • Not like Java – Dynamic, functional language – Not object-oriented (!) – Persistent, immutable data structures – Lazy sequence abstraction – Software transactional memory – Multimethods and ad-hoc hierarchies – Macros • Compared to Common Lisp/Scheme – Persistent, immutable data structures – First-class Vectors, Sets, and Maps – Focus on concurrency – No tail call optimization; explicit calls to recur and trampoline required 34
  • 35.
    Clojure: Alphagram Java privatestatic String alphagram(String s) { char[] chars = s.toCharArray(); Arrays.sort(chars); return String.valueOf(chars); } Clojure (defn alphagram [word] (apply str (sort word))) Clojure anonymous function (fn [word] (apply str (sort word))) Clojure with placeholder syntax #(apply str (sort %)) 35
  • 36.
    Clojure: Multimap Java Map<String,List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } Clojure (group-by alphagram (iterator-seq (java.util.Scanner. System/in))) Clojure with placeholder syntax (group-by #(apply str (sort %)) (iterator-seq (java.util.Scanner. System/in))) 36
  • 37.
    Clojure: Filtering AndSorting Java List<List<String>> winners = new ArrayList<List<String>>(); for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) winners.add(group); Collections.sort(winners, new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { return o2.size()-o1.size(); } }); Clojure (def words-in (iterator-seq (java.util.Scanner. System/in))) (defn select-anagrams [words] (sort-by #(- (count %)) (filter #(> (count %) min-group-size) (vals (group-by alphagram words))))) 37
  • 38.
    Clojure: Printing Java for(List<String> winner: winners) System.out.println(winner.size() + ": " + winner); } Clojure (doseq [winner (select-anagrams words-in)] (println (count winner) ": " winner)) 38
  • 39.
    Clojure: Complete Example Keeping it functional (defn alphagram [word] (apply str (sort word))) (def min-group-size (Integer/valueOf (first *command-line-args*))) (def words-in (iterator-seq (java.util.Scanner. System/in))) (defn select-anagrams [words] (sort-by #(- (count %)) (filter #(> (count %) min-group-size) (vals (group-by alphagram words))))) (doseq [winner (select-anagrams words-in)] (println (count winner) ":" winner)) Let there be bindings! (let [alphagram #(apply str (sort %)) map (group-by alphagram words-in) filtered (filter #(> (count %) min-group-size) (vals map)) winners (sort-by #(- (count %)) filtered)] (doseq [winner winners] (println (count winner) ": " winner))) 39
  • 40.
    Java Reminder import java.util.*; publicclass Anagram { public static void main(String[] args) { int minGroupSize = Integer.parseInt(args[0]); Map<String, List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } List<List<String>> winners = new ArrayList<List<String>>(); for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) winners.add(group); Collections.sort(winners, new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { return o2.size()-o1.size(); (defn alphagram [word] (apply str (sort word))) } (def min-group-size }); (Integer/valueOf (first *command-line-args*))) for (List<String> winner: winners) (def words-in System.out.println(winner.size() + ": " + winner); (iterator-seq (java.util.Scanner. System/in))) } (defn select-anagrams [words] (sort-by #(- (count %)) private static String alphagram(String s) { (filter #(> (count %) min-group-size) char[] chars = s.toCharArray(); (vals Arrays.sort(chars); (group-by alphagram words))))) return String.valueOf(chars); } (doseq [winner (select-anagrams words-in)] } (println (count winner) ":" winner)) 40
  • 41.
  • 42.
    What is JRuby? •Like Java – Have access to Java standard libraries and third party libraries – Runs in a JVM • Not like Java – Language is Ruby; latest release conforms to Ruby 1.8.7 – Dynamically typed – Can compile to class files – Have access to the Ruby standard libraries and any pure Ruby third party library • Not like Ruby – No access to Ruby native-C API – No access to Ruby continuations 42
  • 43.
    JRuby Example: Alphagram Java private static String alphagram(String s) { char[] chars = s.toCharArray(); Arrays.sort(chars); return String.valueOf(chars); } JRuby word.chars.sort.join 43
  • 44.
    JRuby: Multimap Java Map<String,List<String>> anagrams = new HashMap<String, List<String>>(); for (Scanner s = new Scanner(System.in); s.hasNext();) { String word = s.next(); String alphagram = alphagram(word); List<String> group = anagrams.get(alphagram); if (group == null) anagrams.put(alphagram, group = new ArrayList<String>()); group.add(word); } JRuby anagrams = words.group_by { |word| word.chars.sort.join } 44
  • 45.
    JRuby: Filtering, Sorting,Printing Java List<List<String>> winners = new ArrayList<List<String>>(); for (List<String> group : anagrams.values()) if (group.size() >= minGroupSize) winners.add(group); Collections.sort(winners, new Comparator<List<String>>() { public int compare(List<String> o1, List<String> o2) { return o2.size()-o1.size(); } }); for (List<String> winner: winners) System.out.println(winner.size() + ": " + winner); JRuby filtered = anagrams.values.select {|array| array.length > 4 } winners = filtered.sort_by { |array| array.length } winners.each {|each| puts “#{each.size} : #{each.join(‘, ‘)}"} 45
  • 46.
    JRuby: Complete Example anagrams= words.group_by {|word| word.chars.sort.join} filtered = anagrams.values.select {|array| array.length > 4} winners = filtered.sort_by { |array| array.length } winners.each {|each| puts “#{each.size} : #{each.join(‘, ‘)}"} 46
  • 47.
    JRuby: Complete Example– Let’s Make It Better class String def collation self.chars.sort.join end end class Symbol def to_proc proc { |*args| args[0].send(self, *args[1...args.size]) } end end module Enumerable def partitioned_with(&transformer) group_by(&transformer).values end def longer_than(size) self.select {|e| e.length > size} end def sorted_by_size self.sort_by(&:length) end end 47
  • 48.
    JRuby: Better CompleteExample groups = words.partitioned_with(&:collation) winners = groups.longer_than(4).sorted_by_size winners.each{|each| puts "#{each.size}: #{each.join(', ')}"} 48
  • 49.
    Takeaways • JVM providesa robust, industrial strength, scalable platform • You can take advantage of JVM and the rest of the Java ecosystem without the complexity of Java the language • Don’t have to wait for Java to adopt the features already available in other languages: closures, dynamic capabilities, rich, humane interfaces • Not all languages are enterprise ready – These languages are still worth looking into • Pragmatic Programmer advice: Learn a new language every year. When you learn a new language, you learn a new way to think. 49
  • 50.