For example, I want to create a function that can return any number (negative, zero, or positive).
However, based on certain exceptions, I\'d like the function to re
Most languages will handle your specific example without Exceptions or union types because IEEE floating point includes a representation for NaN. In Java, use Double.NaN:
public static double quadratic(double a, double b, double c, int polarity) {
double x = b*b - 4*a*c;
// When x < 0, Math.sqrt(x) retruns NaN
if (x < 0) {
return Double.NaN;
}
return (-b + Math.sqrt(x) * polarity) / (2*a);
}
That produces your exact output that you wanted:
x = 4.0
x = 3.0
x = NaN
x = NaN
Exceptions are The Old Java Way of solving similar problems:
public static double quadratic(double a, double b, double c, int polarity) {
double x = b*b - 4*a*c;
// When x < 0, Math.sqrt(x) returns NaN
if (x < 0) {
throw new Exception("NaN")
}
return (-b + Math.sqrt(x) * polarity) / (2*a);
}
Here's your client code for an Exception.
a=1; b=-7; c=12;
// x = 4.0
try {
System.out.println("x = " + quadratic(a, b, c, 1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
// x = 3.0
try {
System.out.println("x = " + quadratic(a, b, c, -1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
// "invalid" coefficients.
a=4; b=4; c=16;
// Oopsie: NaN
try {
System.out.println("x = " + quadratic(a, b, c, 1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
// Oopsie: NaN
try {
System.out.println("x = " + quadratic(a, b, c, -1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
To truly pass or return unrelated types to or from a method, you want Union types which Java does not really support. But Paguro provides Union Types which you can use in Java like this (using Or):
public static Or<Double,String> quadratic(double a, double b,
double c, int polarity) {
double x = b*b - 4*a*c;
// When x < 0, Math.sqrt(x) retruns NaN
if (x < 0) {
return Or.bad("NaN");
}
return Or.good((-b + Math.sqrt(x) * polarity) / (2*a));
}
@Test public void testQuadradic() {
double a, b, c;
a=1; b=-7; c=12;
// x = Good(4.0)
System.out.println("x = " + quadratic(a, b, c, 1));
// x = 3.0
System.out.println(
(String) quadratic(a, b, c, -1)
.match(good -> "x = " + good,
bad -> "Oopsie: " + bad));
// "invalid" coefficients.
a=4; b=4; c=16;
// x = Bad("NaN")
System.out.println("x = " + quadratic(a, b, c, 1));
// Oopsie: NaN
System.out.println(
(String) quadratic(a, b, c, -1)
.match(good -> "x = " + good,
bad -> "Oopsie: " + bad));
}
For your specific example, just use Floating Point. For a more general solution, I find union types more useful than Exceptions. You can use union types as arguments to a method that might take two different inputs which have no common interface or ancestor. They are also more friendly to Functional Programming.
Absolutely! In your case, since the return values can be positive, 0, negative, or false, probably the best return value would be a JSONObject. In your code, you would add this import:
import org.json.JSONObject;
and in the function:
JSONObject retval = new JSONObject();
double x = b*b - 4*a*c;
if(x < 0){
retval.put("result", false);
}
else{
retval.put("result", x);
}
You potentially could also add another key:value pair to the retval to include the result type to help with checking it in the calling function.
I would say it is possible. But not directly.
I haven't gone through the program given in the question. I am answering this knowing this is an old post. Might help someone.
Add your values to a Map like below. And get it with its key!
public static HashMap returnAnyType(){
String x = "This";
int a = 9;
HashMap<String, Object> myMap = new HashMap();
myMap.put("stringVal", x);
myMap.put("intVal", a);
return myMap;
}
String theStringFromTheMap = (String) returnAnyType().get("stringVal");
int theIntFromTheMap = (Integer) returnAnyType().get("intVal");
System.out.println("String : " + theStringFromTheMap + " is great !");
System.out.println("Integer: " + Math.addExact(theIntFromTheMap, 10));
Output (both are returned from same method):
String : This is great! Integer: 19
Note:
This is not a good practice. But it helps sometimes when it is needed!
Write a function that returns an Object
. Have it either return the Boolean
or Integer
wrapper objects. Then use instanceof to figure out which to use.
no. the best you can do is return on instance of a class that handles all the things you might want to return.
something like
public class ReturnObj {
public bool yesno; // yes or no
public int val; // for int values
public String mode; // mode describing what you returned, which the caller will need to understand.
}
obviously, you need to play with the names....
Also, this seems like a code smell. You might be able to remove the need to do something like this by qualifying what path you want outside of your function, and then call a specific function to get a boolean or a specific function to get an int, depending on the qualification.