I have seen the symbol
???
used in scala code, i however don't know if it's meant to be pseudo code or actual scala code, but my eclipse IDE for scala doesn't flag it and the eclipse worksheet actually evaluates it.
I haven't been able to find anything via google search.
Any help will be appreciated.
Thanks
Yes, this is a valid identifier.
Since Scala 2.10, there is a ??? method in Predef which simply throws a NotImplementedError.
def ??? : Nothing = throw new NotImplementedError
This is intended to be used for quickly sketching the skeleton of some code, leaving the implementations of methods for later, for example:
class Foo[A](a: A) {
def flatMap[B](f: A => Foo[B]): Foo[B] = ???
}
Because it has a type of Nothing (which is a subtype of every other type), it will type-check in place of any value, allowing you to compile the incomplete code without errors. It's often seen in exercises, where the solution needs to be written in place of ???.
To search for method names that are ASCII or unicode strings:
SO search: https://stackoverflow.com/search?q=[scala]+%22%3F%3F%3F%22
finds this thread Scala and Python's pass
scalex covers scala 2.9.1 and scalaz 6.0 http://scalex.org/?q=%3C%3A%3C
Related
Following code does not appear as compiling in IntelliJ. It is complaining that the type returned from the eval should be A where I would expect it to infer during usage. The code compiles fine using sbt but does not compile on IntelliJ with both Scala version 2 and 3 (it runs fine but shows error message in code). Is there a special configuration (e.g. sbt params, jvm args etc) that is required for code below to appear as compiled on IntelliJ?
object Solution1 {
trait Expr[A]
case class B(bool: Boolean) extends Expr[Boolean]
case class I(i: Int) extends Expr[Int]
def eval[A](expr: Expr[A]): A = expr match {
case B(b) => b
case I(i) => i
}
}
Generalized algebraic data types (GADTs) are known to be extremely difficult to implement correctly in Scala. AFAIK both the scalac and dotty compilers currently have type soundness holes, particularly using covariant GADTs.
Your eval should return a value of type T, but since i has type Int and b has type Boolean, it seems the compiler is able to see that because I is a subtype of Expr[Int], T must be equal to Int and then T must be equal to Boolean in the same way.
I am surprised this type checks. It's odd because one would expect T to keep it's meaning. It seems Scala 2's GATDs implementation is still faulty.
I'm not surprised Intellij's Scala Plugin flags it red. You can report this, but I'm not sure whether they can do anything about it as it seems Scala is flawed here for the time being. It needs special treatment for them.
I'm just in the process of upgrading from Scala 2.10.x to 2.11.2 and I'm receiving the following warning with the following code:
override def validateKey(key: String): Either[InvalidKeyError, Unit] =
keys.contains(key) match {
case true => Right()
case false => Left(InvalidKeyError(context, key))
}
Adaptation of argument list by inserting () has been deprecated: this
is unlikely to be what you want. signature: Right.apply[A, B](b: B):
scala.util.Right[A,B] given arguments: after adaptation:
Right((): Unit)
I am able to solve this by changing the "true" case statement to:
case true => Right(()) //() is a shortcut to a Unit instance
Is this the proper way to address this warning?
Edit: perhaps a "why we have to do this now" type answer would be appropriate, my cursory investigation seems to indicate that Scala inserting "Unit" when it thinks it needs to causes other problems
Automatic Unit inference has been deprecated in scala 2.11, and the reason behind this is that it can lead to confusing behavior, especially for people learning the language.
Here's an example
class Foo[T](value: T)
val x = new Foo
This should not compile, right? You are calling the constructor with no arguments, where one is required. Surprisingly, until scala 2.10.4 this compiles just fine, with no errors or warnings.
And that's because the compiler inferred a Unit argument, so it actually replaced your code with
val x = new Foo[Unit](()) // Foo[Unit]
As the newly introduced warning message says, this is unlikely to be what you want.
Another famous example is this
scala> List(1,2,3).toSet()
// res1: Boolean = false
calling toSet() should be a compile-time error, since toSet does not take arguments, but the compiler desperately tries to make it compile, ultimately interpreting the code as
scala> List(1,2,3).toSet.apply(())
which means: test whether () belongs to the set. Since it's not the case, you get a false!
So, starting from scala 2.11, you have to be explicit if you want to pass () (aka Unit) as an argument. That's why you have to write:
Right(())
instead of
Right()
examples taken from Simplifying Scala — The Past, Present and Future by Simon Ochsenreither.
Perhaps it should be Right(()). Have you tried that?
My explanation is that since the Right.apply is polymorphic it can take all kind of parameters, doing Right() means passing in a Unit and the compiler simply advise you that maybe that's not what you want, he doesn't know that this is what you actually want.
If you see your deprecate message it states:
... after adaptation: Right((): Unit)
Which means that the compiler has automatically decided that you are passing in a Unit, since this is kinda like void he doesn't really likes it, specifically passing in a Unit like () explicitly tells the compiler that you do want a Unit there. Anyway seems a new deprecation form scala 2.11, I can't reproduce this on 2.10.4.
I'm just in the process of upgrading from Scala 2.10.x to 2.11.2 and I'm receiving the following warning with the following code:
override def validateKey(key: String): Either[InvalidKeyError, Unit] =
keys.contains(key) match {
case true => Right()
case false => Left(InvalidKeyError(context, key))
}
Adaptation of argument list by inserting () has been deprecated: this
is unlikely to be what you want. signature: Right.apply[A, B](b: B):
scala.util.Right[A,B] given arguments: after adaptation:
Right((): Unit)
I am able to solve this by changing the "true" case statement to:
case true => Right(()) //() is a shortcut to a Unit instance
Is this the proper way to address this warning?
Edit: perhaps a "why we have to do this now" type answer would be appropriate, my cursory investigation seems to indicate that Scala inserting "Unit" when it thinks it needs to causes other problems
Automatic Unit inference has been deprecated in scala 2.11, and the reason behind this is that it can lead to confusing behavior, especially for people learning the language.
Here's an example
class Foo[T](value: T)
val x = new Foo
This should not compile, right? You are calling the constructor with no arguments, where one is required. Surprisingly, until scala 2.10.4 this compiles just fine, with no errors or warnings.
And that's because the compiler inferred a Unit argument, so it actually replaced your code with
val x = new Foo[Unit](()) // Foo[Unit]
As the newly introduced warning message says, this is unlikely to be what you want.
Another famous example is this
scala> List(1,2,3).toSet()
// res1: Boolean = false
calling toSet() should be a compile-time error, since toSet does not take arguments, but the compiler desperately tries to make it compile, ultimately interpreting the code as
scala> List(1,2,3).toSet.apply(())
which means: test whether () belongs to the set. Since it's not the case, you get a false!
So, starting from scala 2.11, you have to be explicit if you want to pass () (aka Unit) as an argument. That's why you have to write:
Right(())
instead of
Right()
examples taken from Simplifying Scala — The Past, Present and Future by Simon Ochsenreither.
Perhaps it should be Right(()). Have you tried that?
My explanation is that since the Right.apply is polymorphic it can take all kind of parameters, doing Right() means passing in a Unit and the compiler simply advise you that maybe that's not what you want, he doesn't know that this is what you actually want.
If you see your deprecate message it states:
... after adaptation: Right((): Unit)
Which means that the compiler has automatically decided that you are passing in a Unit, since this is kinda like void he doesn't really likes it, specifically passing in a Unit like () explicitly tells the compiler that you do want a Unit there. Anyway seems a new deprecation form scala 2.11, I can't reproduce this on 2.10.4.
The following Scala code works correctly:
val str1 = "hallo"
val str2 = "huhu"
val zipped: IndexedSeq[(Char, Char)] = str1.zip(str2)
However if I import the implicit method
implicit def stringToNode(str: String): xml.Node = new xml.Text(str)
then the Scala (2.10) compiler shows an error: value zip is not a member of String
It seems that the presence of stringToNode somehow blocks the implicit conversion of str1 and str2 to WrappedString. Why? And is there a way to modify stringToNode such that zip works but stringToNode is still used when I call a function that requires a Node argument with a String?
You have ambiguous implicits here. Both StringOps and xml.Node have the zip-method, therefore the implicit conversion is ambiguous and cannot be resolved. I don't know why it doesn't give a better error message.
Here are some links to back it up:
http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringOps
and
http://www.scala-lang.org/api/current/index.html#scala.xml.Node
edit: it was StringOps, not WrappedString, changed the links :) Have a look at Predef: http://www.scala-lang.org/api/current/index.html#scala.Predef$
to see predefined implicits in Scala.
I would avoid using implicits in this case. You want 2 different implicit conversions which both provide a method of the same name (zip). I don't think this is possible. Also, if you import xml.Text, you can convert with just Text(str) which should be concise enough for anyone. If you must have this implicit conversion to xml.Node, I would pack the implicit def into an object and then import it only in the places where you need it to make your code readable and to, possibly, avoid conflicts where you also need to zip strings. But basically, I would very much avoid using implicits just to make convenient conversions.
Like #Felix wrote, it is generally a bad idea to define implicit conversions between similar data types, like the one you used. Doing that weakens type system, leads to ambiguities like you encountered and may produce extremely unclear ("magic") code which is very hard to analyze and debug.
Implicit conversions in Scala are mostly used to define lightweight, short-lived wrappers in order to enrich API of wrapped type. Implicit conversion that converts String into WrappedString falls into that category.
Twitter's Effective Scala has a section about this issue.
I want to come out a way to define a new method in some existing class in scala.
For example, I think the asInstanceOf[T] method has too long a name, I want to replace it with as[T].
A straight forward approach can be:
class WrappedAny(val a: Any) {
def as[T] = a.asInstanceOf[T]
}
implicit def wrappingAny(a: Any): WrappedAny = new WrappedAny(a)
Is there a more natural way with less code?
Also, a strange thing happens when I try this:
scala> class A
defined class A
scala> implicit def toA(x: Any): A = x
toA: (x: Any)A
scala> toA(1)
And the console hang. It seems that toA(Any) should not pass the type checking phase, and it can't when it's not implicit. And putting all the code into a external source code can produce the same problem. How did this happen? Is it a bug of the compiler(version 2.8.0)?
There's nothing technically wrong with your approach to pimping Any, although I think it's generally ill-advised. Likewise, there's a reason asInstanceOf and isInstanceOf are so verbosely named; it's to discourage you from using them! There's almost certainly a better, statically type-safe way to do whatever you're trying to do.
Regarding the example which causes your console to hang: the declared type of toA is Any => A, yet you've defined its result as x, which has type Any, not A. How can this possibly compile? Well, remember that when an apparent type error occurs, the compiler looks around for any available implicit conversions to resolve the problem. In this case, it needs an implicit conversion Any => A... and finds one: toA! So the reason toA type checks is because the compiler is implicitly redefining it as:
implicit def toA(x: Any): A = toA(x)
... which of course results in infinite recursion when you try to use it.
In your second example you are passing Any to a function that must return A. However it never returns A but the same Any you passed in. The compiler then tries to apply the implicit conversion which in turn does not return an A but Any, and so on.
If you define toA as not being implicit you get:
scala> def toA(x: Any): A = x
<console>:6: error: type mismatch;
found : Any
required: A
def toA(x: Any): A = x
^
As it happens, this has been discussed on Scala lists before. The pimp my class pattern is indeed a bit verbose for what it does, and, perhaps, there might be a way to clean the syntax without introducing new keywords.
The bit about new keywords is that one of Scala goals is to make the language scalable through libraries, instead of turning the language into a giant quilt of ideas that passed someone's criteria for "useful enough to add to the language" and, at the same time, making other ideas impossible because they weren't deemed useful and/or common enough.
Anyway, nothing so far has come up, and I haven't heard that there is any work in progress towards that goal. You are welcome to join the community through its mailing lists and contribute to its development.