Polyglot Grails

4,924 views

Published on

Talk from the Spring IO 2012 conference.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,924
On SlideShare
0
From Embeds
0
Number of Embeds
2,439
Actions
Shares
0
Downloads
26
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 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’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’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
  • Clojure code is automatically reloaded\n
  • Clojure code is automatically reloaded\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Object orientation - supports partial classes (traits)\n
  • \n
  • \n\n
  • \n\n
  • \n
  • \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
  • Polyglot Grails

    1. 1. Polyglot Grails
    2. 2. Me• @mgryszko• @osoco• Groovy/Grails (sometimes Java) hacker• test addicted and clean code lover
    3. 3. Osoco• Small but outstanding • Quality preachers software development shop • TDD mantra singers• Groovy and Grails • On EC2 cloud nine hackers
    4. 4. Osoco• Small but outstanding • Quality preachers software development shop • TDD mantra singers• Groovy and Grails • On EC2 cloud nine hackers Julián David
    5. 5. Polyglot
    6. 6. Polyglot programming• term coined 2006 by Neil Ford• general + special-purpose languages• http://memeagora.blogspot.com/2006/12/polyglot- programming.html
    7. 7. http://www.flickr.com/photos/pinelife/269961241/
    8. 8. Maybe you didn’t know... http://www.flickr.com/photos/pinelife/269961241/
    9. 9. Maybe you didn’t know...But you are already polyglot programmer! http://www.flickr.com/photos/pinelife/269961241/
    10. 10. From relational algebra to JVM• relational algebra, rise of RDBMS -> SQL• world-wide-web -> JavaScript, HTML (?)• multilanguage platforms - .NET, JVM
    11. 11. > 200 languages on JVM
    12. 12. > 200 languages on JVM
    13. 13. > 200 languages on JVM
    14. 14. Why polyglot?• General purpose languages evolve too slowly• Specific-languages solve specific problems (DSLs included)• New challenges• Old habits die hard
    15. 15. Do we have to speakGroovy with Grails?
    16. 16. Do we have to speak Groovy with Grails?• Yes...• Groovy and Grails are inseparable
    17. 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
    18. 18. Grails is alreadypolyglot, can we push it further?
    19. 19. Grails plugins • Clojure • Scala • JRuby
    20. 20. Grails plugins • Clojure • Scala • JRuby
    21. 21. Clojure• Functional language• Lisp reloaded• Built-in support for concurrency• Java interoperability
    22. 22. Clojure• Functional language• Lisp reloaded• Built-in support for concurrency• Java interoperability
    23. 23. Functional language• Not pure functional• Explicit state management• Immutable, lazy and infinite data structures• Higher-order functions• Dynamically typed*
    24. 24. Functional language• Not pure functional• Explicit state management• Immutable, lazy and infinite data structures• Higher-order functions• Dynamically typed*
    25. 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. 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
    27. 27. Concurrency• Managed references (refs, agents, atoms, vars)• Software Transactional Memory• Actors• Atoms (~ java.util.concurrent.atomic.Atomic* )• Vars (~ ) java.lang.ThreadLocal
    28. 28. Concurrency• Managed references (refs, agents, atoms, vars)• Software Transactional Memory• Actors• Atoms (~ java.util.concurrent.atomic.Atomic* )• Vars (~ ) java.lang.ThreadLocal
    29. 29. Java interoperability• Import Java classes• Direct access to class/instance fields and methods• Syntactic sugar• Implement Java interfaces and classes on the fly• Create Java classes
    30. 30. Java interoperability• Import Java classes• Direct access to class/instance fields and methods• Syntactic sugar• Implement Java interfaces and classes on the fly• Create Java classes
    31. 31. Why Clojure & Grails?• Concurrency• Laziness• Rich collection library • Relational algebra
    32. 32. Why Clojure & Grails?• Concurrency• Laziness• Rich collection library • Relational algebra
    33. 33. Clojure and Grails• Install Clojure plugin http://grails.org/plugin/clojure grails install-plugin clojure• Put your sources under src/clj• Use grails namespace (ns grails)• Access Clojure code through clj property
    34. 34. Clojure and Grails• Install Clojure plugin http://grails.org/plugin/clojure grails install-plugin clojure• Put your sources under src/clj• Use grails namespace (ns grails)• Access Clojure code through clj property
    35. 35. Demo - bootstrap• Clojure code can access Grails objects• Sample note added during bootstrap
    36. 36. Demo - bootstrap• Clojure code can access Grails objects• Sample note added during bootstrap
    37. 37. Demo - tag counter• Note taking application• Notes can be tagged• Calculate most popular tags
    38. 38. Demo - tag counter• Note taking application• Notes can be tagged• Calculate most popular tags
    39. 39. Plugin gotchas• Uses Clojure 1.2• No access to Groovy-augmented methods e.g. String.reverse()
    40. 40. Plugin gotchas• Uses Clojure 1.2• No access to Groovy-augmented methods e.g. String.reverse()
    41. 41. Scala• Object-functional• Statically typed but with type inference• Concurrency through actors• Almost as fast as Java
    42. 42. Scala• Object-functional• Statically typed but with type inference• Concurrency through actors• Almost as fast as Java
    43. 43. Functional language• Immutability• Higher-order functions• Pattern matching + case classes• Lazy evaluation• Monads• Parser combinators
    44. 44. Functional language• Immutability• Higher-order functions• Pattern matching + case classes• Lazy evaluation• Monads• Parser combinators
    45. 45. Why Scala in Grails?• High performance without Java• Functional features• DSLs
    46. 46. Why Scala in Grails?• High performance without Java• Functional features• DSLs
    47. 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. 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. 49. Demo shortest path• Calculate shortest path between two cities• Use Scala4Graph library
    50. 50. Demo shortest path• Calculate shortest path between two cities• Use Scala4Graph library
    51. 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. 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. 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. 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. 55. Ruby• JRuby - Ruby 1.8.7 & 1.9.2 compatible• Object-oriented, dynamic• Some functional features• Tones of gems
    56. 56. Ruby• JRuby - Ruby 1.8.7 & 1.9.2 compatible• Object-oriented, dynamic• Some functional features• Tones of gems
    57. 57. Why Ruby in Grails?• Hard to find a valid reason...• Rails app migration to Grails?• Particular gem?
    58. 58. Why Ruby in Grails?• Hard to find a valid reason...• Rails app migration to Grails?• Particular gem?
    59. 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. 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
    61. 61. Demo - BOFH server• http://en.wikipedia.org/wiki/ Bastard_Operator_From_Hell• bofh-excuse gem
    62. 62. Demo - BOFH server• http://en.wikipedia.org/wiki/ Bastard_Operator_From_Hell• bofh-excuse gem
    63. 63. Plugin gotchas• No gem installation• No access to Grails classes
    64. 64. Plugin gotchas• No gem installation• No access to Grails classes
    65. 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
    66. 66. My ranking for
    67. 67. My ranking for
    68. 68. My ranking for
    69. 69. My ranking for
    70. 70. Thank you! ¡Gracias! Danke! Dziękuję!
    71. 71. Source code• http://github.com/mgryszko/grails-polyglot-demo

    ×