I've read today about the Java 8 release. But I don't understand fully the concept of reference methods in Java 8. Does this mean that Java now has the support of functions as first class objects? I have seen, how to construct a reference to function. But it seems to me, that the Converter object they provide has quite limited functionality. Is it now possible in Java:
to pass the function as the argument to another function?
to return the function as the return value from another function?
and what about closures? Are they implemented fully like in functional languages, or they do have some limitations? It seems to me that there are some limitations (you cannot change the value of the variable you reference in a closure, it must be marked as final and etc).
The most important aspects of first-class functions have been blended into the existing Java type system. No true function type has been introduced; any single-method interface is its own "function type". So, as for your first two questions, you can freely pass around instances of such functional interfaces.
There are many subtle changes to the semantics, which allow one to use lambda syntax/method references to implement any such interface. You can even use higher-order functions such as compose, which returns a generic Function type, and pass it to a method which expects a compatible functional interface type.
you cannot change the value of the variable you reference in a closure
This is not a limitation specific to Java. In fact, most FP languages don't support mutable variables of any kind. Note that there is no requirement to use the final keyword on the variable; the concept of effectively final takes care of that.
It is possible. How do you do it?
First construct a "Functional Interface" (or use one of the provided ones). A functional interface is an interface with a single method. java.lang.Runnable is an example.
Second, write a method that takes a functional interface as a parameter.
public void doAThing(Runnable r) {
r.run();
}
Third, write a method with the correct signature.
public class MyClass {
public void runAThing() {
System.out.println("I executed!");
}
}
Fourth, call the function passing in a method reference.
MyClass mc = new MyClass();
doAThing(mc::runAThing);
You'll note that none of the classes you've wrote ever explicitly implements Runnable. This is handled for you by the compiler.
You can do something similar using a lamdba expression:
doAThing(() -> System.out.println("I executed as a lamdba expression!"));
To return the function as a value from another function, just return an instance of Runnable.
Methods are not first class objecs in Java, apart from the already existing usage in reflection, to answer your questions:
Yes, you can pass it on, but it needs to satisfy the signature.
For a void method() you use a Runnable, like this:
Runnable method = this::method if it is in the same class, and then run the actual method with method.run().
However for a double method() you need to use a DoubleSupplier, like this:
DoubleSupplier method = this::method, and then use it as double d = method.get().
And many more signatures, and you can even define your own with Functional Interfaces.
Yes it is possible, but only specific signatures as shown in Point 1.
Lambdas behave exactly as anonymous inner classes, which are closures by itself, Java has had support for closures since they introduced anonymous inner classes. The only thing that is added now is that the syntax is much prettier.
No, not first class functions. Lambda expression are wrapped in a interface, and some syntatic sugar applied for brevity.
But you can;t create a function on its own and pass it around different methods, whether thats a key point or not is a different question.
Related
I'm using the "final"-keyword for method-parameters like the "const"-keyword in C/C++ even if it's meaning in JAVA is not 100% the same as in C/C++. I do that mainly to easily distinguish between input- and output-parameters. Like here:
interface Test
{
public void myMethod(final int input1, final float input2, SomeResults output);
}
When I then create an implemention of the interface (or abstract class) and let eclipse generate the overloaded methods eclipse will ommit all "final"-keywords which is really bad. There is an option within the SaveActions-Part of the Java-Editor settings but there I can just enforce eclipse to use "final" everywhere where it is possible which is definitely not my intention. How can I force eclipse to NOT IGNORE my "final"-keywords in interface methods or abstract methods and put them in generated method stubs of implementions and child classes instead?
How can I force eclipse to NOT IGNORE my final keywords in interface methods or abstract methods and put them in generated method stubs of implementations and child classes instead?
I don't think it is possible ... unless you are willing to modify Eclipse.
I am afraid that what you are doing doesn't have any effect.
As stated I use the final keyword only to clarify that a parameter is a "pure input" variable. Regarding that primitives will always be passed by value is known to me.
That is not what final means.
All parameters are "pure input" ... in the sense that they are passed by value. There is no such thing as an "out" parameter in Java.
Conversely, if a parameter's type is a reference type, then declaring it final does not stop the method body from mutating the actual parameter. In other words, it doesn't stop the method body from using the parameter to simulate an "out" parameter.
In Java, declaring a formal parameter as final in an abstract method declarator doesn't have any meaning. It only has meaning if the method declarator is followed by a method body. (Then it means that the variable cannot be assigned to.) Therefore, it would be suspect if a tool (e.g. an Eclipse stub generator) were to place any meaning on the final in the the former context.
My advice would be not to place this unintended (by the Java designers) meaning on final, in either interfaces or in classes. If you want to express "this is not an "out" parameter, either do it in the javadocs, or invent a custom annotation to express it. (In the latter case, you could potentially implement a static checker to ensure that the method body does not mutate the parameter object.)
Will this cause confusion to use interchangeably terms "function" vs "method" in java7 and java8?
I know that java 8 introduced some concept like lambda calculus, which allows inserting small bits of functional paradigm to be used.
Functions as in lambda calculus, functional programming.
When speaking about Java-8 you may use the word "function" to refer to the functional interface (interface with single abstract method), the class implementing such interface or the expression of the functional interface type (including lambda expression or method reference). You should not however call methods as functions. This become even more important than in previous Java versions as if you see the word "function" in Java-7 related discussion, you can assume that the "method" was meant. But in Java-8 people may think that you are speaking about functional interface, not about method.
So it's ok to say:
The Stream.map method accepts a function as a parameter.
Or
A Collector interface aggregates four functions: supplier, accumulator, combiner and finisher.
Or
I pass the Objects::nonNull function to the Stream.filter method.
But the following would sound confusing:
I get a strange exception when I use Math.sqrt function.
You probably may get away with interchanging function and method during non formal talk but if you want to be precise keep in mind that:
method is always associated with some object or class, function is not (although in Java you can't define functions outside class or object),
function must always return a value, method might not return anything (void return type is not a real value).
In general - you now know that there's a difference between a function and a method so just keep it in mind and use proper term from now on.
Functions are different from methods irrespective of java version.
Though with java 8 these terms are more meaningful now.
With earlier versions of java also, you can see functions as the static methods as these are not bound to the class data.
I was reading a textbook and I was wondering how come the argument we pass to the function is neither a primitive or an user-defined instance of a class.
SwingUtilities.invokeLater(new Runnable()
{
public void run() {
new ButtonDemo();
}
});
I have learned that it was either one of those two. But it seems here that it passes an user-defined constructor method, e.g. Runnable(). It seems they want to run the thread at a later time, but when? And is this even legal, I assume it is, but I never heard of such a thing in my Java class.
This is actually passing an instance of an anonymous inner class implementing the Runnable interface. Read about them in the Java tutorial.
I was wondering how come the argument we pass to the function is neither a primitive or an user-defined instance of a class.
It is an instance of a user-defined class. The only difference is that this class does not have a name *.
It is a real instance of a class, though - it can do most of the things a named class can do. Among other things, it can provide implementations of methods of its base class or an interface, which is what is used to pass "a piece of executable code" to a method.
* At least, not a user-visible one: Java compiler does assign each anonymous class an internal name, which usually contains a dollar sign.
The code inside SwingUtilities is something like this
private Runnable runnable;
private void invoke(){//called at some point from inside the runnable
runable.run();
}
public void invokeLater(Runnable runnable){
this.runnable=runnable;
}
These are called callbacks.
This called anonymous class, where you define a class for a single use and do not provide it a name.
To understand them better, refer to this tutorial: http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
Read about Anonymous Classes. This are treated as separate classes. If you compile your code and say the file name is Test.java. By compiling there will two class file Test.class and Test$1.class and if you have more inner classes you will have Test$2.class, Test$3.class and so on.
Passing code as function arguments
Java will have lambda expressions in release 8. It will worth checking out this as well: http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
In Java:
class Base {
public Base() { System.out.println("Base::Base()"); virt(); }
void virt() { System.out.println("Base::virt()"); }
}
class Derived extends Base {
public Derived() { System.out.println("Derived::Derived()"); virt(); }
void virt() { System.out.println("Derived::virt()"); }
}
public class Main {
public static void main(String[] args) {
new Derived();
}
}
This will output
Base::Base()
Derived::virt()
Derived::Derived()
Derived::virt()
However, in C++ the result is different:
Base::Base()
Base::virt() // ← Not Derived::virt()
Derived::Derived()
Derived::virt()
(See http://www.parashift.com/c++-faq-lite/calling-virtuals-from-ctors.html for C++ code)
What causes such a difference between Java and C++? Is it the time when vtable is initialized?
EDIT: I do understand Java and C++ mechanisms. What I want to know is the insights behind this design decision.
Both approaches clearly have disadvatages:
In Java, the call goes to a method which cannot use this properly because its members haven’t been initialised yet.
In C++, an unintuitive method (i.e. not the one in the derived class) is called if you don’t know how C++ constructs classes.
Why each language does what it does is an open question but both probably claim to be the “safer” option: C++’s way prevents the use of uninitialsed members; Java’s approach allows polymorphic semantics (to some extent) inside a class’ constructor (which is a perfectly valid use-case).
Well you have already linked to the FAQ's discussion, but that’s mainly problem-oriented, not going into the rationales, the why.
In short, it’s for type safety.
This is one of the few cases where C++ beats Java and C# on type safety. ;-)
When you create a class A, in C++ you can let each A constructor initialize the new instance so that all common assumptions about its state, called the class invariant, hold. For example, part of a class invariant can be that a pointer member points to some dynamically allocated memory. When each publicly available method preserves the class invariant, then it’s guaranteed to hold also on entry to each method, which greatly simplifies things – at least for a well-chosen class invariant!
No further checking is then necessary in each method.
In contrast, using two-phase initialization such as in Microsoft's MFC and ATL libraries you can never be quite sure whether everything has been properly initialized when a method (non-static member function) is called. This is very similar to Java and C#, except that in those languages the lack of class invariant guarantees comes from these languages merely enabling but not actively supporting the concept of a class invariant. In short, Java and C# virtual methods called from a base class constructor can be called down on a derived instance that has not yet been initialized, where the (derived) class invariant has not yet been established!
So, this C++ language support for class invariants is really great, helping do away with a lot of checking and a lot of frustrating perplexing bugs.
However, it makes a bit difficult to do derived class specific initialization in a base class constructor, e.g. doing general things in a topmost GUI Widget class’ constructor.
The FAQ item “Okay, but is there a way to simulate that behavior as if dynamic binding worked on the this object within my base class's constructor?” goes a little into that.
For a more full treatment of the most common case, see also my blog article “How to avoid post-construction by using Parts Factories”.
Regardless of how it's implemented, it's a difference in what the language definition says should happen. Java allows you to call functions on a derived object that hasn't been fully initialized (it has been zero-initialized, but its constructor has not run). C++ doesn't allow that; until the derived class's constructor has run, there is no derived class.
Hopefully this will help:
When your line new Derived() executes, the first thing that happens is the memory allocation. The program will allocate a chunk of memory big enough to hold both the members of Base and Derrived. At this point, there is no object. It's just uninitialized memory.
When Base's constructor has completed, the memory will contain an object of type Base, and the class invariant for Base should hold. There is still no Derived object in that memory.
During the construction of base, the Base object is in a partially-constructed state, but the language rules trust you enough to let you call your own member functions on a partially-constructed object. The Derived object isn't partially constructed. It doesn't exist.
Your call to the virtual function ends up calling the base class's version because at that point in time, Base is the most derived type of the object. If it were to call Derived::virt, it would be invoking a member function of Derived with a this-pointer that is not of type Derrived, breaking type safety.
Logically, a class is something that gets constructed, has functions called on it, and then gets destroyed. You can't call member functions on an object that hasn't been constructed, and you can't call member functions on an object after it's been destroyed. This is fairly fundamental to OOP, the C++ language rules are just helping you avoid doing things that break this model.
In Java, method invocation is based on object type, which is why it is behaving like that (I don't know much about c++).
Here your object is of type Derived, so jvm invokes method on Derived object.
If understand Virtual concept clearly, equivalent in java is abstract, your code right now is not really virtual code in java terms.
Happy to update my answer if something wrong.
Actually I want to know what's the insight behind this design decision
It may be that in Java, every type derives from Object, every Object is some kind of leaf type, and there's a single JVM in which all objects are constructed.
In C++, many types aren't virtual at all. Furthermore in C++, the base class and the subclass can be compiled to machine code separately: so the base class does what it does without whether it's a superclass of something else.
Constructors are not polymorphic in case of both C++ and Java languages, whereas a method could be polymorphic in both languages. This means, when a polymorphic method appears inside a constructor, the designers would be left with two choices.
Either strictly conform to the semantics on non-polymorphic
constructor and thus consider any polymorphic method invoked within a
constructor as non-polymorphic. This is how C++ does§.
Or, compromise
the strict semantics of non-polymorphic constructor and adhere to the
strict semantics of a polymorphic method. Thus polymorphic methods
from constructors are always polymorphic. This is how Java does.
Since none of the strategies offers or compromises any real benefits compared to other and yet Java way of doing it reduces lots of overhead (no need to differentiate polymorphism based on the context of constructors), and since Java was designed after C++, I would presume, the designer of Java opted for the 2nd option seeing the benefit of less implementation overhead.
Added on 21-Dec-2016
§Lest the statement “method invoked within a constructor as non-polymorphic...This is how C++ does” might be confusing without careful scrutiny of the context, I’m adding a formalization to precisely qualify what I meant.
If class C has a direct definition of some virtual function F and its ctor has an invocation to F, then any (indirect) invocation of C’s ctor on an instance of child class T will not influence the choice of F; and in fact, C::F will always be invoked from C’s ctor. In this sense, invocation of virtual F is less-polymorphic (compared to say, Java which will choose F based on T)
Further, it is important to note that, if C inherits definition of F from some parent P and has not overriden F, then C’s ctor will invoke P::F and even this, IMHO, can be determined statically.
While I am learning Haskell, I noticed its type class, which is supposed to be a great invention that originated from Haskell.
However, in the Wikipedia page on type class:
The programmer defines a type class by specifying a set of function or
constant names, together with their respective types, that must exist
for every type that belongs to the class.
Which seems rather close to Java's Interface to me (quoting Wikipedia's Interface(Java) page):
An interface in the Java programming language is an abstract type that
is used to specify an interface (in the generic sense of the term)
that classes must implement.
These two looks rather similar: type class limit a type's behavior, while interface limit a class' behavior.
I wonder what are the differences and similarities between type class in Haskell and interface in Java, or maybe they are fundamentally different?
EDIT: I noticed even haskell.org admits that they are similar. If they are so similar (or are they?), then why type class is treated with such hype?
MORE EDIT: Wow, so many great answers! I guess I'll have to let the community decide which is the best one. However, while reading the answers, all of them seem to just say that "there are many things typeclass can do while interface cannot or have to cope with generics". I cannot help but wondering, are there anything interfaces can do while typeclasses cannot? Also, I noticed that Wikipedia claims that typeclass was originally invented in the 1989 paper *"How to make ad-hoc polymorphism less ad hoc", while Haskell is still in its cradle, while Java project was started in 1991 and first released in 1995. So maybe instead of typeclass being similar to interfaces, its the other way around, that interfaces were influenced by typeclass? Are there any documents/papers support or disprove this? Thanks for all the answers, they are all very enlightening!
Thanks for all the inputs!
I would say that an interface is kind of like a type class SomeInterface t where all of the values have the type t -> whatever (where whatever does not contain t). This is because with the kind of inheritance relationship in Java and similar languages, the method called depends on the type of object they are called on, and nothing else.
That means it's really hard to make things like add :: t -> t -> t with an interface, where it is polymorphic on more than one parameter, because there's no way for the interface to specify that the argument type and return type of the method is the same type as the type of the object it is called on (i.e. the "self" type). With Generics, there are kinda ways to fake this by making an interface with generic parameter that is expected to be the same type as the object itself, like how Comparable<T> does it, where you are expected to use Foo implements Comparable<Foo> so that the compareTo(T otherobject) kind of has type t -> t -> Ordering. But that still requires the programmer to follow this rule, and also causes headaches when people want to make a function that uses this interface, they have to have recursive generic type parameters.
Also, you won't have things like empty :: t because you're not calling a function here, so it isn't a method.
What is similar between interfaces and type classes is that they name and describe a set of related operations. The operations themselves are described via their names, inputs, and outputs. Likewise there may be many implementations of these operations that will likely differ in their implementation.
With that out of the way, here are some notable differences:
Interfaces methods are always associated with an object instance. In other words, there is always an implied 'this' parameter that is the object on which the method is called. All inputs to a type class function are explicit.
An interface implementation must be defined as part of the class that implements the interface. Conversely, a type class 'instance' can be defined completely seperate from its associated type...even in another module.
In general, I think its fair to say that type classes are more powerful and flexible than interfaces. How would you define an interface for converting a string to some value or instance of the implementing type? It's certainly not impossible, but the result would not be intuitive or elegant. Have you ever wished it was possible to implement an interface for a type in some compiled library? These are both easy to accomplish with type classes.
Type classes were created as a structured way to express "ad-hoc polymorphism", which is basically the technical term for overloaded functions. A type class definition looks something like this:
class Foobar a where
foo :: a -> a -> Bool
bar :: String -> a
What this means is that, when you use apply the function foo to some arguments of a type that belong to the class Foobar, it looks up an implementation of foo specific to that type, and uses that. This is very similar to the situation with operator overloading in languages like C++/C#, except more flexible and generalized.
Interfaces serve a similar purpose in OO languages, but the underlying concept is somewhat different; OO languages come with a built-in notion of type hierarchies that Haskell simply doesn't have, which complicates matters in some ways because interfaces can involve both overloading by subtyping (i.e., calling methods on appropriate instances, subtypes implementing interfaces their supertypes do) and by flat type-based dispatch (since two classes implementing an interface may not have a common superclass that also implements it). Given the huge additional complexity introduced by subtyping, I suggest it's more helpful to think of type classes as an improved version of overloaded functions in a non-OO language.
Also worth noting is that type classes have vastly more flexible means of dispatch--interfaces generally apply only to the single class implementing it, whereas type classes are defined for a type, which can appear anywhere in the signature of the class's functions. The equivalent of this in OO interfaces would be allowing the interface to define ways to pass an object of that class to other classes, define static methods and constructors that would select an implementation based on what return type is required in calling context, define methods that take arguments of the same type as the class implementing the interface, and various other things that don't really translate at all.
In short: They serve similar purposes, but the way they work is somewhat different, and type classes are both significantly more expressive and, in some cases, simpler to use because of working on fixed types rather that pieces of an inheritance hierarchy.
I've read the above answers. I feel I can answer slightly more clearly:
A Haskell "type class" and a Java/C# "interface" or a Scala "trait" are basically analogous. There is no conceptual distinction between them but there are implementation differences:
Haskell type classes are implemented with "instances" that are separate from the data type definition. In C#/Java/Scala, the interfaces/traits must be implemented in the class definition.
Haskell type classes allow you to return a this type or self type. Scala traits do as well (this.type). Note that "self types" in Scala are a completely unrelated feature. Java/C# require a messy workaround with generics to approximate this behavior.
Haskell type classes let you define functions (including constants) without an input "this" type parameter. Java/C# interfaces and Scala traits require a "this" input parameter on all functions.
Haskell type classes let you define default implementations for functions. So do Scala traits and Java 8+ interfaces. C# can approximate something like this with extensions methods.
In Master minds of Programming, there's an interview about Haskell with Phil Wadler, the inventor of type classes, who explain the similarities between interfaces in Java and type classes in Haskell:
A Java method like:
public static <T extends Comparable<T>> T min (T x, T y)
{
if (x.compare(y) < 0)
return x;
else
return y;
}
is very similar to the Haskell method:
min :: Ord a => a -> a -> a
min x y = if x < y then x else y
So, type classes are related to interfaces, but the real correspondance would be a static method parametrized with a type as above.
Watch Phillip Wadler's talk Faith, Evolution, and Programming Languages. Wadler worked on Haskell and was a major contributor to Java Generics.
I can't speak to the "hype"-level, if it seems that way fine. But yes type classes are similar in lots of ways. One difference that I can think of is that it Haskell you can provide behavior for some of the type class's operations:
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
x == y = not (x /= y)
which shows that there are two operations, equal (==), and not-equal (/=), for things that are instances of the Eq type class. But the not-equal operation is defined in terms of equals (so that you'd only have to provide one), and vice versa.
So in probably-not-legal-Java that would be something like:
interface Equal<T> {
bool isEqual(T other) {
return !isNotEqual(other);
}
bool isNotEqual(T other) {
return !isEqual(other);
}
}
and the way that it would work is that you'd only need to provide one of those methods to implement the interface. So I'd say that the ability to provide a sort of partial implemention of the behavior you want at the interface level is a difference.
Read Software Extension and Integration with Type Classes where examples are given of how type classes can solve a number of problems that interfaces cannot.
Examples listed in the paper are:
the expression problem,
the framework integration problem,
the problem of independent extensibility,
the tyranny of the dominant decomposition, scattering and tangling.
They are similar (read: have similar use), and probably implemented similarly: polymorphic functions in Haskell take under the hood a 'vtable' listing the functions associated with the typeclass.
This table can often be deduced at compile time. This is probably less true in Java.
But this is a table of functions, not methods. Methods are bound to an object, Haskell typeclasses are not.
See them rather like Java's generics.
As Daniel says, interface implementations are defined seperately from data declarations. And as others have pointed out, there's a straightforward way to define operations that use the same free type in more than one place. So its easy to define Num as a typeclass. Thus in Haskell we get the syntactic benefits of operator overloading without actually having any magic overloaded operators -- just standard typeclasses.
Another difference is that you can use methods based on a type, even when you don't have a concrete value of that type hanging around yet!
For example, read :: Read a => String -> a. So if you have enough other type information hanging around about how you'll use the result of a "read", you can let the compiler figure out which dictionary to use for you.
You can also do things like instance (Read a) => Read [a] where... which lets you define a read instance for any list of readable things. I don't think that's quite possible in Java.
And all this is just standard single-parameter typeclasses with no trickery going on. Once we introduce multi-parameter typeclasses, then a whole new world of possibilities opens up, and even more so with functional dependencies and type families, which let you embed much more information and computation in the type system.