Related
Upon reading the following:
A lot of people define static typing and dynamic typing with respect
to the point at which the variable types are checked. Using this
analogy, static typed languages are those in which type checking is
done at compile-time, whereas dynamic typed languages are those in
which type checking is done at run-time.
This analogy leads to the analogy we used above to define static and
dynamic typing. I believe it is simpler to understand static and
dynamic typing in terms of the need for the explicit declaration of
variables, rather than as compile-time and run-time type checking.
Source
I was thinking that the two ways we define static and dynamic typing: compile-time checking and explicit type declaration are a bit like apples and oranges. A characteristic in all statically typed languages (from my knowledge) is the reference variables have a defined type. Can there be a language that has the benefits of compile-time checking (like Java) but also the ability to have variables unbounded to a specific type (like Python)?
Note: Not exactly type inference in a language like Java, because the variables are still assigned a type, just implicitly. This theoretical language wouldn't have reference types, so there would be no casting. I'm trying to avoid the use of "static typing" vs "dynamic typing" because of the confusion.
There could be, but should there be?
Imagine in hypothetical-pseudo-C++:
class Object
{
public:
virtual Object invoke(const char *name, std::list<Object> args);
virtual Object get_attr(const char *name);
virtual const Object &set_attr(const char *name, const Object &src);
};
And that you have a language that arranges:
to make Object class the root base class of all classes
syntactic sugar to turn blah.frabjugate() into blah.invoke("frabjugate") and
blah.x = 10 into blah.set_attr("x", 10)
Add to this something combining attributes of boost::variant and boost::any and you have a pretty good start. All the dynamicism (both good and runtime bugs bad) of Python with the eloquence and rigidity (yay!) of C++ or Java. With added run-time bloat and efficiency of hash-table lookups vs. call/jmp machine instructions.
In languages like Python, when you call blah.do_it() it has to do potentially multiple hash table lookups of the string "do_it" to find out if your instance blah or its class has a callable thing called "doit" every time it is called. This is the most extreme late-binding that could be imaged:
flarg.do_it() # replaces flarg.do_it()
flarg.do_it() # calls a different flarg.do_it()
You could have your hypothetical language give some control over when the binding occurs. C++-like standard methods are crudely static bound to the apparent reference type, not the real instance type. C++ virtual methods are late-bound to the object instance type. Python-like attributes and methods are extremely late bound to the current version of the object instance.
I think you could definitely program in a strong static typed language in a dynamic style, just as you could build an interpreter in a language like C++ or Java. Some syntax hooks could make it look a little more seamless. But maybe you could do the same in reverse: maybe a Python decorator that automatically checks argument types, or a MetaClass that does it at compile time? [no, I don't think this is possible...]
I think you should view it as a union of features. but you'd get both the best and the worst of both worlds...
Can there be a language that has the benefits of compile-time checking (like Java) but also the ability to have variables unbounded to a specific type (like Python)?
Actually mostly language have support for both, so yes. The difference is which form is preferred/easier and generally used. Java prefers static types but also supports dynamic casts and reflection.
This theoretical language wouldn't have reference types, so there would be no casting.
You have to consider that language also need to perform reasonably well so you have to consider how they will be implemented. You could have a super type but this makes optimisation very hard and you code will most likely either run slowly or use much more resources.
The more popular languages tend to make pragmatic implementation choices. They are not purely one type or another and are willing to borrow styles even if they don't handle them as cleanly as a "pure" language.
what exactly do they allow the compiler or programmer to do that dynamic types can't?
It is generally accepted that the quicker you find a bug, the cheaper it is to fix. When you first start programming, the cost of maintenance isn't high in your mind, but once you have much more experience you will realise that a successful project costs far more to maintain than it did to develop and fixing long standing bugs can be really costly.
static languages have two advantages
you pick up bugs sooner rather than later. The sooner the better. With dynamic languages you might never discover a bug if the code is never run.
the cost of maintenance is easier. Static languages make clearer the assumption made when the code was first written and are more likely to detect issues if you don't have enough test coverage (btw, you never have enough test coverage)
No you cannot. The difference here boils down to early binding versus late binding. Early binding means matching everything up on the binary level upfront, fixing it in code. The result is rigid, type-safe and fast code. Late binding means there is some kind of runtime interpretation involved. This results in flexiblility (potentially unsafe) at the cost of performance.
The two approaches are different on a technical level (compilation versus interpretation) and the programmer would have to choose which is desired when, which would defeat the benefit of having both in the first place.
In languages that use a (common) language runtime however you do get some of what you are asking for through reflection. But it is organized differently and still type-safe. It is not the implicit kind of binding you refer to but requires a bit of work and awareness from the programmer.
As far as what is possible with static types that is impossible with dynamic types: nothing. They are both Turing complete
The value of static types is finding bugs early. In Python, something as simple as a misspelled name isn't caught until you run the program, and even then only if the line of code with the misspelling is run.
class NuclearReactor():
def turn_power_off(self):
...
def shut_down_cleanly(self):
self.turn_power_of()
What is real difference between Class and Structure when you are dealing with Object Oriented Programming. This question is asked many times during my interviews for SE.
Some people says that there is only one difference:
Structure members are public by default and Class members are private by default.
Some says there are many differences.
After reading many articles and forums, I have the following differences:
Classes DEFAULT to having private members. Structures DEFAULT to having public members.
Structures are values type.
Classes are reference type.
Structure stores in memory via stack.
Classes stored in memory via heap.
Structure doesn’t support inheritance.
Classes support inheritance.
Constructor works in different way.
‘new’ operator works in different way.
Allocating memory for structure is very fast because this takes place inline or on the stack.
What are your opinion on my above list or you have a different one. Thanks
This is pretty language-specific. You seem to be mixing a fair share of both C++ and C#, both of which are very different languages (despite superficial similarities in syntax).
In C++ structs indeed default to public member visibility while class defaults to private. In C# struct is used to declare value types which are passed by value (note that the stack allocation is an implementation detail, not a contract).
Generally both languages seem to have the same idea of what struct and class should represent: struct is for simple data structures which do little more than holding data, while classes have state and methods to manipulate it. They are used to build objects in some concrete or abstract sense while data structures are just that: data in a structured form; they don't need to do much with that data or even know what data that is. Essentially they're dumb and don't care.
But that's just how the language designers thought they should be used. People are good at mis-using things so not every struct you see may be a simple, dumb data structure and not every class you see may be a full-blown class with lots of methods and whatnot. It's merely a convention and if people follow it others can look at the code and see "Oh, nice, that's a struct so I don't expect much logic here and move on to more interesting things." It might work ... in theory.
ETA: Since you mentioned in a comment that you are particularly interested in PHP or Java: Both languages do not have any distinction at the syntax or language level of class or struct which is why your question strikes me as a little odd. In both Java and PHP you model things as classes, regardless of whether they are just data structures without logic or actual classes with everything there is.
This is entirely language dependent, so there can be no single correct answer. If you are interested in a specific language, please specify it in your question.
From an OO perspective, there are no difference. They are both types that have a public API with methods (and properties if your language supports them).
From a technical standpoint, there can be many differences, but that depends on the language and/or platform.
When it comes to OO design, I simply choose to ignore that such a thing as a struct exists at all as it gives me no additional capabilities or features. As we dive deeper into the implementation, a class may turn out to be better implemented as a struct, but it's a pure implementation detail.
Difference between Structure and Classes
-The major difference between class and structure is that the declaration of structure
starts with the keyword 'struct' whereas on the other hand, a class starts with the
keyword 'class'.
-In class the data member and member are private by default whereas in structure they
are public by default.
-Data hiding is supported in classes but not in structure.
-Structure deals with variables only whereas objects deal with real-world objects.
-If we explicitly specify the access type of each member, then a structure will behave exactly
as a class.
In C++, I have to explicitly specify 'virtual' keyword to make a member function 'overridable', as there involves an overhead of creating virtual tables and vpointers, when a member function is made overridable (so every member function is implicitly not overridable for performance reasons).
It also allows a member function to be hidden (if not overridden) when a subclass provides a separate implementation with the same name and signature.
The same technique is used in C# as well. I am wondering why Java waved away from this behavior and made every method overridable by default and provided the ability to disable overriding behavior on explicit use of 'final' keyword.
The better question might be "Why does C# have non-virtual methods?" Or at the very least, why aren't they virtual by default with the option to flag them as non-virtual?
In C++, there is the idea (as Brian so nicely pointed out) that if you don't want it, you don't pay for it. The problem is that if you do want it, this usually means you end up paying through the nose for it. In most Java implementations, they are designed explicitly for lots of virtual calls; the vtable implementations tend to be fast, scarcely more expensive than non-virtual calls, meaning the primary advantage of non-virtual functions is lost. Furthermore, JIT compilers can inline virtual functions at runtime. As such, for efficiency reasons, there is very little reason actually to use non-virtual functions.
Thus, it largely comes down to the principle of least surprise. It tells us that all methods to behave the same way, not half of them being virtual and half of them being non-virtual. Since we need to have at least some virtual methods to achieve this polymorphism thing, it makes sense to have them all be virtual. Furthermore, having two methods with the same signature is just asking to shoot yourself in the foot.
Polymorphism also dictates that the object itself should have control over what it does. It's behavior should not be determinate on whether the client thinks it's a FooParent or a FooChild.
EDIT: So I'm being called on my assertions. This next paragraph is conjecture on my part, not a statement of fact.
An interesting side effect of all this is that Java programmers tend to use interfaces very heavily. Since the virtual method optimizations make the cost of interfaces essentially non-existent, they allow you to use a List (for example) instead of an ArrayList, and switch it out for a LinkedList at some later date with a simple one-line change and no additional penalty.
EDIT: I'll also pony up a couple sources. While not the original sources, they do come from Sun explaining some of the workings on HotSpot.
Inlining
VTable
Taken from here (#34)
There’s no virtual keyword in Java
because all non-static methods always
use dynamic binding. In Java, the
programmer doesn’t have to decide
whether to use dynamic binding. The
reason virtual exists in C++ is so you
can leave it off for a slight increase
in efficiency when you’re tuning for
performance (or, put another way, "If
you don’t use it, you don’t pay for
it"), which often results in confusion
and unpleasant surprises. The final
keyword provides some latitude for
efficiency tuning – it tells the
compiler that this method cannot be
overridden, and thus that it may be
statically bound (and made inline,
thus using the equivalent of a C++
non-virtual call). These optimizations
are up to the compiler.
A bit circular, perhaps.
So Java's rationale is probably something like this: the whole point of an object-oriented language is that things can be extended. So in terms of pure design, it really makes little sense to treat extensible as the "special case".
Remember that Java has the luxury of compiling at runtime. So some of the performance arguments in C++ compilation go out the window. In C++, if a class might be overridden, then the compiler has to take extra steps. In Java, there's no mystery about it: at any given moment in time, the JVM knows whether or not a particular method/class has been overridden or not, and that's essentially what counts.
Note that the final keyword is essentially about program design, not optimisation. The JVM doesn't need this information to see whether or not a class/method has been overridden!!
If the question is about to ask what is the better approach between java and C++/C# then it was already discussed in opposite direction in another thread, and many resource available on the net
Why C# implements methods as non-virtual by default?
http://www.artima.com/intv/nonvirtual.html
Recent introduction of #Override annotation and its wide adoption in new code, suggest that the exact answer to the question "Why all java methods are implicitly overridable?" is indeed because the designer made a mistake. (And they already fixed it)
Oh ! I'm going to get negative vote for this.
Java tries to move closer to a more dynamic language definition, where everything is an object and everything is a virtual method. It also wants to avoid ambiguity and hard to understand constructs, which it's designers viewed as a flaw in C++, therefore no operator overloading, and in this case no ability to have two public method signatures on one class hierarchy invoking different methods depending on the type of the variable referencing it.
C# is more concerned about the stability of subclasses and making sure that the subclasses behave predictably. C++ is concerned about performance.
Three different design priorities, leading to different choices.
I would say that in Java cost of virtual method is low compared to whole VM costs. In C++ it is significant cost, compared to assembly-like C background. Nobody would decide to make all methods called through pointer by default as result of C to C++ migration. It's too big change.
I've been mulling about a post by Misko Hevery that static methods in Java are a death to testability. I don't want to discuss the testability issue but more on the concept of static methods. Why do people hate it so much?
It's true that we don't have closures (but we have a slightly awkward anonymous functions), lambdas & functions as first class objects. In a way, I think static methods can be used to mimic functions as first class objects.
One characteristic of functional programming is immutability of data. static does imply that you don't need an object (instance) representing state, so that's not a bad start. You do however have state on the class level, but you can make this final. Since (static) methods aren't first-class functions at all, you will still need ugly constructions like anonymous classes to approach a certain style of functional programming in Java.
FP is best done in an functional language, since it has the necessary language support for things like higher-order functions, immutability, referential transparency and so on.
However, this does not mean that you can't program in a functional style in an imperative language like Java. Other examples can be given as well. It's not because you are programming in Java that you are doing OOP. You can program with global data and unstructured control flows (goto) in a structured language as C++. I can do OOP in a functional language like Scheme. Etc.
Steve McConnell mentions the difference of programming in a language versus programming into a language in Code Complete (also a very popular reference on SO).
So, in short, if you say that "static methods mimic first-class functions", I do not agree.
If, however, and I think that this was more the point you were trying to get across, you would say that "static methods can help for programming in a functional style in Java", I agree.
Static methods make testing hard because they can't be replaced, it's as simple as that.
How can static methods "mimic" functions as first class objects1? Arguably they're worse than anything else on this front. You can "mimic" functions as first class objects by creating single-method interfaces, and indeed Google's Java Collections does exactly this in a number of places (for predicates, projections etc). That can't be done with static methods - there's no way (other than with reflection) to pass the concept of "when you want to apply a function, use this method.
No, I can't see how static methods help here. They discourage state-changing (as the only state available is the global state and any mutable state passed in via the parameters) but they don't help on the "functions as first class objects" side.
C# has better support for this (with lambda expressions and delegates) but even that's not as general as it might be. (Compare it with F#, for example.)
1 As of Java 8, method references will allow methods to be converted to instances of appropriate single-method interfaces, which will make all of this more relevant. Back in 2009 that was a long way off though...
Functional != function, and for the record I will claim that a method != function...
Java is a statically typed, object oriented language. Java has also maintained a relative purity in that manner but it's no where near a functional language.
While it's true that you can mimic the behavior of functional programming with imperative programming you're never gonna get that tidy syntax which you'll wanna have for lambda calculus. In a way, if the language doesn't support proper lambda calculus it's not a functional programming language.
C++ has functions, but C++ also have classes. C++ therefore have two type of functions, member functions and functions. When you say method you mean a member function. Because the method is invoked on an instance of an object. But when you say static method you mean just function (in the C/C++ sense). This is just a vocabulary for referring to elements of your code. And in Java code can not exist outside a class, a method would imply that it belongs to some class i.e. type.
So far nothing of what I've said relates to functional programming but I think you get the point where you wrong.
I suggest you look at pure functional programming languages such as Haskell or Erlang. Because functional programming languages generally don't have closers either.
Your claim that static methods can be used to mimic functions as first class objects sounds really bizarre to me. It sounds more like a dynamic programming language than functional programming.
My biggest objection against static methods is that they are not polymorphic and that they are not used in an object-oriented way, instead one has to you the class (not an object) to access them.
If you only use static methods then you are programming in a procedural, non-object-oriented style.
However, the only context I can think of where this would be OK is during the first programming lessons before object orientation is introduced.
In Java, you can't give a function as an argument to another function.
In a functional language, if you have a function
def addOne(i) = i + 1
you can pass that to another function that eg applies it to all elements of a list.
In Java, with
public static int addOne(int i) { return i + 1; }
there is no way to do that.
I've been reading a lot lately about the next release of Java possibly supporting closures. I feel like I have a pretty firm grasp on what closures are, but I can't think of a solid example of how they would make an Object-Oriented language "better". Can anyone give me a specific use-case where a closure would be needed (or even preferred)?
As a Lisp programmer I would wish that the Java community understands the following difference: functions as objects vs. closures.
a) functions can be named or anonymous. But they can also be objects of themselves. This allows functions to be passed around as arguments, returned from functions or stored in data structures. This means that functions are first class objects in a programming language.
Anonymous functions don't add much to the language, they just allow you to write functions in a shorter way.
b) A closure is a function plus a binding environment. Closures can be passed downwards (as parameters) or returned upwards (as return values). This allows the function to refer to variables of its environment, even if the surrounding code is no longer active.
If you have a) in some language, then the question comes up what to do about b)? There are languages that have a), but not b). In the functional programming world a) (functions) and b (functions as closures) is nowadays the norm. Smalltalk had a) (blocks are anonymous functions) for a long time, but then some dialects of Smalltalk added support for b) (blocks as closures).
You can imagine that you get a slightly different programming model, if you add functions and closures to the language.
From a pragmatic view, the anonymous function adds some short notation, where you pass or invoke functions. That can be a good thing.
The closure (function plus binding) allows you for example to create a function that has access to some variables (for example to a counter value). Now you can store that function in an object, access it and invoke it. The context for the function object is now not only the objects it has access to, but also the variables it has access to via bindings. This is also useful, but you can see that variable bindings vs. access to object variables now is an issue: when should be something a lexical variable (that can be accessed in a closure) and when should it be a variable of some object (a slot). When should something be a closure or an object? You can use both in the similar ways. A usual programming exercise for students learning Scheme (a Lisp dialect) is to write a simple object system using closures.
The result is a more complicated programming language and a more complicated runtime model. Too complicated?
They don't make an Object-Oriented language better. They make practical languages more practical.
If you're attacking a problem with the OO hammer - represent everything as interactions between objects - then a closure makes no sense. In a class-based OO language, closures are the smoke-filled back rooms where stuff gets done but no one talks about it afterwards. Conceptually, it is abhorrent.
In practice, it's extremely convenient. I don't really want to define a new type of object to hold context, establish the "do stuff" method for it, instantiate it, and populate the context... i just want to tell the compiler, "look, see what i have access to right now? That's the context i want, and here's the code i want to use it for - hold on to this for me 'till i need it".
Fantastic stuff.
The most obvious thing would be a pseudo-replacement for all those classes that just have a single method called run() or actionPerformed() or something like that. So instead of creating a Thread with a Runnable embedded, you'd use a closure instead. Not more powerful than what we've got now, but much more convenient and concise.
So do we need closures? No. Would they be nice to have? Sure, as long as they don't feel bolted on, as I fear they would be.
I suppose for supporting core functional programming concepts, you need closures. Makes the code more elegant and composable with the support for closures. Also, I like the idea of passing around lines of code as parameters to functions.
There are some very useful 'higher order functions' which can do operations on lists using closures. Higher order functions are functions having 'function objects' as parameters.
E.g. it is a very common operation to apply some transformation to every element in a list. This higher order function is commonly called 'map' or 'collect'. (See the *. spread operator of Groovy).
For example to square each element in a list without closures you would probably write:
List<Integer> squareInts(List<Integer> is){
List<Integer> result = new ArrayList<Integer>(is.size());
for (Integer i:is)
result.add(i*i);
return result;
}
Using closures and map and the proposed syntax, you could write it like that:
is.map({Integer i => i*i})
(There is a possible performance problem here regarding boxing of primitive types.)
As explained by Pop Catalin there is another higher order function called 'select' or 'filter': It can be used to get all the elements in a list complying to some condition. For example:
Instead of:
void onlyStringsWithMoreThan4Chars(List<String> strings){
List<String> result = new ArrayList<String>(str.size()); // should be enough
for (String str:strings)
if (str.length() > 4) result.add(str);
return result;
}
Instead you could write something like
strings.select({String str => str.length() > 4});
using the proposal.
You might look at the Groovy syntax, which is an extension of the Java language to support closures right now. See the chapter on collections of the Groovy User Guide for more examples what to do with closures.
A remark:
There is perhaps some clarification needed regarding the term 'closure'. What I've shown above are strictly spoken no closures. They are just 'function objects'.
A closure is everything which can capture - or 'close over' - the (lexical) context of the code surrounding it. In that sense there are closures in Java right now, i.e. anonymous classes:
Runnable createStringPrintingRunnable(final String str){
return new Runnable(){
public void run(){
System.out.println(str); // this accesses a variable from an outer scope
}
};
}
Java doesn't need closures, an Object oriented language can do everything a closure does using intermediate objects to store state or do actions (in Java's case inner classes).
But closures are desirable as a feature because they greatly simplify the code and increase readability and as a consequence the maintainability of the code.
I'm no Java specialist but I'm using C# 3.5 and closures are one of my favorite features of the language, for example take the following statement as an example:
// Example #1 with closures
public IList<Customer> GetFilteredCustomerList(string filter) {
//Here a closure is created around the filter parameter
return Customers.Where( c => c.Name.Contains(filter)).ToList();
}
now take an equivalent example that doesn't use closures
//Example #2 without closures, using just basic OO techniques
public IList<Customer> GetFilteredCustomerList(string filter) {
return new Customers.Where( new CustomerNameFiltrator(filter));
}
...
public class CustomerNameFiltrator : IFilter<Customer> {
private string _filter;
public CustomerNameFiltrator(string filter) {
_filter = filter;
}
public bool Filter(Customer customer) {
return customer.Name.Contains( _filter);
}
}
I know this is C# and not Java but the idea is the same, closures are useful for conciseness, and make code shorter and more readable. Behind the scenes, the closures of C# 3.5 do something that's looks very similar to example #2 meaning the compiler creates a private class behind the scenes and passes the 'filter' parameter to it.
Java doesn't need closures to work, as a developer you don't need them either, but, they are useful and provide benefits so that means that they are desirable in a language that is a production language and one of it's goals is productivity.
I've been reading a lot lately about the next release of Java possibly supporting closures. I feel like I have a pretty firm grasp on what closures are, but I can't think of a solid example of how they would make an Object-Oriented language "better."
Well, most people who use the term "closure" actually mean "function object", and in this sense, function objects make it possible to write simpler code in certain circumstances such as when you need custom comparators in a sort function.
For example, in Python:
def reversecmp(x, y):
return y - x
a = [4, 2, 5, 9, 11]
a.sort(cmp=reversecmp)
This sorts the list a in reverse order by passing the custom comparison functoin reversecmp. The addition of the lambda operator makes things even more compact:
a = [4, 2, 5, 9, 11]
a.sort(cmp=lambda x, y : y - x)
Java does not have function objects, so it uses "functor classes" to simulate them. In Java you do the equivalent operation by implementing a custom version of the Comparator class, and passing that to the sort function:
class ReverseComparator implements Comparator {
public compare(Object x, Object y) {
return (Integer) y - (Integer) x;
}
...
List<Integer> a = Arrays.asList(4, 2, 5, 9, 11);
Collections.sort(a, new ReverseComparator());
As you can see, it gives the same effect as closures, but is clumsier and more verbose. However, the addition of anonymous inner classes obviates most of the pain:
List<Integer> a = Arrays.asList(4, 2, 5, 9, 11);
Comparator reverse = new Comparator() {
public Compare(Object x, Object y) {
return (Integer) y - (Integer) x;
}
}
Collections.sort(a, reverse);
So I would say that the combination of functor classes + anonymous inner classes in Java is sufficient to compensate for the lack of true function objects, making their addition unnecessary.
Java has had closures since 1.1, just in a very cumbersome and limited way.
They are often useful wherever you have a callback of some description. A common case is to abstract away control flow, leaving the interesting code to call an algoritm with a closure that has no external control flow.
A trivial example is for-each (although Java 1.5 already has that). Whilst you can implement a forEach method in Java as it stands, it's far too verbose to be useful.
An example which already makes sense with existing Java is implementing the "execute around" idiom, whereby resource acquisition and release is abstracted. For instance, file open and close can be done within try/finally, without the client code having to get the details right.
When closures finally arrive in Java, I will gleefully get rid of all my custom comparator classes.
myArray.sort( (a, b) => a.myProperty().compareTo(b.myProperty() );
...looks a helluva lot better than...
myArray.sort(new Comparator<MyClass>() {
public int compare(MyClass a, MyClass b) {
return a.myProperty().compareTo(b.myProperty();
}
});
A few people have said, or implied, that closures are just syntactic sugar - doing what you could already do with anonymous inner classes and making it more convenient to pass parameters in.
They are syntactic sugar in the same sense that Java is syntactic sugar for assembler (that "assembler" could be bytecode, for sake of argument). In other words they raise they level of abstraction, and this is an important concept.
Closures promote the concept of the function-as-object to a first class entity - one that increases the expressiveness of code, rather than cluttering it with even more boilerplate.
An example that's close to my heart has already been mentioned by Tom Hawtin - implementing the Execute Around idiom, which is just about the only way to get RAII into Java. I wrote a blog entry on exactly that subject a couple of years ago when I first heard closures might be coming.
Ironically, I think the very reason that closures would be good for Java (more expressiveness with less code) may be what rattles many Java advocates. Java has a mindset of "spell everything out the long way". That and the fact that closures are a nod towards a more functional way of doing things - which I also see as a Good Thing, but may water down the pure OO message that many in the Java community hold dear.
I have been thinking a lot about the topic of this very interesting question in
the last few days. First of all, if I have understood correctly, Java already has
some basic notion of closures (defined through anonymous classes) but the new feature
that is going to be introduced is the support for closures based on anonymous functions.
This extension will definitely make the language more expressive but I am not sure
if it really fits with the rest of the language.
Java has been designed as an object-oriented language with no support for functional programming: Will the new semantics be easy to understand? Java 6 does not even have functions, will Java 7 have anonymous functions but no "normal" functions?
My impression is that as new programming styles or paradigms like functional
programming become more popular, everyone wants to use them in their
favourite OOP language. This is understandable: one wants to continue to use
a language they're familiar with while adopting new features. But in this way
a language can become really complex and lose coherence.
So my attitude at the moment is to stick to Java 6 for OOP (I hope Java 6 will still
be supported for a while) and, in case I really get interested in doing OOP + FP,
to take a look at some other language like Scala (Scala was defined to be multi-
paradigm from the beginning and can be well integrated with Java) rather than switching
to Java 7.
I think Java owes its success to the fact that it combines a simple language with very
powerful libraries and tools, and I do not think that new features like closures will
make it a better programming language.
Now that JDK8 is about to be released there is more information available that can enrich the answers to this question.
Bria Goetz, language architect at Oracle, has published a series of papers (yet drafts) on the current state of lambda expressions in Java. It does also cover closures as they are planning to release them in the upcoming JDK, which should be code complete around January 2013 and should be released around midyear 2013.
The State of Lambda: in the first page or two this article attempts to answer the question presented here. Although I still found it short in arguments, but is is full of examples.
The State of Lambda - Libraries Edition: this is also very interesting because it covers advantages like lazy evaluation and parallelism.
The Translation of Lambda Expressions: which basically explains the desugaring process done by the Java compiler.
As a java developer who is trying to teach themselves lisp in an attempt to become a better programmer, I would say that I would like to see the Josh Block proposal for closures implemented. I find myself using anonymous inner classes to express things like what to do with each element of a list when aggregating some data. To would be nice to represent that as a closure, instead of having to create an abstract class.
Closures in an imperative language (examples: JavaScript, C#, the forthcoming C++ refresh) are not the same as anonymous inner classes. They need to be able to capture modifiable references to local variables. Java's inner classes can only capture local final variables.
Almost any language feature can be criticised as non-essential:
for, while, do are all just syntactic sugar over goto/if.
Inner classes are syntactic sugar over classes with a field pointing to the outer class.
Generics are syntactic sugar over casts.
Exactly the same "non-essential" argument should have blocked the inclusion of all the above features.
Java Closure Examples
Not only that benjismith, but I love how you can just do...
myArray.sort{ it.myProperty }
You only need the more detailed comparator you've shown when the natural language comparison of the property doesn't suit your needs.
I absolutely love this feature.
What about readability and maintainability...one-liner closures are harder to understand and debug, imo
Software has looong life and you can get people with rudimentary knowledge of the language to maintain it...So spread out logic better than one-liners for easy maintenance...You generally don't have a software star looking after software after its release...
You might want to look at Groovy, a language that's mostly compatible with Java, and runs on the JRE, but supports Closures.
The lack of binding in anonymous function [i.e. if the variables (and method arguments if there is an enclosing method) of the outer context are declared final then they are available but not otherwise], I don't quite understand what that restriction actually buys.
I use "final" profusely anyways. So, if my intent was to use the same objects inside the closure, I would indeed declare those objects final in the enclosing scope. But what would be wrong in letting the "closure [java a.i.c.]" just get a copy of the reference as if passed via a constructor (well that in fact is how it is done).
If the closure wants to overwrite the reference, so be it; it will do so without changing the copy that the enclosing scope sees.
If we argue that that would lead to unreadable code (e.g. maybe it's not straight-forward to see what the object reference is at the time of the constructor call for the a.i.c.), then how about at least making the syntax less verbose? Scala? Groovy?