• Post Reply Bookmark Topic Watch Topic
  • New Topic

Is Java 8 corrupting the language for convenience sake  RSS feed

 
Tim Bee
Ranch Hand
Posts: 91
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was just thinking about it this morning and I believe that with the changes to the Interface implementation, Java has jumped the shark.
Interfaces used to be contracts that a program had to fulfill, in terms of methods that had to be implemented.
Now, with default methods being defined in the interface itself, that is no longer true.

Is this allowed in any other languages?
 
Pierre-Yves Saumont
Author
Ranch Hand
Posts: 103
17
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Whether it is allowed in other languages is irrelevant. If all improvements that were not already allowed in other languages were to be discarded, there would never be any improvement at all.

Regarding you main question: "Is Java 8 corrupting the language for convenience sake", is this really a question? From the kind of words you are using it seems more like your own answer. If it is really a question, you should define what you mean by "corrupting" and "convenience". Otherwise, I shall be tempted to think that "corrupting" means changing for something you dislike, and "convenience" is something that is inherently bad.

Java 8 is not only about default methods in interfaces or automatic parallelization. The main improvment is the the availability of lambdas and method references. These allow doing pretty much the same thing that was already possible with classes (mainly anonymous ones, but not only), but without using classes. In other words, if you feel concerned about performance, you should probably appreciate this. And to speak specifically about default methods in interfaces, what is the problem? No one is forced to use them. They have been added to allow the programmer ignoring the changes in existing interfaces. You can now add methods to existing interfaces without forcing your users to implement them, which means without breaking legacy code. Is this what you call "corrupting the language"? The alternative was to have any change to existing interfaces making all programs using them stop working. This I would call "corruption". The only solution, before default methods, was to never change an existing interface. But not all changes mean "corruption". Sometimes, something that does not change becomes "corrupted" with time, just because the world is changing. Default methods allows for evolution. You may of course call this "corruption".
 
Tim Bee
Ranch Hand
Posts: 91
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Pierre-Yves Saumont wrote:Whether it is allowed in other languages is irrelevant. If all improvements that were not already allowed in other languages were to be discarded, there would never be any improvement at all.

Regarding you main question: Java 8 is not only about default methods in interfaces or automatic parallelization.


I don't think it is irrelevant. My point is, if these are OOP concepts and no other OO languages allow this then why does Java? You can't just say you are an OO language and then not abide by the concepts that define OO languages.

As for the point about Java 8 not only being about default methods, I realize that but that is what I chose to make my point about.
 
Tim Bee
Ranch Hand
Posts: 91
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
From Oracle:

....Implementing an interface allows a class to become more formal about the behavior it promises to provide. Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.

https://docs.oracle.com/javase/tutorial/java/concepts/interface.html
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Bee wrote:If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.

OK, so now it's different because you can define default methods. That doesn't mean you have to, so I don't see what the problem is.

It's true that this means an interface now has some of the characteristics that used to be associated with abstract classes, but again, I don't see any major issue with it. In fact, it's actually something that people (including me) have asked about before now.

My objection - if any - is the explosion in the APIs of some existing classes due to Streams. You only have to look at Comparator to see what I mean. On the other hand, I really like lambdas and Streams, because they remind me of Unix script-style programming, so I'm prepared to put up with it.
Some of the method signatures don't half look ugly though.

So my advice: If you don't like a feature, don't use it; but your question sounds more like "why doesn't OO look like it did before?"
To which the answer is: because it's moved on.

Winston
 
Tim Bee
Ranch Hand
Posts: 91
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Tim Bee wrote:If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.

OK, so now it's different because you can define default methods. That doesn't mean you have to, so I don't see what the problem is.

It's true that this means an interface now has some of the characteristics that used to be associated with abstract classes, but again, I don't see any major issue with it. In fact, it's actually something that people (including me) have asked about before now.

My objection - if any - is the explosion in the APIs of some existing classes due to Streams. You only have to look at Comparator to see what I mean. On the other hand, I really like lambdas and Streams, because they remind me of Unix script-style programming, so I'm prepared to put up with it.
Some of the method signatures don't half look ugly though.

So my advice: If you don't like a feature, don't use it; but your question sounds more like "why doesn't OO look like it did before?"
To which the answer is: because it's moved on.

Winston

It's funny because when I go for an interview, I am expected to rigidly know all of these definitions or else I am deemed to not know Java or OOP.
Now, Java just changes whatever it wants. So why is it so important for me to know all of these definitions if they can just be changed by some corporation?
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Bee wrote:It's funny because when I go for an interview, I am expected to rigidly know all of these definitions or else I am deemed to not know Java or OOP.

Well, in terms of Java, if you want a job working with version 8, you'd better learn it.

As far as OOP "definitions" are concerned, I'm not sure that an 'interface' specifically precludes default implementations (but I could be wrong). And, as I say, it's something many of us have wished for in the past, because it can save having to create an abstract class.

What I will concede is that version 8 is a major event in the Java language. Personally, I think it's great for the most part; you, obviously not - but if you're interviewing for a company that intends using it (or already does), then I hate to say, but you're going to have to bite the bullet. Alternatively, there might be other languages out there that don't go through these major "quakes", and maybe you'll be happier with one of them.

Winston
 
Tim Bee
Ranch Hand
Posts: 91
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Tim Bee wrote:It's funny because when I go for an interview, I am expected to rigidly know all of these definitions or else I am deemed to not know Java or OOP.

Well, in terms of Java, if you want a job working with version 8, you'd better learn it.

As far as OOP "definitions" are concerned, I'm not sure that an 'interface' specifically precludes default implementations (but I could be wrong). And, as I say, it's something many of us have wished for in the past, because it can save having to create an abstract class.

What I will concede is that version 8 is a major event in the Java language. Personally, I think it's great for the most part; you, obviously not - but if you're interviewing for a company that intends using it (or already does), then I hate to say, but you're going to have to bite the bullet. Alternatively, there might be other languages out there that don't go through these major "quakes", and maybe you'll be happier with one of them.

Winston


I was in an interview on Tuesday and was asked if an interface can have a method that could run. I said I don't know, I never have done that before myself.
But the answer is, in Java 8 it is possible. Maybe it shouldn't be but it is.
 
Pierre-Yves Saumont
Author
Ranch Hand
Posts: 103
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Bee wrote:From Oracle:

....Implementing an interface allows a class to become more formal about the behavior it promises to provide. Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.

https://docs.oracle.com/javase/tutorial/java/concepts/interface.html


This is simply false. When you extend an adapter class, all methods of the interface implemented by the adapter do not appear in your source code, but you are still producing something of the interface type. The interface contract says that all methods of the interface must be implemented. It does not say where they must be implemented. It must be (by necessity) somewhere in the hierarchy, be it the class you are creating or a class you are extending, whether directly or not. With Java 8, it may be in the interface itself. It does not change anything to the contract so, yes, it is convenient, and no, I would not call this "corrupting".

Tim Bee wrote:when I go for an interview, I am expected to rigidly know all of these definitions or else I am deemed to not know Java or OOP.


No you're not. I don't think any interviewer would agree that you are expected to "rigidly" know all these definitions. At least not any good interviewer. When the definitions are arguable, you should still show that you know them, but also that you understand their limits.
 
Stephan van Hulst
Saloon Keeper
Posts: 7735
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think having default method implementations or higher order functions conflicts with object orientation at all, but like most features, you can abuse them.

I like to think of OO as behavior belonging to an instance of a data-type. The reason to do this, is that you can hide the data belonging to the type. Anything that improves hiding (or encapsulation) makes something more Object Oriented.

Default methods actually aid in this endeavor! If you can define behavior in terms of other behavior, and not data, you're improving encapsulation.

If anything, it's inheritance that breaks OO. I've often wondered what Java programs would look like if people were only allowed to implement interfaces, and were not allowed to extend classes. I'm convinced everything would be *much* better.
 
Stephan van Hulst
Saloon Keeper
Posts: 7735
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Bee wrote:Interfaces used to be contracts that a program had to fulfill, in terms of methods that had to be implemented.
Now, with default methods being defined in the interface itself, that is no longer true.

This is not a logical conclusion. The fact that an interface can also provide an implementation for its contract, doesn't stop it from defining a contract.

If so, we were not allowed to depend on the fact that Strings are immutable. String, being a class, implements its own contract and following your reasoning, it then can't define a contract.
 
Stephan van Hulst
Saloon Keeper
Posts: 7735
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:My objection - if any - is the explosion in the APIs of some existing classes due to Streams. You only have to look at Comparator to see what I mean.

I don't see why that's a problem. Most of these methods are very useful, and the only reason it *seems* like the Comparator API exploded is because generics and primitives don't get along. That's a limitation of Java's generics, not streams.
 
Tim Moores
Saloon Keeper
Posts: 3834
80
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Bee wrote:You can't just say you are an OO language and then not abide by the concepts that define OO languages.


There is no single definition of what an OO language is. Some languages are more OO than others, and Java is certainly not close to "pure OO", whatever that may actually be.

These days the trend goes towards functional languages, and Java incorporates elements of those, just like it has elements of procedural languages, which also were all the rage at one point.

So I agree with the stance that languages - and the thinking behind languages - evolves. If some language is at some point deemed too baroque, or stops adapting, it will likely decline.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:I don't see why that's a problem. Most of these methods are very useful...

I'm not denying that. I'm just saying that most of them don't belong in Comparator because it changes the nature of the beast.

A Comparator compares two objects for order. End of story. If you want to start writing "extractors" or "stacked" comparisons, do it somewhere else.

And I don't know about anyone else, but I've already written my own class called Index to do precisely that; and I FAR prefer my API to Java8's.

The rest are utility methods that, IMO, belong in a Comparators class. And if this is the start of a trend of putting utility methods in interfaces, then javadoc should be re-written to separate the static API of interfaces from the rest.

Of the methods I DO like:
1. reverse() is 7 releases too late.
2. naturalOrder() is 3 releases too late.
3. reverseOrder() is redundant.
4. nullsFirst() is at least 3 releases too late, and redundantly paired with nullsLast().

And the last 3 should be in a utility class or section.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7735
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:A Comparator compares two objects for order. End of story. If you want to start writing "extractors" or "stacked" comparisons, do it somewhere else.

I wrote a long post with lots of examples for which I wanted to challenge you to write counterexamples, but after doing so, I have to concede this point.

3. reverseOrder() is redundant.
4. nullsFirst() is at least 3 releases too late, and redundantly paired with nullsLast().

These are not redundant. These are very useful when you want to use method references rather than lambdas. If I can use a method reference I will, because they make the code much more readable. reverseOrder() would be redundant if Java allowed chained method references. nullsFirst() is not redundant because it's not the reverse operation of nullsLast().
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:These are not redundant. These are very useful when you want to use method references rather than lambdas. If I can use a method reference I will, because they make the code much more readable. reverseOrder() would be redundant if Java allowed chained method references.

Oh, OK. I didn't know that.

Personally, I find Method refs a bit "C++"ish (never did like that '::' operator ), but to my mind
  reverseOrder() == naturalOrder().reverse()
so if we're going to have to start bloating APIs simply in order to allow people to use method refs, I'm not happy.

nullsFirst() is not redundant because it's not the reverse operation of nullsLast().

Sure it is. What about:
  orderNulls(boolean higher)
or:
  allowNulls(int result)
?

Personally, I like the latter because it allows a Comparator to return a specific result when a null is discovered.
But again, it's all far too late for me because I've already written an Order class that does precisely that.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7735
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Assume we have a list [2, null, 1, 3].
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Stephan van Hulst wrote:nullsFirst() is not redundant because it's not the reverse operation of nullsLast().
Sure it is...

Actually, I take that back a little, I wouldn't mind so much having two methods if they were instance methods - the reason being that reverse() and nullsFirst/Last() could then be additive, viz:
  someComparator.reverse().nullsFirst()
but I still reckon that allowNulls(int result) is better.

[Edit] And hopefully I've answered your previous post too.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7735
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:   allowNulls(int result)

Personally, I like the latter because it allows a Comparator to return a specific result when a null is discovered.

This won't work, because it's not transitive:

Unless you mean to flip the sign of the provided int when you reverse the operands, but I don't really see the use of using a specific value because the exact return value of the compare() method is meaningless.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think what bothers me - and here perhaps I do agree with the OP (Tim Bee) to some extent - is that the same care that was taken in creating these new features doesn't go into creating the APIs that use them.

In the case of Comparator it seems to me like the designers at Oracle went function mad:
"Oooh, we've got these new things called functional interfaces. Why don't we stick them everywhere and in every way we possibly can? Oh, and anything that can even remotely use Streams we've got to add methods for, including ones for all the primitive variants..."

Well you know what Oracle? We have to live with these new bloated APIs. FOREVER.

I think my approach with changes as major as this would be to wait one release for adding the functionality to existing classes, except in cases like BufferedReader, which absolutely scream out for a method like lines().

It's the old "what not how" problem in reverse: We get a fair bit of input on what gets included in a release, but virtually none on how it's done.

Winston
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Unless you mean to flip the sign of the provided int when you reverse the operands...

Correct. Such a method would probably also have to throw an exception if you supplied 0; however, those are documentation issues, not semantic ones (IMO).

but I don't really see the use of using a specific value because the exact return value of the compare() method is meaningless.

Then why wasn't it specified to return -1, 0 or 1?

The fact is that there may be all sorts of reasons for using specific values that you or I don't need to know about, providing the method sticks to its contract.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7735
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:Then why wasn't it specified to return -1, 0 or 1?

Because for some types it's very easy to implement the method using the subtraction operator.

Why would you limit the result to -1, when it's just as easy to perform compare(a,b) < 0 as it is to perform compare(a,b) == -1?
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Because for some types it's very easy to implement the method using the subtraction operator.

Precisely. There's a reason that the implementor knows that we don't need to.

And who's to say that the same may not be true of a special value for nulls? I can't think of one off the top of my head, but just because I can't doesn't mean that there isn't one out there...

However, I think we're straying off-point a bit. My take is that, in general, I like the new features in v8; but I think they've been over-zealously implemented in some cases (see this-3).

Winston
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Bee wrote:I was just thinking about it this morning...

And Tim, I've given you a cow for sparking such a robust discussion.

Winston
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!