List of Scala's "magic" functions

SyntaxScala

Syntax Problem Overview


Where can I find a list of Scala's "magic" functions, such as apply, unapply, update, +=, etc.?

By magic-functions I mean functions which are used by some syntactic sugar of the compiler, for example

o.update(x,y) <=> o(x) = y

I googled for some combination of scala magic and synonyms of functions, but I didn't find anything.

I'm not interested with the usage of magic functions in the standard library, but in which magic functions exists.

Syntax Solutions


Solution 1 - Syntax

As far as I know:

Getters/setters related:

apply
update
identifier_=

Pattern matching:

unapply
unapplySeq

For-comprehensions:

map
flatMap
filter
withFilter
foreach

Prefixed operators:

unary_+
unary_-
unary_!
unary_~

Beyond that, any implicit from A to B. Scala will also convert A <op>= B into A = A <op> B, if the former operator isn't defined, "op" is not alphanumeric, and <op>= isn't !=, ==, <= or >=.

And I don't believe there's any single place where all of Scala's syntactic sugars are listed.

Solution 2 - Syntax

In addition to update and apply, there are also a number of unary operators which (I believe) qualify as magical:

  • unary_+
  • unary_-
  • unary_!
  • unary_~

Add to that the regular infix/suffix operators (which can be almost anything) and you've got yourself the complete package.

You really should take a look at the Scala Language Specification. It is the only authoritative source on this stuff. It's not that hard to read (as long as you're comfortable with context-free grammars), and very easily searchable. The only thing it doesn't specify well is the XML support.

Solution 3 - Syntax

Sorry if it's not exactly answering your question, but my favorite WTF moment so far is @ as assignment operator inside pattern match. Thanks to soft copy of "Programming in Scala" I found out what it was pretty quickly.

Using @ we can bind any part of a pattern to a variable, and if the pattern match succeeds, the variable will capture the value of the sub-pattern. Here's the example from Programming in Scala (Section 15.2 - Variable Binding):

expr match {
  case UnOp("abs", e @ UnOp("abs", _)) => e
  case _ =>
}

> If the entire pattern match succeeds, > then the portion that matched the > UnOp("abs", _) part is made available > as variable e.

And here's what Programming Scala says about it.

That link no longer works. Here is one that does.

Solution 4 - Syntax

I'll also add _* for pattern matching on an arbitrary number of parameters like

case x: A(_*)

And operator associativity rule, from Odersky-Spoon-Venners book:

> The associativity of an operator in Scala is determined by its last > character. As mentioned on <...>, any method that ends > in a ‘:’ character is invoked on its right operand, passing in the > left operand. Methods that end in any other character are the other > way around. They are invoked on their left operand, passing in the > right operand. So a * b yields a.*(b), but a ::: b yields b.:::(a).


Maybe we should also mention syntactic desugaring of for expressions which can be found here


And (of course!), alternative syntax for pairs

a -> b //converted to (a, b), where a and b are instances

(as correctly pointed out, this one is just an implicit conversion done through a library, so it's probably not eligible, but I find it's a common puzzler for newcomers)


Solution 5 - Syntax

I'd like to add that there is also a "magic" trait - scala.Dynamic:

> A marker trait that enables dynamic invocations. Instances x of this trait allow method invocations x.meth(args) for arbitrary method names meth and argument lists args as well as field accesses x.field for arbitrary field names field. > > If a call is not natively supported by x (i.e. if type checking fails), it is rewritten according to the following rules: > > foo.method("blah") ~~> foo.applyDynamic("method")("blah") > foo.method(x = "blah") ~~> foo.applyDynamicNamed("method")(("x", "blah")) > foo.method(x = 1, 2) ~~> foo.applyDynamicNamed("method")(("x", 1), ("", 2)) > foo.field ~~> foo.selectDynamic("field") > foo.varia = 10 ~~> foo.updateDynamic("varia")(10) > foo.arr(10) = 13 ~~> foo.selectDynamic("arr").update(10, 13) > foo.arr(10) ~~> foo.applyDynamic("arr")(10) > > As of Scala 2.10, defining direct or indirect subclasses of this trait is only possible if the language feature dynamics is enabled.

So you can do stuff like

import scala.language.dynamics

object Dyn extends Dynamic {
  def applyDynamic(name: String)(a1: Int, a2: String) {
    println("Invoked " + name + " on (" + a1 + "," + a2 + ")");
  }
}

Dyn.foo(3, "x");
Dyn.bar(3, "y");

Solution 6 - Syntax

They are defined in the Scala Language Specification. As far as I know, there are just three "magic" functions as you mentioned.

Scalas Getter and Setter may also relate to your "magic":

scala> class Magic {
 |     private var x :Int = _
 |     override def toString = "Magic(%d)".format(x)
 |     def member = x
 |     def member_=(m :Int){ x = m }
 | }

defined class Magic

scala> val m = new Magic

m: Magic = Magic(0)

scala> m.member

res14: Int = 0

scala> m.member = 100

scala> m

res15: Magic = Magic(100)

scala> m.member += 99

scala> m

res17: Magic = Magic(199)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionElazar LeibovichView Question on Stackoverflow
Solution 1 - SyntaxDaniel C. SobralView Answer on Stackoverflow
Solution 2 - SyntaxDaniel SpiewakView Answer on Stackoverflow
Solution 3 - SyntaxYardenaView Answer on Stackoverflow
Solution 4 - Syntaxpagoda_5bView Answer on Stackoverflow
Solution 5 - SyntaxPetrView Answer on Stackoverflow
Solution 6 - SyntaxEastsunView Answer on Stackoverflow