From 96a42a2eda85489bb7dba25d9e8597bd35d7bcbd Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 3 Feb 2010 17:34:31 +0000 Subject: Striking while the iron is hot, renamed removeD... Striking while the iron is hot, renamed removeDuplicates to unique and deprecated removeDuplicates. The debate between distinct and unique was vigorous but unique won by a freckle. (Dark horse 'nub' was disqualified for taking performance enhancers.) The only thing which might need review is the choice of name, but review by odersky. --- src/compiler/scala/tools/nsc/Global.scala | 2 +- src/compiler/scala/tools/nsc/Interpreter.scala | 4 ++-- src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala | 2 +- src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 4 ++-- src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala | 2 +- src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala | 2 +- src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala | 2 +- src/compiler/scala/tools/nsc/interpreter/PackageCompletion.scala | 4 ++-- src/compiler/scala/tools/nsc/interpreter/ReflectionCompletion.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/Namers.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 2 +- src/library/scala/collection/SeqLike.scala | 2 +- src/library/scala/collection/SeqProxyLike.scala | 2 +- src/library/scala/collection/immutable/List.scala | 3 +++ src/library/scala/collection/immutable/Stream.scala | 4 ++-- src/library/scala/collection/interfaces/SeqMethods.scala | 2 +- src/partest/scala/tools/partest/nest/Worker.scala | 2 +- test/files/run/Course-2002-13.scala | 4 ++-- test/files/run/colltest1.scala | 4 ++-- test/files/run/hashCodeBoxesRunTime.scala | 2 +- test/files/run/hashCodeDistribution.scala | 2 +- test/files/scalacheck/list.scala | 4 ++-- 22 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 9b77890486..8a20a5e1f2 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -736,7 +736,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable /** Compile list of source files */ def compileSources(_sources: List[SourceFile]) { - val depSources = dependencyAnalysis.filter(_sources.removeDuplicates) // bug #1268, scalac confused by duplicated filenames + val depSources = dependencyAnalysis.filter(_sources.unique) // bug #1268, scalac confused by duplicated filenames val sources = scalaObjectFirst(depSources) if (reporter.hasErrors) return // there is a problem already, e.g. a diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala index 34a82b987b..1c792f0671 100644 --- a/src/compiler/scala/tools/nsc/Interpreter.scala +++ b/src/compiler/scala/tools/nsc/Interpreter.scala @@ -239,7 +239,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { private def keyList[T](x: collection.Map[T, _]): List[T] = x.keysIterator.toList sortBy (_.toString) def allUsedNames = keyList(usedNameMap) def allBoundNames = keyList(boundNameMap) - def allSeenTypes = prevRequests.toList flatMap (_.typeOf.valuesIterator.toList) removeDuplicates + def allSeenTypes = prevRequests.toList flatMap (_.typeOf.valuesIterator.toList) unique def allValueGeneratingNames = allHandlers flatMap (_.generatesValue) def allImplicits = partialFlatMap(allHandlers) { case x: MemberHandler if x.definesImplicit => x.boundNames @@ -1129,7 +1129,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { } filterNot isSynthVarName /** Another entry point for tab-completion, ids in scope */ - def unqualifiedIds() = (unqualifiedIdNames() map (_.toString)).removeDuplicates.sorted + def unqualifiedIds() = (unqualifiedIdNames() map (_.toString)).unique.sorted /** For static/object method completion */ def getClassObject(path: String): Option[Class[_]] = classLoader tryToLoadClass path diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala index 83342fb207..643860b2bc 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala @@ -490,7 +490,7 @@ trait BasicBlocks { ss ++ (ss flatMap findSucc) } - succs.flatMap(findSucc).removeDuplicates + succs flatMap findSucc unique } /** Returns the precessors of this block. */ diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index ec9c371534..b346c491ed 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -183,7 +183,7 @@ abstract class GenJVM extends SubComponent { case _ => () } - parents = parents.removeDuplicates + parents = parents.unique if (parents.length > 1) { ifaces = new Array[String](parents.length - 1) @@ -332,7 +332,7 @@ abstract class GenJVM extends SubComponent { // put some radom value; the actual number is determined at the end buf.putShort(0xbaba.toShort) - for (AnnotationInfo(tp, List(exc), _) <- excs.removeDuplicates if tp.typeSymbol == definitions.ThrowsClass) { + for (AnnotationInfo(tp, List(exc), _) <- excs.unique if tp.typeSymbol == definitions.ThrowsClass) { val Literal(const) = exc buf.putShort( cpool.addClass( diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index 4f8bb63e74..4d323ec4d2 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -1708,7 +1708,7 @@ abstract class GenMSIL extends SubComponent { def isInterface(s: Symbol) = s.isTrait && !s.isImplClass val parents: List[Type] = if (sym.info.parents.isEmpty) List(definitions.ObjectClass.tpe) - else sym.info.parents.removeDuplicates + else sym.info.parents.unique val superType = if (isInterface(sym)) null else msilTypeFromSym(parents.head.typeSymbol) if (settings.debug.value) diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index 00eea9b0f3..2841902e07 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -82,7 +82,7 @@ abstract class DeadCodeElimination extends SubComponent { collectRDef(m) mark sweep(m) - accessedLocals = accessedLocals.removeDuplicates + accessedLocals = accessedLocals.unique if (m.locals diff accessedLocals nonEmpty) { log("Removed dead locals: " + (m.locals diff accessedLocals)) m.locals = accessedLocals.reverse diff --git a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala index 10993b42fd..436c860b8c 100644 --- a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala +++ b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala @@ -158,7 +158,7 @@ class RefinedBuildManager(val settings: Settings) extends Changes with BuildMana atPhase(currentRun.erasurePhase.prev) { changeSet(info, sym) } - changesOf(oldSym) = (changes ++ changesErasure).removeDuplicates + changesOf(oldSym) = (changes ++ changesErasure).unique case _ => // a new top level definition changesOf(sym) = diff --git a/src/compiler/scala/tools/nsc/interpreter/PackageCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/PackageCompletion.scala index a0d83e1880..fb0dbcdded 100644 --- a/src/compiler/scala/tools/nsc/interpreter/PackageCompletion.scala +++ b/src/compiler/scala/tools/nsc/interpreter/PackageCompletion.scala @@ -113,7 +113,7 @@ object PackageCompletion { // all the dotted path to classfiles we can find by poking through the jars def getDottedPaths(map: ConcurrentHashMap[String, List[CompletionInfo]], classpath: List[URL]): Unit = { val cp = classpath map (_.getPath) - val jars = cp.removeDuplicates filter (_ endsWith ".jar") + val jars = cp.unique filter (_ endsWith ".jar") // for e.g. foo.bar.baz.C, returns (foo -> bar), (foo.bar -> baz), (foo.bar.baz -> C) // and scala.Range$BigInt needs to go scala -> Range -> BigInt @@ -137,7 +137,7 @@ object PackageCompletion { def oneJar(jar: String): Unit = { val classfiles = getClassFiles(jar) - for (cl <- classfiles.removeDuplicates ; (k, _v) <- subpaths(cl)) { + for (cl <- classfiles.unique ; (k, _v) <- subpaths(cl)) { val v = CompletionInfo(_v, cl, jar) if (map containsKey k) { diff --git a/src/compiler/scala/tools/nsc/interpreter/ReflectionCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/ReflectionCompletion.scala index 28ad2b7611..ee9dfc5b56 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReflectionCompletion.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReflectionCompletion.scala @@ -45,7 +45,7 @@ trait ReflectionCompletion extends CompletionAware { val excludeMethods = List("hashCode", "equals", "wait", "notify", "notifyAll") private def allInterfacesFor(cl: Class[_], acc: List[Class[_]]): List[Class[_]] = { - if (cl == null) acc.removeDuplicates + if (cl == null) acc.unique else allInterfacesFor(cl.getSuperclass, acc ::: cl.getInterfaces.toList) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index e64a78e8e4..223eb6785c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -727,7 +727,7 @@ trait Namers { self: Analyzer => } if (!hasCopy(decls) && !parents.exists(p => hasCopy(p.typeSymbol.info.decls)) && - !parents.flatMap(_.baseClasses).removeDuplicates.exists(bc => hasCopy(bc.info.decls))) + !parents.flatMap(_.baseClasses).unique.exists(bc => hasCopy(bc.info.decls))) addCopyMethod(cdef, templateNamer) case None => } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 5234bb44f1..4f414893f8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -190,7 +190,7 @@ abstract class RefChecks extends InfoTransform { case List(MixinOverrideError(_, msg)) => unit.error(clazz.pos, msg) case MixinOverrideError(member, msg) :: others => - val others1 = others.map(_.member.name.decode).filter(member.name.decode != _).removeDuplicates + val others1 = others.map(_.member.name.decode).filter(member.name.decode != _).unique unit.error( clazz.pos, msg+(if (others1.isEmpty) "" diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index 5b866e5b3d..b0587b43fa 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -610,7 +610,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => * * @return A new $coll which contains the first occurrence of every element of this $coll. */ - def removeDuplicates: Repr = { + def unique: Repr = { val b = newBuilder var seen = Set[A]() //TR: should use mutable.HashSet? for (x <- this) { diff --git a/src/library/scala/collection/SeqProxyLike.scala b/src/library/scala/collection/SeqProxyLike.scala index 3dfac63dde..492e16e0b7 100644 --- a/src/library/scala/collection/SeqProxyLike.scala +++ b/src/library/scala/collection/SeqProxyLike.scala @@ -50,7 +50,7 @@ trait SeqProxyLike[+A, +This <: SeqLike[A, This] with Seq[A]] extends SeqLike[A, override def union[B >: A, That](that: Seq[B])(implicit bf: CanBuildFrom[This, B, That]): That = self.union(that)(bf) override def diff[B >: A, That](that: Seq[B]): This = self.diff(that) override def intersect[B >: A, That](that: Seq[B]): This = self.intersect(that) - override def removeDuplicates: This = self.removeDuplicates + override def unique: This = self.unique override def patch[B >: A, That](from: Int, patch: Seq[B], replaced: Int)(implicit bf: CanBuildFrom[This, B, That]): That = self.patch(from, patch, replaced)(bf) override def padTo[B >: A, That](len: Int, elem: B)(implicit bf: CanBuildFrom[This, B, That]): That = self.padTo(len, elem)(bf) override def indices: Range = self.indices diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index 415a31a02e..9b95d02b5a 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -288,6 +288,9 @@ sealed abstract class List[+A] extends LinearSeq[A] b.toList } + @deprecated("use `unique' instead") + def removeDuplicates: List[A] = unique + /**

* Sort the list according to the comparison function * `lt(e1: a, e2: a) => Boolean`, diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 7b9db5e21e..10e60a9417 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -344,9 +344,9 @@ self => /** Builds a new stream from this stream in which any duplicates (wrt to ==) removed. * Among duplicate elements, only the first one is retained in the result stream */ - override def removeDuplicates: Stream[A] = + override def unique: Stream[A] = if (isEmpty) this - else new Stream.Cons(head, tail.filter(head !=).removeDuplicates) + else new Stream.Cons(head, tail.filter(head !=).unique) /** Returns a new sequence of given length containing the elements of this sequence followed by zero * or more occurrences of given elements. diff --git a/src/library/scala/collection/interfaces/SeqMethods.scala b/src/library/scala/collection/interfaces/SeqMethods.scala index df0307174d..2baaee83f7 100644 --- a/src/library/scala/collection/interfaces/SeqMethods.scala +++ b/src/library/scala/collection/interfaces/SeqMethods.scala @@ -44,7 +44,7 @@ trait SeqMethods[+A, +This <: SeqLike[A, This] with Seq[A]] extends IterableMeth def padTo[B >: A, That](len: Int, elem: B)(implicit bf: CanBuildFrom[This, B, That]): That def patch[B >: A, That](from: Int, patch: Seq[B], replaced: Int)(implicit bf: CanBuildFrom[This, B, That]): That def prefixLength(p: A => Boolean): Int - def removeDuplicates: This + def unique: This def reverse: This def reverseIterator: Iterator[A] def segmentLength(p: A => Boolean, from: Int): Int diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index d671eea561..99582f9e48 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -457,7 +457,7 @@ class Worker(val fileManager: FileManager) extends Actor { val outURL = outDir.getCanonicalFile.toURI.toURL val classpath: List[URL] = List(outURL, scalacheckURL, latestCompFile.toURI.toURL, latestLibFile.toURI.toURL, - latestActFile.toURI.toURL, latestPartestFile.toURI.toURL).removeDuplicates + latestActFile.toURI.toURL, latestPartestFile.toURI.toURL).unique val logWriter = new PrintStream(new FileOutputStream(logFile)) diff --git a/test/files/run/Course-2002-13.scala b/test/files/run/Course-2002-13.scala index 27551b735b..fa5390e534 100644 --- a/test/files/run/Course-2002-13.scala +++ b/test/files/run/Course-2002-13.scala @@ -66,7 +66,7 @@ object Terms { override def toString() = a + (if (ts.isEmpty) "" else ts.mkString("(", ",", ")")); def map(s: Subst): Term = Con(a, ts map (t => t map s)); - def tyvars = (ts flatMap (t => t.tyvars)).removeDuplicates; + def tyvars = (ts flatMap (t => t.tyvars)).unique; } private var count = 0; @@ -113,7 +113,7 @@ object Programs { case class Clause(lhs: Term, rhs: List[Term]) { def tyvars = - (lhs.tyvars ::: (rhs flatMap (t => t.tyvars))).removeDuplicates; + (lhs.tyvars ::: (rhs flatMap (t => t.tyvars))).unique; def newInstance = { var s: Subst = List(); for (val a <- tyvars) { s = Binding(a, newVar(a)) :: s } diff --git a/test/files/run/colltest1.scala b/test/files/run/colltest1.scala index f12c234f74..b07e6b0e59 100644 --- a/test/files/run/colltest1.scala +++ b/test/files/run/colltest1.scala @@ -80,7 +80,7 @@ object Test extends Application { val tenPlus = ten map (_ + 1) assert((ten zip tenPlus) forall { case (x, y) => x + 1 == y }) val dble = ten flatMap (x => List(x, x)) - assert(dble.removeDuplicates == ten) + assert(dble.unique == ten) assert(ten.length == 10) assert(ten(0) == 1 && ten(9) == 10) assert((ten lengthCompare 10) == 0 && (ten lengthCompare 1) > 0 && (ten lengthCompare 11) < 0) @@ -122,7 +122,7 @@ object Test extends Application { assert((ten diff (ten filter (_ % 2 == 0))) == (ten filterNot (_ % 2 == 0))) assert((ten intersect ten) == ten) assert((ten intersect List(5)) == List(5)) - assert((ten ++ ten).removeDuplicates == ten) + assert((ten ++ ten).unique == ten) assert(ten.patch(3, List(4, 5, 6, 7), 4) == ten) assert(ten.patch(0, List(1, 2, 3), 9) == List(1, 2, 3, 10)) assert(empty.padTo(10, 7) == Array.fill(10)(7).toSeq) diff --git a/test/files/run/hashCodeBoxesRunTime.scala b/test/files/run/hashCodeBoxesRunTime.scala index 3eacacb663..9ead89beb4 100644 --- a/test/files/run/hashCodeBoxesRunTime.scala +++ b/test/files/run/hashCodeBoxesRunTime.scala @@ -5,7 +5,7 @@ object Test import java.{ lang => jl } import scala.runtime.BoxesRunTime.{ hashFromNumber, hashFromObject } - def allSame[T](xs: List[T]) = assert(xs.removeDuplicates.size == 1, "failed: " + xs) + def allSame[T](xs: List[T]) = assert(xs.unique.size == 1, "failed: " + xs) def mkNumbers(x: Int): List[Number] = List(x.toByte, x.toShort, x, x.toLong, x.toFloat, x.toDouble) diff --git a/test/files/run/hashCodeDistribution.scala b/test/files/run/hashCodeDistribution.scala index dbb6e833bd..64cae398f1 100644 --- a/test/files/run/hashCodeDistribution.scala +++ b/test/files/run/hashCodeDistribution.scala @@ -8,7 +8,7 @@ object Test { val hashCodes = for (x <- 0 until COUNT; y <- 0 until COUNT) yield C(x,y).hashCode - val uniques = hashCodes.removeDuplicates + val uniques = hashCodes.unique val collisionRate = (totalCodes - uniques.size) * 1000 / totalCodes assert(collisionRate < 5, "Collision rate too high: %d / 1000".format(collisionRate)) diff --git a/test/files/scalacheck/list.scala b/test/files/scalacheck/list.scala index 87ecd70a48..f08b0d0394 100644 --- a/test/files/scalacheck/list.scala +++ b/test/files/scalacheck/list.scala @@ -7,14 +7,14 @@ object Test extends Properties("List") { property("concat size") = forAll { (l1: List[Int], l2: List[Int]) => (l1.size + l2.size) == (l1 ::: l2).size } property("reverse") = forAll { (l1: List[Int]) => l1.reverse.reverse == l1 } - property("toSet") = forAll { (l1: List[Int]) => sorted(l1.toSet.toList) sameElements sorted(l1).removeDuplicates } + property("toSet") = forAll { (l1: List[Int]) => sorted(l1.toSet.toList) sameElements sorted(l1).unique } property("flatten") = forAll { (xxs: List[List[Int]]) => xxs.flatten.length == (xxs map (_.length) sum) } property("startsWith/take") = forAll { (xs: List[Int], count: Int) => xs startsWith (xs take count) } property("endsWith/takeRight") = forAll { (xs: List[Int], count: Int) => xs endsWith (xs takeRight count) } property("fill") = forAll(choose(1, 100)) { count => forAll { (x: Int) => val xs = List.fill(count)(x) - (xs.length == count) && (xs.removeDuplicates == List(x)) + (xs.length == count) && (xs.unique == List(x)) } } } -- cgit v1.2.3