Win a copy of Cross-Platform Desktop Applications: Using Node, Electron, and NW.js this week in the JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Regarding Multiple Return Types  RSS feed

 
Charley Grossman
Greenhorn
Posts: 8
1
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I'm currently writing a program (on codewars.com) which asks me to write a method whic has a double return type and a double parameter. I am to calculate the area of a circle with the given double radius argument, and return that area up to two decimal places. If the given radius is less than 0, of course an area cannot be calculated. Simple enough.

The problem is that if the method is passed a value, say x <= 0, it is to return a boolean false. This is a new idea to me. This method, which has a double return type, is supposed to return both a double upon a legal argument, and to return a false upon an illegal one. As far as the instructions go, all of this is done in the single method.

At first I tried a constructor that would take in multiple return values...then I hit a wall. Next, I wrote a simple method to return boolean false, and I called this method within my method of focus upon an illegal argument (a radius of zero or less, to refresh). Codewars did not like this. Finally, I have been catching up (hah) on exception handling, looking for a way to use something in the Throwable class to help me with this double return type dilemma.

Here is the problem description from the website:
Complete the function circleArea so that it will return the area of a circle with the given radius. Round the returned number to two decimal places (except for Haskell). If the radius is not positive or not a number, return false.

Thank you for taking the time to read. This is my first post to the Coderanch. Please, do tell me if I have posted this question to the right subforum; I want to become acclimated to the Coderanch environment.

Cheers,
T
 
Ron McLeod
Saloon Keeper
Posts: 1561
222
Android Angular Framework Eclipse IDE Java Linux MySQL Database Redhat TypeScript
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch!

Your idea of throwing an exception when the method is given bad input seems like the right action to take. Take a look at IllegalArgumentException - it is often used when a method has been passed invalid data.
 
Charley Grossman
Greenhorn
Posts: 8
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ron,

Thanks for some assurance. I still have not found a way to return the boolean value of false alongside any implementation of the java.lang.Throwable Class. While IllegalArgumentException does fit the bill semantically in most ways, it won't help my method (double circleArea(double radius)) to return a boolean value. Unless I have missed something in the documentation. Someone please tell me if I have.

Thanks
 
Scott Bee
Greenhorn
Posts: 16
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Charley Grossman wrote:
Here is the problem description from the website:
Complete the function circleArea so that it will return the area of a circle with the given radius. Round the returned number to two decimal places (except for Haskell). If the radius is not positive or not a number, return false.

Hi, Charley.

Because Java is a strongly typed language, it is not possible for a single method to sometimes return a boolean and sometimes return a double.

It sounds like the Codewars problem was originally written to target a different language and the adapted (incorrectly) for Java. My experience with Codewars is generally positive but sometimes mistakes slip through the crowdsourced process.

I would recommend skipping this kata as it won't help you develop useful Java skills. In the Java world, an exception is the way to approach a bad input, but that option isn't listed in the problem description.

Good luck!

Scott
 
Stefan Evans
Bartender
Posts: 1836
10
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In java, you can't return false from a method that declares it returns a double.
You could quite happily do that in javascript which isn't a typed language.

The interesting thing though is that is asking you to return the number to two decimal places. You can't do that with a double either.
And it intimates that this question applies to multiple languages (because it exempts Haskell from the rounding requirement)

Perhaps your method signature should instead be:



Using a String as a return value, you can return the string "false" and a String representing the number rounded to 2dp.
Its fugly, but if those are your requirements, that is about the only way I could see to return the correct value.


Or (in retrospect) you could just return 0, and work under the standard assumption that 0 is false :-)
 
Ron McLeod
Saloon Keeper
Posts: 1561
222
Android Angular Framework Eclipse IDE Java Linux MySQL Database Redhat TypeScript
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well .. your method can only return one type - either a double or a boolean, or something else. I'm guessing that the problem statement wasn't specifically targeted for statically-typed languages such as Java. I'm sure with other languages such as Ruby or Python, this is quite do-able.

If you don't want to throw an exception, two other ideas come to mind:
    - use a return type of Double and set it to null if an answer cannot be calculated, otherwise set it ot the calculated area
    - create a custom class for the return type with a boolean type field for the sucess/failure of the calculation, and a double type field with the calulated area

My preference would be to throw an exception though.

Edit: I got interrupted while typing my response and didn't see that Scott and Stefan already stated what I was thinking.
 
Charley Grossman
Greenhorn
Posts: 8
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello all,

Thank you for your replies! I gave in and looked at some possible solutions submitted by other users on this website. Alas, the were throwing exceptions. In fact, one of the best submissions virtually mirrored an answer I wrote, then scraped because an exception does not technically return a value of boolean type.

I'm a bit disappointed with how the question was written. I fully agree that it was poorly written from a Java context. Misusing a keyword such as return is a gross mistake in my book. I'll either roll with the punches and learn to not be so exact on that website, or look elsewhere.

I'm closing this post now. I appreciate all of the great replies (except for that one guy who said "I agree." Then posted a sketchy URL).

Cheers,
T
 
Campbell Ritchie
Sheriff
Posts: 55330
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome again

You said double return type in the first post, so why are you telling us about booleans now. Also why are you rounding the result? Return the result and let any methods using that result do any rounding, formatting displays or whatever.
 
Knute Snortum
Sheriff
Posts: 3940
92
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Has anyone suggested using java.util.Optional?
 
Stephan van Hulst
Saloon Keeper
Posts: 7709
141
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think Optional is applicable, for the same reason boolean is not applicable: A circle doesn't have an optional area. A circle with negative radius doesn't exist, and passing a negative argument should throw an exception.
 
Paweł Baczyński
Bartender
Posts: 2047
44
Firefox Browser IntelliJ IDE Java Linux Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And if optional value was applicable I would suggest java.util.OptionalDouble.
 
L Foster
Ranch Hand
Posts: 242
14
Android Angular Framework AngularJS Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, @Charlie, my 2 cents, here.

I like the suggestion given of the 'throw' in event of bad arguments. The other thing you could do, is return Double, the wrapper class. Then make that null if you get a negative value. You can then check, where it would have been 'false' for a boolean, whether your returned value is null for the Double. A Double is an object and can be null, unlike the double (lowercase) primitive.

Still another (although I like the throw notion better), might be to build a special type to return your value, which can expose both a boolean value and a double. Call the getter there "isValid()". if not isValid(), something went wrong, including the negative result. Technically, you can then return both. This is how you have your cake and eat it too.
 
Campbell Ritchie
Sheriff
Posts: 55330
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Not convinced, I am afraid. I still prefer the notion of throwing an illegal argument exception if you pass a negative (or even non‑positive) radius.
 
Paweł Baczyński
Bartender
Posts: 2047
44
Firefox Browser IntelliJ IDE Java Linux Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, you can return two types.

A quiz. Put something in the marked place to make this code work.

Note. Don't even try to write programs like this.
 
Scott Bee
Greenhorn
Posts: 16
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paweł Baczyński wrote:Put something in the marked place to make this code work.


If there were a supertype of both boolean and double, we could put that in place of /**/. Of course those things are primitive and don't have supertypes. But then there's autoboxing, which gives us types in a hierarchy.

Does the correct answer start with O?
 
Stephan van Hulst
Saloon Keeper
Posts: 7709
141
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
L Foster wrote:The other thing you could do, is return Double, the wrapper class. Then make that null if you get a negative value. You can then check, where it would have been 'false' for a boolean, whether your returned value is null for the Double. A Double is an object and can be null, unlike the double (lowercase) primitive.

Since Java 8 there is no reason to return null anymore. For collections, return an empty collection. For other types, return java.util.Optional, or one of the primitive Optional variants.

Still another (although I like the throw notion better), might be to build a special type to return your value, which can expose both a boolean value and a double. Call the getter there "isValid()". if not isValid(), something went wrong, including the negative result. Technically, you can then return both. This is how you have your cake and eat it too.

This is exactly what java.util.Optional does.
 
Campbell Ritchie
Sheriff
Posts: 55330
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is of course not what Optional was designed for. You can find out more in books like Java8 in Action by Urma Fusco and Mycroft (Manning 2014), I think about page 224. They point out that Brian Goetz who designed Optional intended it to be used only for the endpoint of a potentially empty Stream.

Answer: put pressure on Oracle to enhance Optional and OptionalXXX so they can be used as Stephan suggests. It may only require that those classes implement Serializable for them to be completely usable like that.

At this point I think this thread merits duplication in the Java8 forum.
 
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:..For collections, return an empty collection....

And for arrays, return a 0-length array.

Charley Grossman wrote:...because an exception does not technically return a value of boolean type...

Technically, there IS a way to do exactly what the question asks for:but nobody in their right mind would do it.

And that's why it's a bad question - at least for Java.

Another alternative that doesn't seem to have been mentioned, if you don't want to throw an Exception, is to return Double.NaN.
But that's not what the question asked for.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7709
141
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:And for arrays, return a 0-length array.

Preferably, don't return arrays at all. I almost exclusively use arrays as private instance fields, and when a user needs access to an element, I provide an accessor that takes an index:
 
Campbell Ritchie
Sheriff
Posts: 55330
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:. . . return Double.NaN. . . .
What a wonderful suggestion But if you could have a circle with radius −2 it would have a positive area since (−2)² is +4.
 
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:Preferably, don't return arrays at all.

What about something like BigInteger.divideAndRemainder()?

TBH, I have a Pair class that I use for stuff like that, but just saying...

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7709
141
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Methods like those are even worse offenders in my opinion. I once explained in another thread why the Java standard API doesn't contain Tuple classes. Tuples don't say anything about what it is they contain. I will have to go to the documentation of divideAndRemainder() every time to figure out how many elements the array contains and what they mean. How much clearer would it have been if they had a class BigInteger.DivisionResult:

Would implementing a simple inner class with a concise API really come at such a cost that we have to resort to arrays instead?
 
Campbell Ritchie
Sheriff
Posts: 55330
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One of many enhancements we wish had been made. It would still be possible, since there is only one method likely to return it.
 
chris webster
Bartender
Posts: 2407
33
Linux Oracle Postgres Database Python Scala
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Given Java's reliance on exceptions for error conditions, I'd want to avoid returning magic values that might indicate some error conditions. An exception breaks out of the normal execution path - hence the name - so if you have illegal arguments, it makes sense to raise the corresponding exception and handle it in the calling code appropriately. If you code a bunch of magic values for some error cases, what happens when you accidentally stumble across another error condition? Do you raise an exception, or add another magic value? Either way, you end up with two different ways of responding to errors, which sounds messy to me.

 
Campbell Ritchie
Sheriff
Posts: 55330
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
…and remember what C code is like where you have to search for error conditions. Even returning −1 from a search operation to denote “not found” is iffy.
 
chris webster
Bartender
Posts: 2407
33
Linux Oracle Postgres Database Python Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:..and remember what C code is like ...

I've spent the last 20 years trying to forget what C code is like!
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Even returning −1 from a search operation to denote “not found” is iffy.

Oh Gawd. I'm not sure I'd want to live in a world full of custom-built SearchResult objects...OR have to put all my searches in a try...catch block.

-1 is fine by me for most searches.

Winston
 
Stevens Miller
Bartender
Posts: 1444
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The question, as presented, is what we lawyers and we programmers both refer to as "a crock." A Java method that returns a double cannot return false, end of story.

Now, the many suggestions here are, most of them, good alternatives (I'm on the "throw an exception" team, myself), and even those that are not practical ideas are worth knowing, for the sake of your education. I'd look at this, however, as a challenge to my workplace diplomacy, as programmers are often given specifications that are, by any fair reckoning, crocks. One can argue with the person who gave you the spec, but if a person gives you a spec that is a crock, arguing with them usually just irritates them and does little for your professional advancement. What to do? Pick a working solution similar to something like the above and, when it is time to deliver your result, simply explain that you went "beyond" what the spec required. Other programmers (who must write code that will call your method), will probably realize that you've replaced a crock with a working alternative, the end system will run (or, at least, if it doesn't run, it won't be because of your method), and the person who gave you the spec in the first place will probably never know that you saved their butt for them. (Which means, of course, that your compensation for doing so will be limited to having the deep satisfaction of knowing you have served the interests of the group, but life is like that sometimes.)

Excellent discussion by all above, given how ridiculous that initial problem was. Amazing how often the people here can turn a sow's ear into a silk purse that way.
 
chris webster
Bartender
Posts: 2407
33
Linux Oracle Postgres Database Python Scala
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Campbell Ritchie wrote:Even returning −1 from a search operation to denote “not found” is iffy.

Oh Gawd. I'm not sure I'd want to live in a world full of custom-built SearchResult objects...OR have to put all my searches in a try...catch block.

-1 is fine by me for most searches.

Winston

Actually that's exactly where an Option type comes in handy, as in Scala. Your function's return type is Option, and the actual return value is either Some(result) or None. The return type is clear and can be checked at compile time, and Scala knows how to handle Options, so you can implement your search function without relying on arbitrary magic values or having to deal with nulls

http://m.alvinalexander.com/scala/using-scala-option-some-none-idiom-function-java-null

 
Stephan van Hulst
Saloon Keeper
Posts: 7709
141
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Like Java's Optional?

I'm a huge fan of fluent interfaces. Collections.binarySearch() could have returned an object that has an ifFound() method, which returns an object that has an otherwise() method:
 
Stephan van Hulst
Saloon Keeper
Posts: 7709
141
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is actually a major gripe I have with the Optional class. ifPresent() returns void, but should have returned something on which I can call otherwise().
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
chris webster wrote:Actually that's exactly where an Option type comes in handy, as in Scala...

Thanks for that chris. I realise I'm a bit of a dinosaur when it comes to this stuff - including Stephan's binarySearch() example, which I actually like a LOT.

To me, binarySearch() returning a negative value when it doesn't find what it's looking for is not a "magic" value; it's extremely informative. It says:
"I couldn't find this value, but if you need to insert it, it should be put immediately before position −returnValue - 1".

Similarly, if I call a method like indexOf() - which I far prefer to contains() - I need to be pretty thick not to work out that if it returns an impossible index value, it probably means that it couldn't find what I was looking for. Furthermore, it's documented.

What I do see is that Optional is probably very useful for functional situations, which is presumably why it's appeared in v8. I worry a little that it seems "fiddly" though - ie, it violates the "Tell, don't ask" principle - but maybe it's a low-level exception that allows higher-level objects to follow it better.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7709
141
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:To me, binarySearch() returning a negative value when it doesn't find what it's looking for is not a "magic" value; it's extremely informative. It says:
"I couldn't find this value, but if you need to insert it, it should be put immediately before position −returnValue - 1".

That's interesting, the first time I looked at the documentation for binarySearch() I was trying to figure out for quite a while what I had to do with the return value to get the insertion point. It wasn't intuitive at all, and I probably made some off-by-one mistakes. I doesn't help that I'm not very good at maths.

Furthermore, it's documented.

I don't want to go to the documentation to figure out what a return value means. I like it to be clear as soon as I see it.
 
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 want to go to the documentation to figure out what a return value means.

Hmm, but you're happy to go to it to work out what Exceptions it throws...?

Winston
 
Ron McLeod
Saloon Keeper
Posts: 1561
222
Android Angular Framework Eclipse IDE Java Linux MySQL Database Redhat TypeScript
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Charley - thanks for your post - it kicked-off a great discussion with over 30 replies.

Please enjoy a cow.
 
Alex Lieb
Ranch Hand
Posts: 61
3
Java Netbeans IDE Notepad
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I actually kind of like this question... Specifically because I don't really like any of the solutions to it.

I'm pretty sure I saw between 5 and 50 people already say this above, but in Java methods are set up to only be able to return one type. And there are sort of ways to get around that, but a lot of them are insane. Someone up there said if they were objects that had a common super class, you could return the super class, but since they're both primitives, you can't do that. If you really wanted to do that though, you could always use the wrapper objects for those primitives. The wrapper objects are both subclasses of "Object", so you could also do this:



It still doesn't technically fulfil the requirements, because 'Boolean' is not the same thing as 'boolean', and 'Double' is not the same as 'double', but because Double only wraps doubles and Boolean only wraps boolean values, it would ensure that whatever wrapped primitive you returned could never be anything other than a double or a boolean. So there is that. Since we're talking about a case where the parameter value is invalid, yeah, making it throw an exception would probably be the best way to handle this, but I thought I might as well throw my insane idea out there too.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!