6

I have just started learning Scala. I am fairly comfortable with OO design, and less so with functional programming; although, I have been programming long enough that FP is not completely unnatural to me either. From the first day of my Scala adventure, I have had this, shall we say, unease with the apparent dialectic that is going on between OO and FP. Clearly, one can go all the way one way or the other. My first tendency was to see classes as sort of packages that hold the functions together that I want to pass around, which balances the scales towards functional side. I feel there has to be a better way of balancing the act. I am also unsure how to proceed with certain familiar situations under this scenario. For example, if I had the following (artificial) class:

class ValueGenerator { def value() = { "1" } def value(line: String) = { line } } 

in OO programming I would call the value with the proper signature when I needed, to get the result I need. The methods have the same signature, because they logically correspond to similar actions. In OO, I would pass around the object reference, and the methods that receive a ValueGenerator object would make the call to the right value depending on the situation. As far as I can see, at least it is my tendency, that in Scala the norm is to pass around the method. But in this case, although the methods do the same thing, they don't have the same signature, hence cannot be substituted for each other (or can they?). In other words, can the sender method decide the function to be sent regardless of the function's signature? This seems unlikely as the receiver would not know how to invoke it. What is the correct action in a situation like this. Or does one go with their gut instinct? Is there a rule of thumb you follow when it comes to OO vs FB?

As a side note, it was interesting to see that a friend of mine who is also learning Scala had the exact thoughts (or lack thereof) as me on this issue.

3
  • 2
    The methods does not have the same signature: one takes one argument of type String, the other takes no arguments. From section 2.10.2 of the JVM Spec: "The signature of a method consists of the name of the method and the number and type of formal parameters (§2.10.1) of the method [...]" Commented Mar 28, 2011 at 6:51
  • Also, you should notice that a method is something, a function is something else. You do not pass methods around, you can only pass functions around. You can, though, lift a method into a function. Commented Mar 28, 2011 at 7:03
  • See also jim-mcbeath.blogspot.com/2009/05/… Commented Mar 28, 2011 at 14:33

3 Answers 3

9

They don't have the same signature, and generally you want methods that don't have the same signature to have different names. Overloading buys you very little and costs you a lot (namely, type inference and implicit resolution).

That said, they cannot be substituted for one another since they don't have the same type. If you would convert these methods to functions, one would have type Function0[String] and the other would have type Function1[String, String].

Sign up to request clarification or add additional context in comments.

Comments

4

In the code you've provided, there is no reason you need to have two separate method signatures:

class ValueGenerator { def value(line: String = "1") = { line } } 

REPL session:

scala> new ValueGenerator() res1: ValueGenerator = ValueGenerator@fa88fb scala> res1.value("Foo") res2: String = Foo scala> res1.value() res3: String = 1 

Keep in mind you can only do this with methods. Functions don't support default arguments:

scala> val f = res1.value(_) f: (String) => String = <function1> scala> f("Bar") res5: String = Bar scala> f() ***Oops*** scala> val f = (line: String) => line f: (String) => String = <function1> scala> val f = (line: String = "1") => line ***Oops*** 

Comments

2

As far as I can see, at least it is my tendency, that in Scala the norm is to pass around the method.

I doubt that that's the norm (why do you think so?) or that there's even a norm for this at all in Scala.

But in this case, although the methods do the same thing, they don't have the same signature, hence cannot be substituted for each other (or can they?). In other words, can the sender method decide the function to be sent regardless of the function's signature?

They cannot be substituted for each other because they have different signatures, so they have different types.

The scenario that you describe sounds like a perfect fit for the OO way of doing things: just pass the ValueGenerator object and let the client decide which method to call in that object.

1 Comment

Well, I don't know what the norm is, but there are design patterns and best practices for any given language, and given time all languages tend to loosely converge on such usage. For example, in this case, I could do it the OO way, but I could also store line in the class, and have only one method for value, which I can pass around, to deal with it. Two different approaches to accomplish the same thing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.