Skip to content

Conversation

lihaoyi
Copy link
Contributor

@lihaoyi lihaoyi commented Oct 3, 2025

This PR is a proof-of-concept implementation porting over the Ammonite import $ivy functionality to the Scala REPL, using the Scala-CLI using dep syntax. Once this lands, along with other related PRs (#24127, #23849) we can probably deprecate Ammonite and refer people to the main Scala REPL since it'll have acquired all the important features

Tested manually:

$ JAVA_HOME=~/Library/Caches/Coursier/arc/https/cdn.azul.com/zulu/bin/zulu17.56.15-ca-jdk17.0.14-macosx_aarch64.tar.gz/zulu17.56.15-ca-jdk17.0.14-macosx_aarch64/ bin/scala
The `--offline` option is experimental
Please bear in mind that non-ideal user experience should be expected.
If you encounter any bugs or have feedback to share, make sure to reach out to the maintenance team at https://github.com/VirtusLab/scala-cli
Welcome to Scala 3.8.0-RC1-bin-SNAPSHOT-git-17e82e6 (17.0.14, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
                                                                                                                          
scala> import scalatags.Text.all._
-- [E006] Not Found Error: -----------------------------------------------------
1 |import scalatags.Text.all._
  |       ^^^^^^^^^
  |       Not found: scalatags
  |
  | longer explanation available when compiling with `-explain`
1 error found
                                                                                                                          
scala> //> using dep "com.lihaoyi::scalatags:0.13.1"
Resolved 1 dependencies (5 JARs)
                                                                                                                          
scala> import scalatags.Text.all._
                                                                                                                          
scala> div("hello world").render
val res0: String = "<div>hello world</div>"

Both io.get-coursier:interface and org.virtuslab:using_directives are zero-dependency Java libraries, and so can be used directly without worrying about binary compatibility. Both libraries are widely used in the Scala ecosystem (SBT, Mill, ScalaCLI, Bazel, ...) and should be pretty trustworthy and reliable

Not sure if we want to put this into the compiler codebase, but that's where the REPL logic currently lives, and I figure anyone working on the compiler may find it useful as well. e.g. You can pull in third-party libraries when working in the REPL to see how a new language feature interacts with an existing library.

We can move the logic out of the compiler codebase if we want, but as a first pass this integration seems relatively straightforward. The "correct" way of re-organizing this would be to split the dotty.tools.repl into a separate subproject from the rest of compiler so programmatic non-REPL use cases (e.g. build tools) don't need to pull it in, but that would be a larger refactor beyond the scope of this PR

// Update both compiler classpath and classloader
val prevOutputDir = ctx.settings.outputDir.value
val prevClassLoader = rendering.classLoader()
rendering.myClassLoader = DependencyResolver.addToCompilerClasspath(
Copy link
Member

Choose a reason for hiding this comment

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

just a nod to just a nod to #24119 which has sensitive state towards whatever the current classloader is.

@lihaoyi
Copy link
Contributor Author

lihaoyi commented Oct 3, 2025

The failure looks like a network flake

@hamzaremmal
Copy link
Member

hamzaremmal commented Oct 4, 2025

I think we should extract the repl to be its own artifact before accepting this change. @Gedochao lets add splitting the repl from the compiler to next week's core.

@Gedochao Gedochao added the stat:needs decision Some aspects of this issue need a decision from the maintainance team. label Oct 8, 2025
@Gedochao Gedochao requested review from tgodzik and Gedochao October 8, 2025 08:54
@SethTisue
Copy link
Member

It makes a great deal of architectural sense for the REPL to be its own artifact. The REPL is conceptually separate, and most consumers of the compiler don't consume the REPL. (Making the separation in Scala 2 was a long term goal of @adriaanm's that he did a great deal of work on, but we just never got it over the finish line.)

@Gedochao Gedochao removed the stat:needs decision Some aspects of this issue need a decision from the maintainance team. label Oct 8, 2025
@Gedochao
Copy link
Contributor

Gedochao commented Oct 8, 2025

We will explore making REPL its own artifact, in which case the approach from this PR could work.
It's also in the works whether we'd want to do it in 3.8 (for //> using dep to be available in the new 3.9 LTS later), or should this feature wait for 3.10.
@lihaoyi this may take us some time, we'll comment on this PR once a strategy gets established.
cc @WojciechMazur

@Gedochao Gedochao added the stat:needs decision Some aspects of this issue need a decision from the maintainance team. label Oct 8, 2025
@lihaoyi
Copy link
Contributor Author

lihaoyi commented Oct 8, 2025

Since this isn't a language feature, presumably we can introduce it anytime? It's only for interactive use so there's no backwards compatibility concerns

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stat:needs decision Some aspects of this issue need a decision from the maintainance team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants