Scala 2.8 handles Boolean and java.lang.Boolean properly? - scala

Consider the following:
scala> val a:java.lang.Boolean = true
a: java.lang.Boolean = true
scala> val b = true
b: Boolean = true
scala> a == b
res4: Boolean = true
scala> b == a
<console>:8: warning: comparing values of types Boolean
and java.lang.Boolean using `==' will always yield false
b == a
^
res5: Boolean = true
The warning says that it will yield false but it yields true.
Scala 2.8.

A bit of source code control archaeology shows that handling of those warnings were improved after 2.8.1. Here is the annotated revisions to the unit tests for those warnings.
https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/test/files/neg/checksensible.scala?annotate=blame&rev=25638
This is compared to rev 19169 in 2.8.1 final that is a lot more basic:
https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_8_1_final/test/files/neg/checksensible.scala
I think this gives a sense that more attention was provided to this after 2.8.1.
Looking at some bug reports, it seems the warning are really just that - hopefully helping identify errors. If you know what you're doing (such as comparing java Boolean and scala Boolean), then you can ignore.

Interestingly, this has regressed. In recent warning enhancements I must be excluding numerics and missing boolean. The error message in trunk for comparing java.lang.Boolean and Boolean is impressively confusing.

Related

Why Bool(true) != Bool(true) in chisel3?

If I run a scala console in my sbt project and import chisel3 package like it:
$ sbt
sbt:CIC> console
scala> import chisel3._
import chisel3._
scala>
Then if I declare two Bool variables, there are not equal :
scala> val value1 = true.B
value1: chisel3.Bool = Bool(true)
scala> val value2 = true.B
value2: chisel3.Bool = Bool(true)
scala> value1 == value2
res0: Boolean = false
scala> value1.==(value2)
res3: Boolean = false
scala> value1.`==`(value2)
res4: Boolean = false
scala> value1
res5: chisel3.Bool = Bool(true)
scala> value2
res6: chisel3.Bool = Bool(true)
Is it normal ?
Note: I tried to use the hardware equality === without success :
scala> value1 === value2
chisel3.internal.ChiselException: Error: Not in a UserModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox.
at chisel3.internal.throwException$.apply(Error.scala:155)
at chisel3.internal.Builder$.forcedUserModule(Builder.scala:494)
at chisel3.internal.Builder$.pushOp(Builder.scala:558)
at chisel3.Bits.compop(Bits.scala:206)
at chisel3.UInt.do_$eq$eq$eq(Bits.scala:617)
at .$anonfun$res1$2(<console>:17)
at chisel3.internal.prefix$.apply(prefix.scala:49)
at .$anonfun$res1$1(<console>:17)
at chisel3.internal.plugin.package$.autoNameRecursively(package.scala:52)
... 31 elided
scala>
Is it a bug or a normal behavior ?
I need to compare some Bool() values in my tester2 testbench.
The solution I found to use equality is to use .litValue:
scala> value1.litValue == value2.litValue
res2: Boolean = true
But it remain a strange behavior.
The short answer is that while we probably should make equality work as one might expect for literals, it is not as clear cut a decision as one might think.
Thinking about Chisel's primary purpose as a hardware generator language, writing Chisel is fundamentally metaprogramming where we have to reason about two different phases: Chisel elaboration time (aka Scala run-time), and the actual hardware you're generating that is used in simulation and synthesis.
== returns a Scala Boolean so it only makes sense at elaboration time and means nothing to the resulting Verilog. Chisel provides === which returns a chisel3.Bool which is a hardware value that will show up in the Verilog.
Thinking in terms of Wires and Regs, == doesn't really make sense because these hardware components don't have statically knowable values during elaboration time. Thus in Chisel3, == is implemented a referential equality, ie. it is true only if the two objects are the exact same object.
Now as I said at the beginning, there is an argument that we should make == work for literals at least, even if it won't work for hardware components like Wires. It's not 100% clear if this is the right move because it could confuse people that sometimes they use == (only with literals) and sometimes they use === (with everything else). Because of testing libraries like chiseltest, I tend to agree that we should make == work for literals, but I just want to note that there is disagreement on this point.

scala mutable.Map put/get handles null's in an unexpected way?

I know one is not supposed to use nulls in scala but sometimes when interoperating with Java it happens. The way a scala mutable map handles this seems off though:
scala> import scala.collection.mutable
import scala.collection.mutable
scala> val m: mutable.Map[String, String] = mutable.Map.empty
m: scala.collection.mutable.Map[String,String] = Map()
scala> m.put("Bogus", null)
res0: Option[String] = None
scala> m.get("Bogus")
res1: Option[String] = Some(null)
scala> m.getOrElse("Bogus", "default")
res2: String = null
I would have expected m.get to return None in this case. Almost seems like a bug, like somewhere in the code there was a Some(v) instead of Option(v)
Is there discussion w/r/t to changing this behavior?
I would have expected m.get to return None in this case.
Why? None would mean the key "Bogus" is not in the map, but you just put it in (with value null).
Java's Map API has problems distinguishing "the value for this key is null" from "this key is not in the map", but Scala's doesn't.
Null is subtype of String:
scala> implicitly[Null <:< String]
res3: Null <:< String = <function1>
Therefore null is a valid String value:
scala> val s: String = null
s: String = null
If you want to store a null as a String in a map, it's your good right.
Compared to Java's Map#get (let's call it javaLikeGet), the Scala's get behaves roughly as follows:
def get(k: K) = if (containsKey(k)) {
Some(this.javaLikeGet(k))
} else {
None
}
and not like what you have assumed:
def get(k: K) = Option(this.javaLikeGet(k))
The latter version (presumably what you thought) would get a null for an existing key, pass it to Option(...), and return None. But the former version (which imitates how the real implementation works) would notice that the key exists, and wrap the null returned by javaLikeGet into a Some.
The simple and consistent rule is:
If the key k exists, then get(k) returns Some[V], otherwise it returns None.
This is much less surprising than the strange behavior of Java's get that returns null in two entirely different situations.
This is the Billion-Dollar Mistake, but Scala is not the language that is likely to fix it, because it has to interop with Java. My guess is that there is and will be no discussion about changing this behavior, at least not until something fundamentally changes in the entire programming landscape.

determine if T of Manifest[T] is a collection

currently i have this:
private def isCollectionLike[T](manifest: Manifest[T]):Boolean = {
manifest.runtimeClass.toString.contains("scala.collection")
}
I don't like this solution, can you purpose a better one?
Just callingClass#isAssignable should be enough:
def isCollectionLike[T](manifest: Manifest[T]):Boolean = {
classOf[scala.collection.TraversableLike[_,_]].isAssignableFrom(manifest.runtimeClass)
}
Mandatory REPL test:
scala> isCollectionLike(manifest[List[Int]])
res17: Boolean = true
scala> isCollectionLike(manifest[String])
res18: Boolean = false
scala> isCollectionLike(manifest[scala.collection.SeqLike[Int,_]])
res19: Boolean = true
Note though that this won't work with arrays, for the simple reason that scala arrays now (since scala 2.8) map directly to the udnerlying JVM arrays,
and as such do not inherit TraversableLike (If interested you can have a look at http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html).
scala> isCollectionLike(manifest[Array[String]])
res20: Boolean = false
So you'll have to handle it as a special case, or find a better way to test for a collection.
As a side note, these days there is an alternative to java reflection scala's own reflection api (and in addition Manifest is deprecated in favor of TypeTag),
which has the immense advantage of understanding all the scala specific features
(that Class instance retruned by runtimeClass does not know anything about scala).
But it is also more complex, and (currently) not thread safe at all, which is a major limitation.
Plus in your case you will still have to handle arrays as a special case anyway.

Splitter.isParallel returns false? (Version 2.10.2)

I have code that monitors the progress of a foreach method but needs to be able to detect whether the foreach loop will happen in parallel to choose the appropriate progress tracking algorithm. Spent time tracking down a bug and isolated it to this:
scala> Vector(1,2,3).iterator.isParallel
res11: Boolean = false
scala> Vector(1,2,3).isParallel
res12: Boolean = false
scala> Vector(1,2,3).par.isParallel
res13: Boolean = true
...
scala> Vector(1,2,3).par.splitter.isParallel
res13: Boolean = false
scala> Vector(1,2,3).par.iterator.isParallel
res14: Boolean = false
Is this a bug or do I misunderstand the function?
the isParallel method is defined in the TraversableOps class, which you get from various of the collection classes via an implicit conversion. The relevant source snippet (from scala/collection/parallel/package.scala) is:
implicit def traversable2ops[T](t: scala.collection.GenTraversableOnce[T]) = new TraversableOps[T] {
def isParallel = t.isInstanceOf[Parallel]
...
}
As can be seen from this, a class needs to extend the Parallel marker trait to return true from this method. As it turns out, the various parallelised collections do this, but their iterators don't. That is, it appears that Parallel has only been used to mark the actual collections, not their helpers. I don't know whether that is as intended or if it could be argued to be an oversight.

Scala method and values names

Why this fails to compile:
scala> val a? = true
<console>:1: error: illegal start of simple pattern
val a? = true
^
and this works?
scala> val a_? = true
a_?: Boolean = true
According to the Scala language specification (looking at 2.8, doubt things have changed much since):
idrest ::= {letter | digit} [`_' op]
That is, an identifier can start with a letter or a digit followed by an underscore character, and further operator characters. That makes identifiers such as foo_!#! valid identifiers. Also, note that identifiers may also contain a string of operator characters alone. Consider the following REPL session:
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java 1.6.0_16).
scala> val +aff = true
<console>:1: error: illegal start of simple pattern
val +aff = true
^
scala> val ??? = true
???: Boolean = true
scala> val foo_!#! = true
foo_!#!: Boolean = true
scala> val %^#%# = true
%^#%#: Boolean = true
scala> val ^&*!%# = 42
^&*!%#: Int = 42
Hope this answers your question.
Scala's grammar for identifiers is defined in such a way.
? is defined to be an operator character. And an identifier must obey the following rules:
it must be a lower-case letter which may be followed by an element of an 'idrest' syntactic category, which is defined as 'letters or digits, possibly followed by _ and an op char.'
See Scala Language Specification for more details.