How to stop printing the results of expressions in REPL

Hi there,

I am not sure if the question is asked before. I wonder if there is a way to control SBT’s console to stop automatically printing the results of expressions.

Typically, when I have a List with thousands of elements from some expressions, the console (REPL) usually take some time to print the results until targetting the output limitations. I hope to stop this behavior.

After searching on the internet, some people mentioned that :power mode under console, but I did not have that (my SBT version is 1.10.0). Others mentioned the scalacOptions += "-Dscala.repl.maxprintstring=0". I put it in build.sbt, but does not affect the behaviors in SBT console.

Thanks!

Welcome.

The REPL is not a good choice for such large computations. Don’t use the REPL for this. The REPL is for quick small experimentation. You can write scripts to output results to a text file instead.

On the REPL, you can prefer using lazy val or LazyList, and use .take(...) method to print only a section of it.

scala> lazy val x = (for i <- 0 until 1_000_000 yield i).toList
lazy val x: List[Int]
                                                                                                                        
scala> x.take(10)
val res0: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
                                                                                                                        
scala> x.drop(100).take(10)
val res1: List[Int] = List(100, 101, 102, 103, 104, 105, 106, 107, 108, 109)

It’s possible that Ammonite REPL has better options for suppressing printing, not sure. Worth checking out.

2 Likes

Thank you!
I am now trying to see if I can use Scala for some regular jobs I can do in R / Python. I can give Ammonite REPL a try later.

It seems you saw some incorrect instructions. 0 here means “no limit”, which is the opposite of what you wanted.

Also, for setting a Java system property, scalacOptions is too late — the JVM has already started. You need to put it in a .jvmopts file:

% echo '-Dscala.repl.maxprintstring=200' > .jvmopts
% sbt
[warn] No sbt.version set in project/build.properties, base directory: /Users/tisue/tmp/20240621
[info] welcome to sbt 1.10.0 (Eclipse Adoptium Java 17.0.11)
[info] set current project to root-20240621 (in build file:/Users/tisue/tmp/20240621/)
[info] sbt server started at local:///Users/tisue/.sbt/1.0/server/9077db0b2bee7d6b8bab/sock
[info] started sbt server
sbt:root-20240621> console
[info] Starting scala interpreter...
Welcome to Scala 2.12.19 (OpenJDK 64-Bit Server VM, Java 17.0.11).
Type in expressions for evaluation. Or try :help.

scala> List.range(0, 1000)
res0: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39...

But I think only the Scala 2 REPL respects scala.repl.maxprintstring, Scala 3 doesn’t seem to.

1 Like

A worksheet or a scala-cli script may be better suite for that than the bare REPL.

I suggest you tale a look at https://almond.sh/ and Home - Polynote. Because Scala works on the JVM, Jupyter for Java · GitHub may also be of interest.

HTHs

1 Like

Doing it programmatically used to be easier, but in 2.13

Welcome to Scala 2.13.14 (OpenJDK 64-Bit Server VM, Java 21.0.2).
Type in expressions for evaluation. Or try :help.

scala> $intp
val res0: scala.tools.nsc.interpreter.Repl = scala.tools.nsc.interpreter.IMain@2b2954e1

scala> $intp.reporter
val res1: scala.tools.nsc.interpreter.ReplReporter = scala.tools.nsc.interpreter.shell.ReplReporterImpl@576b7c74

scala> $intp.reporter.asInstanceOf[scala.tools.nsc.interpreter.shell.ReplReporterImpl].maxPrintString = 100
// mutated $intp.reporter.asInstanceOf[scala.tools.nsc.interpreter.shell.ReplReporterImpl].maxPri...

scala> 1.to(1000).toList
val res2: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1...

scala>

I noticed the string length includes formatting.

Also, the “max elements” is pegged at 1000, so

scala> 1.to(10000).toList
val res1: List[Int] = List(1, 2, [snip], 998, 999, 1000)

where -Dscala.repl.maxprintstring=0

1 Like

Thank you! I am pretty new to both Java and Scala.
I am now using Scala 3.3.3 (since it’s long-term maintained). But certainly can try Scala 2.

BTW, why Scala 3 removes the features in REPL instead of keeping it? I previously thought this was the SBT version problem.

wow, they are cool. I run Scala in our server through terminal, so is lack of plotting support. I think the Jupyter-like features the provide will be a plus.

Thanks! Yes, when I use Scala 3 and SBT 1.10, I did not see $intp.

Do you mean Scala-cli can provide better interactive mode than SBT REPL? I am thinking to use Scala with interactive mode for some simple data statistics as I did in R. With both the sbt-mode and Scala-mode support, I can use Scala quite like R in my Emacs environment.

I know this might be not a good way. I see others mentioned Jupyter-like worksheet, which might be better than bare REPL.

Do you mean Scala-cli can provide better interactive mode than SBT REPL

No, you get the same REPL either way.

why Scala 3 removes the features in REPL instead of keeping it?

The Scala 3 REPL is a fresh implementation, because the REPL and the compiler are so intertwined and the Scala 3 compiler is entirely new code. I don’t think anything truly important is missing, but some minor/obscure things are.

Thanks! Now I use lazy, which works pretty good.
The function with parameters not in the same line cannot be recognized well, so I now write a function with a long line for the parameters. Except this, everything seems great!