According to "Programming in Scala" one can pass the argument -Xprint:typer to the compiler and gets the code back as it looks after all the implicites are actually applied.
I also found that I can set compiler arguments in the project properties.
But I can't find any resulting output anywhere ...
So where do I have to look?
If you start Eclipse from a console, you should see the printed output there.
With the Scala IDE 2.1 Milestone 1 you can press Ctrl-1 to make implicits explicit
From http://scala-ide.org/download/milestone.html#scala_ide_21_milestone_1
Highlight Implicits It has never been easier to know where implicits
are applied. And, by pressing Cmd/Ctrl+1, turn an implicit conversion
into an explicit call!
Related
Most of the time, all you get is an implicit not found error. You don't know where in the chain of implicit construction it failed. Apparently you can't use runtime debug or print statement. So how do you debug type-level program other than staring at your code really hard?
I wish I had a better answer, but here it goes: Start passing the parameters explicitly, one at a time until it gives you a more useful error. (adding-prinlns-equivalent for implicits params)
You can use ??? for undefined code parts (because it have bottom type Nothing) and _ for unknown types. Also see -Ytyper-debug compiler option (more options here: https://docs.scala-lang.org/overviews/compiler-options/index.html). According to problem with implicit parameters and wrappers, "Idea" has nice feature "Show Implicit Hints" and "Implicit Arguments" (Main menu > Help > Find Action... and type e.g. implicit). Also, you can use Null bottom type instance null for AnyRef like null: YourTypeHere.
I am using slick's for expression, and seeing some strangeness in terms of intellij's inferred type. Here are the unexpected result:
Why in the second case, it is not Query[Int, Int] but instead becomes Query[Nothing, Nothing]. I seem to lose some type information.
What's to say? IDEA has it's own parser and typer and it is not that hard to confuse it. If you care about fidelity between your IDE and the Scala compiler, the Scala IDE (which runs in Eclipse) would be better for you.
Personally, I dislike Eclipse more than I do the vagaries of the IDEA Scala plug-in.
At the moment, I type in type annotations for public vals, vars and defs in my Scala classes, traits and objects[1] - either by inferring the types of them mentally, or occasionally by hovering over the identifier in Eclipse to find out what the presentation compiler thinks the type should be[2]. How can I conveniently add these type annotations automatically?
The purpose of adding in explicit types is to "lock in" the type of a public member of a template, so that if a developer changes the definition of the member in future in a way that results in an incompatible type, they will get a compile-time error unless they deliberately change the type annotation as well.
Footnotes:
[1] except if they override a member in a supertype and the type should be the same as the type of the overridden member, which is usually the case for overrides in my code.
[2] This isn't always correct; the presentation compiler seems to be weak when it comes to members that override members in supertypes.
This has been implemented in the Scala IDE in Kepler Eclipse 4.3 update.
Use ctrl/cmd-1 on the identifier and choose "Add explicit type ...".
See here.
For those who use IDEA on Mac, the following works:
⌥ (Alt) + return
That is, press and hold Alt and hit return/enter.
Then select "Add type annotation to value definition".
There is a feature request for a quick fix to insert inferred type in declarations (scala-ide#1433), but there has not been any contributions on it yet.
This is not direct solution to your problem, but if you unit test those functions then your tests will "enforce" return types and will break when someone changes return types.
For example, in specs2 it could look something like:
foo(arg1) must be equalTo Success
Another partial solution is the scalastyle SBT plugin (http://www.scalastyle.org/rules-0.2.0.html) which can warn you about public members with inferred types.
In Eclipse: Hover over the identifier, click to expand the hover, triple-click to select all, Ctrl+C (or Cmd+C) to copy, click on the code to remove the hover, click back to where you were, Ctrl+V to paste, then finally delete all the wrong/over-verbose/redundant stuff.
It'd probably be quicker to just type in the correct type.
Does anyone have a better way?
Using IDEA Intellij 15: File menu > Settings > Editor > Intentions
Minimize the Intentions and select Scala > Type and make sure that "Toggle Type Annotation" is checked.
Then when you select a (variable or function) definition and hit Alt+[Enter] it asks you if you want to insert the inferred type - hit [carriage-return] to do so.
I know that's 2 key-strokes, but it's still better than selecting, copying and pasting.
I am writing a macro in Scala, but when I call it I get an error message saying "Double does not take parameters". Clearly there is something wrong with how the macro builds the AST. So how can I see the expanded macro? Is there a way to call the macro implementation at runtime?
Provide -Ymacro-debug-lite or -Ymacro-debug-verbose option to the compiler.
Off the top of my head, detalization of printed ASTs is governed by -Yshow-trees-compact, -Yshow-trees-stringified, -Xprint-types, -uniqid and -Yshow-symkinds. You can find other gems by running scala -X and scala -Y (or inspecting the sources of scala settings at https://github.com/scala/scala/blob/2.10.x/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala).
Also, despite being essentially a macro, reification has its own tracing mechanism that can be configured by -Yreify-copypaste and -Yreify-debug.
There is Macrocosm's desugar which can show how your source code, including, but no limited to macros, is transformed into.
println("TRANSFORMATION:\n"+ desugar{
println("a string")
MY_MACRO("something")
})
How can I see the types inferred by the Scala compiler for expressions etc.? I have some code with complicated type inference and implicit conversions, and it's hard to see what's going on just by reading the code.
I've tried adding
scalacOptions in Compile += "-Xprint-types"
in build.sbt, but this has no effect.
Using scalac directly isn't very appealing because I have lots of dependencies.
I use the Eclipse Scala plugin and ENSIME to write code, and SBT to build.
It needs to be
scalacOptions in Compile ++= Seq("-Xprint-types", "-Xprint:typer")
instead.
Unfortunately the output isn't very readable. :(
This exact feature has been added in Eclipse Scala IDE 3.0!
Select any portion of code and press Ctrl-Shift-W T (replacing Ctrl by Cmd on Mac) to see the inferred type.
Hoist the expression to a non-local def or val, without an explicit type - then it will appear in the Outline view in Eclipse, with an inferred type assigned.
However, this isn't an ideal solution because it requires some work, and it can't be used when recursion is involved.