3. Osoco
• Small but outstanding • Quality preachers
software development
shop • TDD mantra singers
• Groovy and Grails • On EC2 cloud nine
hackers
4. Osoco
• Small but outstanding • Quality preachers
software development
shop • TDD mantra singers
• Groovy and Grails • On EC2 cloud nine
hackers
Julián David
6. Polyglot programming
• term coined 2006 by Neil Ford
• general + special-purpose languages
• http://memeagora.blogspot.com/2006/12/polyglot-
programming.html
14. Why polyglot?
• General purpose languages evolve too
slowly
• Specific-languages solve specific problems
(DSLs included)
• New challenges
• Old habits die hard
16. Do we have to speak
Groovy with Grails?
• Yes...
• Groovy and Grails are inseparable
17. Do we have to speak
Groovy with Grails?
• Yes...
• Groovy and Grails are inseparable
• But...
• Non-Groovy code can be executed from
Grails components
23. Functional language
• Not pure functional
• Explicit state management
• Immutable, lazy and infinite data structures
• Higher-order functions
• Dynamically typed*
24. Functional language
• Not pure functional
• Explicit state management
• Immutable, lazy and infinite data structures
• Higher-order functions
• Dynamically typed*
25. Lisp reloaded
• Everything is sequence (extended Lisp list)
• Extended data structures - maps, sets
• Less parentheses, commas = whitespaces
• Multimethods dispatch on anything
• Metadata
• Tail call optimization on JVM
26. Lisp reloaded
• Everything is sequence (extended Lisp list)
• Extended data structures - maps, sets
• Less parentheses, commas = whitespaces
• Multimethods dispatch on anything
• Metadata
• Tail call optimization on JVM
45. Why Scala in Grails?
• High performance without Java
• Functional features
• DSLs
46. Why Scala in Grails?
• High performance without Java
• Functional features
• DSLs
47. Scala and Grails
• Install Scala plugin
http://www.grails.org/plugin/scala
grails install-plugin scala
• Put your source under src/scala
• Add explicit Scala dependencies
compile "org.scala-lang:scala-compiler:2.9.1",
"org.scala-lang:scala-library:2.9.1"
48. Scala and Grails
• Install Scala plugin
http://www.grails.org/plugin/scala
grails install-plugin scala
• Put your source under src/scala
• Add explicit Scala dependencies
compile "org.scala-lang:scala-compiler:2.9.1",
"org.scala-lang:scala-library:2.9.1"
49. Demo
shortest path
• Calculate shortest path
between two cities
• Use Scala4Graph library
50. Demo
shortest path
• Calculate shortest path
between two cities
• Use Scala4Graph library
51. Plugin gotchas
• No access to Groovy/Grails classes
• Execute Grails with --verbose option for
Scala compiler error
• No IDE support for executing Scala code
tests
52. Plugin gotchas
• No access to Groovy/Grails classes
• Execute Grails with --verbose option for
Scala compiler error
• No IDE support for executing Scala code
tests
53. Plugin gotchas
• DSL objects must be 100% Scala
• Boilerplate code for accessing Scala results
scalaList.foreach(
[apply: {groovyList << it}] as Function1
)
• Scala components can be Spring beans
54. Plugin gotchas
• DSL objects must be 100% Scala
• Boilerplate code for accessing Scala results
scalaList.foreach(
[apply: {groovyList << it}] as Function1
)
• Scala components can be Spring beans
55. Ruby
• JRuby - Ruby 1.8.7 & 1.9.2 compatible
• Object-oriented, dynamic
• Some functional features
• Tones of gems
56. Ruby
• JRuby - Ruby 1.8.7 & 1.9.2 compatible
• Object-oriented, dynamic
• Some functional features
• Tones of gems
57. Why Ruby in Grails?
• Hard to find a valid reason...
• Rails app migration to Grails?
• Particular gem?
58. Why Ruby in Grails?
• Hard to find a valid reason...
• Rails app migration to Grails?
• Particular gem?
59. Ruby and Grails
• Install Ruby plugin
http://www.grails.org/plugin/ruby
grails install-plugin ruby
• Put your sources under src/ruby
• Access Ruby code through ruby property
60. Ruby and Grails
• Install Ruby plugin
http://www.grails.org/plugin/ruby
grails install-plugin ruby
• Put your sources under src/ruby
• Access Ruby code through ruby property
65. Speak your mother
tongue
• plug in your compiler on compileStart
event (Scala plugin)
• use JSR223 javax.script.ScriptEngine
(Ruby plugin)
• use custom interpreter (Clojure plugin,
clojure.lang.Compiler)
• trigger code reloading when changed
Person: polyglot is someone with a high degree of proficiency in several languages; hyperpolyglot: more that 6 languages\nComputing: polyglot is a computer program or script written in a valid form of multiple programming languages, which performs the same operations or output independent of the programming language used to compile or interpret it.\n
My first professional work as a software developer was writing Clipper code. Clipper was a compiler for dBASE code with object-oriented extensions. This was in the days of DOS, and the entire application was written in a single language. We didn't even use SQL. Instead, the data storage was shared DBF files on a new concept, the LAN (I remember reading a PC-Magazine of that era declaring that the current year was the "Year of the LAN").\n\nWe are entering a new era of software development. For most of our (short) history, we've primarily written code in a single language. Of course, there are exceptions: most applications now are written with both a general purpose language and SQL. Now, increasingly, we're expanding our horizons. More and more, applications are written with Ajax frameworks (i.e., JavaScript). If you consider the embedded languages we use, it's even broader: XML is used as an embedded configuration language widely in both the Java and .NET worlds.\n\nBut I'm beginning to see a time where even the core language (the one that gets translated to byte code) will cease its monoculture. Pretty much any computer you buy has multiple processors in it, so we're going to have to get better writing threading code. Yet, as anyone who has read Java Concurrency in Practice by Brian Goetz (an exceptional book, by the way), writing good multi-threading code is hard. Very hard. So why bother? Why not use a language that handles multiple threads more gracefully? Like a functional language? Functional languages eliminate side effects on variables, making it easier to write thread-safe code. Haskell is such a language, and implementations exist for both Java (Jaskell) and .NET (Haskell.net). Need a nice web-based user interface? Why not use Ruby on Rails via JRuby (which now support RoR).\n\nApplications of the future will take advantage of the polyglot nature of the language world. We have 2 primary platforms for "enterprise" development: .NET and Java. There are now lots of languages that target those platforms. We should embrace this idea. While it will make some chores more difficult (like debugging), it makes others trivially easy (or at least easier). It's all about choosing the right tool for the job and leveraging it correctly. Pervasive testing helps the debugging problem (adamant test-driven development folks spend much less time in the debugger). SQL, Ajax, and XML are just the beginning. Increasingly, as I've written before, we're going to start adding domain specific languages. The times of writing an application in a single general purpose language is over. Polyglot programming is a subject I'm going to speak about a lot next year. Stay tuned...\n\n
\n
\n
1. First computer programs were monolingual (up to end 70ties). Late 70ties and 80ties Oracle pushed first commercial RDBMS (Oracle v2) to the market. A couple of weeks later IBM introduced System/38, an architecture with a built-in RDBMS.\n\nSQL is a declarative language with some procedural (imperative) extensions.\n\nWhy SQL and RDBMS became so popular?\nBest mix of simplicity, robustness, flexibility, performance, scalability, and compatibility in managing generic data.\n\n2. In addition to an imperative language for the core solution, JavaScript and HTML were added to the programmer&#x2019;s palette. \n\nHTML ~ declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.\n\n3. New general purpose languages (Java, C#) built on the top of execution environments (JVM, CLR - Common Language Runtime).\n\nAlthough new languages, they carried some baggage of the past (C-like syntax). But they separated language definition from the execution environment specification.\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Specific-languages solve specific problems - HTML for markup building, SQL for relational calculus\nNew challenges - multiprocessor and multicore machines, scaling by more concurrency\nOld habits die hard - we got used to old-school languages, so paradigm shift is painful\n\n
Perfect description for Groovy and Grails\n- built on the top of a stable language (Java), platform (JVM) and frameworks (Spring, Hibernate)\n- uses Groovy for the rapid development\n- facilitates creation of DSLs (Groovy builders, metaprogramming capabilities)\n
Perfect description for Groovy and Grails\n- built on the top of a stable language (Java), platform (JVM) and frameworks (Spring, Hibernate)\n- uses Groovy for the rapid development\n- facilitates creation of DSLs (Groovy builders, metaprogramming capabilities)\n
Perfect description for Groovy and Grails\n- built on the top of a stable language (Java), platform (JVM) and frameworks (Spring, Hibernate)\n- uses Groovy for the rapid development\n- facilitates creation of DSLs (Groovy builders, metaprogramming capabilities)\n
Grails assumes that components (controllers, services, domain objects) are written in Groovy and bases its functionality on this premise. Language constructs determine component behaviour.\n\nThanks to Groovy dynamic nature and a flexible build system, we can plug code written in other JVM languages into Grails components\n
Grails assumes that components (controllers, services, domain objects) are written in Groovy and bases its functionality on this premise. Language constructs determine component behaviour.\n\nThanks to Groovy dynamic nature and a flexible build system, we can plug code written in other JVM languages into Grails components\n
\n
\n
\n
\n
\n
Functions should have no side-effects. You can mark that a function introduces side effects with do*\nHigher-order functions - functions are treated like data\nDynamically typed - by default, but allow this behaviour to be overridden through the use of explicit type hints that result in static typing. One reason to use such hints would be to achieve the performance benefits of static typing in performance-sensitive parts of code.\n
Lisp reloaded\n- homoiconic - Clojure code is just Clojure data\n- Polish prefix notation\n- less paretheses (LISP = Lost In Stupid Parentheses, Lots of Irritating Superfluous Parentheses)\n- multimethods - polymorphism in Lisp\n- metadata used e.g. to attach documentation, type hinting\n- TCO - not supported natively on JVM. Clojure enforces it through loop/fn - recur\n\n
Managed references\nref - shared changes, synchronous, coordinated changes (in a transaction)\nagent - shared changes, asynchronous, independent changes\natom - shared changes, synchronous, independent changes\nvar - isolated changes\n\nSTM - works like database with ACI properties (atomicity, consistency, isolation). Not D (durable)\nData mutated inside a transaction (dosync). Changes isolated from other threads. First thread that completely executes the block of code that&#x2019;s the transaction is allowed to commit the changed values. Once a thread commits, when any other thread attempts to commit, that transaction is aborted and the changes are rolled back.\nThe commit performed when a transaction is successful is atomic in nature. This means that even if a transaction makes changes to multiple refs, as far as the outside world is concerned, they all appear to happen at the same instant (when the transaction commits). STM systems can also choose to retry failed transactions, and many do so until the transaction succeeds. Clojure also supports this automatic retrying of failed transactions, up to an internal limit.\n\nAtomic - if a transaction mutates several refs, the changes become visible to the outside world at one instant. Either all the changes happen, or, if the transaction fails, the changes are rolled back and no change happens.\n\nIsolation - in-transaction changes visible only to the transaction\n\nConsistency - refs accept validator functions when created. These functions are used to check the consistency of the data when changes are made to them. If the validator function fails, the transaction is rolled back.\n\nActor (agent)\nReceives a message (function) that updates a mutable state.\nMay be used for side-effects inside the transaction - a message to an agent during a transaction is sent only once, even a transaction is restarted\n\nVar\nCan have a root binding (visible to all threads) and a local per-thread binding\n
Syntactic sugar\n- constructor call (SimpleDateFormat. "yyyy-MM-dd")\n- dot special form (. rnd nextInt 10)\n- dot dot \n(. (. (Calendar/getInstance) getTimeZone) getDisplayName)\n(.. (Calendar/getInstance) getTimeZone getDisplayName)\n- doto ~ Groovy with\n(let [calendar-obj (Calendar/getInstance)]\n (doto calendar-obj\n (.set Calendar/AM_PM Calendar/AM)\n (.set Calendar/HOUR 0)\n (.set Calendar/MINUTE 0)\n (.set Calendar/SECOND 0)\n (.set Calendar/MILLISECOND 0))\n (.getTime calendar-obj)))\n- Java methods -> first-class functions\n(map #(.getBytes %) ["amit" "rob" "kyle"])\n(map (memfn getBytes) ["amit" "rob" "kyle"])\n- bean - convert Java object into Closure map\n(bean (Calendar/getInstance))\n- array macros\n\nImplementing Java interfaces and classes\n- to use them in Clojure code\n- proxy macro\n- partial implementation of a interface/class\n- multiple classes/interfaces in a single proxy\n\nCreate Java classes\n - to use them in Java code\n
Clojure contrib can be added as Maven dependency\n dependencies {\n compile 'org.clojure:clojure-contrib:1.2.0'\n }\n\n\n\n
No access to Groovy/Grails classes - no joint Groovy/Scala compilation\n
No access to Groovy/Grails classes - no joint Groovy/Scala compilation\n
DSL classes must be 100% Scala\n- Groovy classes cannot participate in pattern matching - they are not case classes\n- Scala cannot access Groovy code - implicit conversions only for Scala objects\n
DSL classes must be 100% Scala\n- Groovy classes cannot participate in pattern matching - they are not case classes\n- Scala cannot access Groovy code - implicit conversions only for Scala objects\n
TCO - recompile Ruby with vm_opts.h #define OPT_TAILCALL_OPTIMIZATION 1\nFunctions with side effect are marked with !\nEverything is expression\nHigher-order functions, partial functions and currying\n\n
\n\n
\n\n
\n
\n
The Bastard Operator From Hell (BOFH), a fictional character created by Simon Travaglia, is a rogue system administrator who takes out his anger on users (often referred to as lusers), colleagues, bosses, and anyone else who gets in his way.\n
The Bastard Operator From Hell (BOFH), a fictional character created by Simon Travaglia, is a rogue system administrator who takes out his anger on users (often referred to as lusers), colleagues, bosses, and anyone else who gets in his way.\n
Gems must be installed locally and their source code moved to the Grails project\n
Gems must be installed locally and their source code moved to the Grails project\n
Alternative JRuby integration\nhttp://kenai.com/projects/jruby/pages/RedBridge\n
Clojure - full access to Grails classes, concurrency made easy language concepts complementing Groovy ones\nJRuby - proof of concept\n
Clojure - full access to Grails classes, concurrency made easy language concepts complementing Groovy ones\nJRuby - proof of concept\n
Clojure - full access to Grails classes, concurrency made easy language concepts complementing Groovy ones\nJRuby - proof of concept\n
\n
The Bastard Operator From Hell (BOFH), a fictional character created by Simon Travaglia, is a rogue system administrator who takes out his anger on users (often referred to as lusers), colleagues, bosses, and anyone else who gets in his way.\n