Class Cast Exception on a simple code ( "==" override ) - scala

This is a simplified code of what is happening in our application:
class First { def ==(first:First)= "mystring"}
case class Second(first:First)
Second(new First) == Second(new First)
this give:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean
I understand that I'm doing something wrong but I don't understand what.
EDIT
I have modified the code by changing:
class First { def ==(first:First)= true}
and now the error in REPL is:
error: type mismatch;
found : First(in object $iw)
required: First(in object $iw)
Second(new First) == Second(new First)
even more unexpected to me :\
UPDATE the second example is my fault. I changed class First in REPL interactively causing the strange result. Starting from scratch It works. Still the first one...

The updated version (with == returning a Boolean) works for me.
The reason for your weird error is, probably, because you were trying it in REPL, and redefined the First class, but not Second.
REPL does some trickery to allow you redefine classes and variables, which is usually not possible in scala, so you basically end up having two versions of First, and your Second definition still references the older one, while the one you send to the constructor with new First() is the new one - thus the mismatch.
Just redefine the Second class again, and it will work.
There isn't much wrong with redefining == BTW, but it's just more common to override equals in these cases, which would have the same effect. The default implementation of == just calls equals, so, one problem with it is that someone downstream may override equals in one of your subclasses, and be stumped by the fact that it does not do what they expected.

Never override == operator, it's provided by the scala compiler, with the semantics similar to Object.equals method from java. This is the reason that it always returns boolean. So i assume that when you implemented your own operator scala tries to cast it's result to boolean.

Because Second is a case class and it doesn't define or inherit custom equals method, the generated code for Second#equals should look like
override def equals(x: Any): Boolean = x match {
case x: Second => first == x.first
case _ => false
}
The == in the first branch will be your ==(First), not the usual ==(Any), because it's the more specific overload. So you "should" get a compilation error when declaring Second.
But from the stack trace it seems the compiler inserts a cast somewhere instead, either (x match ...).asInstanceOf[Boolean] or (first == x.first).asInstanceOf[Boolean]. To be honest, I can't really think of a reason why it would be written this way. But this makes Second compile and your later call fail.

Related

Why SAM rule doesn't work on parameterless method

// ok
val sam0: MySamWithEmptyParameter = () => 100
// doesn't work
// val sam1: MySamWithParameterless = () => 100
trait MySamWithEmptyParameter {
def receive(): Int
}
trait MySamWithParameterless {
def receive: Int
}
Why sam1 fails to override the receive method? The scalac compile both of traits to same code.
abstract trait TestSAM$MySamWithEmptyParameter extends Object {
def receive(): Int
};
abstract trait TestSAM$MySamWithParameterless extends Object {
def receive(): Int
};
SI-10555 talks exactly about this. This was a simple design decision to only support an explicit empty parameter list, even though the two compile down to an empty parameter list anyway.
The relevant part of the Specification says (emphasis mine):
the method m must have a single argument list;
This is indeed a bit awkward as eta expansion does work for methods with an empty parameter list.
Edit
Contacted the guys at Lightbend. Here is a response by Adrian Moors, Scala team lead:
The original reason was to keep the spec simple, but perhaps we should revisit. I agree it’s surprising that it works for def a(): Int, but not in your example.
Internally, methods that don’t define an argument list at all, and those that do (even if empty) are treated differently.
This has led to confusion/bugs before — to name just one: https://github.com/scala/scala-dev/issues/284.
In 2.13, we’re reworking eta-expansion (it will apply more aggressively, but ()-insertion will happen first). We’ve been back and forth on this, but the current thinking is:
0-ary methods are treated specially: if the expected type is sam-equivalent to Function0, we eta-expand; otherwise, () is inserted (in dotty, you are required to write the () explicitly, unless the method is java-defined) — I’m still not sure about whether we should ever eta-expand here
for all other arities, a method reference is eta-expanded regardless of the expected type (if there’s no type mismatch, this could hide errors when you refactor a method to take arguments, but forget to apply them everywhere. However, since functions are first-class values, it should be easy to construct them by simplify referring to a method value).
The upshot is that we can deprecate method value syntax (m _), since it’s subsumed by simply writing m. (Note that this is distinct from placeholder syntax, as in m(, _).)
(See also the thread around this comment: https://github.com/lampepfl/dotty/issues/2570#issuecomment-306202339)

Scala method definition with `functionName` : `dataType` = `functionName`

I have come across this new method definition. Need explanation what exactly happens here.
Parent trait
sealed trait Generic{
def name : String = name // what is the body of this function call?
def id : Int = id
def place : String = place
}
Child case classes
case class Capital(
countryName : String,
override val id: Int,
override val place:String
) extends Generic
warning: method place in trait Generic does nothing other than call itself recursively I get this warning message is there anything wrong in using these types of methods?
How exactly compiler treat these type of function calls def name : String = name?
Is it this call treats its body as its method name?
You are providing default implementations in the trait that are infinite loops, very much like in the following example:
def infiniteLoop: Unit = infiniteLoop
This is arguably the most useless and dangerous code that you could possibly put in a method of a trait. You could only make it worse by making it non-deterministic. Fortunately, the compiler gives you a very clear and precise warning:
warning: method place in trait Generic does nothing other than call itself recursively
"Is there anything wrong in using these types of methods"?: having unproductive infinite loops in your code is usually considered wrong, unless your goal is to produce as much heat as possible using computer hardware.
"How exactly compiler treat these type of function calls"?: Just like any other tail recursive function, but additionally it outputs the above warning, because it sees that it is obviously not what you want.
"Is it this call treats its body as its method name?": The body of each method declaration is what follows the =-sign. In your case, the otherwise common curly braces around the function body are omitted, and the entire function body consists only of the recursive call to itself.
If you don't want to have any unnecessary infinite loops around, simply leave the methods unimplemented:
sealed trait Generic{
def name: String
def id: Int
def place: String
}
This also has the additional advantage that the compiler can warn you if you forget to implement one of these methods in a subclass.
Ok, so in your trait you define methods body via recursion. Means that these methods, if not overridden (and they should not as soon as you have defined them somehow), will call itself recursively till StackOverflowError happens. For example, you did not override name method in Capital, so in this case you get StackOverflowError at runtime:
val c = Capital("countryName", 1, "place")
c.name
So, you are warned, that you have recursive definition. Trait is sealed, so at least it cannot be overridden in other places, but anyway, such definition is something like put mines on your road and rely on your memory, that you will not forget about them (and anybody else will be care enough to check trait definition before extending)

How to copy a case class and add a mixin?

I'd like to have a base case class I can extend at will into different types. I had something like this working previously, but I must have screwed something up, because now I'm getting compile errors.
trait JobLike
case class Task(name: String) {
def as[T <: JobLike]: Task with T = new Task(this.name) with T
}
The problem is, this gives me a compiler error like this:
java.lang.UnsupportedOperationException: addChild inapplicable for type T
at scala.reflect.internal.Symbols$Symbol.addChild(Symbols.scala:1835)
at scala.tools.nsc.typechecker.Namers$Namer.$anonfun$templateSig$1(Namers.scala:1119)
at scala.tools.nsc.typechecker.Namers$Namer.templateSig(Namers.scala:1107)
at scala.tools.nsc.typechecker.Namers$Namer.classSig(Namers.scala:1178)
at scala.tools.nsc.typechecker.Namers$Namer.memberSig(Namers.scala:1788)
at scala.tools.nsc.typechecker.Namers$Namer.typeSig(Namers.scala:1751)
at scala.tools.nsc.typechecker.Namers$Namer$MonoTypeCompleter.completeImpl(Namers.scala:836)
...
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:82)
at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:85)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:101)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)</code>
I swear, I had something working yesterday that basically did just this, but now it's throwing this error.
You managed to hit a compiler bug! While that's certainly an issue, and should be reported, the thing is that your code isn't possible anyway, and it's better that it's crashing and bringing you here than "working" and doing something horribly wrong. Because T can be any subtype of JobLike, there's simply no way to mix it in at compile time. I could very well do trait Boom extends JobLike { def something: Int }; task.as[Boom], and then task couldn't create a Boom because there's no implementation for something.
You can provide asJobLike: Task with JobLike instead of a general as[T]: Task with T, which is completely possible. (Note that it's discouraged to make subtypes of case classes, so you may want to create a new class. The reason is that it breaks the reflexivity of equals.)
Something rather filthy that you can do is call (new Task(this.name) with JobLike).asInstanceOf[Task with T]. asInstanceOf only checks the cast for the leftmost type in the with, so this will not ClassCastException off the bat (you can also do "a".asInstanceOf[String with Int].). It will generally sorta work (modulus asInstanceOf[T] being false) as long as T has no members.
Something horrible that you can also do is use runtime reflection to dynamically create the required class. The trick as a whole is filthy and completely unsafe, so I won't say it here, but have a link.

Using private constructor in a macro

I want to use a private constructor in a macro. This example is a positive integer, but the basic pattern could not only be used for other numeric types like even numbers, but also string derived types like email addresses or a directory name. By making the constructor private the user is denied the opportunity to make an illegal type. I have the following code:
object PosInt
{
import language.experimental.macros
import reflect.runtime.universe._
import reflect.macros.Context
def op(inp: Int): Option[PosInt] = if (inp > 0) Some(new PosInt(inp)) else None
def apply(param: Int): PosInt = macro apply_impl
def apply_impl(c: Context)(param: c.Expr[Int]): c.Expr[PosInt] =
{
import c.universe._
param match {
case Expr(Literal(i)) if (i.value.asInstanceOf[Int] > 0) =>
case Expr(Literal(i)) if (i.value.asInstanceOf[Int] == 0) => c.abort(c.enclosingPosition, "0 is not a positive integer")
case Expr(Literal(i)) => c.abort(c.enclosingPosition, "is not a positive integer")
case _ => c.abort(c.enclosingPosition, "Not a Literal")
}
reify{new PosInt(param.splice)}
}
}
class PosInt (val value: Int) extends AnyVal
However if I make the PosInt Constructor private, although the Macro compiles as expected I get an error if try to use the macro. I can't work out how to build the expression tree manually, but I'm not sure if that would help anyway. Is there anyway I can do this?
You still can't use a private constructor even if PosInt is not a value class. I'll accept an answer that doesn't use a value class. The disadvantage of value classes is that they get type erasure. Plus classes that I'm interested in like subsets of 2d co-ordinates can't be implement as value classes anyway. I'm not actually interested in Positive Integers, I'm just using them as a simple test bed. I'm using Scala 2.11M5. Scala 2.11 will have the addition of the quasiquotes feature. I haven't worked out how to use, quasiquotes yet, as all the material at the moment on them seems to assume a familiarity with Macro Paradise, which I don't have.
Unfortunately for what you are trying to achieve, macros do not work this way. They just manipulate the AST at compile time. Whatever the final result is, it is always something you could have written literally in Scala (without the macro).
Thus, in order to constrain the possible values of PosInt, you will need a runtime check somewhere, either in a public constructor or in a factory method on the companion object.
If runtime exceptions are not palatable to you, then one possible approach would be:
Make the constructor private on the class.
Provide (for example) a create method on the companion object that returns Option[PosInt] (or Try[PosInt], or some other type of your choice that allows you to express a "failure" when the argument is out of range).
Provide an apply method on the companion object similar to your example, which verifies at compile time that the argument is in range and then returns an expression tree that simply calls create(x).get.
Calling .get on the Option is acceptable in this case because you are sure that it will never be None.
The downside is that you have to repeat the check twice: once at compile time, and once at runtime.
I'm not an expert, but I figured I'll give it a shot...
In Java, the scope of a private constructor is limited to the same class... so the PosInt object would need to be moved into the scope of the same class from which it's being called.
With that said, I found an article that shows two ways you can keep the object from being inherited # http://www.developer.com/java/other/article.php/3109251/Stopping-Your-Class-from-Being-Inherited-in-Java-the-Official-Way-and-the-Unofficial-Way.htm
It describes using the "final" keyword in the class declaration to prevent it from being inherited. That's the "official" way. The "unofficial" way is to make the constructor private, but add a public static method that returns an object of the class...
Yes, I know, it is an old question... but it was left unanswered. You never know when an old question will be the top hit in someone's search results...

Usages of Null / Nothing / Unit in Scala

I've just read: http://oldfashionedsoftware.com/2008/08/20/a-post-about-nothing/
As far as I understand, Null is a trait and its only instance is null.
When a method takes a Null argument, then we can only pass it a Null reference or null directly, but not any other reference, even if it is null (nullString: String = null for example).
I just wonder in which cases using this Null trait could be useful.
There is also the Nothing trait for which I don't really see any more examples.
I don't really understand either what is the difference between using Nothing and Unit as a return type, since both doesn't return any result, how to know which one to use when I have a method that performs logging for example?
Do you have usages of Unit / Null / Nothing as something else than a return type?
You only use Nothing if the method never returns (meaning it cannot complete normally by returning, it could throw an exception). Nothing is never instantiated and is there for the benefit of the type system (to quote James Iry: "The reason Scala has a bottom type is tied to its ability to express variance in type parameters."). From the article you linked to:
One other use of Nothing is as a return type for methods that never
return. It makes sense if you think about it. If a method’s return
type is Nothing, and there exists absolutely no instance of Nothing,
then such a method must never return.
Your logging method would return Unit. There is a value Unit so it can actually be returned. From the API docs:
Unit is a subtype of scala.AnyVal. There is only one value of type
Unit, (), and it is not represented by any object in the underlying
runtime system. A method with return type Unit is analogous to a Java
method which is declared void.
The article you quote can be misleading. The Null type is there for compatibility with the Java virtual machine, and Java in particular.
We must consider that Scala:
is completely object oriented: every value is an object
is strongly typed: every value must have a type
needs to handle null references to access, for example, Java libraries and code
thus it becomes necessary to define a type for the null value, which is the Null trait, and has null as its only instance.
There is nothing especially useful in the Null type unless you're the type-system or you're developing on the compiler. In particular I can't see any sensible reason to define a Null type parameter for a method, since you can't pass anything but null
Do you have usages of Unit / Null / Nothing as something else than a
return type?
Unit can be used like this:
def execute(code: => Unit):Unit = {
// do something before
code
// do something after
}
This allows you to pass in an arbitrary block of code to be executed.
Null might be used as a bottom type for any value that is nullable. An example is this:
implicit def zeroNull[B >: Null] =
new Zero[B] { def apply = null }
Nothing is used in the definition of None
object None extends Option[Nothing]
This allows you to assign a None to any type of Option because Nothing 'extends' everything.
val x:Option[String] = None
if you use Nothing, there is no things to do (include print console)
if you do something, use output type Unit
object Run extends App {
//def sayHello(): Nothing = println("hello?")
def sayHello(): Unit = println("hello?")
sayHello()
}
... then how to use Nothing?
trait Option[E]
case class Some[E](value: E) extends Option[E]
case object None extends Option[Nothing]
I've never actually used the Null type, but you use Unit, where you would on java use void. Nothing is a special type, because as Nathan already mentioned, there can be no instance of Nothing. Nothing is a so called bottom-type, which means, that it is a sub-type of any other type. This (and the contravariant type parameter) is why you can prepend any value to Nil - which is a List[Nothing] - and the list will then be of this elements type. None also if of type Option[Nothing]. Every attempt to access the values inside such a container will throw an exception, because that it the only valid way to return from a method of type Nothing.
Nothing is often used implicitly. In the code below,
val b: Boolean =
if (1 > 2) false
else throw new RuntimeException("error")
the else clause is of type Nothing, which is a subclass of Boolean (as well as any other AnyVal). Thus, the whole assignment is valid to the compiler, although the else clause does not really return anything.
In terms of category theory Nothing is an initial object and Unit is a terminal object.
https://en.wikipedia.org/wiki/Initial_and_terminal_objects
Initial objects are also called coterminal or universal, and terminal objects are also called final.
If an object is both initial and terminal, it is called a zero object or null object.
Here's an example of Nothing from scala.predef:
def ??? : Nothing = throw new NotImplementedError
In case you're unfamiliar (and search engines can't search on it) ??? is Scala's placeholder function for anything that hasn't been implemented yet. Just like Kotlin's TODO.
You can use the same trick when creating mock objects: override unused methods with a custom notUsed method. The advantage of not using ??? is that you won't get compile warnings for things you never intend to implement.