250 likes | 469 Views
Groovy. Making Java more funky. Why?. Compared to scripting languages like Ruby and Python, Java is starting to look very verbose A lot of coding is required for unit tests these days Dynamically typed languages can be more productive
E N D
Groovy Making Java more funky
Why? • Compared to scripting languages like Ruby and Python, Java is starting to look very verbose • A lot of coding is required for unit tests these days • Dynamically typed languages can be more productive • However the Java platform rocks & there’s tons of good stuff to reuse, lets build on it, not move away from it • Java should have its own native scripting language using all the neat features from Ruby, Python, C# etc
Aims • To be simple, powerful and concise • Allow any Groovy class/script to be compiled into bytecode for seamless integration into any Java project (e.g. implementing Java interfaces, being JUnit test cases etc) • Work nicely in scripting use cases such as glue to configure components, UIs, build systems etc • Be the default choice for unit tests & an alternative to complex XML config files
Why not Ruby, Python, … • Want something that generates normal Java classes that can be used in Java land inside a Java project • Want to keep the Java platform & APIs - just have a better syntax - rather than learning a whole new API • Designed by and for Java programmers and to use Java friendly syntax and reuse the Java platform • We can do better than the alternatives! • Right tool for the right job • Groovy’s initial niche is scripting, constructing and testing Java objects
Quick taster class Foo { doSomething() { [‘edam’, ‘cheddar’, ‘brie’].each { cheese | print “I like ${cheese}” } for ch in “some text” { print(c) } sql.query(“select * from foo where x = ${bar}”) { results | print “hello ${results.name} you like ${results.cheese}” } }
Differences from Java • Dynamic and Static typing • Native XPath like expression language for easy object navigation • Closures & blocks & iteration • Neat syntax for maps & lists • New markup syntax for working with structured data in a neat way (build files, UI configs, component configurations etc) • New helper methods added to the JDK • New keywords
Dynamic & Static typing • Both dynamically and statically typed • You get to choose when to be dynamic and when to use static typing • x = 123 • y = “hello “ + x • Or • Integer x = 123 • String y = “hello” + x
Dynamic and static typing • For ‘scripts’ you can keep completely dynamically typed and work like Ruby / Python • If you wish to expose a method / interface back to Java land you can use static typing • I.e. specifying types of variables, parameters and return types is optional to use when you want/need • To have full control over interface implementation & method overloaded when working in a Java world
Native expression language • Its common to do assertions & comparisons which can get lengthy in Java • No casting required in Groovy, plus path navigations through collections, beans, maps, arrays are all possible assert customer.orders.filter { o | o.amount > 1000 }.size() > 2 assert foo.propertyA[12].propertyB == 123 for x in customer.orders.deliveryNote { .. } • Pretty much all XPath like things are possible directly on Java objects together with logical branching, looping, assertions etc
Neat syntax for maps & lists • Both lists and maps are first class language constructs foo = [1, 2, [4, 5], ‘hello’] assert foo instanceof List bar = [‘james’:’Cheddar’, ‘bob’:’Edam’] assert bar.james == ‘Cheddar’ assert bar[‘bob’] == ‘Edam’
New markup syntax • Alternative to XML but much less typing. Similar to native Map & List notation but for trees of anything • Can be used to support the construction & processing of any markup (beans, UIs, XML, database stuff, whatever) • Works in event based or ‘DOMish’ style modes
New markup syntax foo = swing.frame(title:’Cheese’) { panel { borderLayout { center { table(model:new MySpecialTableModel(someParam)) } south { panel { button(text:”Eat", actionListener:{ bar.eatCheese() }) button(text:"Cancel", actionListener:{ bar.close() }) } } } } }
Use case: build systems Maven.project(default:jar) { goal(name:’war’, depends:[compile, test]) { for d in pom.dependencies { if d.id.startsWith(“commons-”) { copy(destdir:”${basedir}/foo”) { includes(name:”**/*.groovy”) } } } } }
Use case: containers import org.blah.Foo Import org.acme.*; main(args) { builder = new NanoContainerBuilder() container(class:NanoContainer) { component(class:Foo) component(class:Bar, params:[123, “Cheese”]) container(class:PicoContainer) { component(class:Whatnot) component(class:Foo, param1:123, param2:new Cheese('edam'))} componentByKey("OrderDatabase", SomeHelper.createJdbConnection("order")) componentByKey("SalesDatabase", SomeHelper.createJdbConnection("sales") ) } } }
New language features • Operator overloading • Mixins • Properties syntax for easy definition of beans • Ditto for working with listeners & event handlers via closures • Using keyword for easier auto-closing of resources. • Or use closures • Easy method interception on classes or objects • Use MetaClass for method & property dispatching so easy to do wacky things if needed
New helper methods added to the JDK • In GroovyLand we can add new methods to the JDK to help productivity & polymorphism • E.g. new closure methods: each, select, filter, collect • Helper methods for easier coding [5, 2, 4].sort() >>> [2, 4, 5] someArray.print() >>> [foo, bar]
Operator overloading • Lots of stuff in Java is just plain hard for no good reason. Lets allow operator overloading to make things easier • working with collections, data structures, numeric types etc map = [1:23, 4:56] map[1] = ‘abcdef’ num = aBigDecimal * 1234.545
Everything is an object • No need for the horribleness of boxing & unboxing list = [1, 2, 3] list.add(6) list.add(“abcdef”) X = list[2]
Things to ponder • …
Support XSD/SQL named tuples • See the XS paper • Named tuples with automatic cardinality validations • Ideal for working with XML or SQL data • Allows typed structures to be defined Class Author { String name PhoneNumber* phoneNumbers Address+ address } Notice the use of *, +, !, ? which is like the use in DTD to specify cardinality
XSD / SQL named tuples • It’d be easy to map relational queries or XML to these tuples for nice processing in Groovy • Could be dynamic at runtime or static in build process • Essentially this provides XSD-like validation, very cheaply & easily • Can be implemented very efficiently • Generating bytecode dynamically representing the static schemas using static typing
Where we are today • We have the parser & bytecode generator working with most basic functionality • Classes, properties, method calls, closures, maps, lists, markup, assertions, looping & branching etc • We’re already using Groovy to unit test Groovy • Still a bit of work to do on the parser • First beta release should be soon I hope • A week or two if bob gets cracking :)