简体   繁体   中英

Do the mutable Collection.empty methods violate Scala's zero-argument naming convention?

This is how the .empty method is declared in the scala.collection.mutable.Map object in Scala 11.5:

def empty[A, B]: Map[A, B]

Shouldn't this method have empty parentheses, like this?

def empty[A, B](): Map[A, B]

The page on Scala's naming conventions suggests, without saying it explicitly, that omitting the parentheses on a 0-arity method is the convention for pure-functional code, and including empty parentheses means that the method has a side-effect. (I think I've run into an error message that's more explicit about this.)

The mutable .empty method has a side-effect, since you can distinguish the results of separate calls to .empty . Shouldn't it get empty parentheses, even though its mate in immutable.Map doesn't?

Regarding my own code, is there a special naming convention I should follow when creating and returning a mutable object from a 0-arity method?

No. scala.collection.mutable.Map.empty[A, B] does not have any side effects. It is a method that returns a new mutable.Map[A, B] every time you call it.

mutable.Map#empty (the method in the trait itself) also returns a new empty mutable.Map of the same type. It does not empty the collection (like it appears it might), so there are no side effects.

See the source if you're unsure.

It's all a bit of a mess on the JVM.

In the presence of operations like eq/ne and System.identityHashCode, even creating a new immutable object has observable side-effects (namely increasing some counter deep in the bowels of the JVM so that the next object will have a different reference hashCode). So in JVM land, a function that does nothing except returning a new object is considered as side-effect free as you can get. If the object returned is mutable, referential transparency goes out of the window anyway, even though the function that produces the mutable object itself is considered side-effect free.

If you are really pedantic about it, there are no side-effect free functions on the JVM that return non-primitives.

scala> import scala.collection.immutable._
scala> SortedSet.empty[Int] eq SortedSet.empty[Int]
res4: Boolean = false

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM