June 20, 2007

PittJUG: Closures for the Java Programming Language

Tonight I went to a PittJUG meeting on Closures. Neal Gafter from Google gave a great talk. You could tell he'd done it before and that he really cared about it, and also that he was barely scratching the surface and could talk about this for many more hours. (And that he'd love to do so!)

Some notes from the talk:

  • Same talk as @ JavaOne
  • been working on this for ~ year
  • what are they? why do you want to do this? what does it add?
  • MJD quote about laughing at languages without closures
  • Goals:
    • Concise "function" literals (currently impl w/anon inner classes)
    • Backward compatible (surprise!)
    • allow "Control APIs" (extend languages, kinda like foreach loops) </ul>
    • Control API:
      • specific to an API, not generic (if)
      • on par with built-in statements
      • example: JDK 5 foreach, specific to Collections API
      • showed implementation of foreach using anonymous instances; not awful, but more verbose and no free variables (as they're called here); also ambiguous references to code from calling scope, also no throwing of checked exceptions ("Exception Transparency"), also ambiguous references to the code that needs to actually return something...
      • result: inner classes don't cut it for the purpose of expressing control statements, impose too many constraints and control constructs require that the code they invoke don't change the meaning of the control (boils down to: "Incomplete capture of lexical context" -- return/break/continue, this, immutable local variables)
      • example right now: security manager API that will execute your code in a specific sandbox
    • Basics of syntax for control statements: pass a block of code (w/curlies) as the last parameter of a method
    • </ul>

      Example: implement locking using imported 'withLock' to guard a block of code:

        declare:   withLock( someLock, someCode ); (not shown, spoken)
        usage:     withLock( getLock ) {
                       fee();
                       fi();
                       fo();
                   }  <-- look! no semicolon after the block
      

      Closure expressions:

          { [ parameter declarations ] => [block statements] [expression] }
      
      • object that represents code + lexical context
      • may return from enclosing method
      • Closure conversion: compiler figures out at compile time what type the closure is: if it's a no-arg closure that returns nothing, it can be taken as a Runnable
        • Can be cases where the closure can match multiple overloaded methods, but he only found one case in the JDK where this would have happened (in Executor stuff)
      • Possible for API author to restrict what the closures can do (no non-local returns when the calling context doesn't exist later)
      • If no 'target type', assumes a 'natural function type'

      Function types:

           { [ parameter declarations ] => return type [ throws ... ] }
      
      • parameters and return values can be generics
      • these aren't required, can still use interfaces to declare what the function does (better when they're named)
      • </ul>
        { String => int throws NumberFormatException}
          becomes 
        java.lang.function.IO<String,NumberFormatException>
                           ^^ I = int, O = Object
          or
        package java.lang.function;
        public interface IO<A, X extends Exception> {
            int invoke( A arg ) throws X;
                ^^^^^^always named invoke (like proxies)
        }
        
        • Function interfaces are generated by javac at runtime, won't find in JDK.

        Finally:

        • Lots of examples (before/after)
        • Easy to digest classes of items that this can be used for:
          • Locking
          • More iterations (for eachEntry( Key, Value : map ))
          • Closeables (streams, DB connections)
          </li>
        • Others:
          • Fork/Join Concurrency (Doug Lea, exists now but no good way to express)
          • Higher order utilities
          • AOP? (register advice and cutpoints, then match them up at runtime)
          • Continuations? (bounded continuations...)
          • Multiple dispatch?

        Homepage of closures proposal: http://www.javac.info/

Next: That was quick: RI for JSR-311 (REST)
Previous: New additions: Verizon Fios and security system