SlideShare una empresa de Scribd logo
1 de 82
In pursuit of expressivity:
Groovy and Scala compared



          Chris Richardson
     Author of POJOs in Action
   Founder of CloudFoundry.com
     chris@chrisrichardson.net
           @crichardson
Overall presentation goal


 Examine the good,
 the bad and the ugly
      aspects of
    developing with
   Groovy and Scala

     4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                          Slide 2
About Chris
              •    Grew up in England and live in Oakland, CA
              •    Over 25+ years of software development
                   experience including 14 years of Java
              •    Speaker at JavaOne, SpringOne, NFJS,
                   JavaPolis, Spring Experience, etc.
              •    Organize the Oakland JUG (
                   http://bit.ly/ebjava) and the Groovy Grails
                   meetup (http://bit.ly/oakgrails)




                                     http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/



     4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                                           Slide 3
Agenda
o  Evolution of programming
   languages
o  Favorite Groovy features
o  The frustration of using Groovy
o  Scala: expressiveness and compile-
   time checking
o  The trouble with Scala



      4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                           Slide 4
Lots of programming languages
 This site lists 8512 languages, complete with 17837 bibliographic records
 featuring 11064 extracts from those references. It is in effect a family
 tree of languages with 5445 links, making it not only the biggest
 programming language family tree around, but also one of the largest
 idea-genealogical projects undertaken.

 http://hopl.murdoch.edu.au/




               4/3/11             Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                              Slide 5
The Elite v. The Masses

The Elite                                             Mainstream

o  Lisp                                               o  Thought Lisp and
   n    Invented in the 1960s                           Smalltalk were:
   n    Dynamic functional                                     n        Weird (Too different
         language                                                         from Algol)
   n    Dynamic object-oriented                                n        Too resource hungry
         language (mid-1980s)                                             (probably were for the
o  Smalltalk                                                              time)
   n    Invented in the 1970s                        o  So the mainstream used:
   n    Dynamic object-oriented
                                                         Pascal, C, C++, ….
         language                                     o  Not so safe, manual
o  Safe, garbage collection,                             memory management,
   rich, …                                               primitive, …




            4/3/11    Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                             Slide 6
LISP/CLOS – an early (late 1980s)
dynamic language
 (defclass Account ()
   ((account-id :accessor account-id :initarg :account-id)
    (balance :accessor account-balance :initarg :balance))                                    Develop by adding and
 )                                                                                            changing program
                                                                                              elements in a running VM
 (defmethod debit ((Account account) amount)
  (decf (account-balance account) amount))

 (defmethod credit ((Account account) amount)
  (incf (account-balance account) amount))


     CL-USER 5 > (setq a (make-instance 'account :account-id "abc123" :balance 10.0))
     #<ACCOUNT 200C05AF>

     CL-USER 6 > (describe a)

     #<ACCOUNT 200C05AF> is an ACCOUNT
     ACCOUNT-ID   "abc123"
     BALANCE    10.0

     CL-USER 7 > (debit a 5)
     5.0

     CL-USER 8 > (describe a)

     #<ACCOUNT 200C05AF> is an ACCOUNT
     ACCOUNT-ID   "abc123"
     BALANCE    5.0


               4/3/11             Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                                                   7
… a very dynamic language

  (defclass Account ()
    ((account-id :accessor account-id :initarg :account-id)                               Existing instances
     (balance :accessor account-balance :initarg :balance)                                are updated when
     (description :accessor account-description :initarg :description))                   the class is redefined
  )


  CL-USER 9 > (describe a)

  #<ACCOUNT 2168DCBF> is an ACCOUNT
  ACCOUNT-ID   "abc123"
  BALANCE     10.0
  DESCRIPTION    #<unbound slot>

  CL-USER 10 > (setf (account-description a) "checking account")
  "checking account"

  CL-USER 11 > (describe a)

  #<ACCOUNT 2168DCBF> is an ACCOUNT
  ACCOUNT-ID   "abc123"
  BALANCE     10.0
  DESCRIPTION   "checking account"




            4/3/11            Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                                              8
Along came Java
o  Provided the masses with:
  n  Garbage collection
  n  Safety, reliability and security


o  And 10+ years passed…




       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 9
Ruby on Rails woke up the Java
community

o  Ruby on Rails:
  n  Significantly more productive
  n  Simplicity of Convention over
      Configuration
o  Motivated the Java community to
   improve: frameworks such as Spring
   improved considerably
o  And…


       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 10
…Highlighted Problems with Java
o  Tedious collection processing
o  Painful object construction code
   n  No literals for collections
   n  Need to use Builders for creating hierarchies
o  Tedious XML processing
o  Types:
   n  Verbose declarations
   n  Generics are complicated
o  Fixed set of control constructs
o  Limited support for DSLs
                          =>
o  Reopened the debate about programming
   languages
o  Dynamic languages became interesting again

         4/3/11     Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                Slide 11
Dynamic languages on the JVM
o  JRuby
   n  http://jruby.codehaus.org
   n  Ruby on the JVM
o  Jython
   n  http://www.jython.org/Project
   n  Python on the JVM
o  Clojure
   n    http://clojure.org/
   n    Functional programming language
   n    Software Transactional Memory
   n    …
o  Groovy
   n  http://groovy.codehaus.org/
   n  Java-compatible, dynamic language


           4/3/11    Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                 Slide 12
Small but growing




     4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                          Slide 13
Static languages on the JVM
   o  (Java)
   o  Fortress
   o  Gosu
   o  Scala
   o  …


http://www.is-research.de/info/vmlanguages/?s=static




                           4/3/11                  Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                                               Slide 14
Scala and Gosu adoption – Smaller
but growing




     4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                          Slide 15
Agenda
o  Evolution of programming languages
o  Favorite Groovy features
o  The frustration of using Groovy
o  Scala: expressiveness and compile-
   time checking
o  The trouble with Scala




      4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                           Slide 16
About Groovy
o  Object-oriented, dynamic language
o  Made popular by the Grails
   framework:
  n  Rails-like productivity
  n  Using robust Java frameworks including
      Spring and Hibernate




   4/3/11     Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                          Slide 17
The good news
o  Easy to learn
  n  Designed to be Java compatible
  n  Interactive Shell
o  Great support for DSLs
o  Closures:
  n  Easy collection processing
  n  New control constructs
o  Property/method missing mechanism
o  Good XML handling
o  Meta-classes for dynamically defining
   new program elements => foundation
   for Grails
       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 18
Intentionally compatible with Java
o  Groovy objects are Java objects
o  Groovy collections are Java collections
o  Groovy can call Java
  n  e.g. leverage all those Java libraries
o  Java can call Groovy, e.g. Groovy
   objects can be:
  n  Spring beans
  n  Hibernate objects
o  Easy to write a module of a project
   Groovy => Easy to incrementally adopt
       4/3/11    Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                             Slide 19
Groovy can look like Java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

class EC2RequestExecutor {                                                               Java-like syntax

Log logger = LogFactory.getLog(getClass())

 public String calculateRFC2104HMAC(String data, String key) {
   try {
     SecretKeySpec signingKey = new SecretKeySpec(key.getBytes("UTF8"),
                                                     HMAC_SHA1_ALGORITHM)
     Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM)
     mac.init(signingKey)
     byte[] rawHmac = mac.doFinal(data.getBytes())
     return new String(Base64.encodeBase64(rawHmac))
   }
   catch (Exception e) {
     throw new RuntimeException("Failed to generate HMAC : ", e)
 }
}




         4/3/11              Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                                            Slide 20
Groovy is concise and expressive
def configureAsMaster() {
      writeFile fileName: "/etc/my.cnf", templateName: "/templates/master.my.cnf"

       restartService "mysqld"

       exec command: "mysql -u root",
                templateName: "/templates/createSchema.sql",                                 No parens
                templateArgs: [schemaSpec: schemaSpec]                                       Keyword parameters


       executeSchemaScripts()
  }




      class TomcatServer {               tomcatServer.contexts
                                                                                                 No get…()
       def getContexts() {
            webApps.context
        }
      }




              4/3/11             Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                                             Slide 21
An interactive shell




     Great for experimentation and learning



      4/3/11     Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                             Slide 22
Literals for lists and maps

def myList = ["a", "b", "c"]




def params = ['Action': 'RunInstances',
       'MinCount': n.toString(), 'MaxCount': n.toString(),
       ' ImageId': awsProperties."imageId.${instanceType}",
       'KeyName': awsProperties.keyName,
       ' InstanceType': instanceType] + extraParams

def response = requestor.executeRequest(params)



            4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                      Slide 23
GStrings
o  Templating mechanism
o  Embedded Groovy expressions
o  Multi-line strings



def schemaScript = """
  DROP SCHEMA IF EXISTS ${schemaSpec.name};
  CREATE SCHEMA ${schemaSpec.name};
     """




           4/3/11      Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                   Slide 24
Closures – collection processing

 public EC2Server findInstance(String instanceId) {
   def server = servers.find {instanceId == it.instanceId}
   if (server)
     return server
   else throw new RuntimeException(….)
 }

assertEquals(["aa", "bb", "cc"],
  ["a", "b", "c"].collect { elem -> elem + elem }

Simplified collection processing
No ugly anonymous inner classes



            4/3/11       Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                     Slide 25
Closures – new control structures
public class Ssh {

def withTunnel(String publicDnsName, int localPort, int remotePort, Closure closure) {
    SshConnection sshConnection = makeSshConnection(publicDnsName);
    try {
      sshConnection.connect()
      …
      return closure.call()
    } finally {
       sshConnection.close()
    }
  }
}

class EC2 {

String snapshotEbsVolume(String hostName, EbsVolume ebsVolume, String schemaName) {
     int localPort = PortUtil.allocatePort()
     def result = ssh.withTunnel(hostName, localPort, 3306) {
        …
     }
     return (String)result
  }

}



                     4/3/11         Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                                Slide 26
Closures details
groovy:000> x = { println z }
===> groovysh_evaluate
$_run_closure1@658ba380
groovy:000> x.delegate = [z: 99]
===> Foo@564a5320
groovy:000> x.call()
                       Used to resolve
99                     unbound methods and
                       properties
===> null
                                                                            For example, Builders
                                                                            set the delegate


       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                             Slide 27
Simple reusable code
interface Quackable {
  void quack();
                                                                                    Java:
}                                                                                   complexity of
class QuackableContainer<T extends Quackable>
                                                                                    generics

void add(T element) {
  element.quack();
  …
}
…
}

class QuackableContainer {                  Groovy: just assume that
void add(element) {                         there is a quack() method
  element.quack()
  …
}

           4/3/11       Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                          Slide 28
Method Missing
public class ClassWithMissingMethods {


    def methodMissing(String name, args) {
       Closure method = makeMethodImplementation(name)
       if (method) {
            method(args)
       } else {
            throw new MissingMethodException(name, getClass(), args)
       }
    }

    def makeMethodImplementation(String name) {
       ….
    }

}



    def foo = new ClassWithMissingMethods()
    foo.nonExistentMethod()


                 4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                           Slide 29
Groovy metaclasses
public class StringMetaclassExampleTest extends GroovyTestCase {

    void testAddMethodToString() {
       String.metaClass.doubleString = { -> delegate + delegate }
       String.metaClass.static.makePowerString = { String s, int n ->
          def result = s
          n.times { result = result.doubleString() }
          result
       }
       assertEquals "JavaZoneJavaZone", "JavaZone".doubleString()
       assertEquals "OsloOsloOsloOslo", String.makePowerString("Oslo", 2)
    }
}



     Runtime definition of program elements

     The foundation of many powerful features

                 4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                           Slide 30
XML and GPath expressions
                                                            <RunInstancesResponse>
                                                            …
                                                            <instancesSet>
                                                              <item>
                                                                 <instanceId>i-4ef21327</instanceId>
                                                                 <imageId>ami-3795705e</imageId>
                                                                 <instanceState>
                                                                    <code>0</code>
def client = new HttpClient()                                       <name>pending</name>
…                                                                </instanceState>
def responseStream =                                             <dnsName/>
                                                            …
  getMethod.getResponseBodyAsStream()
                                                            </RunInstancesResponse>
def parser = new XmlParser(false, false)
def response = parser.parseText(responseStream)

def newServers = response.instancesSet.item.collect {
   new EC2Server(this, awsProperties, ssh,
     it.instanceId.text(),
     it.instanceState.name.text())
}


          4/3/11           Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                             Slide 31
Metaclasses enhance JDK classes
groovy:000> new File("/Users/cer/.bashrc").text
===> export PATH=/Users/cer/tools/apache-maven-3.0/bin:
$PATH




groovy:000> l = [1,2,3]
===> [1, 2, 3]
groovy:000> l.getClass()
===> class java.util.ArrayList
groovy:000> l.getClass().metaClass.foo = { delegate.size }
===> groovysh_evaluate$_run_closure1@13a66c87
groovy:000> l.foo()
===> 3

          4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                               Slide 32
Builders
def report(String path, hosts, cpuCount, threadCount) {
  def builder = new groovy.xml.MarkupBuilder(new OutputStreamWriter(new FileOutputStream(path)))
  builder.performanceReport {
   cpus cpuCount
   threads threadCount
   hosts.entrySet().each {hostName, metric ->
    host {
     name hostName                                                     <performanceReport>
     cpuUtil metric.getAverageBusy()                                      <cpus>1</cpus>
    }                                                                     <threads>10</threads>
   }
                                                                          <host>
   requests {
     timing.sort{ a, b-> a.key <=> b.key}.each{ requestName, metric->       <name>database</name>
      request {                                                             <cpuUtil>3.27</cpuUtil>
       name requestName                                                   </host>
       art metric.average()                                               <host>
       errors metric.errorPercentage()
                                                                            <name>tomcat0</name>
      }
     }                                                                      <cpuUtil>94.32</cpuUtil>
   }                                                                      </host>
   def durationValue = (endTime – startTime)/1000.0                    …
   duration durationValue                                                <duration>557.943</duration>
   def tpsValue = transactionCount/ durationValue
                                                                          <tps>10.753786677133686</tps>
   tps tpsValue
   art averageResponseTime()                                              <art>916.6578333333</art>
  }                                                                    </performanceReport>
 }



             4/3/11               Copyright (c) 2011 Chris Richardson. All rights reserved.   Slide 33
Grails plugins use metaclasses
o  Key part of the Grails plugins
o  Plugins can dynamically add methods,
   e.g. GORM persistence methods
o  Injected methods are closures that
   have access to the Spring application
   context
  n  Less need for traditional dependency
      injection
  n  Alternative to AOP static crosscutting or
      (non-POJO) inheritance

       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 34
Grails/GORM persistence methods
 class Customer {                                            Implemented using
    String name                                              metaclasses and method
 }                                                           missing



 Customer c = new Customer("John Doe")

 if (!c.save())
    fail "validation failed: ${c.errors}"

 Customer c2 = Customer.get(c.id)

 c2.delete()

 assertNull Customer.get(c.id)


 def customers = Customer.findAllByName(“Fred”)


           4/3/11       Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                      Slide 35
Commentable plugin example
class CommentableGrailsPlugin {

 def doWithDynamicMethods = { ctx ->

 for(domainClass in application.domainClasses) {
    if(Commentable.class.isAssignableFrom(domainClass.clazz)) {

     domainClass.clazz.metaClass {
      'static' {
        getRecentComments {-> … }
      }

      addComment { poster, String text ->                                        }

      getComments = {-> }
…
}



         4/3/11      Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                     Slide 36
Grails DSL for ORM
 class Customer {

   static transients = ["networth"]

  static mapping = {
      id column: ‘customer_id’                                                  Closures
      table ‘crc_customer’
      columns {

     }
       name column: ‘customer_name’                                             Method
   }                                                                            missing
   def getNetworth() { … }
    }
 ...

         4/3/11     Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                           Slide 37
Grails Controllers -
o  Accessing request/response
o  Databinding
  n  b.properties = params
  n  new B(params)
o  …




       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 38
Agenda
o  Evolution of programming languages
o  Favorite Groovy features
o  The frustration of using Groovy
o  Scala: expressiveness and compile-
   time checking
o  The trouble with Scala




      4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                           Slide 39
Getting complex Groovy code to
work can be frustrating

o  Dynamic language = less information
   for IDE:
  n    Limited compile-time checking
  n    Limited refactorings
  n    Limited completion
  n    No todo list of errors




         4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                              Slide 40
Groovy fans say "write unit tests“
BUT…



                                                                                            Groovy




                                                                          When you have typos
                           versus




                                                                                                Java




     4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                           Slide 41
Unit tests don't always catch errors
  void testPollStatus_discoveringNewServer() {
       mockEC2RequestExecutor.demand.executeRequest {params ->
         ….
       }
       def mockEC2Server = new MockFor(EC2Server.class)
       ….
      mockEC2Server.use {
          mockEC2RequestExecutor.use {
             ec2 = new EC2(awsProperties)
             ec2.pollStatus()                 public class EC2 {
             assertEquals 1, ec2.servers.size()
          }                                     public pollStatus() {
       }                                          def params = ['Action':
    }                                                               'DescribeInstances']
                                                  def p =
                                                   requestor.executeRequest(params)
class EC2RequestExecutor {                         …
                                                }
 public Node executeEc2Request(Map            …
parameters) {                                 }         Method signature changes are
  …                                                     often missed
}

                                                                                          Slide 42
              4/3/11          Copyright (c) 2011 Chris Richardson. All rights reserved.
The trouble with duck typing
o  Interface between components not
   defined in a single place
o  It is scattered throughout callers
o  Difficult to understand
o  Difficult to change




      4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                           Slide 43
The outcome: fear of change

                                Did my tests
                                catch all
                                the obvious errors?




     4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                          Slide 44
Agenda
o  Evolution of programming languages
o  Favorite Groovy features
o  The frustration of using Groovy
o  Scala: expressiveness and
   compile-time checking
o  The trouble with Scala




      4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                           Slide 45
Distilling a language

                                                                                  Builders


                                                                                 Dynamic methods
                                                                                  and properties

                                                                                  Gpath-based
                                                                                  XML handling
                                                                               Dynamic features

                                                                                Static features


                                                                                   Closures


 Groovy
                                                                                   Literals for
                                                                                   collections
                                                                                    GStrings




          4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                                   Slide 46
Scala – a modern (2003) static
language
o  Object-oriented
   n  Pure object-oriented language
   n  All values are objects      “I can honestly say if someone had
   n  Class-based                 shown me the Programming in
                                                                 Scala book by by Martin Odersky,
o  Functional                                                    Lex Spoon & Bill Venners back in
   n  Functions are values                                      2003 I'd probably have never
                                                                 created Groovy.”
   n  Higher-order functions
   n  Currying                                                  James Strachan, Creator of Groovy
                                                                 http://macstrac.blogspot.com/
o  Statically typed                                              2009/04/scala-as-long-term-
   n  Expressive                                                replacement-for.html

   n  Type inference
o  Extensible to support domain specific languages
   n  Methods as infix and postfix operators
   n  Automatic closure construction


          4/3/11      Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                            Slide 47
The good news
o  Fully interoperable with Java
o  Interactive shell
o  Rich, extensible language
o  Closures
o  Good XML processing
o  Named arguments and default
   parameter values
o  Option class avoids null references
o  Traits provide “multiple inheritance”
       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 48
Scala command line




    4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                         Slide 49
Simple example
object StringFunctions {

    def reverseSentence(sentence : String) = sentence.split(" ").reverse.mkString(" ")

}




import org.junit._
import Assert._

@Test
class StringFunctionsTest {

     @Test
     def testReverseSentence() = {
       val input = "Hello New York"
       val expected = "York New Hello"
       assertEquals(expected, StringFunctions.reverseSentence(input))
     }
}


                 4/3/11         Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                            Slide 50
Collection literals example
@Test
class ScalaCollectionExamplesTest {

@Test
 def listExample() = {
   val myList = List(1, 2, 3)
   assertEquals(3, myList.length)
   assertEquals(List(0, 1, 2, 3), 0::myList)
   assertEquals(List(2, 3), myList.tail)
   assertEquals(1, myList.head)
 }

    @Test
    def testMapExampleList() : Unit = {
      val myMap = Map( "x" -> 1, "y" -> 2, "z" -> 3)
      assertEquals(1, myMap("x"))
    }
}




             4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                       Slide 51
Closure example

@Test
class ScalaCollectionExamplesTest {

    @Test
    def testMapList() = {
      val myList = List(1, 2, 3)
      assertEquals(List(2,4,6), myList.map ( x => x * 2))
      assertEquals(List(2,4,6), myList.map ( _ * 2))
    }

    @Test
    def testFilterList() = {
      val myList = List(1, 2, 3)
      assertEquals(List(1, 3), myList.filter( _ % 2 == 1));
    }

}




              4/3/11         Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                         Slide 52
Defining new control constructs 1
class ExampleControlConstructExampleTest {

def withOutputStream[T](f : File)(body : InputStream => T) = {
   val fis = new FileInputStream(f)
   try {
     body(fis)
   } finally {
     fis.close
   }
 }

 @Test
 def withOpenFileExample {
   withOutputStream(new File("/Users/cer/.bashrc")) {fis =>
     println(fis.available)
   }
 }

            4/3/11     Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                   Slide 53
Defining new control constructs 2

                                               By-name parameter




 var assertsEnabled = false

  def myAssert(message : String, assertion : => Boolean) {
    if (assertsEnabled) {
      if (!assertion)
        throw new RuntimeException(message)
    }
  }

  @Test
  def assertionsDisabled = {
    myAssert("never", { println("you will not see me") ; false })
  }




          4/3/11         Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                     Slide 54
Pattern matching
case class Organization(name: String,
     industry: Industry.Value, revenue: Double, assets: Double, liabilities: Double) {

}

object Industry extends Enumeration {
 val Banking, GreenEnergy, IT, Other = Value

}

class LoanApprovalPolicy {

    def isLoanApproved(organization : Organization) = organization match {
      case Organization(_, Industry.GreenEnergy, _, _, _) => true
      case Organization(_, Industry.Banking, _, assets, liabilities)
           if liabilities < assets * 1.5 => true
      case Organization(_, Industry.Banking, _, _, _) => false
      case Organization(_, _, _, assets, liabilities) if assets > liabilities => true
      case _ => false
    }

}


                  4/3/11          Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                              Slide 55
XML generation
@Test
class ScalaXmlExampleTest {

  @Test
  def xmlLiterals() {
   val now = new Date()
   val loanRequestor =
        new Organization("Community Bank, Inc", Industry.Banking, 10, 10, 5)

      val doc = <loanRequest>
             <time>{now.getTime()}</time>
             <requester>{loanRequestor.name}</requester>
             <industry>{loanRequestor.industry}</industry>
             <revenue>{loanRequestor.revenue}</revenue>
             <assets>{loanRequestor.assets}</assets>
             <liabilities>{loanRequestor.liabilities}</liabilities>
       </loanRequest>

      val docAsString : String = doc.toString()
      println(docAsString)
  }



                4/3/11         Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                           Slide 56
XML parsing
class ScalaXmlExampleTest {

  @Test
  def xmlProcessing() {
   val doc = xml.XML.loadString(docAsString)
   assertEquals ("Community Bank, Inc", (doc  "requester").text)

   doc match {
      case <loanRequest>{children @ _* }</loanRequest> =>
       for (x <- children if !x.isInstanceOf[scala.xml.Text]) {
         processChildren(x)
       }
    }
  }

  def processChildren(node : scala.xml.Node ) = {
    node match {
      case <time>{value}</time> => println(value.text)
      case <requester>{value}</requester> => println(value.text)
      …
    }
  }


              4/3/11          Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                          Slide 57
DSL Example
class OrganizationDslTest {
  val o : Organization = (Organization
                       called "Bernie Madoff & Associates"
                       in Industry.Banking
                       withRevenuesOf (10 million)
                       withAssetsOf (10 billion)
                       withLiabilitiesOf (30 billion))

}
     object Organization {
      def called(name : String) = new OrganizationBuilder(name)

      class OrganizationBuilder(name : String) {
        var industry : Industry.Value = null
        def in(industry : Industry.Value) = { this.industry = industry; this }
        def withRevenuesOf(…) = …
        …
        def make()= new Organization(name, industry, revenue, assets, liabilities)
     }

         implicit def organizationBuilderToOrganization(builder : OrganizationBuilder)
         = builder.make
     }

                 4/3/11         Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                            Slide 58
Named arguments and default values

o  Arguments can be named
o  Parameters can have default values
o  Benefits:
  n  Clearer code – Booleans aren’t so evil
  n  Avoids confusing overloaded methods/
      constructors
  n  Less need for the Builder pattern

def foo(x: Int = 10, y: Int = 20) = x * y

foo() should be(200)
foo(y = 30, x = 50) should be(1500)
foo(x = 50) should be(1000)

        4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                             Slide 59
Constructing object hierarchies
  object ExampleSwingApp extends SimpleGUIApplication {

      def top = new MainFrame {
        title = "Example Swing App"                                    Defines method declared
                                                                       abstract in superclass
          val button = new Button {
            text = "press"
          }                                                             Sets property
          contents = button

          var count = 0                                                   Statements/
          listenTo(button)
          reactions += {                                                  expressions that
            case ButtonClicked(b) =>                                      are executed
              count = count + 1
              Console.println(count);
              b.text = "press: " + count                                                 Nesting of new Class {
          }
      }                                                                                  }
                                                                                         mirrors object hierarchy
  }


              4/3/11         Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                                           Slide 60
Pimping existing classes
scala> 5.times { println("Hello") }
<console>:6: error: value times is not a member of Int
      5.times { println("Hello") }
       ^
scala> class IntWithTimes(n: Int) {
    |    def times(body: => Unit) = for (x <- 1 to n) body
    | }
defined class IntWithTimes

scala> implicit def toIntWithTimes(n: Int) = new IntWithTimes(n)
toIntWithTimes: (n: Int)IntWithTimes

scala> 5.times { println("Hello") }
Hello
Hello
Hello                                                                          Implicit conversion
Hello
Hello


              4/3/11     Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                               Slide 61
Implicit parameters 1
@Test
def implicitParamsImplicitVar {
 implicit val defaultValue = 8

    def m(i : Int) (implicit j : Int) = i * j

    assertEquals(48, m(6))

    assertEquals(42, m(6)(7))

}
         4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                              Slide 62
Implicit parameters 2
scala> implicit def toInt : Int = 5
toInt: Int

scala> def m(i : Int) (implicit j : Int) = i * j
m: (i: Int)(implicit j: Int)Int

scala> m(6)
res6: Int = 30

scala> m(6)(7)
res7: Int = 42
        4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                             Slide 63
Null References

                                        My Billion Dollar
                                            mistake




     4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                          Slide 64
Use Options instead of null…
var x : Option[Int] = Some(5)
var y : Option[Int] = None
var z : Option[Int] = Some(7)

assertEquals(5, x.get)
try {
   y.get
   fail
 } catch {
     case _ : NoSuchElementException =>
 }

assertEquals(5, x.getOrElse(10))
assertEquals(10, y.getOrElse(10))


         4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                              Slide 65
… more options
assertEquals(Some(7), x.map(_ + 2))
assertEquals(None, y.map(_ + 2))
assertEquals(None, x.filter(_ == 2))
assertEquals(Some(5), x.filter(_ == 5))

assertEquals(Some(35),
   for (a <- x ; b <- z) yield a * b)



       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 66
Traits
o  Consist of members
  n  methods
  n  fields
  n  types
o  The members can be abstract
o  Multiple traits can be mixed into a class
  n  Alternative to multiple inheritance
  n  Class must define abstract members
o  Uses:
  n  Modularizing applications
  n  Enriching interfaces
  n  Decorating classes

       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 67
RESTful WS using Spring MVC and
  Scala
o  Handling HTTP request                                          Photo management
   n    Extract values from URL
   n    Invoke appropriate handler
                                                                  application
   n    Generate response (XML)
o  Sounds like a job for Scala's                                  GET /album
   n    Pattern matching                                         GET /album/<albumId>
   n    XML support                                              POST /album
                                                                  …


                                                     <album>
                                                        <id>6699</id>
GET /album/6699                                          <photos>…</photos>
                                                         …
                                                     </album>


              4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                        Slide 68
Pattern matching HTTP Requests
  o  Match against
       n  URL – represented as a List
       n  Method
       n  …
  o  Returns XML
request match {
case Request(List("album"), "GET", _, _) =>
   listAlbums
case Request(List("album", albumId), "GET", _, _) =>
    findAlbum(albumId)
}
                                  def findAlbum(albumId : String) = {
                                     def album = albumService.findAlbum(albumId)
                                     <album>
                                      <id>{album.getId()}</id>
                                      <photos>…</photos>
                                      …
                                     </album>
                                   }


                4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                          Slide 69
The Extractor

object Request {
   def unapply(request : HttpServletRequest)
        : Option[ (List[String], String, RequestBody, Binder)]
     ={
     val path =
      List.fromArray(request.getPathInfo().split("/")).tail
     Some(path,
            request.getMethod,
            new RequestBody(request),
            new Binder(request))
   }
}



             4/3/11    Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                   Slide 70
Package as WSEndpoints
trait WsEndpoint extends PartialFunction[HttpServletRequest, Node] {

    def isDefinedAt(request : HttpServletRequest) = wsDispatchRules.isDefinedAt(request)

    def apply(request : HttpServletRequest) = wsDispatchRules(request)

    protected def wsDispatchRules : PartialFunction[HttpServletRequest, Node]

}         @Component
          class AlbumWsEndpoint extends WsEndpoint {

           @Autowired
           def setAlbumService(albumService : AlbumService) = …

           def wsDispatchRules = {
             case Request(List("album", albumId), "GET", _, _) => findAlbum(albumId)
             …
           }

           def findAlbum(albumId : String) = {
              def album = albumService.findAlbum(albumId)
              <album>…</album>
            }

                    4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                              Slide 71
Integrate with Spring MVC 1
@Component
class WsEndpointHandlerMapping extends HandlerMapping {

@Autowired
def setApplicationContext(applicationContext : ApplicationContext) {
  this.applicationContext = applicationContext
}

def endpoints = …applicationContext.getBeansOfType(classOf[WsEndpoint])…

override def getHandler(request : HttpServletRequest) : HandlerExecutionChain = {
   val endpointForRequest = endpoints.find( _.isDefinedAt(request))
   endpointForRequest match {
     case Some(endpoint) => new HandlerExecutionChain(endpoint)
     case None => null
   }
 }



                       Maps HTTP request to WSEndpoint



                  4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                            Slide 72
Integrate with Spring MVC 2
@Component
class WsEndpointHandlerAdapter extends HandlerAdapter {

 override def supports(handler : Object) = {
           handler.isInstanceOf[WsEndpoint]
 }

 override def handle(request : HttpServletRequest ,
                     response : HttpServletResponse , handler : Object ) : ModelAndView = {

     val endpoint = handler.asInstanceOf[WsEndpoint]

     val node = endpoint(request)
     response.setContentType("text/xml")
     response.getWriter.print(node.toString)

     null
 }


                Invokes WSEndpoint and generates HTTP response

                     4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                               Slide 73
Scala and Spring DI
o  Scala and Spring DI play together
o  @Component on Scala classes works
o  @Autowired fields:
  n  Annotation ends up on field and
      generated methods è fail
  n  Need to define and annotate setters




       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 74
Agenda
o  Evolution of programming languages
o  Favorite Groovy features
o  The frustration of using Groovy
o  Scala: expressiveness and compile-
   time checking
o  The trouble with Scala




      4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                           Slide 75
Really bad news
o  Scala IDEs are ok and slowly
   improving BUT have a really really
   long way to go compared to Java
o  Limited refactoring => painful to
   maintain code quality?




      4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                           Slide 76
More bad news…
o  Expressiveness comes from complex
   language features
o  Generics are better than Java but still
   complex
                   BUT
o  The investment in learning these
   features is repaid with every
   application you write


       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 77
…more bad news
o  Lift is not Grails (or Rails)
o  A subset of the Scala community has
   a functional programming background
   => Obsessed with their Monads
o  Implicit conversions make it possible
   to write “incomprehensible” code
o  Scala Collections != Java Collections
  n  BUT Implicit conversions simplify
      interoperability

       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 78
Summary
o  The Java Language has stagnated and
   need to be replaced
o  Dynamic languages are one option
o  But many benefits of those languages
   are due to good language design
o  Scala = expressiveness + static typing
o  But Grails derives much of its power
   from the dynamic features of Groovy
o  Therefore, choose the right tool:
  n  Web application è Use Groovy and Grails
  n  Complex business logic/middleware è
      Consider Scala

       4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                            Slide 79
Summary – Pessimistic view
o  Languages used by mainstream
   developers have improved
   substantially
o  But are those languages that much
   better than the 25+ year old “ivory
   tower” languages: LISP, Smalltalk,
   ML, … ?




      4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                           Slide 80
Final thoughts
o  Learn some languages including
   Haskell
o  Watch the 50 in 50 presentation by
   Guy Steele and Dick Gabriel:
   http://blog.jaoo.dk/2008/11/21/art-
   and-code-obscure-or-beautiful-code/

"Those who cannot remember the past
     are condemned to repeat it”
               http://en.wikipedia.org/wiki/George_Santayana




      4/3/11        Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                                Slide 81
The end
                                    Twitter:


                                    @crichardson


                                    Send email:

                                    chris@chrisrichardson.net




    4/3/11   Copyright (c) 2011 Chris Richardson. All rights reserved.
                                                                         Slide 82

Más contenido relacionado

Similar a In pursuit of expressivity: Groovy and Scala compared

Spark Intro @ analytics big data summit
Spark  Intro @ analytics big data summitSpark  Intro @ analytics big data summit
Spark Intro @ analytics big data summitSujee Maniyam
 
There is something about JavaScript - Choose Forum 2014
There is something about JavaScript - Choose Forum 2014There is something about JavaScript - Choose Forum 2014
There is something about JavaScript - Choose Forum 2014jbandi
 
Webpack & EcmaScript 6 (Webelement #32)
Webpack & EcmaScript 6 (Webelement #32)Webpack & EcmaScript 6 (Webelement #32)
Webpack & EcmaScript 6 (Webelement #32)srigi
 
Open Tracing, to order and understand your mess. - ApiConf 2017
Open Tracing, to order and understand your mess. - ApiConf 2017Open Tracing, to order and understand your mess. - ApiConf 2017
Open Tracing, to order and understand your mess. - ApiConf 2017Gianluca Arbezzano
 
Scality Launches Open Source Cloud Program with $100,000 Incentive Fund for S...
Scality Launches Open Source Cloud Program with $100,000 Incentive Fund for S...Scality Launches Open Source Cloud Program with $100,000 Incentive Fund for S...
Scality Launches Open Source Cloud Program with $100,000 Incentive Fund for S...Marc Villemade
 
Guidance, Code and Education: ScalaCenter and the Scala Community, Heather Mi...
Guidance, Code and Education: ScalaCenter and the Scala Community, Heather Mi...Guidance, Code and Education: ScalaCenter and the Scala Community, Heather Mi...
Guidance, Code and Education: ScalaCenter and the Scala Community, Heather Mi...OW2
 
How to migrate SourcePro apps from Solaris to Linux
How to migrate SourcePro apps from Solaris to LinuxHow to migrate SourcePro apps from Solaris to Linux
How to migrate SourcePro apps from Solaris to LinuxRogue Wave Software
 
"React Native" by Vanessa Leo e Roberto Brogi
"React Native" by Vanessa Leo e Roberto Brogi "React Native" by Vanessa Leo e Roberto Brogi
"React Native" by Vanessa Leo e Roberto Brogi ThinkOpen
 
Practicing at the Cutting Edge: Learning and Unlearning about Java Performance
Practicing at the Cutting Edge: Learning and Unlearning about Java PerformancePracticing at the Cutting Edge: Learning and Unlearning about Java Performance
Practicing at the Cutting Edge: Learning and Unlearning about Java PerformanceC4Media
 
JavaScript nicht nur für Programmierer: Einblicke in die weltweit am meisten ...
JavaScript nicht nur für Programmierer: Einblicke in die weltweit am meisten ...JavaScript nicht nur für Programmierer: Einblicke in die weltweit am meisten ...
JavaScript nicht nur für Programmierer: Einblicke in die weltweit am meisten ...Peter Hecker
 
Evolution of programming language
Evolution of programming languageEvolution of programming language
Evolution of programming languageSameer Saini
 
JBUG 11 - Outside The Java Box
JBUG 11 - Outside The Java BoxJBUG 11 - Outside The Java Box
JBUG 11 - Outside The Java BoxTikal Knowledge
 
Graal VM: Multi-Language Execution Platform
Graal VM: Multi-Language Execution PlatformGraal VM: Multi-Language Execution Platform
Graal VM: Multi-Language Execution PlatformThomas Wuerthinger
 
A Strong Object Recognition Using Lbp, Ltp And Rlbp
A Strong Object Recognition Using Lbp, Ltp And RlbpA Strong Object Recognition Using Lbp, Ltp And Rlbp
A Strong Object Recognition Using Lbp, Ltp And RlbpRikki Wright
 
Optimizing for programmer happiness
Optimizing for programmer happinessOptimizing for programmer happiness
Optimizing for programmer happinessJosh Schramm
 

Similar a In pursuit of expressivity: Groovy and Scala compared (20)

Spark Intro @ analytics big data summit
Spark  Intro @ analytics big data summitSpark  Intro @ analytics big data summit
Spark Intro @ analytics big data summit
 
There is something about JavaScript - Choose Forum 2014
There is something about JavaScript - Choose Forum 2014There is something about JavaScript - Choose Forum 2014
There is something about JavaScript - Choose Forum 2014
 
Webpack & EcmaScript 6 (Webelement #32)
Webpack & EcmaScript 6 (Webelement #32)Webpack & EcmaScript 6 (Webelement #32)
Webpack & EcmaScript 6 (Webelement #32)
 
Open Tracing, to order and understand your mess. - ApiConf 2017
Open Tracing, to order and understand your mess. - ApiConf 2017Open Tracing, to order and understand your mess. - ApiConf 2017
Open Tracing, to order and understand your mess. - ApiConf 2017
 
Scality Launches Open Source Cloud Program with $100,000 Incentive Fund for S...
Scality Launches Open Source Cloud Program with $100,000 Incentive Fund for S...Scality Launches Open Source Cloud Program with $100,000 Incentive Fund for S...
Scality Launches Open Source Cloud Program with $100,000 Incentive Fund for S...
 
Guidance, Code and Education: ScalaCenter and the Scala Community, Heather Mi...
Guidance, Code and Education: ScalaCenter and the Scala Community, Heather Mi...Guidance, Code and Education: ScalaCenter and the Scala Community, Heather Mi...
Guidance, Code and Education: ScalaCenter and the Scala Community, Heather Mi...
 
How to migrate SourcePro apps from Solaris to Linux
How to migrate SourcePro apps from Solaris to LinuxHow to migrate SourcePro apps from Solaris to Linux
How to migrate SourcePro apps from Solaris to Linux
 
Introduction of java
Introduction  of javaIntroduction  of java
Introduction of java
 
"React Native" by Vanessa Leo e Roberto Brogi
"React Native" by Vanessa Leo e Roberto Brogi "React Native" by Vanessa Leo e Roberto Brogi
"React Native" by Vanessa Leo e Roberto Brogi
 
Preparing for Scala 3
Preparing for Scala 3Preparing for Scala 3
Preparing for Scala 3
 
Jax keynote
Jax keynoteJax keynote
Jax keynote
 
NoSQL @ Qbranch -2010-04-15
NoSQL @ Qbranch -2010-04-15NoSQL @ Qbranch -2010-04-15
NoSQL @ Qbranch -2010-04-15
 
Practicing at the Cutting Edge: Learning and Unlearning about Java Performance
Practicing at the Cutting Edge: Learning and Unlearning about Java PerformancePracticing at the Cutting Edge: Learning and Unlearning about Java Performance
Practicing at the Cutting Edge: Learning and Unlearning about Java Performance
 
JavaScript nicht nur für Programmierer: Einblicke in die weltweit am meisten ...
JavaScript nicht nur für Programmierer: Einblicke in die weltweit am meisten ...JavaScript nicht nur für Programmierer: Einblicke in die weltweit am meisten ...
JavaScript nicht nur für Programmierer: Einblicke in die weltweit am meisten ...
 
Evolution of programming language
Evolution of programming languageEvolution of programming language
Evolution of programming language
 
JBUG 11 - Outside The Java Box
JBUG 11 - Outside The Java BoxJBUG 11 - Outside The Java Box
JBUG 11 - Outside The Java Box
 
Graal VM: Multi-Language Execution Platform
Graal VM: Multi-Language Execution PlatformGraal VM: Multi-Language Execution Platform
Graal VM: Multi-Language Execution Platform
 
A Strong Object Recognition Using Lbp, Ltp And Rlbp
A Strong Object Recognition Using Lbp, Ltp And RlbpA Strong Object Recognition Using Lbp, Ltp And Rlbp
A Strong Object Recognition Using Lbp, Ltp And Rlbp
 
Optimizing for programmer happiness
Optimizing for programmer happinessOptimizing for programmer happiness
Optimizing for programmer happiness
 
Core java part1
Core java  part1Core java  part1
Core java part1
 

Más de Chris Richardson

The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?Chris Richardson
 
More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternChris Richardson
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...Chris Richardson
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Chris Richardson
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsChris Richardson
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfChris Richardson
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Chris Richardson
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...Chris Richardson
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Chris Richardson
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 Chris Richardson
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureChris Richardson
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Chris Richardson
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled servicesChris Richardson
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Chris Richardson
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...Chris Richardson
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Chris Richardson
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...Chris Richardson
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationChris Richardson
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate PlatformChris Richardson
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolithChris Richardson
 

Más de Chris Richardson (20)

The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?
 
More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-pattern
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patterns
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled services
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders application
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate Platform
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith
 

Último

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 

Último (20)

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 

In pursuit of expressivity: Groovy and Scala compared

  • 1. In pursuit of expressivity: Groovy and Scala compared Chris Richardson Author of POJOs in Action Founder of CloudFoundry.com chris@chrisrichardson.net @crichardson
  • 2. Overall presentation goal Examine the good, the bad and the ugly aspects of developing with Groovy and Scala 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 2
  • 3. About Chris •  Grew up in England and live in Oakland, CA •  Over 25+ years of software development experience including 14 years of Java •  Speaker at JavaOne, SpringOne, NFJS, JavaPolis, Spring Experience, etc. •  Organize the Oakland JUG ( http://bit.ly/ebjava) and the Groovy Grails meetup (http://bit.ly/oakgrails) http://www.theregister.co.uk/2009/08/19/springsource_cloud_foundry/ 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 3
  • 4. Agenda o  Evolution of programming languages o  Favorite Groovy features o  The frustration of using Groovy o  Scala: expressiveness and compile- time checking o  The trouble with Scala 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 4
  • 5. Lots of programming languages This site lists 8512 languages, complete with 17837 bibliographic records featuring 11064 extracts from those references. It is in effect a family tree of languages with 5445 links, making it not only the biggest programming language family tree around, but also one of the largest idea-genealogical projects undertaken. http://hopl.murdoch.edu.au/ 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 5
  • 6. The Elite v. The Masses The Elite Mainstream o  Lisp o  Thought Lisp and n  Invented in the 1960s Smalltalk were: n  Dynamic functional n  Weird (Too different language from Algol) n  Dynamic object-oriented n  Too resource hungry language (mid-1980s) (probably were for the o  Smalltalk time) n  Invented in the 1970s o  So the mainstream used: n  Dynamic object-oriented Pascal, C, C++, …. language o  Not so safe, manual o  Safe, garbage collection, memory management, rich, … primitive, … 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 6
  • 7. LISP/CLOS – an early (late 1980s) dynamic language (defclass Account () ((account-id :accessor account-id :initarg :account-id) (balance :accessor account-balance :initarg :balance)) Develop by adding and ) changing program elements in a running VM (defmethod debit ((Account account) amount) (decf (account-balance account) amount)) (defmethod credit ((Account account) amount) (incf (account-balance account) amount)) CL-USER 5 > (setq a (make-instance 'account :account-id "abc123" :balance 10.0)) #<ACCOUNT 200C05AF> CL-USER 6 > (describe a) #<ACCOUNT 200C05AF> is an ACCOUNT ACCOUNT-ID "abc123" BALANCE 10.0 CL-USER 7 > (debit a 5) 5.0 CL-USER 8 > (describe a) #<ACCOUNT 200C05AF> is an ACCOUNT ACCOUNT-ID "abc123" BALANCE 5.0 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. 7
  • 8. … a very dynamic language (defclass Account () ((account-id :accessor account-id :initarg :account-id) Existing instances (balance :accessor account-balance :initarg :balance) are updated when (description :accessor account-description :initarg :description)) the class is redefined ) CL-USER 9 > (describe a) #<ACCOUNT 2168DCBF> is an ACCOUNT ACCOUNT-ID "abc123" BALANCE 10.0 DESCRIPTION #<unbound slot> CL-USER 10 > (setf (account-description a) "checking account") "checking account" CL-USER 11 > (describe a) #<ACCOUNT 2168DCBF> is an ACCOUNT ACCOUNT-ID "abc123" BALANCE 10.0 DESCRIPTION "checking account" 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. 8
  • 9. Along came Java o  Provided the masses with: n  Garbage collection n  Safety, reliability and security o  And 10+ years passed… 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 9
  • 10. Ruby on Rails woke up the Java community o  Ruby on Rails: n  Significantly more productive n  Simplicity of Convention over Configuration o  Motivated the Java community to improve: frameworks such as Spring improved considerably o  And… 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 10
  • 11. …Highlighted Problems with Java o  Tedious collection processing o  Painful object construction code n  No literals for collections n  Need to use Builders for creating hierarchies o  Tedious XML processing o  Types: n  Verbose declarations n  Generics are complicated o  Fixed set of control constructs o  Limited support for DSLs => o  Reopened the debate about programming languages o  Dynamic languages became interesting again 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 11
  • 12. Dynamic languages on the JVM o  JRuby n  http://jruby.codehaus.org n  Ruby on the JVM o  Jython n  http://www.jython.org/Project n  Python on the JVM o  Clojure n  http://clojure.org/ n  Functional programming language n  Software Transactional Memory n  … o  Groovy n  http://groovy.codehaus.org/ n  Java-compatible, dynamic language 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 12
  • 13. Small but growing 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 13
  • 14. Static languages on the JVM o  (Java) o  Fortress o  Gosu o  Scala o  … http://www.is-research.de/info/vmlanguages/?s=static 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 14
  • 15. Scala and Gosu adoption – Smaller but growing 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 15
  • 16. Agenda o  Evolution of programming languages o  Favorite Groovy features o  The frustration of using Groovy o  Scala: expressiveness and compile- time checking o  The trouble with Scala 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 16
  • 17. About Groovy o  Object-oriented, dynamic language o  Made popular by the Grails framework: n  Rails-like productivity n  Using robust Java frameworks including Spring and Hibernate 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 17
  • 18. The good news o  Easy to learn n  Designed to be Java compatible n  Interactive Shell o  Great support for DSLs o  Closures: n  Easy collection processing n  New control constructs o  Property/method missing mechanism o  Good XML handling o  Meta-classes for dynamically defining new program elements => foundation for Grails 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 18
  • 19. Intentionally compatible with Java o  Groovy objects are Java objects o  Groovy collections are Java collections o  Groovy can call Java n  e.g. leverage all those Java libraries o  Java can call Groovy, e.g. Groovy objects can be: n  Spring beans n  Hibernate objects o  Easy to write a module of a project Groovy => Easy to incrementally adopt 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 19
  • 20. Groovy can look like Java import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; class EC2RequestExecutor { Java-like syntax Log logger = LogFactory.getLog(getClass()) public String calculateRFC2104HMAC(String data, String key) { try { SecretKeySpec signingKey = new SecretKeySpec(key.getBytes("UTF8"), HMAC_SHA1_ALGORITHM) Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM) mac.init(signingKey) byte[] rawHmac = mac.doFinal(data.getBytes()) return new String(Base64.encodeBase64(rawHmac)) } catch (Exception e) { throw new RuntimeException("Failed to generate HMAC : ", e) } } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 20
  • 21. Groovy is concise and expressive def configureAsMaster() { writeFile fileName: "/etc/my.cnf", templateName: "/templates/master.my.cnf" restartService "mysqld" exec command: "mysql -u root", templateName: "/templates/createSchema.sql", No parens templateArgs: [schemaSpec: schemaSpec] Keyword parameters executeSchemaScripts() } class TomcatServer { tomcatServer.contexts No get…() def getContexts() { webApps.context } } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 21
  • 22. An interactive shell Great for experimentation and learning 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 22
  • 23. Literals for lists and maps def myList = ["a", "b", "c"] def params = ['Action': 'RunInstances', 'MinCount': n.toString(), 'MaxCount': n.toString(), ' ImageId': awsProperties."imageId.${instanceType}", 'KeyName': awsProperties.keyName, ' InstanceType': instanceType] + extraParams def response = requestor.executeRequest(params) 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 23
  • 24. GStrings o  Templating mechanism o  Embedded Groovy expressions o  Multi-line strings def schemaScript = """ DROP SCHEMA IF EXISTS ${schemaSpec.name}; CREATE SCHEMA ${schemaSpec.name}; """ 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 24
  • 25. Closures – collection processing public EC2Server findInstance(String instanceId) { def server = servers.find {instanceId == it.instanceId} if (server) return server else throw new RuntimeException(….) } assertEquals(["aa", "bb", "cc"], ["a", "b", "c"].collect { elem -> elem + elem } Simplified collection processing No ugly anonymous inner classes 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 25
  • 26. Closures – new control structures public class Ssh { def withTunnel(String publicDnsName, int localPort, int remotePort, Closure closure) { SshConnection sshConnection = makeSshConnection(publicDnsName); try { sshConnection.connect() … return closure.call() } finally { sshConnection.close() } } } class EC2 { String snapshotEbsVolume(String hostName, EbsVolume ebsVolume, String schemaName) { int localPort = PortUtil.allocatePort() def result = ssh.withTunnel(hostName, localPort, 3306) { … } return (String)result } } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 26
  • 27. Closures details groovy:000> x = { println z } ===> groovysh_evaluate $_run_closure1@658ba380 groovy:000> x.delegate = [z: 99] ===> Foo@564a5320 groovy:000> x.call() Used to resolve 99 unbound methods and properties ===> null For example, Builders set the delegate 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 27
  • 28. Simple reusable code interface Quackable { void quack(); Java: } complexity of class QuackableContainer<T extends Quackable> generics void add(T element) { element.quack(); … } … } class QuackableContainer { Groovy: just assume that void add(element) { there is a quack() method element.quack() … } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 28
  • 29. Method Missing public class ClassWithMissingMethods { def methodMissing(String name, args) { Closure method = makeMethodImplementation(name) if (method) { method(args) } else { throw new MissingMethodException(name, getClass(), args) } } def makeMethodImplementation(String name) { …. } } def foo = new ClassWithMissingMethods() foo.nonExistentMethod() 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 29
  • 30. Groovy metaclasses public class StringMetaclassExampleTest extends GroovyTestCase { void testAddMethodToString() { String.metaClass.doubleString = { -> delegate + delegate } String.metaClass.static.makePowerString = { String s, int n -> def result = s n.times { result = result.doubleString() } result } assertEquals "JavaZoneJavaZone", "JavaZone".doubleString() assertEquals "OsloOsloOsloOslo", String.makePowerString("Oslo", 2) } } Runtime definition of program elements The foundation of many powerful features 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 30
  • 31. XML and GPath expressions <RunInstancesResponse> … <instancesSet> <item> <instanceId>i-4ef21327</instanceId> <imageId>ami-3795705e</imageId> <instanceState> <code>0</code> def client = new HttpClient() <name>pending</name> … </instanceState> def responseStream = <dnsName/> … getMethod.getResponseBodyAsStream() </RunInstancesResponse> def parser = new XmlParser(false, false) def response = parser.parseText(responseStream) def newServers = response.instancesSet.item.collect { new EC2Server(this, awsProperties, ssh, it.instanceId.text(), it.instanceState.name.text()) } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 31
  • 32. Metaclasses enhance JDK classes groovy:000> new File("/Users/cer/.bashrc").text ===> export PATH=/Users/cer/tools/apache-maven-3.0/bin: $PATH groovy:000> l = [1,2,3] ===> [1, 2, 3] groovy:000> l.getClass() ===> class java.util.ArrayList groovy:000> l.getClass().metaClass.foo = { delegate.size } ===> groovysh_evaluate$_run_closure1@13a66c87 groovy:000> l.foo() ===> 3 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 32
  • 33. Builders def report(String path, hosts, cpuCount, threadCount) { def builder = new groovy.xml.MarkupBuilder(new OutputStreamWriter(new FileOutputStream(path))) builder.performanceReport { cpus cpuCount threads threadCount hosts.entrySet().each {hostName, metric -> host { name hostName <performanceReport> cpuUtil metric.getAverageBusy() <cpus>1</cpus> } <threads>10</threads> } <host> requests { timing.sort{ a, b-> a.key <=> b.key}.each{ requestName, metric-> <name>database</name> request { <cpuUtil>3.27</cpuUtil> name requestName </host> art metric.average() <host> errors metric.errorPercentage() <name>tomcat0</name> } } <cpuUtil>94.32</cpuUtil> } </host> def durationValue = (endTime – startTime)/1000.0 … duration durationValue <duration>557.943</duration> def tpsValue = transactionCount/ durationValue <tps>10.753786677133686</tps> tps tpsValue art averageResponseTime() <art>916.6578333333</art> } </performanceReport> } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 33
  • 34. Grails plugins use metaclasses o  Key part of the Grails plugins o  Plugins can dynamically add methods, e.g. GORM persistence methods o  Injected methods are closures that have access to the Spring application context n  Less need for traditional dependency injection n  Alternative to AOP static crosscutting or (non-POJO) inheritance 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 34
  • 35. Grails/GORM persistence methods class Customer { Implemented using String name metaclasses and method } missing Customer c = new Customer("John Doe") if (!c.save()) fail "validation failed: ${c.errors}" Customer c2 = Customer.get(c.id) c2.delete() assertNull Customer.get(c.id) def customers = Customer.findAllByName(“Fred”) 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 35
  • 36. Commentable plugin example class CommentableGrailsPlugin { def doWithDynamicMethods = { ctx -> for(domainClass in application.domainClasses) { if(Commentable.class.isAssignableFrom(domainClass.clazz)) { domainClass.clazz.metaClass { 'static' { getRecentComments {-> … } } addComment { poster, String text -> } getComments = {-> } … } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 36
  • 37. Grails DSL for ORM class Customer { static transients = ["networth"] static mapping = { id column: ‘customer_id’ Closures table ‘crc_customer’ columns { } name column: ‘customer_name’ Method } missing def getNetworth() { … } } ... 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 37
  • 38. Grails Controllers - o  Accessing request/response o  Databinding n  b.properties = params n  new B(params) o  … 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 38
  • 39. Agenda o  Evolution of programming languages o  Favorite Groovy features o  The frustration of using Groovy o  Scala: expressiveness and compile- time checking o  The trouble with Scala 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 39
  • 40. Getting complex Groovy code to work can be frustrating o  Dynamic language = less information for IDE: n  Limited compile-time checking n  Limited refactorings n  Limited completion n  No todo list of errors 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 40
  • 41. Groovy fans say "write unit tests“ BUT… Groovy When you have typos versus Java 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 41
  • 42. Unit tests don't always catch errors void testPollStatus_discoveringNewServer() { mockEC2RequestExecutor.demand.executeRequest {params -> …. } def mockEC2Server = new MockFor(EC2Server.class) …. mockEC2Server.use { mockEC2RequestExecutor.use { ec2 = new EC2(awsProperties) ec2.pollStatus() public class EC2 { assertEquals 1, ec2.servers.size() } public pollStatus() { } def params = ['Action': } 'DescribeInstances'] def p = requestor.executeRequest(params) class EC2RequestExecutor { … } public Node executeEc2Request(Map … parameters) { } Method signature changes are … often missed } Slide 42 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved.
  • 43. The trouble with duck typing o  Interface between components not defined in a single place o  It is scattered throughout callers o  Difficult to understand o  Difficult to change 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 43
  • 44. The outcome: fear of change Did my tests catch all the obvious errors? 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 44
  • 45. Agenda o  Evolution of programming languages o  Favorite Groovy features o  The frustration of using Groovy o  Scala: expressiveness and compile-time checking o  The trouble with Scala 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 45
  • 46. Distilling a language Builders Dynamic methods and properties Gpath-based XML handling Dynamic features Static features Closures Groovy Literals for collections GStrings 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 46
  • 47. Scala – a modern (2003) static language o  Object-oriented n  Pure object-oriented language n  All values are objects “I can honestly say if someone had n  Class-based shown me the Programming in Scala book by by Martin Odersky, o  Functional Lex Spoon & Bill Venners back in n  Functions are values 2003 I'd probably have never created Groovy.” n  Higher-order functions n  Currying James Strachan, Creator of Groovy http://macstrac.blogspot.com/ o  Statically typed 2009/04/scala-as-long-term- n  Expressive replacement-for.html n  Type inference o  Extensible to support domain specific languages n  Methods as infix and postfix operators n  Automatic closure construction 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 47
  • 48. The good news o  Fully interoperable with Java o  Interactive shell o  Rich, extensible language o  Closures o  Good XML processing o  Named arguments and default parameter values o  Option class avoids null references o  Traits provide “multiple inheritance” 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 48
  • 49. Scala command line 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 49
  • 50. Simple example object StringFunctions { def reverseSentence(sentence : String) = sentence.split(" ").reverse.mkString(" ") } import org.junit._ import Assert._ @Test class StringFunctionsTest { @Test def testReverseSentence() = { val input = "Hello New York" val expected = "York New Hello" assertEquals(expected, StringFunctions.reverseSentence(input)) } } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 50
  • 51. Collection literals example @Test class ScalaCollectionExamplesTest { @Test def listExample() = { val myList = List(1, 2, 3) assertEquals(3, myList.length) assertEquals(List(0, 1, 2, 3), 0::myList) assertEquals(List(2, 3), myList.tail) assertEquals(1, myList.head) } @Test def testMapExampleList() : Unit = { val myMap = Map( "x" -> 1, "y" -> 2, "z" -> 3) assertEquals(1, myMap("x")) } } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 51
  • 52. Closure example @Test class ScalaCollectionExamplesTest { @Test def testMapList() = { val myList = List(1, 2, 3) assertEquals(List(2,4,6), myList.map ( x => x * 2)) assertEquals(List(2,4,6), myList.map ( _ * 2)) } @Test def testFilterList() = { val myList = List(1, 2, 3) assertEquals(List(1, 3), myList.filter( _ % 2 == 1)); } } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 52
  • 53. Defining new control constructs 1 class ExampleControlConstructExampleTest { def withOutputStream[T](f : File)(body : InputStream => T) = { val fis = new FileInputStream(f) try { body(fis) } finally { fis.close } } @Test def withOpenFileExample { withOutputStream(new File("/Users/cer/.bashrc")) {fis => println(fis.available) } } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 53
  • 54. Defining new control constructs 2 By-name parameter var assertsEnabled = false def myAssert(message : String, assertion : => Boolean) { if (assertsEnabled) { if (!assertion) throw new RuntimeException(message) } } @Test def assertionsDisabled = { myAssert("never", { println("you will not see me") ; false }) } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 54
  • 55. Pattern matching case class Organization(name: String, industry: Industry.Value, revenue: Double, assets: Double, liabilities: Double) { } object Industry extends Enumeration { val Banking, GreenEnergy, IT, Other = Value } class LoanApprovalPolicy { def isLoanApproved(organization : Organization) = organization match { case Organization(_, Industry.GreenEnergy, _, _, _) => true case Organization(_, Industry.Banking, _, assets, liabilities) if liabilities < assets * 1.5 => true case Organization(_, Industry.Banking, _, _, _) => false case Organization(_, _, _, assets, liabilities) if assets > liabilities => true case _ => false } } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 55
  • 56. XML generation @Test class ScalaXmlExampleTest { @Test def xmlLiterals() { val now = new Date() val loanRequestor = new Organization("Community Bank, Inc", Industry.Banking, 10, 10, 5) val doc = <loanRequest> <time>{now.getTime()}</time> <requester>{loanRequestor.name}</requester> <industry>{loanRequestor.industry}</industry> <revenue>{loanRequestor.revenue}</revenue> <assets>{loanRequestor.assets}</assets> <liabilities>{loanRequestor.liabilities}</liabilities> </loanRequest> val docAsString : String = doc.toString() println(docAsString) } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 56
  • 57. XML parsing class ScalaXmlExampleTest { @Test def xmlProcessing() { val doc = xml.XML.loadString(docAsString) assertEquals ("Community Bank, Inc", (doc "requester").text) doc match { case <loanRequest>{children @ _* }</loanRequest> => for (x <- children if !x.isInstanceOf[scala.xml.Text]) { processChildren(x) } } } def processChildren(node : scala.xml.Node ) = { node match { case <time>{value}</time> => println(value.text) case <requester>{value}</requester> => println(value.text) … } } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 57
  • 58. DSL Example class OrganizationDslTest { val o : Organization = (Organization called "Bernie Madoff & Associates" in Industry.Banking withRevenuesOf (10 million) withAssetsOf (10 billion) withLiabilitiesOf (30 billion)) } object Organization { def called(name : String) = new OrganizationBuilder(name) class OrganizationBuilder(name : String) { var industry : Industry.Value = null def in(industry : Industry.Value) = { this.industry = industry; this } def withRevenuesOf(…) = … … def make()= new Organization(name, industry, revenue, assets, liabilities) } implicit def organizationBuilderToOrganization(builder : OrganizationBuilder) = builder.make } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 58
  • 59. Named arguments and default values o  Arguments can be named o  Parameters can have default values o  Benefits: n  Clearer code – Booleans aren’t so evil n  Avoids confusing overloaded methods/ constructors n  Less need for the Builder pattern def foo(x: Int = 10, y: Int = 20) = x * y foo() should be(200) foo(y = 30, x = 50) should be(1500) foo(x = 50) should be(1000) 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 59
  • 60. Constructing object hierarchies object ExampleSwingApp extends SimpleGUIApplication { def top = new MainFrame { title = "Example Swing App" Defines method declared abstract in superclass val button = new Button { text = "press" } Sets property contents = button var count = 0 Statements/ listenTo(button) reactions += { expressions that case ButtonClicked(b) => are executed count = count + 1 Console.println(count); b.text = "press: " + count Nesting of new Class { } } } mirrors object hierarchy } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 60
  • 61. Pimping existing classes scala> 5.times { println("Hello") } <console>:6: error: value times is not a member of Int 5.times { println("Hello") } ^ scala> class IntWithTimes(n: Int) { | def times(body: => Unit) = for (x <- 1 to n) body | } defined class IntWithTimes scala> implicit def toIntWithTimes(n: Int) = new IntWithTimes(n) toIntWithTimes: (n: Int)IntWithTimes scala> 5.times { println("Hello") } Hello Hello Hello Implicit conversion Hello Hello 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 61
  • 62. Implicit parameters 1 @Test def implicitParamsImplicitVar { implicit val defaultValue = 8 def m(i : Int) (implicit j : Int) = i * j assertEquals(48, m(6)) assertEquals(42, m(6)(7)) } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 62
  • 63. Implicit parameters 2 scala> implicit def toInt : Int = 5 toInt: Int scala> def m(i : Int) (implicit j : Int) = i * j m: (i: Int)(implicit j: Int)Int scala> m(6) res6: Int = 30 scala> m(6)(7) res7: Int = 42 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 63
  • 64. Null References My Billion Dollar mistake 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 64
  • 65. Use Options instead of null… var x : Option[Int] = Some(5) var y : Option[Int] = None var z : Option[Int] = Some(7) assertEquals(5, x.get) try { y.get fail } catch { case _ : NoSuchElementException => } assertEquals(5, x.getOrElse(10)) assertEquals(10, y.getOrElse(10)) 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 65
  • 66. … more options assertEquals(Some(7), x.map(_ + 2)) assertEquals(None, y.map(_ + 2)) assertEquals(None, x.filter(_ == 2)) assertEquals(Some(5), x.filter(_ == 5)) assertEquals(Some(35), for (a <- x ; b <- z) yield a * b) 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 66
  • 67. Traits o  Consist of members n  methods n  fields n  types o  The members can be abstract o  Multiple traits can be mixed into a class n  Alternative to multiple inheritance n  Class must define abstract members o  Uses: n  Modularizing applications n  Enriching interfaces n  Decorating classes 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 67
  • 68. RESTful WS using Spring MVC and Scala o  Handling HTTP request Photo management n  Extract values from URL n  Invoke appropriate handler application n  Generate response (XML) o  Sounds like a job for Scala's GET /album n  Pattern matching GET /album/<albumId> n  XML support POST /album … <album> <id>6699</id> GET /album/6699 <photos>…</photos> … </album> 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 68
  • 69. Pattern matching HTTP Requests o  Match against n  URL – represented as a List n  Method n  … o  Returns XML request match { case Request(List("album"), "GET", _, _) => listAlbums case Request(List("album", albumId), "GET", _, _) => findAlbum(albumId) } def findAlbum(albumId : String) = { def album = albumService.findAlbum(albumId) <album> <id>{album.getId()}</id> <photos>…</photos> … </album> } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 69
  • 70. The Extractor object Request { def unapply(request : HttpServletRequest) : Option[ (List[String], String, RequestBody, Binder)] ={ val path = List.fromArray(request.getPathInfo().split("/")).tail Some(path, request.getMethod, new RequestBody(request), new Binder(request)) } } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 70
  • 71. Package as WSEndpoints trait WsEndpoint extends PartialFunction[HttpServletRequest, Node] { def isDefinedAt(request : HttpServletRequest) = wsDispatchRules.isDefinedAt(request) def apply(request : HttpServletRequest) = wsDispatchRules(request) protected def wsDispatchRules : PartialFunction[HttpServletRequest, Node] } @Component class AlbumWsEndpoint extends WsEndpoint { @Autowired def setAlbumService(albumService : AlbumService) = … def wsDispatchRules = { case Request(List("album", albumId), "GET", _, _) => findAlbum(albumId) … } def findAlbum(albumId : String) = { def album = albumService.findAlbum(albumId) <album>…</album> } 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 71
  • 72. Integrate with Spring MVC 1 @Component class WsEndpointHandlerMapping extends HandlerMapping { @Autowired def setApplicationContext(applicationContext : ApplicationContext) { this.applicationContext = applicationContext } def endpoints = …applicationContext.getBeansOfType(classOf[WsEndpoint])… override def getHandler(request : HttpServletRequest) : HandlerExecutionChain = { val endpointForRequest = endpoints.find( _.isDefinedAt(request)) endpointForRequest match { case Some(endpoint) => new HandlerExecutionChain(endpoint) case None => null } } Maps HTTP request to WSEndpoint 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 72
  • 73. Integrate with Spring MVC 2 @Component class WsEndpointHandlerAdapter extends HandlerAdapter { override def supports(handler : Object) = { handler.isInstanceOf[WsEndpoint] } override def handle(request : HttpServletRequest , response : HttpServletResponse , handler : Object ) : ModelAndView = { val endpoint = handler.asInstanceOf[WsEndpoint] val node = endpoint(request) response.setContentType("text/xml") response.getWriter.print(node.toString) null } Invokes WSEndpoint and generates HTTP response 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 73
  • 74. Scala and Spring DI o  Scala and Spring DI play together o  @Component on Scala classes works o  @Autowired fields: n  Annotation ends up on field and generated methods è fail n  Need to define and annotate setters 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 74
  • 75. Agenda o  Evolution of programming languages o  Favorite Groovy features o  The frustration of using Groovy o  Scala: expressiveness and compile- time checking o  The trouble with Scala 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 75
  • 76. Really bad news o  Scala IDEs are ok and slowly improving BUT have a really really long way to go compared to Java o  Limited refactoring => painful to maintain code quality? 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 76
  • 77. More bad news… o  Expressiveness comes from complex language features o  Generics are better than Java but still complex BUT o  The investment in learning these features is repaid with every application you write 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 77
  • 78. …more bad news o  Lift is not Grails (or Rails) o  A subset of the Scala community has a functional programming background => Obsessed with their Monads o  Implicit conversions make it possible to write “incomprehensible” code o  Scala Collections != Java Collections n  BUT Implicit conversions simplify interoperability 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 78
  • 79. Summary o  The Java Language has stagnated and need to be replaced o  Dynamic languages are one option o  But many benefits of those languages are due to good language design o  Scala = expressiveness + static typing o  But Grails derives much of its power from the dynamic features of Groovy o  Therefore, choose the right tool: n  Web application è Use Groovy and Grails n  Complex business logic/middleware è Consider Scala 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 79
  • 80. Summary – Pessimistic view o  Languages used by mainstream developers have improved substantially o  But are those languages that much better than the 25+ year old “ivory tower” languages: LISP, Smalltalk, ML, … ? 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 80
  • 81. Final thoughts o  Learn some languages including Haskell o  Watch the 50 in 50 presentation by Guy Steele and Dick Gabriel: http://blog.jaoo.dk/2008/11/21/art- and-code-obscure-or-beautiful-code/ "Those who cannot remember the past are condemned to repeat it” http://en.wikipedia.org/wiki/George_Santayana 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 81
  • 82. The end Twitter: @crichardson Send email: chris@chrisrichardson.net 4/3/11 Copyright (c) 2011 Chris Richardson. All rights reserved. Slide 82