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

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 

Recently uploaded (20)

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

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 