Forums Register Login

Why Functions Cannot be Nested

+Pie Number of slices to send: Send
This is a rather academic question than Java specific one. But anyway, someone may know it. What is the rationale behind allowing or disallowing nested function declaration (e.g. in C/Java, we cannot nest functions while in Pascal we can)?
[ February 23, 2008: Message edited by: Alec Lee ]
+Pie Number of slices to send: Send
Alec,
I don't know specifically why Java doesn't have nested functions. I suspect it was because they weren't in C/C++ though. Nested functions sound like closures which are being considered by Java 7.
+Pie Number of slices to send: Send
 

Nested functions sound like closures which are being considered by Java 7.



and the debate rages on, on whether they should be included
+Pie Number of slices to send: Send
So that means for some reasons closure is a bad thing? How could that be? Other language like Javascript does have it.
+Pie Number of slices to send: Send
 

Originally posted by Alec Lee:
So that means for some reasons closure is a bad thing? How could that be? Other language like Javascript does have it.



I don't think the issue is whether closure is good or bad. I think the issue is whether it's really that important. When I programmed in Pascal many many years ago, I used nested functions. In over a decade of coding Java, I never had the need for it.

Of course, you can make the argument that if Java had it, I would have used it, instead of working around it... but so what? I probably did work around it, but it must have been incredibly easy to do so (even done subconsciencely), because I never have been annoyed about not having nested functions.

Henry
+Pie Number of slices to send: Send
Interesting discussion. Closures are absolutely essential to writing anything but the most trivial of JavaScript in web pages, but I've never gotten to a situation when writing Java where I wished that we had them.
+Pie Number of slices to send: Send
Just my 2 cents ....

Adding closures to Java is a mistake ... it will add multiples levels of complexity to the language for how much real world benefit? As Henry and Bear indicate ... I dont think the language really needs it. As Martin Odersky said 'its like adding wings to an elephant'.

To me, something like Automatic Resource MGT blocks (a no brainer IMHO) and the Concise Inner class (CICE) syntax are at least focused on real world issues/pain points and will be immediately helpful for the great majority of developers.

This feels like language designers responding to competitive pressures from laguages like Ruby (which has closures).

Regarding Javascript ... a similar sort of debate/battle is ongoing where Brendan Eich and others want to completely change the language to be a lot more like java and other mainstream languages.
+Pie Number of slices to send: Send
 

As Henry and Bear indicate ... I dont think the language really needs it. As Martin Odersky said 'its like adding wings to an elephant'.



Well, I wouldn't go that far... I'm agnostic about it. Don't care either way.

To me, something like Automatic Resource MGT blocks (a no brainer IMHO) and the Concise Inner class (CICE) syntax are at least focused on real world issues/pain points and will be immediately helpful for the great majority of developers



Nope. Still agnostic. Don't care about either of these either...

Henry
+Pie Number of slices to send: Send
I'm not sure how much this topic is really about closures. Closures are certainly related to nested functions, but they don't seem to be the same exactly. I read Wikipedia's article on nested functions, but I don't have a strong grasp of why I might need them. I do have opinions on closures though, and thus the rest of this post will be on that topic.

I like closures a lot; I really wish that Java had had them from the beginning. Yes, it's generally possible to work around their absence, but it's ugly. I really like the loan pattern for ensuring resources get closed properly. We can see it in Groovy for example:

Here the withPrintWriter() method takes care of both creating and closing the PrintWriter. It's really only possible because we can pass the method a closure to tell the method what to do with the PrintWriter. In Java we'd need a try/finally block to close the writer - and that needs to go into every bit of client code that uses a PrintWriter. It's much less work to put the try/finally just one place, inside the withPrintWriter() method. Of course in the real world with Java people often omit the try/finally because either they don't realize it's important to close the writer, or because they find the extra typing excessive. Having a short syntax for closures facilitates methods like withPrintWriter(), which seems like a Good Thing™ to me.

On the other hand, this is one of those cases where it's easier to put a feature in a language at the beginning than it is later on. We can't actually eliminate all the exiting methods that allow people to access PrintWriter without using this nifty withPrintWriter() convenience method. If that method had been available from the beginning, great, but unfortunately we've already got masses of code worldwide that do not make use of the withPrintWriter() method because it, well, doesn't exist yet in Java. Adding it now can seem like an unnecessary complication to some. There are additional complications in the BGGA proposal because of nonlocal returns - special treatment for break, continue and return when they're inside closures. That's mostly because there's a bunch of existing code using break, continue and return that was written without closures, and BGGA don't want to change the rules for how that code would behave if used in closures. Which creates a number of complications. If closures had been part of Java all along, then simpler rules might have been possible. But that's not the case.

For myself, whenever I have the opportunity to choose what language a project will use, I plan to favor a language with closures. If that language is Java, great. But I'd be fairly happy using Ruby, Groovy, Scala or something else instead. To be fair I'm much more proficient in Java at the moment, but I'm also quite tired of things like the try/finally block that people forget to use correctly. I want closures, dammit!
+Pie Number of slices to send: Send
 

Originally posted by Jim Yingst:
(...)
I like closures a lot; I really wish that Java had had them from the beginning. Yes, it's generally possible to work around their absence, but it's ugly.
(...)
In Java we'd need a try/finally block to close the writer - and that needs to go into every bit of client code that uses a PrintWriter. It's much less work to put the try/finally just one place, inside the withPrintWriter() method. Of course in the real world with Java people often omit the try/finally because either they don't realize it's important to close the writer, or because they find the extra typing excessive. Having a short syntax for closures facilitates methods like withPrintWriter(), which seems like a Good Thing™ to me.
(...)



Ilja proposed a workaround for the clients to require using try/finally. I note that in your follow-up, that (besides the nit-pick of Ilja using the keyword 'do' as a method name) you weren't too excited with his suggestion. :roll:

- Anand
+Pie Number of slices to send: Send
Thank you - I was looking for that, but I must have used the wrong search string. I didn't realize that was you who started that thread - cool. Yes, it's possible to implement this in Java, but I think the extra ugliness of having to create an anonymous class will limit the use of this idiom. It's more complex than the try/finally block it eliminates. Plus, many closures need to return an object, operate on a different list of parameters, or throw exceptions. Java's strong typing and checked exceptions get in the way here, since different closure applications would require different method signatures.

Groovy uses a Closure class with method V call(Object[] args), and provides additional language support to smooth over the declaration and to take care of exceptions. Scala has a set of classes - Function0, Function1, Function2... ugh. It's a bit ugly under the hood. But again, there is language support here so that the user doesn't see this. In Java the closest we have is java.util.concurrent.Callable, with method V call() throws Throwable, which can throw any exception but can't have any parameters..

Also I would note that the defining feature of a closure, using traditional definitions, is the ability to reference local variables from the original context. In fact the word closure technically does not refer to the block of code, but to the binding of external free variables. Since Java doesn't really allow this (a nested class can only reference local variables if they're final), calling this construct a "closure" seems to be stretching things. Real closures can both read and write local variables. In practice the term closure seems to be getting corrupted in widespread use, and nowadays often seems to refer to the block of code rather than the binding of variables. I myself have been guilty of this too, in that old thread as well as here. I usually go with the flow. But it seemed worth pointing out here. Anonymous classes in Java can never act like true closures, binding local variables, though they can be used to allow users to create blocks of code to pass to other methods.
+Pie Number of slices to send: Send
Nested methods would be great. From a theoretical point of view they support decomposition and encapsulation, both good things.
From a practical point of view this means refactor is easier because any extracted methods will not pollute the class's scope making the outline view in your favourite ide much more legible.
Currently you have to put the extracted methods into a class which is a hassle
ie

public T1 foo( T2 bar){
return new Foo.execute(bar)
}
class Foo {
public T1 execute(T2 bar) {
doSomething();
return doSomethingElse(bar);
}
Less than ideal but at least the extracted method names don't pollute the class namespace so in your ide of choice you can read the outline and collapse the whole class in both outline and editing pane if you are not interested in foo().



+Pie Number of slices to send: Send
 

Joe Schmoe wrote:



Please check your private messages for an important administrative matter.
+Pie Number of slices to send: Send
Welcome to JavaRanch.

Please note that you are responding to a topic that's more than 1,5 years old. The original poster is most likely not still waiting for an answer.
My cellmate was this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com


reply
reply
This thread has been viewed 10530 times.
Similar Threads
Overloading methods- pardon, functions in JS?
whts your answer
methods in methods
Nested Subclass
jni in linux
Calling constructor from another constructor
Private Vs. Public and other thing about C++ OOP ?
Static Block & Class Decalaration
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 28, 2024 19:21:41.