Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Scala 3  Module 1 – Start here: Scala 3.9 LTS on the JVM

First programs: scala run, scripts and the REPL

Write an @main program with typed arguments, run it and a .sc script with scala run, try code in the REPL, and see what the compile server does.

  • Beginner
  • 15 minutes
  • Examples run with scala 3.9.0, Java 25.0.4.1 and Python 3.14.8
  • By MySmartCoPilot
Free lesson, Pro answers: 15 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

What you will learn

  • Write an @main program and pass it typed arguments with scala run . -- and the arguments
  • Predict what an @main program does with an argument that does not parse, a missing one and an extra one
  • Run a .sc script that reads its arguments from args, and decide when code belongs in .scala files
  • Use the REPL to try expressions and read their types with :type
  • Explain what the compile server does and when to run with --server=false

Before you start

What you’ll learn · Before you start

What you will learn

  • Write an @main program and pass it typed arguments with scala run . -- and the arguments
  • Predict what an @main program does with an argument that does not parse, a missing one and an extra one
  • Run a .sc script that reads its arguments from args, and decide when code belongs in .scala files
  • Use the REPL to try expressions and read their types with :type
  • Explain what the compile server does and when to run with --server=false

Before you start

On this page

A Scala program needs one method marked @main and nothing else. The tip calculator below is seven lines, and scala run . -- 4250 15 compiles it and prints a tip of 638 cents on a bill of 4,250 cents. The same command runs scripts, and scala repl answers one line of code at a time.

This lesson writes that first program, shows what it does when its arguments are wrong, runs a script, explores types in the REPL, and explains the compile server that keeps scala run quick on your computer, and why the runs in this track switch it off.

@main turns a method into a program with typed arguments

Here is the whole program. The arithmetic is an ordinary function, and the method marked @main reads the bill and the percentage from the command line:

tip.scala Scala · tip/tip.scala
// A tip calculator: the arithmetic is a plain function, and @main turns the rest into a program.
def tipCents(billCents: Long, percent: Int): Long =
  (billCents * percent + 50) / 100

@main def tip(billCents: Long, percent: Int): Unit =
  val t = tipCents(billCents, percent)
  println(s"Tip: $t cents. Total: ${billCents + t} cents.")

scala run . compiles every Scala file in the current folder and starts the program, and everything after -- goes to the program as its arguments. The session runs it four times, with good arguments, with a word where a number belongs, with one argument missing and with one too many:

Four runs of the tip program Python · tip_session.py
from session import run

# The tip program with good arguments, with one that does not parse, with one missing and with one too many.
run("""
cd tip
scala run . --server=false -- 4250 15
scala run . --server=false -- 4250 fifteen
scala run . --server=false -- 4250
scala run . --server=false -- 4250 15 99
""")

Output

$ cd tip
$ scala run . --server=false -- 4250 15
Tip: 638 cents. Total: 4888 cents.
$ scala run . --server=false -- 4250 fifteen
Illegal command line after first argument: java.lang.NumberFormatException: For input string: "fifteen"
$ scala run . --server=false -- 4250
Illegal command line after first argument: more arguments expected
$ scala run . --server=false -- 4250 15 99
Tip: 638 cents. Total: 4888 cents.

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 tip_session.py

The first run worked: (4250 * 15 + 50) / 100 is 638 in whole-number arithmetic, so the tip rounds to the nearest cent. The arguments arrive as text, and the @main method: A method marked @main, which the compiler turns into a program: a class with the method's name and a static main method that converts each command-line argument to its parameter's type. converts each one to its parameter’s type before your code runs: "4250" to a Long and "15" to an Int. When a conversion fails, the program prints Illegal command line with the reason, here a NumberFormatException for "fifteen", and when an argument is missing it says more arguments expected. The fourth run shows a quieter case: the extra 99 was ignored.

Step through what happened inside the first run:

Interactive · message by message What scala run . -- 4250 15 does with the two words Step through the first run of the session, then the second, where one word is not a number.
What scala run . -- 4250 15 does with the two words, step 8 of 8. Messages so far: scala run to generated main: "4250" "15"; generated main to your method: tip(4250L, 15); scala run to generated main: "4250" "fifteen".scala runScala CLIgenerated main"fifteen" is not an Intyour methodtip(billCents, percent)"4250" "15"tip(4250L, 15)"4250" "fifteen"exit status 0

The drawing shows the whole scene; its 8 steps are listed below.

Every step as text
  1. Compile the folder. Scala CLI compiles tip.scala. Because def tip is marked @main, the compiler also writes a class named tip with the static main method that the JVM starts.
  2. Start the program. Scala CLI starts a JVM on the class tip and hands it the words after -- as an array of two strings.
  3. Convert the first word. The generated main converts "4250" to the type of the first parameter, Long, with the FromString instance that Scala provides for Long.
  4. Convert the second word. "15" becomes an Int for the parameter percent. Both conversions worked, so your method can run.
  5. Call your method. The generated main calls tip with the converted values. From here on it is your code.
  6. Print the tip. tipCents gives (4250 * 15 + 50) / 100 = 638, and the program prints Tip, 638 cents, and a total of 4888 cents.
  7. A word that is not a number. In the second run the second word is "fifteen". Its conversion to Int fails, so the generated main prints Illegal command line with the NumberFormatException, and your method never runs.
  8. Status 0 all the same. After printing the message the generated main returns normally, so the program ends with exit status 0, as if it had worked.

Trusting the exit status after bad arguments

None of the four runs printed [exit status 1]: on Scala 3.9.0 the generated main reports a bad or missing argument and then ends normally, with status 0, so a script that tests the exit status sees success. When a caller must be able to tell, read the arguments as text and check them yourself, then end with sys.exit(1) on a mistake.

The conversion works for every parameter type that has a FromString instance in scala.util.CommandLineParser: String, Boolean and the number types come with one, and your own types can get one too.

Key idea

The parameters of an @main method are the program’s command-line arguments, converted to their types; a bad or missing argument prints Illegal command line, an extra one is ignored, and the exit status stays 0.

Checkpoint

Check: @main programs and their arguments

  1. Question 1 of 2 In @main def tip(billCents: Long, percent: Int), what turns the word "15" from the command line into an Int?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: The main method that the compiler generated, with the FromString instance for Int

    The generated main converts each command-line word with the FromString instance of its parameter's type, then calls your method with the converted values.

  2. Question 2 of 2 A shell script runs scala run . -- 4250 fifteen and then tests the exit status. What does it see?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Status 0, success, although the program printed Illegal command line

    On Scala 3.9.0 a bad or missing argument makes the generated main print Illegal command line and return, so the process ends with status 0. Check the arguments yourself when a caller must notice.

scala run compiles the whole folder, not one file

scala run . takes the folder, not a file, so it compiles every .scala and .sc file in it. Put the tip program and a hello program in one folder, and the command no longer knows which program to start:

Two programs in one folder Python · mains_session.py
from session import run

# One folder with two @main methods: scala run . must be told which program to start.
run("""
cd two-mains
!scala run . --server=false
scala run . --server=false --main-class hello
""")

Output

$ cd two-mains
$ scala run . --server=false
[error]  Found several main classes: hello, tip
You can run one of them by passing it with the --main-class option, e.g.
  scala run . --server=false --main-class hello

You can pick the main class interactively by passing the --interactive option.
  scala run . --server=false --interactive
[exit status 1]
$ scala run . --server=false --main-class hello
Hello from Scala 3.9.0

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 mains_session.py

Each @main method made a program named after the method, hello and tip, and Scala CLI stops rather than guess. --main-class hello chooses one; --interactive, which the message also offers, asks you to pick from a list, which works at a keyboard but not in a script or CI. A .sc script left in the same folder is compiled along with the rest, so a forgotten file with a mistake in it stops the run too. While you learn, keep one program per folder, or name the file, as in scala run tip.scala, which compiles that file alone.

Checkpoint

Check: What scala run . compiles

  1. One question A folder holds tip.scala and hello.scala, each with an @main method. What does scala run . do?

    Choose one answer.

    Show the answer: One question

    Answer: It stops with Found several main classes and suggests --main-class

    scala run . compiles the whole folder. With two @main methods it prints Found several main classes: hello, tip and stops; --main-class hello or a folder per program fixes it.

A script runs from top to bottom

A script: A .sc file whose top-level statements run from top to bottom, with the command-line arguments in args. Scala CLI wraps it in a class with a main method before it runs. is a .sc file with statements at the top level and no @main method. Scala CLI wraps the statements in a class with a main method of its own, runs them in order, and passes the words after -- in a value named args:

expenses.sc SC · script/expenses.sc
// A script: its statements run from top to bottom, and args holds the words after -- on the command line.
val expenses = List("train" -> 4250L, "hostel" -> 9800L, "food" -> 3675L)
for (name, cents) <- expenses do println(f"$name%-7s $cents%6d")
val total = expenses.map(_._2).sum
println(f"${"total"}%-7s $total%6d")
if args.nonEmpty then
  println(s"Each of ${args.mkString(", ")} pays ${total / args.length} cents.")
The script, without and with arguments Python · script_session.py
from session import run

# A script runs from top to bottom; the words after -- reach it as args.
run("""
cd script
scala run expenses.sc --server=false
scala run expenses.sc --server=false -- Asha Ben
""")

Output

$ cd script
$ scala run expenses.sc --server=false
train     4250
hostel    9800
food      3675
total    17725
$ scala run expenses.sc --server=false -- Asha Ben
train     4250
hostel    9800
food      3675
total    17725
Each of Asha, Ben pays 8862 cents.

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 script_session.py

Without arguments the if at the end does nothing; with two names it splits the total. Look at the share: 17,725 cents between two people is 8,862.5, and dividing two whole numbers drops the half, so one cent is lost. Money in this track is counted in whole cents, so that rounding is always visible.

Scripts suit quick jobs, such as adding up a list, renaming files or trying an idea. Move the code into .scala files as soon as it needs tests, a second file that uses its functions, or a name of its own as a program: definitions in a .scala file can be imported and tested, while a script runs once, from top to bottom.

Checkpoint

Check: Scripts

  1. One question You run scala run expenses.sc -- Asha Ben. What is args.length inside the script?

    Type a number.

    A hint

    args holds the words after --, and only those.

    Show the answer: One question

    Answer: 2 words

    The words after -- reach the script in args, so it holds Asha and Ben, and args.length is 2. The script's own file name is not one of them.

The REPL answers one line at a time

The REPL: Read-eval-print loop: a prompt that compiles and runs each line you type, then prints the value and its type, so you can try code without writing a program., short for read-eval-print loop, compiles and runs each line you type and prints what it got. scala repl opens it, and :quit closes it. The session typed eight lines; each answer comes right after the line it answers:

Eight lines typed into scala repl Python · repl_session.py
from session import repl

# The REPL in a terminal of its own: each line is typed after the scala> prompt, and the REPL answers it.
repl([
    "val bill = 4250L",
    "bill * 15 / 100",
    ":type bill * 15 / 100",
    'val code: Int | String = "A1"',
    "def tipCents(billCents: Long, percent: Int): Long = (billCents * percent + 50) / 100",
    "tipCents(bill, 15)",
    'List("train" -> 4250L, "food" -> 3675L)',
    ":quit",
])

Output

$ scala repl --server=false
Welcome to Scala 3.9.0 (25.0.4.1, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> val bill = 4250L
val bill: Long = 4250L

scala> bill * 15 / 100
val res0: Long = 637L

scala> :type bill * 15 / 100
Long

scala> val code: Int | String = "A1"
val code: Int | String = "A1"

scala> def tipCents(billCents: Long, percent: Int): Long = (billCents * percent + 50) / 100
def tipCents(billCents: Long, percent: Int): Long

scala> tipCents(bill, 15)
val res1: Long = 638L

scala> List("train" -> 4250L, "food" -> 3675L)
val res2: List[(String, Long)] = List(("train", 4250L), ("food", 3675L))

scala> :quit

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 repl_session.py

Read the answers as declarations. val bill: Long = 4250L says that bill is a Long, inferred from the L at the end of 4250L. An expression that you do not name gets one: res0, then res1 and so on, which you can use in later lines. :type prints only the type of an expression, without running it. Int | String is a union type, a value that is either an Int or a String; the REPL is a quick way to see such types. A def answers with its signature, and since Scala 3.8 the REPL pretty-prints results, which is why strings appear in quotes and Long values with their L.

The REPL forgets everything when you quit. For experiments you want to keep, an editor offers worksheets: a file whose name ends in .worksheet.sc. Metals in VS Code evaluates it each time you save it, IntelliJ IDEA when you press its run arrow, and both show each line’s result beside it.

Try it in your own REPL

Open scala repl and type bill * 15 / 100 with val bill = 4250, without the L. The type changes from Long to Int. Then type :type 4250L * 1.5 and see which type a Long times a Double gives.

Checkpoint

Check: The REPL

  1. Question 1 of 2 In a new REPL you type bill * 15 / 100 without naming the result. How can later lines use it?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: As res0, the name the REPL gave it

    Every unnamed result gets a name, res0 first, then res1 and so on. The session's later result was named res1.

  2. Question 2 of 2 bill is 4250L. What does :type bill * 15 / 100 print?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Long

    :type compiles the expression and prints its type without running it. Arithmetic on a Long and Int values gives a Long.

The compile server is fast once it is running, and needs a download first

On your computer, scala run compiles through a compile server: A background JVM that keeps a warm Scala compiler between builds. Scala CLI uses Bloop by default and downloads it on first use; --server=false compiles inside the scala command instead. called Bloop: a background JVM that keeps a warm compiler between runs, so a second run after a small change compiles quickly. Scala CLI downloads Bloop the first time it needs it, starts it, and leaves it running after the command ends; scala --power bloop exit stops it. --server=false skips the server: the scala command starts a fresh compiler for that one run, which starts cold every time, ends with the command and prints the compiler’s own messages unchanged. The Scala CLI documentation suggests it for setups with limited web access, and that is the case the session below shows: a computer that has never downloaded Bloop, with no network:

The first run with the compile server, offline Python · server_session.py
from session import run

# Without network access: the first run with the compile server needs Bloop, which has never been downloaded here.
run("""
cd hello
!scala run .
scala run . --server=false
""", downloads="first")

Output

$ cd hello
$ scala run .
Downloading https://repo1.maven.org/maven2/ch/epfl/scala/bloop-frontend_2.12/2.1.1/bloop-frontend_2.12-2.1.1.pom
Failed to download https://repo1.maven.org/maven2/ch/epfl/scala/bloop-frontend_2.12/2.1.1/bloop-frontend_2.12-2.1.1.pom
[10 more lines of download attempts not shown]
Error: java.lang.Exception: Error getting Bloop class path
For more details, please see '.scala-build/stacktraces/<n>.log'
[exit status 1]
$ scala run . --server=false
Hello from Scala 3.9.0

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 server_session.py

The first command tried to download Bloop from Maven Central, every attempt failed, and it stopped with Error getting Bloop class path. The second compiled and ran the same program with --server=false, from what was already on the computer. Step through both kinds of run:

Interactive · message by message A run with the compile server, and one without it Step through two runs with the server on a computer with a network, then the offline case of the session.
A run with the compile server, and one without it, step 7 of 7. Messages so far: scala command to Bloop server: download and start; scala command to Bloop server: compile the folder; scala command to Your program: start main; scala command to Bloop server: compile what changed; scala command to Your program: start main.scala commanda fresh compiler per runBloop servernot on this computerYour programits own JVMdownload and startcompile the folderstart maincompile what changedstart main

The drawing shows the whole scene; its 7 steps are listed below.

Every step as text
  1. First run, online. The first run that needs the server downloads Bloop from Maven Central, once, and starts it as a JVM of its own in the background.
  2. Compile in the server. Scala CLI asks Bloop to compile the folder. The compiler now stays loaded in the server between runs.
  3. Run the program. With the classes compiled, Scala CLI starts your program in a JVM of its own, as in every run.
  4. The server stays. The scala command ends, but Bloop keeps running, ready for the next run. scala --power bloop exit stops it.
  5. The next run. A second run finds the server warm, so it compiles only what changed since the last run, and the program starts sooner.
  6. Offline, never downloaded. On a computer that has never downloaded Bloop and has no network, every download fails, and scala run stops with Error getting Bloop class path.
  7. --server=false. With --server=false the scala command starts a fresh compiler for this one run, cold each time but with nothing to download, and gone when the run ends. The program runs as before.

So leave the server on for your own work: after its first download it makes every later run in a session faster. Turn it off with --server=false on a computer without network access, in a CI job that should leave no background process behind, and whenever you want the compiler’s messages exactly as it prints them, which is why every run in this track uses it.

Checkpoint

Check: The compile server

  1. One question A CI job runs scala run . in a container without network access and fails with Error getting Bloop class path. What is the simplest fix?

    Choose one answer.

    Show the answer: One question

    Answer: Add --server=false, so the run compiles without the server and has nothing to download

    Bloop is downloaded on first use. A container without network access cannot fetch it, so run with --server=false, which also leaves no server process behind in the job.

Practise: split a bill

The program below shares a bill equally among some people and says how many cents are left over. Both functions return 0 for now, and a second @main method, checks, tests them on four cases. Copy the folder, write the two functions, and run scala run . --main-class checks until all four pass; then try scala run . --main-class split -- 17725 3 on your own numbers:

split.scala Scala · split/split.scala
// Practise: share a bill equally. Write the two functions so that every check passes, then run the checks with
//   scala run . --main-class checks
def shareCents(totalCents: Long, people: Int): Long = 0

def leftoverCents(totalCents: Long, people: Int): Long = 0

@main def split(totalCents: Long, people: Int): Unit =
  val share = shareCents(totalCents, people)
  val left = leftoverCents(totalCents, people)
  println(s"Each of $people people pays $share cents, and $left cents are left over.")

@main def checks(): Unit =
  val cases = List((17725L, 2, 8862L, 1L), (17725L, 3, 5908L, 1L), (900L, 4, 225L, 0L), (5L, 7, 0L, 5L))
  val results =
    for (total, people, share, left) <- cases yield
      val ok = shareCents(total, people) == share && leftoverCents(total, people) == left
      println(s"${if ok then "ok  " else "FAIL"} $total cents among $people: share $share, left over $left")
      ok
  println(s"${results.count(ok => ok)} of ${results.size} checks pass")
  if results.contains(false) then sys.exit(1)

As given, every check fails, the checks end with status 1, and the program itself prints nonsense:

The practice program before you start Python · split_session.py
from session import run

# The practice program as given: both functions return 0, so the checks fail and the program reports nonsense.
run("""
cd split
!scala run . --server=false --main-class checks
scala run . --server=false --main-class split -- 17725 3
""")

Output

$ cd split
$ scala run . --server=false --main-class checks
FAIL 17725 cents among 2: share 8862, left over 1
FAIL 17725 cents among 3: share 5908, left over 1
FAIL 900 cents among 4: share 225, left over 0
FAIL 5 cents among 7: share 0, left over 5
0 of 4 checks pass
[exit status 1]
$ scala run . --server=false --main-class split -- 17725 3
Each of 3 people pays 0 cents, and 0 cents are left over.

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 split_session.py

First hint: whole-number division / drops the remainder, and % gives exactly what it dropped, so 17,725 among 3 is 17725 / 3 cents each and 17725 % 3 cents left over.

Then put the five ideas of this lesson to work in thirteen short questions, from a program’s arguments to the compile server; each one shows why its answer is right as soon as you check it:

Practice that adapts to you

Practise this lesson

13 questions about 5 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 13 What is the name of the program that @main def tip(…) creates?

    Choose one answer.

    Show the answer: Question 1 of 13

    Answer: tip

    @main def tip makes the compiler generate a class tip with a static main method, so the program, and the name that --main-class takes, is tip.

  2. Question 2 of 13 What does the tip program do with scala run . -- 4250 15 99?

    Choose one answer.

    Show the answer: Question 2 of 13

    Answer: It ignores 99 and prints the tip for 4250 and 15

    The generated main reads one word per parameter and ignores the rest, which is another reason to check arguments yourself when they come from other programs.

  3. Question 3 of 13 A deploy script calls the tip program and must stop when the arguments are wrong. Which design makes the program end with status 1 on a bad percentage?

    Choose one answer.

    Show the answer: Question 3 of 13

    Answer: Take the words as text, convert them with toLongOption and toIntOption, and call sys.exit(1) when a conversion fails

    The generated main reports bad arguments with status 0. When status matters, read the words yourself, for example with def main(args: Array[String]) or @main def tip(words: String*), check them, and end with sys.exit(1).

  4. Question 4 of 13 The folder holds tip.scala and hello.scala. Which command compiles and runs only tip.scala?

    Choose one answer.

    Show the answer: Question 4 of 13

    Answer: scala run tip.scala

    scala run . compiles the folder; scala run tip.scala compiles one file. --main-class tip is the other way to pick one program out of a folder.

  5. Question 5 of 13 A folder holds tip.scala and an old script, notes.sc, that you forgot about. Which files does scala run . compile?

    Choose one answer.

    Show the answer: Question 5 of 13

    Answer: Both, because scala run . compiles every .scala and .sc file in the folder

    The folder is the project. Keep each program in its own folder while you learn, so that nothing you forgot is compiled with it.

  6. Question 6 of 13 What is a .sc file to Scala CLI?

    Choose one answer.

    Show the answer: Question 6 of 13

    Answer: A script whose top-level statements run from top to bottom, with its arguments in args

    A script is source code with statements at the top level. Scala CLI compiles it, wraps the statements in a class with a main method, and runs them in order.

  7. Question 7 of 13 Your expenses script has grown to 120 lines, and a colleague wants to reuse its share function and test it. What do you do?

    Choose one answer.

    Show the answer: Question 7 of 13

    Answer: Move the definitions into .scala files, where other code can import them and tests can call them

    Scripts suit quick jobs. As soon as code needs tests, other files that use its functions or a name as a program, it belongs in .scala files.

  8. Question 8 of 13 Which command leaves the REPL?

    Choose one answer.

    Show the answer: Question 8 of 13

    Answer: :quit

    :quit ends the REPL. Commands such as :type and :help start with a colon, while everything else is compiled and run as Scala.

  9. Question 9 of 13 The REPL answered val code: Int | String = "A1". What does the type Int | String mean?

    Choose one answer.

    Show the answer: Question 9 of 13

    Answer: The value is either an Int or a String

    Int | String is a union type: a value of either type. The REPL shows such types as they are, which makes it a quick place to try them.

  10. Question 10 of 13 Which kind of file does an editor such as Metals evaluate when you save it, showing each line's result beside it?

    Choose one answer.

    Show the answer: Question 10 of 13

    Answer: A file whose name ends in .worksheet.sc

    Metals evaluates a .worksheet.sc file each time you save it and shows each result beside its line; IntelliJ IDEA evaluates it with its run arrow and shows the results in a panel on the right.

  11. Question 11 of 13 What is Bloop, in a scala run?

    Choose one answer.

    Show the answer: Question 11 of 13

    Answer: The compile server that Scala CLI uses by default, a background JVM with a warm compiler

    Bloop keeps a warm Scala compiler in a background JVM between runs. Scala CLI downloads it on first use and uses it unless told --server=false.

  12. Question 12 of 13 A scala run that used the compile server has finished. What happens to the server?

    Choose one answer.

    Show the answer: Question 12 of 13

    Answer: It keeps running, ready for the next run, until scala --power bloop exit stops it

    The server stays in the background so the next run finds a warm compiler. scala --power bloop exit stops it, which matters in CI jobs that should leave nothing running.

  13. Question 13 of 13 Why do the recorded runs of this track use --server=false, although repeated runs compile more slowly without the server?

    Choose one answer.

    Show the answer: Question 13 of 13

    Answer: It needs no download or background process, and it prints the compiler's messages as the compiler writes them

    For your own work the server is the better default. --server=false suits offline machines, CI jobs and anyone who wants the compiler's own messages, which the next lesson reads closely.

Interview questions

Fresher · What does @main do in Scala 3, and how is it different from writing def main(args: Array[String]) yourself?

@main on a method tells the compiler to generate a program: a class named after the method, with the standard public static void main(String[]) that the JVM starts. The generated main converts each command-line argument to the type of the matching parameter, using a FromString instance from scala.util.CommandLineParser, and calls your method. A bad or missing argument makes it print Illegal command line with the reason, and it ignores extra arguments. With def main(args: Array[String]) inside an object you get the raw strings and do every conversion and check yourself, which gives you full control over messages and exit status, and it is the form that also compiles with Scala 2. @main is the shorter and recommended way for Scala 3 programs; the hand-written form suits tools that need their own argument handling.

Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.

  1. Mid to senior

    Your CI runs scala test and scala run in containers without internet access. After the image was rebuilt, the jobs fail with Error getting Bloop class path. Explain the cause and give two fixes, with their costs.

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Fresher to mid

    You are writing a small command-line tool in Scala 3 that other scripts call, for example split 17725 3. Design its entry point: an @main method with typed parameters, or your own argument handling? Cover error messages, exit status and testing.

    Model answer, Pro. First step and follow-ups

Key takeaways

  • An @main method is a program: scala run . -- 4250 15 compiles the folder and converts each argument to the type of its parameter.
  • A bad or missing argument prints Illegal command line, an extra one is ignored, and the exit status stays 0, so check arguments yourself when callers rely on the status.
  • scala run . compiles every file in the folder and refuses to guess between two @main methods; choose with --main-class, or keep one program per folder.
  • A .sc script runs its statements from top to bottom with its arguments in args; code that needs tests belongs in .scala files.
  • The REPL prints the name, type and value of every line, :type shows a type without running anything, and worksheets keep experiments in a file.
  • The compile server, Bloop, keeps a warm compiler after a first download; --server=false starts a fresh compiler for each run, leaves nothing running and needs no download of Bloop.

Terms in this lesson

@main method
A method marked @main, which the compiler turns into a program: a class with the method's name and a static main method that converts each command-line argument to its parameter's type.
compile server
A background JVM that keeps a warm Scala compiler between builds. Scala CLI uses Bloop by default and downloads it on first use; --server=false compiles inside the scala command instead.
REPL
Read-eval-print loop: a prompt that compiles and runs each line you type, then prints the value and its type, so you can try code without writing a program.
script
A .sc file whose top-level statements run from top to bottom, with the command-line arguments in args. Scala CLI wraps it in a class with a main method before it runs.

References

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.