Up until recently it was my understanding that two Scala statements below were interchangeable.
expr.op(arg1, arg2,...)
expr op (arg1, arg2,...)
But I've playing around with scala meta, looked at the resulting AST they generate,
Term.Apply(Term.Select(<exprTerm>, Term.Name("op")), Seq(<argTerm1>, <argTerm2>,...))
Term.ApplyInfix(<exprTerm>, Term.Name("op"), Nil, Seq(<argTerm1>, <argTerm2>,...))
and found a Nil
in the AST for the infix expression. Digging further, I found out that the infix option allows for type parameters:
expr op [Type1, Type2,...] (arg1, arg2,...)
In this context, I don't understand what purpose they'd serve. When would they be usefull? Why are they allowed on infix operations but not "apply-select" operations (expr.op(arg1, arg2,...)
)?
These types are not params types, but generics. For example:
object expr {
def op1(param1: Any, param2: Any) = ()
def op2[T](param1: Any, param2: Any) = ()
}
And we will get
expr op1 (1, 2)
// Term.ApplyInfix(Term.Name("expr"), Term.Name("op1"), Nil, List(Lit.Int(1), Lit.Int(2)))
expr op2[Int] (1, 2)
// Term.ApplyInfix(Term.Name("expr"), Term.Name("op2"), List(Type.Name("Int")), List(Lit.Int(1), Lit.Int(2)))
And postfix variant:
expr.op1[Int](1, 2)
//Term.Apply(Term.ApplyType(Term.Select(Term.Name("expr"), Term.Name("op1")), List(Type.Name("Int"))), List(Lit.Int(1), Lit.Int(2)))
But in scalac
if you run it with -Xprint:typer
for code
object Test5 {
object expr {
def op1(param1: Any, param2: Any): Unit = {}
def op2[T](param1: Any, param2: Any): Unit = {}
}
expr.op1("", "", "")
expr op1 ("", "", "")
expr.op2[Int]("", "", "")
expr op2[Int] ("", "", "")
}
you will see that pairs of postfix and infix notations are parsed the same in syntax tree:
Test5.this.expr.op1("", "", "");
Test5.this.expr.op1("", "", "");
Test5.this.expr.op2[Int]("", "", "");
Test5.this.expr.op2[Int]("", "", "")
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