Open phdoerfler opened 3 years ago
Thanks for reporting! I think this might be cool to implement, especially to support Futures etc. This would need to be done in https://github.com/scalameta/mdoc
Thank you for reporting! I think this is an interesting proposal and it's technically possible to implement this. The biggest open question IMO is how to display the values of expressions that evaluate multiple times
@phdoerfler can you provide a concrete example of how the decorations should look like inside for comprehensions?
Since there's only limited space available, I'd pragmatically only output those values for the first element of the collection. I could see how it might be useful to produce a table with the intermediate results of all or the first "few" elements of the collection, but one thing at a time.
I think we should aim for a complete solution from the start. If only the first value is displayed to begin with, I suspect many users will quickly report feature requests to display more values. If we change it to display multiple values then some people will ask for a configuration setting to only display the first value "like it used to work before".
Down the road, I imagine that we can extend the same solution to support more constructs than for comprehensions. For example, for local variables inside methods and lambdas
def increment(i: Int): Int = {
val result = i + 1 // : Int = 11, 12
result
}
increment(10)
increment(11)
List(1, 2).map { i =>
val j = i + 2 // : Int 3, 4
j
}
I think it makes sense to try and think of other syntaxes where the same functionality would be useful.
https://github.com/eed3si9n/expecty does something smart about expressions to capture intermediate values - maybe mdoc could apply some of that for this?
Apple Swift Playgrounds might also be a source of inspiration.
Relation to a Problem
When I mess with collections I usually start with
lines.map(...)
which slowly turns intolines.map(...).map(_.map(...))
etc. at which point I decide: This should really be a for comprehension!So I start all over again to rewrite it as one. This has one big drawback (1): I get very little support from Metals along the way. Here's a particularly messy comprehension: Maybe you can already feel the pain that was writing this comprehension.
Metals only shows the end result. IF it compiles. And that is a big if: More often than not it doesn't because of some mistake somewhere inside the for comprehension.
Had I stuck with my original messy chain of nested
map
,flatMap
andfilter
I could easily rearrange it to see the results of the individual transformation steps aiding in figuring out where it went wrong. (2)(1) Actually, two: Ideally there was a refactoring for converting a chain of
map
and friends into a for loop and vice versa. But that's a (user) story for another time.Preferred Solution
Just like Metals, in worksheet mode, evaluates lines with statements and annotates them with their value, I want Metals to do the same inside for comprehensions. Since there's only limited space available, I'd pragmatically only output those values for the first element of the collection. I could see how it might be useful to produce a table with the intermediate results of all or the first "few" elements of the collection, but one thing at a time.
Alternatives I have considered
A more tedious solution to this problem would be a refactoring as described in (2) and then a manual rearrangement.
Search Terms
scala for comprehension inspection mdoc metals visual studio code worksheet