aspose file tools*
The moose likes Java in General and the fly likes Why Functions Cannot be Nested Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Why Functions Cannot be Nested" Watch "Why Functions Cannot be Nested" New topic
Author

Why Functions Cannot be Nested

Alec Lee
Ranch Hand

Joined: Jan 28, 2004
Posts: 569
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 ]
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 30919
    
158

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.


[Blog] [JavaRanch FAQ] [How To Ask Questions The Smart Way] [Book Promos]
Blogging on Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, OCAJP, OCPJP beta, TOGAF part 1 and part 2
Deepak Bala
Bartender

Joined: Feb 24, 2006
Posts: 6662
    
    5

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


and the debate rages on, on whether they should be included


SCJP 6 articles - SCJP 5/6 mock exams - More SCJP Mocks
Alec Lee
Ranch Hand

Joined: Jan 28, 2004
Posts: 569
So that means for some reasons closure is a bad thing? How could that be? Other language like Javascript does have it.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18981
    
  40

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


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61624
    
  67

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.


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Keith Flo
Ranch Hand

Joined: Nov 29, 2005
Posts: 128

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.


kf
SCJP 5.0 (preparing for SCWCD)
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18981
    
  40

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
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
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!


"I'm not back." - Bill Harding, Twister
Anand Hariharan
Rancher

Joined: Aug 22, 2006
Posts: 257

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


"Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away." -- Antoine de Saint-Exupery
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
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.
Curtis Mayfield
Greenhorn

Joined: Aug 19, 2009
Posts: 1
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().



Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10520
    
    9

Joe Schmoe wrote:


Please check your private messages for an important administrative matter.


[How to ask questions] [Donate a pint, save a life!] [Onff-turn it on!]
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14342
    
  22

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.


Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 8 API documentation
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why Functions Cannot be Nested