This question already has answers here:
What are the precise rules for when you can omit parenthesis, dots, braces, = (functions), etc.?
(6 answers)
Closed 9 years ago.
To my beginner's knowledge of Scala there isn't any way to achieve the last line. I hope I am mistaken, and I just wanted to confirm. Also, I don't understand why, because the compiler should know the owner object of the f method from the import statement.
object A { def f(s: Any) = println(s) }
import A.f
A f 1 //Works
f 2 // Does not compile
For clarification there are two questions:
How should a single parameter method without parenthesis and explicit owner object reference be called? (See the subject.)
What is the reason the compiler cannot understand the last statement?
object A { def f(s: Any) {println(s)} }
import A.f
A f 1 //works
f(2) // works
What are the precise rules for when you can omit parenthesis, dots, braces, = (functions), etc.?
Related
This question already has answers here:
What is the apply function in Scala?
(7 answers)
Closed 1 year ago.
I have below "apply" function, what does apply function do? can you please explain for me?
def apply[K,V](m1:Map[K,V], m2:Map[K,V], merge: (V,V) => V): Map[K,V] =
combine(m1,m2,merge)
The apply function in companion objects and classes has a special meaning in that if an object/class is instantiated without specifying the function, it is the one which is run.
E.g.
object DDF { def apply(text :String) = println(s"got $text") }
DDF("text") // object called like function. function actually called is apply(String) here.
In your example, the apply function merely calls combine. so X(a,b,c) is the same as X.combine(a,b,c).
The technique is how we have achieve multiple constructors on classes too.
This question already has answers here:
What is the eta expansion in Scala?
(2 answers)
Closed 4 years ago.
New to Scala, have searched far and wide for clarification on some ScalaMock syntax. As per this guide, I keep seeing the following general testing pattern:
(myClass.myMethod _).expects()
What exactly is happening here? What function does the class/method/space/underscore serve? How does the compiler treat this?
The appended _ forces the conversion of a method into a function.
To understand why this is necessary, let's try to re-build a tiny piece of Scalamock, namely the expects method. The expects method seems to be invoked on methods of mocked objects. But methods / functions do not have an expects method to begin with. Therefore, we have to use the "pimp my library"-pattern to attach the method expects to functions. We could do something like this:
implicit class ExpectsOp[A, B](f: A => B) {
def expects(a: A): Unit = println("it compiles, ship it...")
}
Now let's define a class Bar with method baz:
class Bar {
def baz(i: Int): Int = i * i
}
and also an instance of Bar:
val bar = new Bar
Let's see what happens if you try to invoke expects on bar.baz:
(bar.baz).expects(42)
error: missing argument list for method baz in class Bar
Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing baz _ or baz(_) instead of baz.
So, it doesn't work without explicit conversion into a function, and we have to enforce this conversion by appending an _:
(bar.baz _).expects(42) // prints: "it compiles, ship it..."
This question already has an answer here:
Difference between function with parentheses and without [duplicate]
(1 answer)
Closed 6 years ago.
I was learning about scala methods and I created two code examples which are somewhat similar in nature, but confused on calling them.
Method #1
def someTestMethod = {
println("Inside a test method")
}
This resorts to a Unit type since it does not return anything.
Method #2
def anotherTestMethod() = {
println("Inside a test method")
}
This resorts to Unit as well, but with a curly brace () added.
What is the difference between the two methods, notice that if I call the first method like someTestMethod(), the scala shell/compiler says
error: Unit does not take parameters, but works well if I call like someTestMethod without the braces.
Also, the second method seems fool proof, in the sense that it can be called either way anotherTestMethod or anotherTestMethod(), why is it so?
When you don't want to pass any parameter to the method, use the first one.
If you want to pass some pass parameters, use the second one with brackets and pass some parameters and use it inside method.
For example:
def someTestMethod1(count : Int) = {
println("Inside a test method"+count)
}
someTestMethod1(10)
This question already has answers here:
Scala foreach strange behaviour
(5 answers)
Closed 7 years ago.
Given these case classes:
case class FeatureDistance(id: Long, distance: Double)
case class SearchResult(score: Float, id: Long)
Why does this not compile?
val distances = List[FeatureDistance](FeatureDistance(1L, 10f))
val results = distances.map(SearchResult(0f, _.id))
But this does:
val results = distances.map(fd => SearchResult(0f, fd.id))
The compilation error says: missing parameter type for expanded function ((x$3) => x$3.id)
Is it because _ is only scoped to the map function so it's not visible in the SearchResult.apply call?
After doing a bit of research, I found a post on the old scala forums that contains this quote:
When you use "_" as a place holder for an anonymous parameter of a function, the scope of that function is the innermost parenthesis containing it.
So, it's just a question of scope. I suspect this has to do with problems that could otherwise result from having nested function calls that use more than one underscore. For instance:
//suppose we have some x:List[List[Int]]
x.map(_.map(_ + 1))
I am a beginning practitioner in Scala and I saw a few different syntax for calling a method. Some are nice, as ignoring parenthesis for a parameterless method, or ignoring the dot as in
1 to 10
but some really puzzle me. for instance:
breakable { ... }
this is simply a method call right? Can I also do that for more than one parameter or a parameter which is not a parameterless function?
Thanks
There are two standard ways of calling methods:
obj.method(params) // dot notation
obj method (params) // operator notation
The above can be modified in the following ways:
If params is a single parameter, you can replace () with {}.
If params is a single parameter and you are using operator notation, you can drop the parenthesis.
If method doesn't take parameters, you can drop (params) (that is, drop the empty ()).
If method ends with :, then it actually binds to the right in operator notation. That is, (params) method_: obj is equivalent to obj.method_:(params).
Either way, spaces are optional as long as identifiers can be told apart. So one can add spaces to the dot notation, like obj . method ( params ) or write .method(params) on the next line -- as often happens with call chaining --, as well as remove spaces from the operator notation, as in a+b.
There's also some stuff with tuple inference, but I try to avoid it, so I'm not sure of the exact rules.
None of these will explain the example you are confused about, however. Before I explain it, however, I'd like to show some syntactic sugars that can also be used to call methods:
obj(params) // equivalent to obj.apply(params)
obj.x = y // equivalent to obj.x_=(y), if obj.x also exists
obj(x) = y // equivalent to obj.update(x, y)
obj op= y // equivalent to obj = obj op y, if op is symbolic
~obj // equivalent to obj.unary_~; also for !, + and -, but no other symbol
Ok, now to the example you gave. One can import members of stable values. Java can do it for static methods with its static import, but Scala has a more general mechanism: importing from packages, objects or common instances is no different: it brings both type members and value members. Methods fall in the latter category.
So, imagine you have val a = 2, and you do import a._. That will bring into scope all of Int methods, so you can call them directly. You can't do +(2), because that would be interpreted as a call to unary_+, but you could call *(4), for example:
scala> val a = 2
a: Int = 2
scala> import a._
import a._
scala> *(4)
res16: Int = 8
Now, here's the rule. You can call
method(params)
If:
method was imported into scope.
You keep the parenthesis (even if there's only one parameter)
Note that there's a precedence issue as well. If you write obj method(params), Scala will presume method belongs to obj, even if it was imported into scope.
If we desugar this we will have:
breakable({ ... })
this matches signature
breakable: (op: ⇒ Unit): Unit
and uses so named call-by-name arguments (you may think of this as pass a block of code as argument)
More over scala allows you to write this:
scala> def foo (op1: => Unit)(op2: => Unit) = {op1;op2;}
foo: (op1: => Unit)(op2: => Unit)Unit
scala> foo { println(1) } { println(2) }
1
2
Above is the example of curried function