SlideShare a Scribd company logo
1 of 70
Download to read offline
Groovy

   An Object Oriented Dynamic
      Language for the JVM
A Java Program
import java.util.*;
class Erase {
   public static void main(String[] args) {
      List l = new ArrayList();
      l.add(quot;Tedquot;);
      l.add(quot;Fredquot;);
      l.add(quot;Jedquot;);
      l.add(quot;Nedquot;);
      System.out.println(l);
      Erase e = new Erase();
      List r = e.filterLongerThan(l, 3);
      System.out.println(r.size());
      for (Iterator i = r.iterator(); i.hasNext(); ) {
          System.out.println(i.next());
      }
   }
   public List filterLongerThan(List l, int length) {
      List result = new ArrayList();
      for (Iterator i = l.iterator(); i.hasNext(); ) {
           String entry = (String) i.next();
           if (entry.length() < length+1) {
               result.add(entry);
            }
      }
      return result;
   }
}
Groovy 1
import java.util.ArrayList
class Erase {
   public static void main(String[] args) {
      List l = new ArrayList()
      l.add(quot;Tedquot;)
      l.add(quot;Fredquot;)
      l.add(quot;Jedquot;)
      l.add(quot;Nedquot;)
      System.out.println(l)
      Erase e = new Erase();
      List r = e.filterLongerThan(l, 3)
      System.out.println(r.size())
      for (i in r) {
          System.out.println(i)
      }
   }
   public List filterLongerThan(List l, int length) {
      List result = new ArrayList()
      for (entry in l) {
           if (entry.length() < length+1) {
              result.add(entry)
           }
      }
      return result
   }
}
Groovy 2
import java.util.ArrayList
class Erase {
   public static void main(args) {
      l = new ArrayList()
      l.add(quot;Tedquot;)
      l.add(quot;Fredquot;)
      l.add(quot;Jedquot;)
      l.add(quot;Nedquot;)
      System.out.println(l)
      e = new Erase();
      r = e.filterLongerThan(l, 3)
      System.out.println(r.size())
      for (i in r) {
          System.out.println(i)
      }
   }
   public filterLongerThan(l, length) {
      result = new ArrayList()
      for (entry in l) {
           if (entry.length() < length+1) {
              result.add(entry)
           }
      }
      return result
   }
}
Groovy 3
import java.util.ArrayList
class Erase {
   public static void main(args) {
      l = [ quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot; ]
      System.out.println(l)

        e = new Erase();
        r = e.filterLongerThan(l, 3)
        System.out.println(r.size())
        for (i in r) {
            System.out.println(i)
        }
    }

    public filterLongerThan(l, length) {
       result = new ArrayList()
       for (entry in l) {
            if (entry.length() < length+1) {
               result.add(entry)
            }
       }
       return result
    }
}
Groovy 4
import java.util.ArrayList
class Erase {
   public static void main(args) {
      l = [ quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot; ]
      System.out.println(l)

        e = new Erase();
        r = e.filterLongerThan(l, 3)
        System.out.println(r.size())
        r.each { println it }
    }

    public filterLongerThan(l, length) {
       result = new ArrayList()
       result = l.findAll { entry | entry.length() < length+1 }
       return result
    }
}
Groovy 5
l = [quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot;]
println l

length = 3
r = l.findAll { e | e.length() < length+1 }
println r.size()
r.each { println it }
Typed Groovy
List l = [quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot;]
println l

Integer length = 3
List r = l.findAll {| String e | e.length() < length+1 }
println r.size()
List r = r.each { println it }
Tim Bray 3/15/2004
    In fact I personally believe that Java’s share of


    enterprise software will decline, but not in favor of
    anything from Redmond. I think that dynamic
    languages (Python and friends), particularly in
    conjunction with Test-Driven Development, are
    looking more like winners all the time. They
    generally are cheaper to program in, run just as
    fast, and have fewer bugs; what’s not to like?
Goals / Applications
    Fluid/Agile application development


        Optional typing
    

    Reuse existing Java code


    Unit testing tasks


    Build automation


    Scripting of Java Applications


    Improve efficiency when working with

        XML
    

        SQL
    
Influences
    Ruby


    Python


    Dylan


    Xen

Language Features
    Optional Typing


    Closures


    Native syntax for lists and maps


    Regex Syntax


    Operator overloading


    GroovyBeans


    Groovy Path Expression language


    Polymorphic iteration and autoboxing


    Compiles direct to Java byte code


    Interoperates cleanly with Java libraries

Environment features
    Groovy Markup


    Ant Scripting


    Groovy SQL


    Groovlets


    UI building - groovy-swt, also a swing


    builder
Optional Type Declarations
    Typed Groovy = Java + Autoboxing +


    Syntax
Closures
    Syntax

        Today
    

             { var | block}
         


        Tomorrow
    

             { | var | block }
         


    Assign to variables

        c = { x | return x == “John” }
    

    Call method

        c.call(“Fred”)
    

    Keyword it

        c = { return it == “John” }
    
Closures and objects
accountFactory = { balance |
   return { op, amount |
     if (op == quot;depositquot;) {
        balance = balance + amount
        return balance
     } else if (op == quot;withdrawquot;) {
        balance = balance - amount
         return balance
     } else if (op == quot;balancequot;) {
        return balance
     }
   }
}

account = accountFactory.call(5)

println account.call(quot;depositquot;, 100)
account.call(quot;withdrawquot;, 10)
println account.call(quot;balancequot;, 0)

105
95
Timing Closure
timer = { closure |
    start = System.currentTimeMillis()
    closure.call()
    println System.currentTimeMillis() - start
}

timer { quot;sleep 10quot;.execute().waitFor() }
Calling closures
    Passing closure after args


        fn(arg1,…,argn, Closure)
    

    Can call


        fn(a,..,n, { x | … } )
    

        fn(a,..,n) { x | … }
    
Closures & control structures
    Operations on lists, ranges

        l = [1,2,3,4,5,6,7]
    

        r = 1..7
    

    collect

        Call the closure on every element and return a list of
    

        the closure results
        l.collect { return it * it }
    

        [1, 4, 9, 16, 25, 36, 49]
    

    each

        Call the closure on every element of the collection
    

        l.each { print it }
    

        1234567
    
Control structures 2
    find


        Return the first collection value that causes
    
        the closure to evaluate to true
        l.find { it == 4 }
    

        4
    

    findAll


        Return a list of all collection values that
    

        cause the closure to evaluate to true
        l.findAll { it > 4 }
    

        [5, 6, 7]
    
Control Structure 3
    every

        return true if every element in collection causes the
    
        closure to evaluate to true
        r.every { it > 0 }
    

             true
         

        r.every { it > 4 }
    

             false
         


    any

        return true if any element in collection causes the
    
        closure to evaluate to true
        r.any { it > 4 }
    

             true
         

        r.any { it > 100 }
    

             false
         
Control Structures 4
    inject


        Iterate over the collection passing each
    

        succesive closure the result of the previous
        closure. Arg to inject is an initial value
        r.inject(1) { x, y | return x * y
    

        }
             5040
         
Closures and I/O
    eachLine

        new File('IO.groovy').eachLine { line |
    
           println(line)
        }

    eachByte


    eachFile


    withReader


    withStream


    withWriter

        new File(quot;groovy-output.txtquot;).withWriter { w |
    
          new File('IO.groovy').eachLine { line |
             w.write(line)
          }
        }

    withPrintWriter


    withOutputStream

Easy to use Java code
    Just import code


    Call it

Syntax
    Standalone functions (closures)


        f = { x, y |
    

         return x+y
        }
    Standalone statements


        f(1,3)
    

        4
    

    Optional Semicolons


    Optional parentheses

List syntax
    Lists are java.util.List instances


    Lists are enclosed in square brackets


    l = [ 1, 2 , 3 ]


    List access via indexing


    l[0]


        1
    
List operations
    << is append

        l << 4
    

        [1,2,3,4]
    

    flatten

        [ [ 1, 2, 3 ], [4, 5, 6] ].flatten()
    

        [ 1, 2, 3, 4, 5, 6]
    

    intersect

        [1, 2, 4, 6, 8, 10, 12].intersect([1,3,6,9,12])
    

        [1,6,12]
    

    minus

        [1, 2, 4, 6] - [2, 4]
    

        [1, 6]
    
List operations 2
    pop


        [1, 2, 4, 6].pop()
    

        6
    

    reverse


        [1, 2, 4, 6].reverse()
    

        [6, 4, 2, 1]
    
Map syntax
    Maps are java.util.Map instances


    Map enclosed with []


    Empty map is written [:]


    Key value pairs separated by ,


    Keys and values separated by :


    m = [ ‘a’:1, ‘b’:2, ‘c’:3 ]


    Values retrieved by key:

        m[‘b’]
    

            2
        
Collection Methods
    l = [ 1, 2, 4, 6, 2, 3, 5]


    count


        l.count(2)
    

        2
    

    join


        l.join(“:”)
    

        “2:4:6:2:3:5”
    
Collections 2
    min

        l.min()
    

        1
    

    max

        l.max()
    

        1
    

    plus

        l.plus(“a”)
    

        [1, 2, 4, 6, 2, 3, 5, a]
    

    sort

        l.sort()
    

        [1, 2, 2, 3, 4, 5, 6]
    
Ranges
    Ranges implement java.util.List


    Notation allows


        Inclusive ..
    

        Exclusive of top …
    


    Integer

        3..7 contains 3, 4, 5, 6, 7
    

        3…7 contains 3, 4, 5, 6
    


    Character

        “a”..”d” contains a, b, c, d
    

        “a”…”d” contains a, b, c
    
Ranges 2
    Implement groovy.lang.Range


        getFrom
    

        getTo
    

    Subinterfaces


        IntRange
    

            contains method
        


        ObjectRange
    

            contains method
        
Ranges and slicing
    You can use ranges to access strings and lists


    s = “this is a test”


    s[1..3]

        his
    

    Reversed ranges give reversed results


    s[3..1]

        sih
    

    Negative indices start from the end


    s[-4..-1]

        test
    

    s[-1..-4]

        tset
    
Methods added to Object
    dump


        l = [‘a’,’b’,’c’]
    

        quot;<java.util.ArrayList@1ecc1 elementData=[a,
    

        b, c] size=3 modCount=3>quot;
    print


    println

Methods added to String
    s=“this is a test”


    contains

        s.contains(“is”)
    

            true
        

        s.contains(“ted”)
    

            false
        


    count

        s.count(“is”)
    

            2
        


    tokenize

        s.tokenize()
    

            [quot;Thisquot;, quot;isquot;, quot;aquot;, quot;testquot;]
        
String methods 2
    minus


        s - “a”
    

             “this is test”
         


    multiply


        s*2
    

             “this is a testthis is a test”
         
Regular Expressions
    Based on JDK 1.4 Regex


    ~”pattern”

        Pattern.compile(“pattern”)
    

        pat = ~quot;.*(d{5})quot;
    

    “text” =~ “pattern”

        Pattern.compile(“pattern”).matcher(“text”)
    

        m = quot;CA 95014quot; =~ pat
    

    “test” ==~ “pattern”

        Pattern.compile(“pattern”).matcher(“text”).matches()
    

        quot;CA 95014quot; ==~ pat
    

        true
    
Operator overloading
    == (Java equals)


    != (Java !equals)


    === (Java ==)


    <=> (Java compareTo)


    >


    >=


    <


    <=

Operator overloading 2
    +


    -


    *


    /


    ++


    --


    x[y]


    x[y] = z

Switch
    Case on various types

        String
    
             case ‘string’:
         


        Range
    
             case 1..10:
         


        In a list
    
             case [‘alpha’, ‘beta’, ‘gamma’]:
         


        Class name (instanceof)
    
             case java.util.Date:
         


        Regex
    
             case ~”d{5}”:
         


    isCase method called for case comparisons

        Override this to allow your classes to be switched on
    
Switch 2
accountFactory = { balance |
   return { op, amount |
     switch (op) {
       case 'deposit':
        balance = balance + amount
        return balance
       case 'withdraw':
        balance = balance - amount
         return balance
       case 'balance':
        return balance
       default:
        throw IllegalArgumentException
     }
   }
}
Looping
    for

        for (i in 1..10) { println i }
    

        l = 1..10
    

        for (i in l) { println i }

    while

        i=0
    

        while (i < 10 ) {
         println i
         i++
        }
Looping 2
    each

        (1..10).each { println it }
    

        l.each { println it }
    



    times

        10.times { println it }
    



    upto

        1.upto(10) { println it }
    



    step

        1.step(10,2) { println it }
    
Here documents
    Shell style

        h1= <<<THEEND
    
        This
        is
        a
        multiline
        string
        THEEND

    Python style

        h2 = “””
    
        This
        is
        a
        Python
        style
        multiline
        string
        “””
String interpolation
    Use ${expr} to insert the value of expr into


    a string
    count = 4


    println “The total count is ${count}”
    The total count is 4

Groovy Beans
    Like Java Beans


    Properties


    Auto generate getters and setters


        for public, protected properties
    
Groovy Beans 2
class Feed {
    String title
    String link
    Person author
    String tagline
    String generator
    String copyright
    String modified
    List entries
}

class Entry {
    String title
    String link
    String id
    String summary
    String content
    Person author
    String created
    String issued
    String modified
}
Groovy Beans 3
class Person {
    String name
    String url
    String email
}


f = new Feed()

f.author = new Person(
   name:'Ted Leung',url:'http://www.sauria.com/blog',
   email:'twl@sauria.com')

f.entries = [
   new Entry(title:'one',summary:'first post'),
   new Entry(title:'two',summary:'the second post'),
   new Entry(title:'three', summary:'post the third'),
   new Entry(title:'four',summary:'the ponderous fourth post')
]
GPath object navigation
    x.y.z = x.getY().getZ()


        f.author.name
    

            Ted Leung
        


    x->y->z (avoids nullptr)


        f->author->name
    

            Ted Leung
        


    Works over lists


        f.entries.name
    

            [ ‘one’, ‘two’, ‘three’, ‘four’ ]
        
GPath and closures
    f.entries.any {


      it.author.email == “twl@sauria.com”
    }
    true

Groovy Markup
    Application of closures


    Functions create elements


    Function arguments create either


    attributes or text content
        Named arguments create attributes
    

        String arguments create text content
    

        Maps create mixed content
    

    Closures create nested content

XML MarkupBuilder
xml = new MarkupBuilder()

atom = xml.atom {
  title(quot;Ted Leung off the airquot;)
  link(quot;http://www.sauria.com/noblogquot;)
  author() {
    person() {
      name(f.author.name)
      url(f.author.url)
      email(f.author.email)
    }
  }
  for (e in f.entries) {
    entry() {
      summary(e.summary)
    }
  }
}
XML MarkupBuilder Result
<atom>
  <title>Ted Leung off the air</title>
  <link>http://www.sauria.com/noblog</link>
  <author>
    <person>
       <name>Ted Leung</name>
       <url>http://www.sauria.com/blog</url>
       <email>twl@sauria.com</email>
    </person>
  </author>
  <entry>
    <title>one</title>
    <summary>first post</summary>
  </entry>
  <entry>
    <title>two</title>
    <summary>the second post</summary>
  </entry>
  <entry>
    <title>three</title>
    <summary>post the third</summary>
  </entry>
  <entry>
    <title>four</title>
    <summary>the ponderous fourth post</summary>
  </entry>
</atom>
Builders
    NodeBuilder


    DOMBuilder


    SAXBuilder


    MarkupBuilder


    AntBuilder


    SwingBuilder


    SWTBuilder

Ant Scripting
import groovy.util.AntBuilder
import org.codehaus.groovy.ant.Groovyc

ant = new AntBuilder()

ant.taskdef(name:'groovyc', classname:'org.codehaus.groovy.ant.Groovyc')

ant.sequential {
  echo(quot;copying filesquot;)
  myDir = quot;binquot;

    delete(dir:myDir)
    mkdir(dir:myDir)
    copy(todir:myDir) {
      fileset(dir:quot;.quot;) {
        include(name:quot;**/*.groovyquot;)
        exclude(name:quot;**/EraseTyped.groovyquot;)
      }
    }

    echo(quot;Compiling Groovy filesquot;)
    groovyc(srcdir:myDir, destdir:myDir)

    echo(quot;donequot;)
}
GroovySQL
      Use closures to make JDBC easier
  

import groovy.sql.Sql
import java.sql.DriverManager

Class.forName(quot;org.hsqldb.jdbcDriverquot;)
connection =
   DriverManager.getConnection(quot;jdbc:hsqldb:hsql://localhostquot;, quot;saquot;, quot;quot;)

sql = new Sql(connection)

sql.eachRow(quot;SELECT name, price FROM pricesquot;) { row |
  println quot;${row.name} costs ${row.price}quot;
}
Groovlets
    Write servlets using Groovy


    Use the GroovyServlet to process scripts


    Allow implicit access to key servlet


    objects
Groovlets 2
if (session.counter == null) {
    session.counter = 1
}

out.println(<<<EOS
<html>
<head>
<title>Groovy Servlet</title>
</head>
<body>
Hello, ${request.remoteHost}: ${session.counter}! ${new Date()}
<br>src
</body>
</html>
EOS)

session.counter = session.counter + 1
Invoking Groovy Scripts
    Interactive Shell


    Interactive Swing Console


    Script compilation

Tool Support
    Eclipse


    IntelliJ


    Ant groovyc task

Embedding Groovy in Java
    Use GroovyShell to execute scripts


    Use GroovyClassLoader to expose


    Groovy objects to Java
        Semi inconvenient due to invokeMethod
    
Implementation
    Each Groovy class is compiled to a Java


    class
    Java classes callable from Groovy


    Groovy classes callable from Java

Applications
    Template Engines


    Gap (groovy, picocontainer, dynaop)


    Query language like JXPath


    IDE Scripting, IDE/Appserver integration


    OpenEJB Telnet client allows groovy


    script execution
        BEA investigating this also
    
Development Process
    Groovy Team @ Codehaus.org


        Led by James Strachan
    

        Open Source
    

            Apache Style License
        


        Small but growing community
    

    JSR-241 (proposed)


        Apache, BEA, Thoughtworks
    
Status
    1.0beta 4


        1.0 scheduled for a couple of months
    

    Eclipse plugin for 2.1.2, 3.0M5

Issues
    Stability


    No static method dispatch


    No eclipse refactoring support


    Syntax still subject to change

Minuses
    Still working out syntax


    Small community for now


    IDE plugins need work


    Not Python or Perl


    Built using Maven

Future features
    Metadata support


    Multiple assignment


    Python style Generators


    Xen style cardinality syntax


    Inner classes


    Mixins


    JDK 1.5 style imports


    JDK 1.5 style varargs


    Syntax extension

Resources
    http://groovy.codehaus.org


    irc://irc.codehaus.org/groovy


    http://www.ociweb.com/jnb/jnbFeb2004


    http://viva.sourceforge.net/talk/jug-mar-


    2004/slides.html
    http://www.sauria.com/blog


More Related Content

What's hot

Java Generics for Dummies
Java Generics for DummiesJava Generics for Dummies
Java Generics for Dummiesknutmork
 
Final JAVA Practical of BCA SEM-5.
Final JAVA Practical of BCA SEM-5.Final JAVA Practical of BCA SEM-5.
Final JAVA Practical of BCA SEM-5.Nishan Barot
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meetMario Fusco
 
The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88Mahmoud Samir Fayed
 
Expression trees in C#
Expression trees in C#Expression trees in C#
Expression trees in C#Oleksii Holub
 
GPars howto - when to use which concurrency abstraction
GPars howto - when to use which concurrency abstractionGPars howto - when to use which concurrency abstraction
GPars howto - when to use which concurrency abstractionVaclav Pech
 
Coding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeCoding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeGanesh Samarthyam
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardMario Fusco
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and FutureJohn De Goes
 
The Ring programming language version 1.9 book - Part 34 of 210
The Ring programming language version 1.9 book - Part 34 of 210The Ring programming language version 1.9 book - Part 34 of 210
The Ring programming language version 1.9 book - Part 34 of 210Mahmoud Samir Fayed
 
The Ring programming language version 1.2 book - Part 21 of 84
The Ring programming language version 1.2 book - Part 21 of 84The Ring programming language version 1.2 book - Part 21 of 84
The Ring programming language version 1.2 book - Part 21 of 84Mahmoud Samir Fayed
 
Oleksii Holub "Expression trees in C#"
Oleksii Holub "Expression trees in C#" Oleksii Holub "Expression trees in C#"
Oleksii Holub "Expression trees in C#" Fwdays
 
The Ring programming language version 1.5.4 book - Part 27 of 185
The Ring programming language version 1.5.4 book - Part 27 of 185The Ring programming language version 1.5.4 book - Part 27 of 185
The Ring programming language version 1.5.4 book - Part 27 of 185Mahmoud Samir Fayed
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8RichardWarburton
 

What's hot (20)

Java Generics for Dummies
Java Generics for DummiesJava Generics for Dummies
Java Generics for Dummies
 
Scala @ TomTom
Scala @ TomTomScala @ TomTom
Scala @ TomTom
 
Final JAVA Practical of BCA SEM-5.
Final JAVA Practical of BCA SEM-5.Final JAVA Practical of BCA SEM-5.
Final JAVA Practical of BCA SEM-5.
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88
 
Expression trees in C#
Expression trees in C#Expression trees in C#
Expression trees in C#
 
GPars howto - when to use which concurrency abstraction
GPars howto - when to use which concurrency abstractionGPars howto - when to use which concurrency abstraction
GPars howto - when to use which concurrency abstraction
 
Coding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeCoding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean Code
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
 
The Ring programming language version 1.9 book - Part 34 of 210
The Ring programming language version 1.9 book - Part 34 of 210The Ring programming language version 1.9 book - Part 34 of 210
The Ring programming language version 1.9 book - Part 34 of 210
 
Sneaking inside Kotlin features
Sneaking inside Kotlin featuresSneaking inside Kotlin features
Sneaking inside Kotlin features
 
The Ring programming language version 1.2 book - Part 21 of 84
The Ring programming language version 1.2 book - Part 21 of 84The Ring programming language version 1.2 book - Part 21 of 84
The Ring programming language version 1.2 book - Part 21 of 84
 
Pattern Matching in Java 14
Pattern Matching in Java 14Pattern Matching in Java 14
Pattern Matching in Java 14
 
Oleksii Holub "Expression trees in C#"
Oleksii Holub "Expression trees in C#" Oleksii Holub "Expression trees in C#"
Oleksii Holub "Expression trees in C#"
 
Strings and Characters
Strings and CharactersStrings and Characters
Strings and Characters
 
The Ring programming language version 1.5.4 book - Part 27 of 185
The Ring programming language version 1.5.4 book - Part 27 of 185The Ring programming language version 1.5.4 book - Part 27 of 185
The Ring programming language version 1.5.4 book - Part 27 of 185
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
 

Similar to SeaJUG March 2004 - Groovy

Functional techniques in Ruby
Functional techniques in RubyFunctional techniques in Ruby
Functional techniques in Rubyerockendude
 
Functional techniques in Ruby
Functional techniques in RubyFunctional techniques in Ruby
Functional techniques in Rubyerockendude
 
object oriented programming java lectures
object oriented programming java lecturesobject oriented programming java lectures
object oriented programming java lecturesMSohaib24
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005Tugdual Grall
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Wsloffenauer
 
Functional programming basics
Functional programming basicsFunctional programming basics
Functional programming basicsopenbala
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Guillaume Laforge
 
Functional Javascript
Functional JavascriptFunctional Javascript
Functional Javascriptguest4d57e6
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard LibraryNelson Glauber Leal
 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slidejonycse
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scalaparag978978
 
Apache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheelApache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheeltcurdt
 
LECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdf
LECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdfLECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdf
LECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdfShashikantSathe3
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 

Similar to SeaJUG March 2004 - Groovy (20)

Java introduction
Java introductionJava introduction
Java introduction
 
Functional techniques in Ruby
Functional techniques in RubyFunctional techniques in Ruby
Functional techniques in Ruby
 
Functional techniques in Ruby
Functional techniques in RubyFunctional techniques in Ruby
Functional techniques in Ruby
 
object oriented programming java lectures
object oriented programming java lecturesobject oriented programming java lectures
object oriented programming java lectures
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws
 
Functional programming basics
Functional programming basicsFunctional programming basics
Functional programming basics
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
Functional Javascript
Functional JavascriptFunctional Javascript
Functional Javascript
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard Library
 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slide
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
 
Apache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheelApache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheel
 
Groovy
GroovyGroovy
Groovy
 
Groovy!
Groovy!Groovy!
Groovy!
 
LECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdf
LECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdfLECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdf
LECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdf
 
Scala
ScalaScala
Scala
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 

More from Ted Leung

DjangoCon 2009 Keynote
DjangoCon 2009 KeynoteDjangoCon 2009 Keynote
DjangoCon 2009 KeynoteTed Leung
 
A Survey of Concurrency Constructs
A Survey of Concurrency ConstructsA Survey of Concurrency Constructs
A Survey of Concurrency ConstructsTed Leung
 
Seeding The Cloud
Seeding The CloudSeeding The Cloud
Seeding The CloudTed Leung
 
Programming Languages For The Cloud
Programming Languages For The CloudProgramming Languages For The Cloud
Programming Languages For The CloudTed Leung
 
MySQL User Conference 2009: Python and MySQL
MySQL User Conference 2009: Python and MySQLMySQL User Conference 2009: Python and MySQL
MySQL User Conference 2009: Python and MySQLTed Leung
 
PyCon US 2009: Challenges and Opportunities for Python
PyCon US 2009: Challenges and Opportunities for PythonPyCon US 2009: Challenges and Opportunities for Python
PyCon US 2009: Challenges and Opportunities for PythonTed Leung
 
Northwest Python Day 2009
Northwest Python Day 2009Northwest Python Day 2009
Northwest Python Day 2009Ted Leung
 
PyCon UK 2008: Challenges for Dynamic Languages
PyCon UK 2008: Challenges for Dynamic LanguagesPyCon UK 2008: Challenges for Dynamic Languages
PyCon UK 2008: Challenges for Dynamic LanguagesTed Leung
 
OSCON 2008: Open Source Community Antipatterns
OSCON 2008: Open Source Community AntipatternsOSCON 2008: Open Source Community Antipatterns
OSCON 2008: Open Source Community AntipatternsTed Leung
 
OSCON 2007: Open Design, Not By Committee
OSCON 2007: Open Design, Not By CommitteeOSCON 2007: Open Design, Not By Committee
OSCON 2007: Open Design, Not By CommitteeTed Leung
 
Ignite The Web 2007
Ignite The Web 2007Ignite The Web 2007
Ignite The Web 2007Ted Leung
 
ApacheCon US 2007: Open Source Community Antipatterns
ApacheCon US 2007:  Open Source Community AntipatternsApacheCon US 2007:  Open Source Community Antipatterns
ApacheCon US 2007: Open Source Community AntipatternsTed Leung
 
OSCON 2005: Build Your Own Chandler Parcel
OSCON 2005: Build Your Own Chandler ParcelOSCON 2005: Build Your Own Chandler Parcel
OSCON 2005: Build Your Own Chandler ParcelTed Leung
 
PyCon 2005 PyBlosxom
PyCon 2005 PyBlosxomPyCon 2005 PyBlosxom
PyCon 2005 PyBlosxomTed Leung
 
OSCON 2004: XML and Apache
OSCON 2004: XML and ApacheOSCON 2004: XML and Apache
OSCON 2004: XML and ApacheTed Leung
 
OSCON 2004: A Developer's Tour of Chandler
OSCON 2004: A Developer's Tour of ChandlerOSCON 2004: A Developer's Tour of Chandler
OSCON 2004: A Developer's Tour of ChandlerTed Leung
 
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJ
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJSeaJUG Dec 2001: Aspect-Oriented Programming with AspectJ
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJTed Leung
 
IQPC Canada XML 2001: How to develop Syntax and XML Schema
IQPC Canada XML 2001: How to develop Syntax and XML SchemaIQPC Canada XML 2001: How to develop Syntax and XML Schema
IQPC Canada XML 2001: How to develop Syntax and XML SchemaTed Leung
 
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic CommunicationIQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic CommunicationTed Leung
 
ApacheCon 2000 Everything you ever wanted to know about XML Parsing
ApacheCon 2000 Everything you ever wanted to know about XML ParsingApacheCon 2000 Everything you ever wanted to know about XML Parsing
ApacheCon 2000 Everything you ever wanted to know about XML ParsingTed Leung
 

More from Ted Leung (20)

DjangoCon 2009 Keynote
DjangoCon 2009 KeynoteDjangoCon 2009 Keynote
DjangoCon 2009 Keynote
 
A Survey of Concurrency Constructs
A Survey of Concurrency ConstructsA Survey of Concurrency Constructs
A Survey of Concurrency Constructs
 
Seeding The Cloud
Seeding The CloudSeeding The Cloud
Seeding The Cloud
 
Programming Languages For The Cloud
Programming Languages For The CloudProgramming Languages For The Cloud
Programming Languages For The Cloud
 
MySQL User Conference 2009: Python and MySQL
MySQL User Conference 2009: Python and MySQLMySQL User Conference 2009: Python and MySQL
MySQL User Conference 2009: Python and MySQL
 
PyCon US 2009: Challenges and Opportunities for Python
PyCon US 2009: Challenges and Opportunities for PythonPyCon US 2009: Challenges and Opportunities for Python
PyCon US 2009: Challenges and Opportunities for Python
 
Northwest Python Day 2009
Northwest Python Day 2009Northwest Python Day 2009
Northwest Python Day 2009
 
PyCon UK 2008: Challenges for Dynamic Languages
PyCon UK 2008: Challenges for Dynamic LanguagesPyCon UK 2008: Challenges for Dynamic Languages
PyCon UK 2008: Challenges for Dynamic Languages
 
OSCON 2008: Open Source Community Antipatterns
OSCON 2008: Open Source Community AntipatternsOSCON 2008: Open Source Community Antipatterns
OSCON 2008: Open Source Community Antipatterns
 
OSCON 2007: Open Design, Not By Committee
OSCON 2007: Open Design, Not By CommitteeOSCON 2007: Open Design, Not By Committee
OSCON 2007: Open Design, Not By Committee
 
Ignite The Web 2007
Ignite The Web 2007Ignite The Web 2007
Ignite The Web 2007
 
ApacheCon US 2007: Open Source Community Antipatterns
ApacheCon US 2007:  Open Source Community AntipatternsApacheCon US 2007:  Open Source Community Antipatterns
ApacheCon US 2007: Open Source Community Antipatterns
 
OSCON 2005: Build Your Own Chandler Parcel
OSCON 2005: Build Your Own Chandler ParcelOSCON 2005: Build Your Own Chandler Parcel
OSCON 2005: Build Your Own Chandler Parcel
 
PyCon 2005 PyBlosxom
PyCon 2005 PyBlosxomPyCon 2005 PyBlosxom
PyCon 2005 PyBlosxom
 
OSCON 2004: XML and Apache
OSCON 2004: XML and ApacheOSCON 2004: XML and Apache
OSCON 2004: XML and Apache
 
OSCON 2004: A Developer's Tour of Chandler
OSCON 2004: A Developer's Tour of ChandlerOSCON 2004: A Developer's Tour of Chandler
OSCON 2004: A Developer's Tour of Chandler
 
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJ
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJSeaJUG Dec 2001: Aspect-Oriented Programming with AspectJ
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJ
 
IQPC Canada XML 2001: How to develop Syntax and XML Schema
IQPC Canada XML 2001: How to develop Syntax and XML SchemaIQPC Canada XML 2001: How to develop Syntax and XML Schema
IQPC Canada XML 2001: How to develop Syntax and XML Schema
 
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic CommunicationIQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
 
ApacheCon 2000 Everything you ever wanted to know about XML Parsing
ApacheCon 2000 Everything you ever wanted to know about XML ParsingApacheCon 2000 Everything you ever wanted to know about XML Parsing
ApacheCon 2000 Everything you ever wanted to know about XML Parsing
 

Recently uploaded

Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 

Recently uploaded (20)

Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 

SeaJUG March 2004 - Groovy

  • 1. Groovy An Object Oriented Dynamic Language for the JVM
  • 2. A Java Program import java.util.*; class Erase { public static void main(String[] args) { List l = new ArrayList(); l.add(quot;Tedquot;); l.add(quot;Fredquot;); l.add(quot;Jedquot;); l.add(quot;Nedquot;); System.out.println(l); Erase e = new Erase(); List r = e.filterLongerThan(l, 3); System.out.println(r.size()); for (Iterator i = r.iterator(); i.hasNext(); ) { System.out.println(i.next()); } } public List filterLongerThan(List l, int length) { List result = new ArrayList(); for (Iterator i = l.iterator(); i.hasNext(); ) { String entry = (String) i.next(); if (entry.length() < length+1) { result.add(entry); } } return result; } }
  • 3. Groovy 1 import java.util.ArrayList class Erase { public static void main(String[] args) { List l = new ArrayList() l.add(quot;Tedquot;) l.add(quot;Fredquot;) l.add(quot;Jedquot;) l.add(quot;Nedquot;) System.out.println(l) Erase e = new Erase(); List r = e.filterLongerThan(l, 3) System.out.println(r.size()) for (i in r) { System.out.println(i) } } public List filterLongerThan(List l, int length) { List result = new ArrayList() for (entry in l) { if (entry.length() < length+1) { result.add(entry) } } return result } }
  • 4. Groovy 2 import java.util.ArrayList class Erase { public static void main(args) { l = new ArrayList() l.add(quot;Tedquot;) l.add(quot;Fredquot;) l.add(quot;Jedquot;) l.add(quot;Nedquot;) System.out.println(l) e = new Erase(); r = e.filterLongerThan(l, 3) System.out.println(r.size()) for (i in r) { System.out.println(i) } } public filterLongerThan(l, length) { result = new ArrayList() for (entry in l) { if (entry.length() < length+1) { result.add(entry) } } return result } }
  • 5. Groovy 3 import java.util.ArrayList class Erase { public static void main(args) { l = [ quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot; ] System.out.println(l) e = new Erase(); r = e.filterLongerThan(l, 3) System.out.println(r.size()) for (i in r) { System.out.println(i) } } public filterLongerThan(l, length) { result = new ArrayList() for (entry in l) { if (entry.length() < length+1) { result.add(entry) } } return result } }
  • 6. Groovy 4 import java.util.ArrayList class Erase { public static void main(args) { l = [ quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot; ] System.out.println(l) e = new Erase(); r = e.filterLongerThan(l, 3) System.out.println(r.size()) r.each { println it } } public filterLongerThan(l, length) { result = new ArrayList() result = l.findAll { entry | entry.length() < length+1 } return result } }
  • 7. Groovy 5 l = [quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot;] println l length = 3 r = l.findAll { e | e.length() < length+1 } println r.size() r.each { println it }
  • 8. Typed Groovy List l = [quot;Tedquot;, quot;Fredquot;, quot;Jedquot;, quot;Nedquot;] println l Integer length = 3 List r = l.findAll {| String e | e.length() < length+1 } println r.size() List r = r.each { println it }
  • 9. Tim Bray 3/15/2004 In fact I personally believe that Java’s share of  enterprise software will decline, but not in favor of anything from Redmond. I think that dynamic languages (Python and friends), particularly in conjunction with Test-Driven Development, are looking more like winners all the time. They generally are cheaper to program in, run just as fast, and have fewer bugs; what’s not to like?
  • 10. Goals / Applications Fluid/Agile application development  Optional typing  Reuse existing Java code  Unit testing tasks  Build automation  Scripting of Java Applications  Improve efficiency when working with  XML  SQL 
  • 11. Influences Ruby  Python  Dylan  Xen 
  • 12. Language Features Optional Typing  Closures  Native syntax for lists and maps  Regex Syntax  Operator overloading  GroovyBeans  Groovy Path Expression language  Polymorphic iteration and autoboxing  Compiles direct to Java byte code  Interoperates cleanly with Java libraries 
  • 13. Environment features Groovy Markup  Ant Scripting  Groovy SQL  Groovlets  UI building - groovy-swt, also a swing  builder
  • 14. Optional Type Declarations Typed Groovy = Java + Autoboxing +  Syntax
  • 15. Closures Syntax  Today  { var | block}  Tomorrow  { | var | block }  Assign to variables  c = { x | return x == “John” }  Call method  c.call(“Fred”)  Keyword it  c = { return it == “John” } 
  • 16. Closures and objects accountFactory = { balance | return { op, amount | if (op == quot;depositquot;) { balance = balance + amount return balance } else if (op == quot;withdrawquot;) { balance = balance - amount return balance } else if (op == quot;balancequot;) { return balance } } } account = accountFactory.call(5) println account.call(quot;depositquot;, 100) account.call(quot;withdrawquot;, 10) println account.call(quot;balancequot;, 0) 105 95
  • 17. Timing Closure timer = { closure | start = System.currentTimeMillis() closure.call() println System.currentTimeMillis() - start } timer { quot;sleep 10quot;.execute().waitFor() }
  • 18. Calling closures Passing closure after args  fn(arg1,…,argn, Closure)  Can call  fn(a,..,n, { x | … } )  fn(a,..,n) { x | … } 
  • 19. Closures & control structures Operations on lists, ranges  l = [1,2,3,4,5,6,7]  r = 1..7  collect  Call the closure on every element and return a list of  the closure results l.collect { return it * it }  [1, 4, 9, 16, 25, 36, 49]  each  Call the closure on every element of the collection  l.each { print it }  1234567 
  • 20. Control structures 2 find  Return the first collection value that causes  the closure to evaluate to true l.find { it == 4 }  4  findAll  Return a list of all collection values that  cause the closure to evaluate to true l.findAll { it > 4 }  [5, 6, 7] 
  • 21. Control Structure 3 every  return true if every element in collection causes the  closure to evaluate to true r.every { it > 0 }  true  r.every { it > 4 }  false  any  return true if any element in collection causes the  closure to evaluate to true r.any { it > 4 }  true  r.any { it > 100 }  false 
  • 22. Control Structures 4 inject  Iterate over the collection passing each  succesive closure the result of the previous closure. Arg to inject is an initial value r.inject(1) { x, y | return x * y  } 5040 
  • 23. Closures and I/O eachLine  new File('IO.groovy').eachLine { line |  println(line) } eachByte  eachFile  withReader  withStream  withWriter  new File(quot;groovy-output.txtquot;).withWriter { w |  new File('IO.groovy').eachLine { line | w.write(line) } } withPrintWriter  withOutputStream 
  • 24. Easy to use Java code Just import code  Call it 
  • 25. Syntax Standalone functions (closures)  f = { x, y |  return x+y } Standalone statements  f(1,3)  4  Optional Semicolons  Optional parentheses 
  • 26. List syntax Lists are java.util.List instances  Lists are enclosed in square brackets  l = [ 1, 2 , 3 ]  List access via indexing  l[0]  1 
  • 27. List operations << is append  l << 4  [1,2,3,4]  flatten  [ [ 1, 2, 3 ], [4, 5, 6] ].flatten()  [ 1, 2, 3, 4, 5, 6]  intersect  [1, 2, 4, 6, 8, 10, 12].intersect([1,3,6,9,12])  [1,6,12]  minus  [1, 2, 4, 6] - [2, 4]  [1, 6] 
  • 28. List operations 2 pop  [1, 2, 4, 6].pop()  6  reverse  [1, 2, 4, 6].reverse()  [6, 4, 2, 1] 
  • 29. Map syntax Maps are java.util.Map instances  Map enclosed with []  Empty map is written [:]  Key value pairs separated by ,  Keys and values separated by :  m = [ ‘a’:1, ‘b’:2, ‘c’:3 ]  Values retrieved by key:  m[‘b’]  2 
  • 30. Collection Methods l = [ 1, 2, 4, 6, 2, 3, 5]  count  l.count(2)  2  join  l.join(“:”)  “2:4:6:2:3:5” 
  • 31. Collections 2 min  l.min()  1  max  l.max()  1  plus  l.plus(“a”)  [1, 2, 4, 6, 2, 3, 5, a]  sort  l.sort()  [1, 2, 2, 3, 4, 5, 6] 
  • 32. Ranges Ranges implement java.util.List  Notation allows  Inclusive ..  Exclusive of top …  Integer  3..7 contains 3, 4, 5, 6, 7  3…7 contains 3, 4, 5, 6  Character  “a”..”d” contains a, b, c, d  “a”…”d” contains a, b, c 
  • 33. Ranges 2 Implement groovy.lang.Range  getFrom  getTo  Subinterfaces  IntRange  contains method  ObjectRange  contains method 
  • 34. Ranges and slicing You can use ranges to access strings and lists  s = “this is a test”  s[1..3]  his  Reversed ranges give reversed results  s[3..1]  sih  Negative indices start from the end  s[-4..-1]  test  s[-1..-4]  tset 
  • 35. Methods added to Object dump  l = [‘a’,’b’,’c’]  quot;<java.util.ArrayList@1ecc1 elementData=[a,  b, c] size=3 modCount=3>quot; print  println 
  • 36. Methods added to String s=“this is a test”  contains  s.contains(“is”)  true  s.contains(“ted”)  false  count  s.count(“is”)  2  tokenize  s.tokenize()  [quot;Thisquot;, quot;isquot;, quot;aquot;, quot;testquot;] 
  • 37. String methods 2 minus  s - “a”  “this is test”  multiply  s*2  “this is a testthis is a test” 
  • 38. Regular Expressions Based on JDK 1.4 Regex  ~”pattern”  Pattern.compile(“pattern”)  pat = ~quot;.*(d{5})quot;  “text” =~ “pattern”  Pattern.compile(“pattern”).matcher(“text”)  m = quot;CA 95014quot; =~ pat  “test” ==~ “pattern”  Pattern.compile(“pattern”).matcher(“text”).matches()  quot;CA 95014quot; ==~ pat  true 
  • 39. Operator overloading == (Java equals)  != (Java !equals)  === (Java ==)  <=> (Java compareTo)  >  >=  <  <= 
  • 40. Operator overloading 2 +  -  *  /  ++  --  x[y]  x[y] = z 
  • 41. Switch Case on various types  String  case ‘string’:  Range  case 1..10:  In a list  case [‘alpha’, ‘beta’, ‘gamma’]:  Class name (instanceof)  case java.util.Date:  Regex  case ~”d{5}”:  isCase method called for case comparisons  Override this to allow your classes to be switched on 
  • 42. Switch 2 accountFactory = { balance | return { op, amount | switch (op) { case 'deposit': balance = balance + amount return balance case 'withdraw': balance = balance - amount return balance case 'balance': return balance default: throw IllegalArgumentException } } }
  • 43. Looping for  for (i in 1..10) { println i }  l = 1..10  for (i in l) { println i } while  i=0  while (i < 10 ) { println i i++ }
  • 44. Looping 2 each  (1..10).each { println it }  l.each { println it }  times  10.times { println it }  upto  1.upto(10) { println it }  step  1.step(10,2) { println it } 
  • 45. Here documents Shell style  h1= <<<THEEND  This is a multiline string THEEND Python style  h2 = “””  This is a Python style multiline string “””
  • 46. String interpolation Use ${expr} to insert the value of expr into  a string count = 4  println “The total count is ${count}” The total count is 4 
  • 47. Groovy Beans Like Java Beans  Properties  Auto generate getters and setters  for public, protected properties 
  • 48. Groovy Beans 2 class Feed { String title String link Person author String tagline String generator String copyright String modified List entries } class Entry { String title String link String id String summary String content Person author String created String issued String modified }
  • 49. Groovy Beans 3 class Person { String name String url String email } f = new Feed() f.author = new Person( name:'Ted Leung',url:'http://www.sauria.com/blog', email:'twl@sauria.com') f.entries = [ new Entry(title:'one',summary:'first post'), new Entry(title:'two',summary:'the second post'), new Entry(title:'three', summary:'post the third'), new Entry(title:'four',summary:'the ponderous fourth post') ]
  • 50. GPath object navigation x.y.z = x.getY().getZ()  f.author.name  Ted Leung  x->y->z (avoids nullptr)  f->author->name  Ted Leung  Works over lists  f.entries.name  [ ‘one’, ‘two’, ‘three’, ‘four’ ] 
  • 51. GPath and closures f.entries.any {  it.author.email == “twl@sauria.com” } true 
  • 52. Groovy Markup Application of closures  Functions create elements  Function arguments create either  attributes or text content Named arguments create attributes  String arguments create text content  Maps create mixed content  Closures create nested content 
  • 53. XML MarkupBuilder xml = new MarkupBuilder() atom = xml.atom { title(quot;Ted Leung off the airquot;) link(quot;http://www.sauria.com/noblogquot;) author() { person() { name(f.author.name) url(f.author.url) email(f.author.email) } } for (e in f.entries) { entry() { summary(e.summary) } } }
  • 54. XML MarkupBuilder Result <atom> <title>Ted Leung off the air</title> <link>http://www.sauria.com/noblog</link> <author> <person> <name>Ted Leung</name> <url>http://www.sauria.com/blog</url> <email>twl@sauria.com</email> </person> </author> <entry> <title>one</title> <summary>first post</summary> </entry> <entry> <title>two</title> <summary>the second post</summary> </entry> <entry> <title>three</title> <summary>post the third</summary> </entry> <entry> <title>four</title> <summary>the ponderous fourth post</summary> </entry> </atom>
  • 55. Builders NodeBuilder  DOMBuilder  SAXBuilder  MarkupBuilder  AntBuilder  SwingBuilder  SWTBuilder 
  • 56. Ant Scripting import groovy.util.AntBuilder import org.codehaus.groovy.ant.Groovyc ant = new AntBuilder() ant.taskdef(name:'groovyc', classname:'org.codehaus.groovy.ant.Groovyc') ant.sequential { echo(quot;copying filesquot;) myDir = quot;binquot; delete(dir:myDir) mkdir(dir:myDir) copy(todir:myDir) { fileset(dir:quot;.quot;) { include(name:quot;**/*.groovyquot;) exclude(name:quot;**/EraseTyped.groovyquot;) } } echo(quot;Compiling Groovy filesquot;) groovyc(srcdir:myDir, destdir:myDir) echo(quot;donequot;) }
  • 57. GroovySQL Use closures to make JDBC easier  import groovy.sql.Sql import java.sql.DriverManager Class.forName(quot;org.hsqldb.jdbcDriverquot;) connection = DriverManager.getConnection(quot;jdbc:hsqldb:hsql://localhostquot;, quot;saquot;, quot;quot;) sql = new Sql(connection) sql.eachRow(quot;SELECT name, price FROM pricesquot;) { row | println quot;${row.name} costs ${row.price}quot; }
  • 58. Groovlets Write servlets using Groovy  Use the GroovyServlet to process scripts  Allow implicit access to key servlet  objects
  • 59. Groovlets 2 if (session.counter == null) { session.counter = 1 } out.println(<<<EOS <html> <head> <title>Groovy Servlet</title> </head> <body> Hello, ${request.remoteHost}: ${session.counter}! ${new Date()} <br>src </body> </html> EOS) session.counter = session.counter + 1
  • 60. Invoking Groovy Scripts Interactive Shell  Interactive Swing Console  Script compilation 
  • 61. Tool Support Eclipse  IntelliJ  Ant groovyc task 
  • 62. Embedding Groovy in Java Use GroovyShell to execute scripts  Use GroovyClassLoader to expose  Groovy objects to Java Semi inconvenient due to invokeMethod 
  • 63. Implementation Each Groovy class is compiled to a Java  class Java classes callable from Groovy  Groovy classes callable from Java 
  • 64. Applications Template Engines  Gap (groovy, picocontainer, dynaop)  Query language like JXPath  IDE Scripting, IDE/Appserver integration  OpenEJB Telnet client allows groovy  script execution BEA investigating this also 
  • 65. Development Process Groovy Team @ Codehaus.org  Led by James Strachan  Open Source  Apache Style License  Small but growing community  JSR-241 (proposed)  Apache, BEA, Thoughtworks 
  • 66. Status 1.0beta 4  1.0 scheduled for a couple of months  Eclipse plugin for 2.1.2, 3.0M5 
  • 67. Issues Stability  No static method dispatch  No eclipse refactoring support  Syntax still subject to change 
  • 68. Minuses Still working out syntax  Small community for now  IDE plugins need work  Not Python or Perl  Built using Maven 
  • 69. Future features Metadata support  Multiple assignment  Python style Generators  Xen style cardinality syntax  Inner classes  Mixins  JDK 1.5 style imports  JDK 1.5 style varargs  Syntax extension 
  • 70. Resources http://groovy.codehaus.org  irc://irc.codehaus.org/groovy  http://www.ociweb.com/jnb/jnbFeb2004  http://viva.sourceforge.net/talk/jug-mar-  2004/slides.html http://www.sauria.com/blog 