I am fairly new to Scala so I apologize if this question seems trivial.
I am using Scala worksheets to evaluate some classes I've written, and it appears that the worksheet I am using does not evaluate the most recently compiled code.
For example,
I have a method which does the following:
def randomPermute(xs: List[Any]): List[Any] = {
randomSelect(xs.length, xs)
}
which, upon initial compilation and evaluation of a basic list, produced:
List('f, 'a, 'c, 'd, 'b, 'e)
However, after I changed this method to
def randomPermute(xs: List[Any]): List[Any] = {
//randomSelect(xs.length, xs)
Nil
}
Upon re-evaluating with the worksheet, I still get a random permutation of the list.
Is there a mistake I'm making in my project settings?
Do I just understand Scala incorrectly?
Note: I am using IntelliJ Idea CE 15
There's an open ticket for this in the bug tracker, it's been open since January without any comment from the devs, so I wouldn't hold my breath for a fix.
Link to the open issue
I'd like to point out that I created a new IntelliJ project and copied all of my files over manually. My new project worked fine with the worksheets. This implies that something artifactory/my project settings was messing with worksheet compilation.
If your project is relatively small it might be fine to just recreate the idea project
Related
This is a general question with a specific example.
How do people getting into scala and using it for big projects handle unreliability of tools/IDE? Do you just accept red markings all over your source code?
I encounter yet another scala codebase where working code is flagged red by idea Cannot resolve symbol Repr.
I start a playground project to explore one of libraries in the codebase - shapeless (as I understand it a highly regarded library in scala community).
I write extremely basic code from the first page of official shapeless guide.
package example
import shapeless._
object Hello extends App {
val genericEmployee = Generic[Employee].to(Employee("Dave", isOld = true))
val genericIceCream = Generic[IceCream].to(IceCream("yellow", isInCone = false))
def genericCsv (gen: String :: Boolean :: HNil) :List[String] = List(gen(0), gen(1).toString())
println(genericCsv(genericIceCream).toString())
}
case class Employee (name: String, isOld: Boolean)
case class IceCream (name: String, isInCone: Boolean)
gen(0) and gen(1) are flagged with No implicits found for parameter at hlist.At[String :: Boolean :: HNil, Nat#N]
The code works.
I also remember errors-but-not-real-errors being caused by Akka HTTP.
There seems to be a fundamental difficulty in IntelliJ supporting libraries relying on macros such as shapeless
#niktrop
Shapeless is heavily using macros. We have no way to support them
generically.
#joroKr21
there is a fundamental barrier for whitebox macros. You have to run a
complete typecheck and expand them just to see what type they return
and this is not feasible to do on every keystroke. Blackbox macros on
the other hand shouldn't pose such problems.
#olafurpg
scala-compiler and intellij-scala are different typecheckers,
scala-reflect macros are currently implemented against scala-compiler
APIs which makes them difficult to support in alternative scala
compilers.
You could try reporting highlighting errors as a bug at
https://youtrack.jetbrains.com/issues/SCL
Here is an example you could use as a template
https://youtrack.jetbrains.com/issue/SCL-16091
Select the affected subsystem as Error Highlighting
This feature is called Type-aware highlighting and can be disabled by clicking on the little T icon in bottom right corner
How to deal with false errors?
So, the truth is you have to remember that sometimes there’s no spoon
error. To help us to fix a highlighting glitch you may report it to
YouTrack as usual or by pressing Alt+Enter on wrong highlight:
I'm considering using cats library in my project to use its traverse/sequence feature on the list of Either. However, in Intellij IDEA, when I do Show type, I see a totally weird inferred type. At the same time, if I copy and paste this code into sbt console, I get nice and clean type. Here's example:
scala> :paste
// Entering paste mode (ctrl-D to finish)
import cats._, cats.syntax.traverse._, cats.std.all._
val xs: List[Either[String, Int]] = List(Right(1), Right(2))
val r = xs.sequenceU
// Exiting paste mode, now interpreting.
import cats._
import cats.syntax.traverse._
import cats.std.all._
xs: List[Either[String,Int]] = List(Right(1), Right(2))
r: scala.util.Either[String,List[Int]] = Right(List(1, 2))
As you can see, the variable r has a nice type: Either[String, List[Int]].
However, Intellij infers the following monster:
Unapply.Aux2Right[Applicative, Either[String, Int], Either, String, Int]#M[List[Unapply.Aux2Right[Applicative, Either[String, Int], Either, String, Int]#A]]
I don't want to inflict the pain of even seeing this type, left alone understanding it, on my colleagues, as it would drop my carma significantly. I've tried this with the latest Intellij 16.1 EAP and EAP build of Scala plugin, as well as with the stable versions of those, it's all the same.
I guess, there's nothing else I can do at this moment, but maybe, just maybe, there's some workaround for this?
P.S. Things like this (i.e. tooling support) slow down adoption of FP at least not less than FP's inherent conceptual complexity. :(
P.P.S. Issue in Intellij's tracker is here.
Apparently, the issue was fixed by Jetbrains. I've checked the nightly build 2.2.40 of Scala plugin here, and now Intellij infers the same type in the aforementioned case as REPL. Great job Jetbrains, and so quickly!
P.S. if you want to give it a try, add nightly repository to your plugins repositories list and check for updates. It's in Settings -> Plugins -> Browse repositories... -> Manage repositories..., then add the Scala plugin nightly repository: https://plugins.jetbrains.com/plugins/nightly/1347.
I'm using Breeze to to do sum simple linear algebra operations on dense matrices. I'm using the Intellij IDEA. Here is an snippet of my code:
import breeze.linalg._
val X1:DenseMatrix[Double] = DenseMatrix.zeros[Double](10, 5) + 1.0
val n1 : Double = X1.rows.toDouble
val one_tall_t1 = DenseMatrix.zeros[Double](1, n1.toInt) + 1.0
val mu1=one_tall_t1*X1/n1
In the last line, the symbols * and / are shown with red color in the IDE. The error message is "Cannot resolve the symbol *".
But Intellij builds the program without any errors, and it runs fine.
I've been trying to find out the reason: since I'm new to Scala, I'm not sure if it is because of Intellij, Breeze, or just my code. In some posts, people have suggested to invalidate cache and restart Intellij, but this does not solve my issue.
I appreciate your comments or solutions!
IntelliJ gets confused by complex implicit searches like those used in Breeze. I file bugs when I can minimize them and get around to it, but it's a slog. (Eclipse, for what it's worth, isn't much better.)
It typically works better if you're just depending on Breeze, not developing inside of it. I assume you're doing that already though.
If I create a Scala Worksheet in Eclipse as follows:
object negative {
2.toString //> res0: String = 2
(2).toString //> res1: String = 2
// compile error
(-2).toString
}
the final line causes a compile error:
';' expected but ')' found. illegal start of simple expression
However, the same three lines compile and run fine within a normal Scala source file.
Why does this not work in the worksheet?
This is using Eclipse 3.7.2, Scala IDE 3.0.0.v-2_10, Scala Worksheet 0.1.4.v-2_10
[Updated: this question originally used toBinaryString, but the problem occurs even with toString, so I have simplified it]
It is a bug. The code in the main object (the first one) of a worksheet is instrumented before being executed. In the 2 mentioned case, the result of the instrumentation is not valid Scala code.
But it is only a problem if the code is at the top level in the main object. If the code is moved to a function or a different object in the same file, it works fine.
Eclipse worksheets are quite beta; for example last I checked, it couldn't handle a #tailrec decoration on a function.
So this is most probably a bug or limitation in Eclipse. After all, the feature seems quite new, and there are many other bugs.
(-2).toBinaryString
gives same error for me.
Note that java.lang.Integer.toBinaryString(-2)works just fine.
Back when reflection was still incipient, on the days of Scala 2.10.0 milestones, I asked a question about how could I use it to see the trees of code snippets from REPL. The excellent answer went further than I asked, and showed how they can be used to parse and evaluate trees as well, so I went ahead and tried to use that on a little project I had going on today.
Unfortunately, code parsed and evaluated that way doesn't seem to see any REPL definition:
scala> val x = 1
x: Int = 1
scala> import scala.tools.reflect.ToolBox
import scala.tools.reflect.ToolBox
scala> val tb = scala.reflect.runtime.universe.runtimeMirror(
getClass.getClassLoader).mkToolBox()
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = ...
scala> tb.eval(tb.parse("x"))
scala.tools.reflect.ToolBoxError: reflective compilation has failed:
not found: value x
Is there a way to get it to recognize definitions made on REPL?
Recently I dug into repl, when trying to make it support type macros, so I'm well equipped to explain why it doesn't work. Getting it to work would be the next step :)
I know that you know that every snippet entered into repl gets wrapped into some boilerplate before being compiled. Therefore that x ends up being a field in a nested-nested-nested object in a package with a weird name.
Apparently, repl keeps track of all defined symbols and then injects the necessary imports along with the boilerplate it generates. Therefore subsequent lines can see that x unqualified. To the contrast, toolboxes simply reuse repl's classloader, but don't do anything about the imports, hence the failure.
A workaround would be to somehow get to an object representing a repl, ask it about defined symbols and then generate corresponding imports into the code that you feed to a toolbox. If you file a ticket, I'll try to code up a workaround after the 2.10.1 code freeze madness ends (supposedly, end of this week).