Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - method precedence

Tags:

methods

scala

I am new to Scala. I wonder whether it is possible to define some precedence with method calls. For example, if I have the chain of method calls:

someObject method1 param1 method2 param2 method3 param3

can this be equivalent to the following:

someObject.method1(param1).method2(param2.method3(param3))

or

someObject method1 param1 method2 (param2 method3 param3)

So I want method3 to take precedence over method2...

The reason I want to do this is that I want to develop a DSL, so I want to avoid using dots and parentheses as much as possible. If you guys find another solution for me, feel free to let me know.

like image 548
Peter Avatar asked Sep 29 '11 12:09

Peter


People also ask

What does => mean in Scala?

=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .

What is the difference between method and function in Scala?

Scala functions are first class values. Difference between Scala Functions & Methods: Function is a object which can be stored in a variable. But a method always belongs to a class which has a name, signature bytecode etc. Basically, you can say a method is a function which is a member of some object.

What is :: operator in Scala?

The ::() operator in Scala is utilized to add an element to the beginning of the List. Method Definition: def ::(x: A): List[A] Return Type: It returns the stated list after adding an element to the beginning of it.

How do you use && in Scala?

It is called Logical AND operator. If both the operands are non zero then condition becomes true. (A && B) is false. It is called Logical OR Operator.


1 Answers

You'll have to use methods with special operator characters to influence precedence as implied by Tomasz. This is partly why lots of Scala DSL make heavy use of operators. Also why some DSL are hard to read if you don't work with them daily.

Given method with using only letters, underscore and digits - you won't be able to influence things, here is what I put together for myself after reading the spec:

  • Any method which takes a single parameter can be used as an infix operator: a.m(b) can be written a m b.
  • Any method which does not require a parameter can be used as a postfix operator: a.m can be written a m.

  • Postfix operators have lower precedence than infix operators, so foo bar baz means foo.bar(baz) while foo bar baz bam means (foo.bar(baz)).bam and foo bar baz bam bim means (foo.bar(baz)).bam(bim).

So without knowing at all what your method signatures are, the following code (because it's all alphanumeric):

someObject method1 param1 method2 param2 method3 param3

will be parsed as:

someObject.method1(param1).method2(param2).method3(param3)

If you rename method3 to |*| or +:+ or whatever operator makes sense, you can achieve what you want:

someObject method1 param1  method2 param2 |*| param3
// same as
someObject.method1(param1).method2(param2.|*|(param3))

For example to see the difference:

implicit def pimp(s:String) = new {
    def |*|(t:String) = t + s
    def switch(t:String) = t + s 
}

scala> "someObject" concat "param1" concat "param2" |*| "param3"
res2: java.lang.String = someObjectparam1param3param2

scala> "someObject" concat "param1" concat "param2" switch "param3"
res3: java.lang.String = param3someObjectparam1param2
like image 112
huynhjl Avatar answered Nov 09 '22 02:11

huynhjl