Skip to content

REPL: uppercase strings have different colors than lowercase #1681

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

Closed
rethab opened this issue Nov 7, 2016 · 10 comments
Closed

REPL: uppercase strings have different colors than lowercase #1681

rethab opened this issue Nov 7, 2016 · 10 comments

Comments

@rethab
Copy link
Contributor

rethab commented Nov 7, 2016

scala> "lowercase"
res16: String = lowercase
scala> "UPPERCASE"
res17: String = UPPERCASE
scala> "lower UPPER lower"
res18: String = lower UPPER lower

2016-11-07_414x156

@smarter
Copy link
Member

smarter commented Nov 7, 2016

I think the correct thing to do here is to print the string with " around it, as a bonus this means that the output of the repl is valid Scala, but it also means that we have to escape our output, e.g.

scala> "\""
res0: String = " // Currently
res0: String = "\"" // Proposed behavior

I think that's a trade-off worth making

@liufengyun
Copy link
Contributor

Thanks for reporting @rethab . @felixmulder can you have a look at this one?

@felixmulder
Copy link
Contributor

felixmulder commented Nov 9, 2016

I believe my time is best spent elsewhere at the moment. The issue stems from how we render results. The main culprit is resultExtractor, which needs to be changed.

This method needs to correctly render strings. But there are a number of issues/questions that will arise when somebody starts to look at this:

  1. Should I just render strings differently?
  2. What about higher kinded types containing strings? List[String]?
  3. How do I deal with multiline strings? Do I escape newlines there?

I think the issue needs to clarify these three points before somebody starts working on this. After that I think that it is an excellent entry-level task that could be handled by outside contributors.

@Blaisorblade
Copy link
Contributor

Regarding 1. and 2., you indeed want to print values as valid Scala, and toString simply can't do that. You don't even need parametric types like List[String], a case class containing String is enough.

scala> case class A(a: String); A("hi there")
defined class A
res0: A = A(hi there)

Maybe there's some local REPL-only solution, but the wider issue remains.

Indeed, many languages with REPLs (say Haskell or Lisps) distinguish how the REPL shows values as expressions (say Haskell Show or Racket print) from how to present values to users (Haskell has putStr for string output, Lisp has display). Scala lacks a Show typeclass.

If you want an existing solution to this (and other problems), there's among others @lihaoyi's PPrint which was born for his Ammonite REPL (and I imagine there are other ports inspired by Haskell's Show). @lihaoyi do you have recommendations?

http://www.lihaoyi.com/upickle-pprint/pprint/

@felixmulder
Copy link
Contributor

Just an FYI, since this is a compiler that needs to bootstrap we can't and don't want to have external dependencies on scala 2 artefacts. There are a couple that are a necessary for the time being (scala-library-2.11.5 and friends) but they will be removed eventually.

We have previously talked about revamping case classes. Perhaps a show/print typeclass could be added in the same go... (On mobile now so hard to link, could you comment there?)

I would love it if we could add a typeclass like you suggest.

@Blaisorblade
Copy link
Contributor

We have previously talked about revamping case classes. Perhaps a show/print typeclass could be added in the same go... (On mobile now so hard to link, could you comment there?)

Right—toString was discussed in #1341, and that ends up leading to issue #1347 on generic programming. In fact a PPrint typeclass is a separate matter since generic programming is just one implementation technique, but it's certainly in scope. So better pretty-printing should wait for that.

Maybe there's space for some specific fix to the original issue, but it might not be worth it.
If that's the plan, the exp:novice label should probably be replaced 😉

@lihaoyi
Copy link
Contributor

lihaoyi commented Nov 10, 2016

com.lihaoyi::pprint definitely works, but it's typeclass derivation is incredibly flaky. Maybe you can try short term, but long term you probably want a more robust solution.

One approach would be to try and replace pprint's typeclass derivation with Shapeless, which I heard (?) is pretty robust. Another is to dump the derivation altogether and go with runtime reflection, which is great (tho doesn't work on Scala.js)

But yes, the output of the REPL should be properly quoted and valid Scala, as far as is possible. Collections, case classes, strings, whatever. You are not going to be able to fix the toString of java.lang.Strings or java Arrays to make them print properly quoted, so you'd need some place to register handlers for the various types. Whether the registration is via implicit-resolution or runtime reflection

@Blaisorblade
Copy link
Contributor

Maybe you can try short term, but long term you probably want a more robust solution

What I wrote is misleading so let me clarify. Felix had good questions on printer design, and to answer those one might want to start from your library design, regardless of how much code can be reused. Among other things, dotty doesn't support current macros (though it'll support scala.meta) or current shapeless. For the derivation mechanism let's look at #1347.

@lihaoyi
Copy link
Contributor

lihaoyi commented Nov 10, 2016

Oh ok. I think all the non-derivation parts of the library are great:

  • The code to pretty-print strings, collections, primitives, case clases
  • That the printer returns an Iterator[String] instead of a plain String (though maybe it should return a geny.Generator at some point)
  • The code formatting things single/multi-line
  • Colors

All that stuff is nice :) and there to use. If we could hook it up to some non-gnarly derivation mechanism we'd be all set

@felixmulder
Copy link
Contributor

Closed via #1761

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants