Pre SIP: scala-cli as new scala command

I agree that the rumor of Scala’s install difficulties is exaggerated. When I show them scala-cli they get impressed and some of them changes their mind…

I give my students an sbt file

Yes that’s an option, but still they need to install one more thing if they want several terminals with the REPL in one window separate from sbt. think the scala-cli “not another a build tool”-approach with one swiss army knife for repl, compile and run including dependency management is the smoothest for a learner.

Ideally, I think it should be called just scala and not the longish and, to a beginner somewhat cryptic, scala-cli

2 Likes

Absolutely agree @soronpo!

I actually raised a similar issue earlier. Windows & Scala 3 UX - consistency · Issue #12550 · lampepfl/dotty · GitHub

Thanks @som-snytt for referencing this discussion.

Another major hurdle to Scala adoption is that SBT plug-ins do not work out of the box with Artifactory in enterprise environments due to not following POM consistency (more detail - The maven pattern for sbt plugins is invalid based on the spec · Issue #3410 · sbt/sbt (github.com)). It’s nice in the open source/academic world that you have direct access to Maven Central, but in large scale enterprises, they cannot afford to give that level of unrestricted access due to severe security challenges (, so place everything behind a proxy which works fine for standard Maven artifacts.

Having worked in several large-scale enterprises (think >10k developers alone), I see a very clear pattern of Scala abandonment entirely because SBT cannot work there. Scala is not that fun to use in Gradle or Maven, and the standard docs are all showing how to get your magic dust with SBT. It’s not that it is demanding, it is actually painstakingly difficult to make it work consistently (3 sets of credentials and repository settings and SBT settings to set up). I massively love SBT (having written articles like Essential SBT) and it is very sad.

While I have not checked out scala-cli in detail, to make it official, it would definitely not hurt to consider 2 aspects:

  • to reuse existing Maven settings.xml (credentials/proxy/repo definitions) in fetching artifacts
  • ensuring scala-cli can itself be downloaded via Maven (so you can even fetch it with mvn dependency commands)
2 Likes

the Rust download page duplicates some content from their getting started page, which is very similar to our own (minus style)

Getting started - Rust Programming Language

do you think its also a problem that the Rust getting started page recommends their online playground first?

That’s a different thing than what happens on scala-lang.org. When you search scala download in search engine it takes you to the Scala download which directs to the getting started page, which is not a download page. The rust download page is a download page.

If a user searches for “getting started with Scala”, then fine, give them other options than downloading. But if they search for download scala, give them the option to download Scala. And in any case, even the getting-started of rust is much clearer than the Scala one.

2 Likes

SBT plug-ins do not work out of the box with Artifactory in enterprise environments due to not following POM consistency

In my experience, in the corporate environments that I’ve been to, sbt worked well. But the Artifactory/Nexus instance admins had to disable the strict consistency check. Then everything worked well.

  • ensuring scala-cli can itself be downloaded via Maven

This is an important point! scala-cli developers, please make note of this. It can be very important for some people in some specific circumstances to be able to download scala-cli via Maven Central (or through an internal corporate Artifactory/Nexus proxy).

2 Likes

Speaking about scala-cli configuration, Configuration | Scala CLI, this seems unfeasible and un-scalable to me for any codebase larger than a HelloWorld, would it be possible to read and aggregate directives bottom-to-top from the scala.conf files? This way we could e.g. define the scala version in the root folder, and main and test library dependencies on the sub-folder level.

Using directives are aggregated from across all the files provided, so it would be perfectly fine to define a config.scala top level and config.scala in main and test directories. However, since tests inherits config from main (so no need to define a Scala version in both) I would suggest having conf.scala and conf.test.scala top level with all configuration.

Using directives has a dedicated guide and hopefully, it will explain a bit more. In case of any further questions, we have both Discord channel and Github discussions to explain, help or discuss changes and suggestions.

I have opened a SIP PR here.

2 Likes

I don’t know if this helps anything, but I’ve been (slowly) writing some new Scala 3 books, and Scala-CLI is a terrific tool for books, especially intro books. It’s so nice to be able to tell the novice Scala user to just install one tool and then you can run .scala files, .sc files, and include third-party libraries:

//> using scala "3"
//> using lib "com.softwaremill.sttp.client3::core::3.7.2"

import sttp.client3.*

@main
def doPost() = 
    val backend = HttpURLConnectionBackend()
    val response = basicRequest
        .body("Hello, world!")
        .post(uri"https://httpbin.org/post?hello=world")
        .send(backend)
    println(response)

Running a simple command like this:

$ scala-cli Post.scala

is so much better than having to explain sbt or Mill to a new developer whose brain is probably already swimming, especially when they just want to run one file that happens to require dependencies.

(But I also understand that I just look at things from the “book writing” and “introducing new developers to Scala” use cases.)

15 Likes

That use case is for sure important when it comes to Scala adoption and the long term growth of our community.

4 Likes

There is a revived discussion on the syntax of what follows the //> directives marker in scala-cli here:

If you have views on this, you are very welcome to contribute to the discussion there.

3 Likes

Hello Contributors!

We are discussing the directives syntax after the magic comment //> related to SIP-46 in this discussion and I would like to summarize the discussion here to get your feedback.

Problem and trade-off

A. The current keyword using in directives after //> overlaps with the Scala keyword, while having another different meaning.

B. Changing the keyword now affects tooling and people’s code but changing it after that SIP-46 is elevated from “experimental” to “stable” may be even worse. Depending on how fast the decision process connected to SIP-46 is governed, we may risk a delay in introducing scala-cli as the new Scala.

Proposed solution

Change the keyword using to use in directives for scala-cli after //> and allow for a “grace-period” when the old keyword still works and deprecation warnings are given etc.

Questions to you

  1. Do you think we should change the keyword using to something else to avoid the overlap with Scala’s using?

  2. Are you fine with use as keyword instead of using after //> ?

By this post I risk opening up to “eternal bike-shedding”, as what is the “best” keyword is a subjective matter. What we can say more objectively is that we want it short and that it should not overlap with other keywords, and the proposed use instead of using fulfills that.

If we can settle on the use keyword fast, while agreeing that the change solves a real problem, there does not have to be much of a delay.

5 Likes

+1 for use

4 Likes

In my opinion using is perfectly fine here and the similarity to the Scala 3 using was an added bonus, which is why it was specifically chosen. It does set the context for running the program. Besides, it has a lot of adoption already in docs and scripts.

I would love to hear exact reason on why it would be wrong to use using.

Some that I can think of don’t really convince me:

  • it will be harder to google → neither use nor using is particularly good at that and I am not convinced first thing a beginner would do is to google using Scala
  • harder to communicate → one would be using directive and the other just using or really most of times they would say using keyword

I can’t really find any solid objective arguments and I think in the long run this will make no difference.

5 Likes

The objective argument is that context of a build and implicit arguments are different things. If that is “solid” is what is debated here :slight_smile:

What do others think? Is it a big deal or not to keep the using while some think it might be confusing to mix up the configuration of the build with arguments to functions?

I’m on the fence myself: on one hand I can live with using on the other hand I think use is more direct and I like that we don’t overload meanings.

(The aim of this thread now is to provide input to the SIP meeting on March 17.)

I think using is fine. Both the implicit using and the comment using record an assumption about the context in which the computation runs. So they are quite analogous from that point of view.

1 Like

If we already have a special comment syntax //> do we need an additional using or use keyword at all? Why not just something like below? Presumably the //> syntax is enough of a marker to discriminate between directives and normal user commentw

//> scala 2
//> options -Xfatal-warnings
//> dep com.lihaoyi::upickle:2.0.0
12 Likes

It ought to say given instead, as it is defining values instead of receiving them

//> given scala 3

By contrast, to consume whatever scala version is provided implicitly,

//> using scala

which could complain that no scala config was provided anywhere.

If there is load or call syntax,

//> load myscript.scala using scala 3
3 Likes

using sounds fine. If the worry is about using using in more than one way, we already have _ doing that. That doesn’t seem to be a big source of confusion.

But I like @lihaoyi’s suggestions to use //>

One other thing I would strongly recommend considering is using a more standard metadata format. What ScalaCLI is doing isn’t so special that it needs an entirely new language made for it. YAML or TOML would be well suited and there is plenty of precedence using it in tooling e.g. YAML frontmatter for Markdown files or TOML config in Rust.

Using a more common language would simplify onboarding of experienced developers, simplify tooling support, avoid the typical problems that appear in ad-hoc languages, and simplify any programmatic queries or transformations that someone may want to perform on their scala directives across their codebase (e.g. bumping dependencies like scala-steward does)

8 Likes