How to remove () from output


#1

Hi all,

I have the following output:

The food order cost is:
$84.9
()

from this function:

def foodBill(foodCost: List[Double]) = {

(

    if (foodTotal.length <= 1) {

    println("The food order cost is: ") 

    foodTotal.foreach(x=>println("$"+ x))

    } else { 

    println("The food order for each table is: ") 

    foodTotal.foreach(x => println("$"+ x))}
)    

}

Thus, my question is how to remove the () from the output and have the following:

The food order cost is:
$84.9

Thanks


#2

The answer to my own question is by calling the function as foodBill(List(84.9)) and not println(foodBill(List(84.9)))


#3

This is a very common error. So much so that I tell my CS1 students at the beginning of the semester that I expect it to happen to all of them. There is one elements if Scala style that you might adopt that could help prevent you from doing this, put return types on your functions. You have the following.

def foodBill(foodCost: List[Double]) = {

Because you don’t specify the return type, Scala infers it. Because this function is several lines long with a conditional, anyone looking at the code has to pay close attention to figure out what it returns. Also, if it should return something different, this approach won’t give you useful error messages. As a general rule, you should provide the expected return type for any function where the return type isn’t immediately obvious to a reader. Generally, that means anything longer than a line or even a complex one-liner. So I would suggest the top line be the following.

def foodBill(foodCost: List[Double]): Unit = {

While that won’t prevent your issue, it makes it clear that this gives back Unit and if you print the result of this, you will print ().

Another general rule for making functions flexible and reusable is to avoid having I/O in them. A function that does a calculation and returns the value is more beneficial than one that just prints it out. For example, if you wanted this output to go to a file or be encoded in JSON, your function wouldn’t do that. If you do have a function like this, which prints, say that in the name. Call this function printFoodBill so it is clear it is just printing, not giving you back a value. Had you done that, the line that caused you problems would have read print(printFoodBill(List(84.9))). Just reading that line of code, you are likely to notice that it has problems.

If you want this as a proper function that returns a value, you might consider something like the following.

def foodBill(foodCost: List[Double]): String = {
    (if (foodCost.length <= 1) {
        "The food order cost is:\n"
    } else { 
        "The food order for each table is:\n"
    })+foodCost.map(x => "$"+ x).mkString("\n")
}

(As I put that in I realized that you also have an extra set of parentheses in your code that plays no productive role along with a few typos.) Note that this version gives you back a String that you might be able to use for other things. Now you can say println(foodBill(List(84.9))).

One last comment on something that worries me in this code. It looks like you are using a List[Double] for two completely different purposes. If it has one element, it is a total. If it has more than one element, it is separate items. That style deeply bothers me. I have to ask, what languages have you used prior to Scala? I’m just wondering where you picked up that style. The problem with it is that it doesn’t allow the type checker to help you find errors. A list of items and a total are very different things that play different roles in your program. It would be ideal if they had different types so that they were never confused with one another. Granted, doing so properly in Scala 2 probably uses more concepts than you have encountered at this point assuming you actually need to have a single variable that could be either the list or the total.