Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference Between Scala Expressions

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,...))?

like image 378
Sledge Avatar asked Mar 14 '18 03:03

Sledge


1 Answers

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]("", "", "")
like image 170
Evgeny Avatar answered Oct 23 '22 17:10

Evgeny