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 | » ]
Alan Keefer

Posts: 29
Nickname: akeefer
Registered: Feb, 2007

Re: New Control Structures for Java Posted: Oct 16, 2008 11:48 AM
Reply to this message Reply
Advertisement
The problem is that the user-side code is fairly . . . um, obscure. If I can't read code and basically instantly know what it's doing, that means there's a large amount of room for improvement.

Everyone gets hung up on what's "more powerful," but if I wanted "more powerful" I'd go write everything in Lisp using insane macros that no one else could ever comprehend. Why don't I? Because I prefer simplicity and readability over sheer expressive power.

Yes, closures are a more limited approach. But they get the job done for 99% of real-world use cases, and they lead to much more readable code and cleaner libraries. Half our code base is in Java, and half of it is in GScript (close enough, anyway), and since we added closures to GScript about a year ago I can assure you that the GScript side is much tighter and more readable than the Java side, and closures and type inference are the two biggest reasons why. The closures make the code readable in a way that for loops and anonymous inner classes just can't.

And honestly, I really just can't get behind Howard's proposal; I absolutely hate having more than one way to do exactly the same thing from a language perspective. From a code perspective it's understandable at times, but at the language level I think it's far less excusable, and there had better be a really good reason. It's the same reason I hate allowing if statements without curly braces; as soon as you add a second line, you now have to change the original line and add the braces in, which is a huge source of potential errors. Similarly, under that proposal you have to carefully limit what the interface/class you're implementing does so that you can use some alternate, short-cut syntax, and if you have to add another method to the parent class you'll have to go through and convert every single declaration that uses the short-hand syntax. Not only that, but you'll need to understand two alternative, drastically different syntaxes for doing exactly the same thing, and you'll have to understand all the rules it uses and know when you can use it and when you can't (or when you can only use part of it).

Closures are such a simple idea and the rules are so consistent and minimal, I just don't understand the huge resistance to them. I don't think any of our developers here would ever want to go back to a language without them. I think if people did work in a language with closures, they'd stop caring about those other things; that's just my opinion, of course.

I also don't agree that parallel algorithms are really that important to the vast majority of developers; I've made this argument on our development blog (http://guidewiredevelopment.wordpress.com/2008/10/06/a-more-clearly-stated-version-of-my-argument/) that I think any focus on that is pretty irrelevant to most (not all, but most) development. Some small subset of people doing heavy computational stuff will perhaps care a lot, but the rest of us are either 1) writing web software that parallelizes per-user or 2) need to fundamentally restructure the large-scale algorithmic approaches we use so that things are split on a much higher level. Swapping in a parallelMap() operation here or there isn't going to buy you much unless it's a really, really big array you're dealing with. So throwing in complicated language features just to enable something that most developers don't need, when there are (to me) clearly better ways to simplify the language's usage and syntax in the most common cases seems like completely the wrong direction.

Carson Gross

Posts: 153
Nickname: cgross
Registered: Oct, 2006

Re: New Control Structures for Java Posted: Oct 16, 2008 12:04 PM
Reply to this message Reply
> I don't see that in his example but maybe you are getting
> that from somewhere else. All the tough parts handled by
> the thread pool and other classes from the JDK.

OK, I'm going to go back to the original conclusion here:

Java has a good selection of tradition control structures and I contend that what is really needed is the ability to write parallel-functional control structures; further I suggest that inner classes with shorter syntax are ideal for this purpose, perhaps with further short syntax for calling these structures.

Again, and as succinctly as I can put it: I do not think that java needs additional parallel-functional control structures. Rather, it needs decent closure support so that library developers (mainly around the Collections) can expose methods that take closures and use existing tools to handle parallelization behind the scenes.

No new control statements. Good closures.

That's all I'm saying.

Cheers,
Carson

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: New Control Structures for Java Posted: Oct 16, 2008 12:22 PM
Reply to this message Reply
> Swapping in a parallelMap() operation here or there isn't
> going to buy you much unless it's a really, really big
> array you're dealing with.

To your point, I think there's a tendency to think about parallelism at too low of a level. The overhead of thread coordination eats up a lot of benefits. The other problem I see is that people seem to want to always fork-join. The problem is that forks create concurrency and joins limit it.

It seems to me that in a lot of cases you can avoid the join completely, even more often when it's a case like this where there's one output value for each key in the map. If all I want to do is display the key and the value or send it to some other process, why wait for the rest of the values to be completed?

One of the things that opened my eyes on this was a paper describing how little implicit parallelization could be achieved in functional code that would seem to be easily parallelizable.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: New Control Structures for Java Posted: Oct 16, 2008 12:42 PM
Reply to this message Reply
> Again, and as succinctly as I can put it: I do not think
> that java needs additional parallel-functional control
> structures. Rather, it needs decent closure support so
> that library developers (mainly around the Collections)
> can expose methods that take closures and use existing
> tools to handle parallelization behind the scenes.

Oh, I agree. I think for Java: add closures and then stop changing the language.

Carson Gross

Posts: 153
Nickname: cgross
Registered: Oct, 2006

Re: New Control Structures for Java Posted: Oct 16, 2008 1:27 PM
Reply to this message Reply
> Swapping in a parallelMap() operation here or there isn't going to
> buy you much unless it's a really, really big array you're
> dealing with. So throwing in complicated language
> features just to enable something that most developers
> don't need, when there are (to me) clearly better ways to
> simplify the language's usage and syntax in the most
> common cases seems like completely the wrong direction.

Yeah, I'm overselling data-parallel operations here because it's the only sort of new parallelism I can envision working out well for the masses, but, as Rhamphoryncus pointed out over on our dev blog (http://guidewiredevelopment.wordpress.com/2008/10/03/dont-believe-the-hype/#comments) the truth is that most data-parallel operations in a J2EE app should be done in the database.

Java needs closures *anyway* so we can have plain ol' map, filter, etc. A side benefit is that, in the few cases where application-level (i.e. above the app server in the J2EE stack in a J2EE app) parallelism can boost performance, developers can try out parallelizing at minimal syntactic cost.

Anders Hejlsberg talks a bit about this topic in this talk at around the 54 minute mark:

http://jaoo.blip.tv/#1324214

Cheers,
Carson

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: New Control Structures for Java Posted: Oct 16, 2008 4:12 PM
Reply to this message Reply
@Peter,

Yes I agree with your comments - but I am asking the question as to what is better a closure with short syntax or an inner class with short syntax?

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: New Control Structures for Java Posted: Oct 16, 2008 4:33 PM
Reply to this message Reply
@Carson, James, Alan,

The point I am making is that inner classes with short syntax will do everything you want and more, therefore they are a better choice to add than a closure because everything you can do with a closure you can do with an inner class and just as succinctly (provided the syntax is the same), but the reverse is not true.

BGGA (and other closure proposals) have odd behaviour, in particular its scoping rules are not the same as normal Java and it only works with interfaces and not classes (no fields, no other methods, no recursion). For example:
String f() {
  return new Object() {
    public toString() {
      String s = super.toString();
      if ( s.endsWith( "A" ) ) { return "A"; }
      return "Not an A";
    } } + " Location";
}

and now refactor into a BGGA closure:
String f() {
  return { =>
    String s = super.toString(); // not the same toString
    if ( s.beginsWith( "A" ) ) { return "A"; } // Doesn't return to the same place
    return "Not an A"; // Doesn't return to the same place
   } + " Location"; // Never actually invoked, toString will be called on the wrapped closure!
}

I think people will often refactor inner classes into closures and vice versa if BGGA is added and this will be an endless source of bugs.

The crux though is, if you think closures are better than inner classes then in a like for like comparison (same syntax same, level of support) give an example were a closure is superior.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: New Control Structures for Java Posted: Oct 16, 2008 4:53 PM
Reply to this message Reply
@Alan,

> The problem is that the user-side code is fairly . . . um,
> obscure. If I can't read code and basically instantly
> know what it's doing, that means there's a large amount of
> room for improvement.

Agreed short code for an inner class instance would be nice.

> Yes, closures are a more limited approach. But they get
> the job done for 99% of real-world use cases, and they
> lead to much more readable code and cleaner libraries.

Why would an inner class with short syntax and other support like read/write to local variables be any different?

> And honestly, I really just can't get behind Howard's
> proposal; I absolutely hate having more than one way to do
> exactly the same thing from a language perspective.

Hang on a second, Java already has inner classes. Closures would be the addition. See previous post for why closures will cause bugs because they appear to be short syntax for an inner class but aren't.

I don't think anyone will have a problem with saying there is a long and short form of syntax for the same thing. E.g. at the moment you can write class X extends Object { ... } or class X { ... } and I have never heard anyone say this is confusing.

But take a look at the toString example I gave, you are not seriously telling me that this won't be a problem - come on!

> Similarly, under that
> proposal you have to carefully limit what the
> interface/class you're implementing does so that you can
> use some alternate, short-cut syntax,

You mean to something that is the same as a closure - single abstract method. With an inner class the object can have any type and any method signature and I don't have to throw away inheritance, fields, etc.

> and if you have to
> add another method to the parent class you'll have to go
> through and convert every single declaration that uses the
> short-hand syntax.

You mean just like you would with a closure. At least with an inner class the meaning wouldn't subtly change and you might be able to add a default method to an abstract class so that the majority of the SAM inner classes don't have to be changed.

> I think if people did work in a language with
> closures, they'd stop caring about those other things;
> that's just my opinion, of course.

Oh but I do work with a number of languages with closures and I am struck by their limited power compared to an inner class.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: New Control Structures for Java Posted: Oct 16, 2008 5:07 PM
Reply to this message Reply
@James,

Great code and an alternative that would be viable with a closure or an inner class. In the use case (assuming BGGA syntax and passing in a thread pool) you have:
   
  final Map<Integer, Character> output = new ForEach<Character, Integer, Character>( pool, { int index =>
    if ( index <= 0 || index >= size - 1 ) { throw ForEach.CONTINUE; }
    in
  } ).execute( input );

I would have using the same style syntax (i.e. BGGA style rather than C3S style):
   
  final Map<Integer, Character> output = forEach( pool, input, { int index, char in =>
    if ( index <= 0 || index >= size - 1 ) { throw CONTINUE; }
    in
  } );

Which is arguably better. Also you can only continue based on an index value, suppose I want to continue based on an input value?

Although you coding is very good the closure has handicapped you when compared to the inner class.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: New Control Structures for Java Posted: Oct 16, 2008 7:52 PM
Reply to this message Reply
> @James,
>
> Although you coding is very good the closure has
> handicapped you when compared to the inner class.

I didn't use a closure. The code I posted compiles under 1.6 but I didn't test it. It should just be a refactoring of the code you posted.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: New Control Structures for Java Posted: Oct 16, 2008 8:02 PM
Reply to this message Reply
Howard, I said before that I would like closures. However, I really haven't taken time to understand the various proposals. I spent a lot of time understanding Java generics before they were released and by and large feel it was a waste of my time.

So, when I think of a closure, I think of a more concise syntax for certain anonymous inner classes. I use them so often that this would be a relief and make my code easier to maintain.

Alan Keefer

Posts: 29
Nickname: akeefer
Registered: Feb, 2007

Re: New Control Structures for Java Posted: Oct 17, 2008 2:18 AM
Reply to this message Reply
@Howard

I think my fundamental problem is that I don't see a good reason to take some obviously functional concepts and techniques and to try to shoehorn them into objects and classes. Some operations are more naturally functional, and sometimes first class functions just make the most sense. So to take something like the map() method or the each() method, then define an interface that contains one function inside it, then devise some syntax and compiler tricks to make it look like you're defining just a function when in reality you're defining a class that defines a single method . . . that just seems like exactly the type overengineered solution that gives Java a bad name. You're going to all this work to make it look like you're passing in a function, so why not just pass in a function already? Why bother with the confusion and overhead of Object Orientation when you don't want it and it just confuses the problem?

If you care about variable capture semantics, I think the closure scoping rules in Java should exactly mimic what you get with an anonymous inner class, i.e. read-only access to final variables. I like keeping the rules simple and consistent. I see no good reason to add in crazy return or exception semantics either (which is one reason the BGGA proposal scares me), and they can have the same rules as if they were on an anonymous inner class.

If you do that, where exactly is the possibility for confusion? Writing userList.map(\u -> u.Name) is pretty hard to screw up. If you start getting really complicated blocks in there, you end up moving them out to a helper function anyway to make the code more readable. I just don't see how simple closures could confuse anyone, unless people insist on things like restricted versus unrestricted closures, crazy return and exception semantics, etc. If they use the same scoping and semantics that people already understand, it's not a problem.

Comparing defaults (like extends Object) to complicated syntax rules (like what you've proposed) isn't really the right comparison. You can always leave off "extends Object." You can always leave off "= null" on a variable declaration that you want to default to null. The problems arise when you have rules that sometimes apply but not always, because then you have to understand those situations, like with if statements or for loops that can leave off curly braces unless they have more than one line underneath them. The type of rules you've proposed are exactly that kind, where they sometimes apply, and you have to know when they apply, so it adds a whole bunch of rules to the language. I'd rather have one, easily-understood feature (a closure is just a function, and everyone understands functions and anonymous-inner-class scoping rules) instead of a whole raft of complicated rules for syntax shortening.

As to arguing that inner classes are better because they have inheritance and fields, that's a total functional-programming anti-pattern. If you're doing something functional you should be using composition, not inheritance, and you should probably be avoiding side effects (like local variable writes) as well. If you have functionality that's so complicated that you need to pass in a full-on object with state and a bunch of methods, go for it; you can still do that. But the whole need for closures is for something lighter-weight and more functional than that, which is exactly the problem space in which state and inheritance is a bad idea. The whole point of using a method like .map() is because you want to make your life simpler; if you need to do something really complicated, there are already plenty of ways to solve that problem. Java scales up in complexity just fine, it just scales down in complexity very poorly.

That's perhaps too long-winded, but the basic point is: there are times where you really do just want a function, not a class.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: New Control Structures for Java Posted: Oct 17, 2008 3:42 PM
Reply to this message Reply
> Howard, I said before that I would like closures.
> However, I really haven't taken time to understand the
> e various proposals. I spent a lot of time understanding
> Java generics before they were released and by and large
> feel it was a waste of my time.
>
> So, when I think of a closure, I think of a more concise
> syntax for certain anonymous inner classes. I use them so
> often that this would be a relief and make my code easier
> to maintain.

Fair enough - there are a few proposals. I had assumed that since your re-factoring turned the example into something that could you BGGA closures that that was your intent. As I said - nice bit of coding.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: New Control Structures for Java Posted: Oct 17, 2008 4:00 PM
Reply to this message Reply
@Alan,

This might surprise you, but I agree with a lot of what you said. For example:

1. There are times when you want to have a single method and I proposed in C3S some pre-defined interfaces Method0 (no arguments), Method1 (1 argument), etc. for this situation.

2. I also agree with you that what ever the short syntax inner class/closure does the long version of inner class should do the same, for example if the short syntax can write to a variable the long form should also.

I guess that the main area of disagreement is that I want to keep Java an OO language and don't want to introduce something that isn't an object and therefore behaves differently and requires boxing to 'play' with objects. With regard to overhead I think anonymous inner class overhead is already small and with the next gen. JVM, Da Vinci, it will be close to zero. Running on the JVM the overhead of a closure is the same as an inner class because there is no support for closures, only objects.

James Iry

Posts: 85
Nickname: jiry
Registered: Nov, 2007

Re: New Control Structures for Java Posted: Nov 5, 2008 6:54 PM
Reply to this message Reply
Scala is a deeply object oriented language. More so than Java. Every value in the language is an OO object with methods, etc. Every value. Including first class functions. There is no reason whatsoever that Java can't remain an OO language if it adds lambdas and closures.

And why be concerned if somehow Java becomes less object oriented? It's already a not-so-terribly object oriented language. It's got primitives which aren't objects, control structures that aren't methods on classes/objects, statics which don't play with inheritance at all, etc, etc.

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