The Artima Developer Community
Sponsored Link

Weblogs Forum
New Control Structures for Java

32 replies on 3 pages. Most recent reply: Nov 10, 2008 8:25 PM by Howard Lovatt

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 32 replies on 3 pages [ « | 1 2 3 ]
Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: New Control Structures for Java Posted: Nov 6, 2008 12:38 AM
Reply to this message Reply
Advertisement
@James,

Sure Java has none OO constructs like primitives and they are a pain, you end up autoboxing them. Same goes for closures you end up autoboxing them, only this time there are two types of closure to box and once you box them you can't unbox them. Why introduce more pain?

In Scala they have eliminated some of the problems by ditching break and continue and introducing yield in for loops that return values. But they still have a problem with return and still need two types of closure ({ () => ... } and { => ... }), consider:

object Main extends Application {
  // Closures version
  def c(): ( Boolean ) => Int = {
    {
      ( b: Boolean ) => if ( b ) {
        return { ( bb: Boolean ) => 1 } // This is a mistake, but not caught by the compiler
      }
      2
    }
  }
 
  // OO version
  def oo(): Function1[Boolean, Int] = {
    return new Function1[Boolean, Int]() {
      override def apply( b: Boolean ): Int = {
        if ( b ) { return 1 } // Can't by mistake say return new Function1 ...
        2
      }
    }
  }
 
  // Main
  {
    println( oo()( true ) )
    println( c()( true ) )
  }
}


This gives a runtime exception when the second println is executed.

I have demonstrated cases were inner classes are superior, so lets turn the question round - where are closures better?

James Iry

Posts: 85
Nickname: jiry
Registered: Nov, 2007

Re: New Control Structures for Java Posted: Nov 6, 2008 8:20 AM
Reply to this message Reply
Howard, I want to make a small correction before answering your question.

If you can read it in your code {x => x + y}, then it's a lambda (or "anonymous function"), not a closure. A closure is a runtime value that has captured bindings from the lexical environment. The lambda I just gave gives rise to many different closures - one distinct closure per captured value of y.

The relationship between lambda and closure is exactly the relationship between class and object.

Where I'm going with that distinction is that Scala by-name parameters ( => Foo) are indeed implemented exactly the same way that no-arg closures are implemented. The runtime object is an instance of a trait with an apply method. So it's a bit inaccurate to say that Scala has "two kinds of closure." But, more importantly, you cannot treat by-name parameters the same way you treat closures. They're just by-name parameters. You don't type in a lambda to create them and you don't apply them to evaluate them. You use them much like by-need parameters do in Haskell, except that they aren't memoized.

Finally, before I move on, Scala lets you nest classes, traits, and object literals. Instances of these all capture bindings from their lexical environment (even mutable references). So if you want to go down the route of saying that lambdas and by-name parameters create two different kinds of closure then we might as well admit all the above and say that Scala has a huge zoo of different types of closure.

Now to the heart of your question: where are lambdas superior to inner classes? The answer depends very much on your definition of superior. I think implementing an entire parser combinator library in a single page of code is superior to implementing it in page after page of anonymous inner classes. I think thinking of functions as ordinary values liberates your view of the world. I think most object oriented programmers over-emphasize mutation precisely because it's syntactically easier to do mutation than to write the equivalent of a higher order functions. Why doesn't the Java standard collection library have map,filter, monadic bind etc? Precisely because it's easier to do that stuff in a loop when you don't have lambdas.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: New Control Structures for Java Posted: Nov 10, 2008 8:25 PM
Reply to this message Reply
@James,

In terms of Scala having two types of closure I agree with you. I look on a closure without arguments as a special case of a closure with arguments. Similarly I look on a closure that doesn't capture outer scope variables as a special case of one that does. My comment was meant to indicate that they found it necessary to support special syntax with subtle differences for named parameters and closures without arguments. My argument is that even in a language built to support closures they are not as simple as people make out.

With regard to your parser/combinator example, I don't see that an inner class with *short syntax* would be significantly different than a closure. I agree that the syntax is not ideal for inner classes in Java. What I am arguing is that the semantics are ideal and that the semantics of the closure isn't.

Flat View: This topic has 32 replies on 3 pages [ « | 1  2  3 ]
Topic: The Adventures of a Pythonista in Schemeland/8 Previous Topic   Next Topic Topic: The Adventures of a Pythonista in Schemeland/9

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use