Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve REPL display of method types #8319

Merged
merged 1 commit into from Sep 26, 2019
Merged

Conversation

bishabosha
Copy link
Member

@bishabosha bishabosha commented Aug 7, 2019

The following examples are implemented, my main question is should methodTypeAsDef stay in the IMain class or go elsewhere - it currently computes the type String as if it will be appended to a method name.

Current behaviour:

val/var

scala> lazy val x = ""
lazy val x: String // unevaluated

scala> val (a, b) = (true, false)
val a: Boolean = true
val b: Boolean = false

scala> var mut = 0
var mut: Int = 0

scala> mut = 1
// mutated mut

def/macro

scala> def foo = ""
def foo: String

scala> def foo[T: ClassTag, A: ClassTag](x: T): String = x.toString
def foo[T, A](x: T)(implicit evidence$1: ClassTag[T], evidence$2: ClassTag[A]): String

scala> def m(x: => Int): Int = macro ???
def m(x: => Int): Int

definitions - I'd prefer to comment // defined class A to make it clear information is lost

scala> object A
object A

scala> trait B
trait B

scala> class C
class C

scala> type D = Unit
type D

Fixes scala/bug#10024

@scala-jenkins scala-jenkins added this to the 2.13.1 milestone Aug 7, 2019
Copy link
Member

@hrhino hrhino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly bikeshedding, but that's the nature of the bug.

Thanks for taking this on!

@bishabosha
Copy link
Member Author

bishabosha commented Aug 7, 2019

also it would be quite good if printedName from scala.reflect.internal.Printers.CodePrinter could be lifted elsewhere, as it decodes names and restores backticks if necessary.

protected def printedName(name: Name, decoded: Boolean = true) = {
  import Chars._
  val decName = name.decoded
  val bslash = '\\'
  val isDot = (x: Char) => x == '.'
  val brackets = List('[',']','(',')','{','}')

  def addBackquotes(s: String) =
    if (decoded && (decName.exists(ch => brackets.contains(ch) || isWhitespace(ch) || isDot(ch)) ||
      (name.isOperatorName && decName.exists(isOperatorPart) && decName.exists(isScalaLetter) && !decName.contains(bslash))))
      s"`$s`" else s

  if (name == nme.CONSTRUCTOR) "this"
  else addBackquotes(quotedName(name, decoded))
}

if (mods.isLazy) codegenln(false, "<lazy>")
else any2stringOf(path, maxStringElements)
if (mods.isLazy) """"""""
else """" = " + """ + any2stringOf(path, maxStringElements)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love the cartoon quality of the long eyebrow, but maybe these lines could be clearer? Anything that doesn't entail counting quotes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I can't tell by looking if it helps me understand what lazy val i = 27 means.

Copy link
Member Author

@bishabosha bishabosha Aug 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've cleaned up the quotes, but right now the repl would print

scala> lazy val i = 27
lazy val i: Int

scala> 

is = <lazy> noise or useful?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

= ???, perhaps

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about

scala> lazy val x = 0
lazy val x: Int // unevaluated

Copy link
Member Author

@bishabosha bishabosha Aug 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

= ???, perhaps

I'm concerned with triple question mark as a beginner could see that as the value in Predef and be confused.

@som-snytt
Copy link
Contributor

This is more like what people ask for ("something I can cut/paste"), but I'm not sure about output for class C. Maybe I'd also miss the sense of "running commentary" like in "// mutated x", such as "defined macro m".

Just speculating, but what if class C -> class C extends AnyRef, that is, fill in the missing parts. Why doesn't class C { def i = 42 } say

class C extends AnyRef {
  def i: Int = 42
}

@bishabosha
Copy link
Member Author

But then if there are too many members to a definition wouldn’t that be polluting to print them out?

@som-snytt
Copy link
Contributor

For things like highlighting lazy or verbose class printing, I'm thinking of the beginner use case. I don't have an answer, but I've often thought that beginner mode would be useful. I assumed that printing "val i" so it looks like code was also a beginner feature.

Also, the jalapeno bagel at the office this morning is really hot, so I have to go get some water now.

@adriaanm
Copy link
Contributor

adriaanm commented Sep 5, 2019

Very nice work! I think it's best to omit members from class definitions and generally the right-hand side of definitions. I like that everything echo'ed is valid syntax. We already have a way to print the tree after type checking (add // print at the end of a line and hit tab). Maybe we could make that more easily discoverable? (For example, add // members omitted, use :print to show in full)

@bishabosha
Copy link
Member Author

bishabosha commented Sep 5, 2019

// members omitted, use :print to show in full

I can't see an option to :print in the :help, is this something new?,

edit: or most likely you mean make a new Issue for it 😀

@adriaanm
Copy link
Contributor

adriaanm commented Sep 5, 2019

Sorry, it's not there yet. I meant we could make the secret // print <TAB> feature more public with a :print command that exposes its functionality and prints a fully desugared & type checked version of the last line.

@adriaanm
Copy link
Contributor

adriaanm commented Sep 5, 2019

Also, this could definitely be left for a follow-up PR.

@som-snytt
Copy link
Contributor

For future ref, I was futzing with repl recently and I thought verbose print could be a mode. print-tab is handy but going into print mode, I can try out a few things and just see it printed verbosely. It could also be a regular setting, :se -Vrepl for verbose repl.

@SethTisue
Copy link
Member

// members omitted, use :print to show in full

(It seems like more noise/annoyance than benefit to me. Separate PR, please, if someone still wants to do it.)

@som-snytt
Copy link
Contributor

// ask @SethTisue to explain this to you

@SethTisue SethTisue modified the milestones: 2.13.1, 2.13.2 Sep 9, 2019
@SethTisue
Copy link
Member

needs rebase (probably very minor)

I suggest we push this to 2.13.2

ValDef repl output is source compatible

Side effecting repl output is source compatible

Method definition repl output is source compatible

Lazy val repl output is source compatible

REPL print remove comments from definitions, print macro as def

also removed `= <method>` from def and `= <lazy>` from lazy val
refactored implementation of withoutImplicit

REPL print restore string2code use for types of valdefs

REPL print, refactor quoted strings

revert partest run/t7455 check for JDK 8

REPL print, add unevaluated comment to lazy val
@bishabosha
Copy link
Member Author

Squashed and rebased

@lrytz
Copy link
Member

lrytz commented Sep 26, 2019

Very nice, thanks @bishabosha!

@lrytz lrytz merged commit 59dec61 into scala:2.13.x Sep 26, 2019
@SethTisue SethTisue added the release-notes worth highlighting in next release notes label Sep 26, 2019
@dwijnand
Copy link
Member

dwijnand commented Feb 6, 2020

This is awesome. Thanks, @bishabosha!

@SethTisue SethTisue changed the title Improve REPL display - Fixes scala/bug#10024 Improve REPL display of method types Feb 11, 2020
@SethTisue SethTisue added the tool:REPL Changes in the Scala REPL Interpreter label Jul 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release-notes worth highlighting in next release notes tool:REPL Changes in the Scala REPL Interpreter
Projects
None yet
8 participants