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:
params
is a single parameter, you can replace ()
with {}
.params
is a single parameter and you are using operator notation, you can drop the parenthesis.method
doesn't take parameters, you can drop (params)
(that is, drop the empty ()
).method
ends with :
, then it actually binds to the right in operator notation. That is, (params) method_: obj
is equivalent to obj.method_:(params)
.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.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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With