Illegal start of toplevel definition

I hope I’m not duplicating a previous discussion, but I have searched and not found any answers here or elsewhere. I am just a newbie in Scala and working through simple exercises using VS Code. I wrote a simple loop…
for (i ← 10 to 0)
** println(i)**
and received the error message on both statements. I have no idea what it means
Thank you

It means that for can’t be a top-level definition.
In other words, it can not be in the outer scope of a file. The fix is to move it inside something that can be a top-level definition; like an object.

What can and can’t be top-level varies depending on the version of the language that you are using, and if you are writing a traditional program, a script, or a worksheet.

For example a Scala 2 program would look like this:

object Main {
  def main(args: Array[String]): Unit = {
    for (i ← 10 to 0 by -1) {
      println(i)
    }
  }
}

But, while learning all that ceremony can be annoying. So, if you rather use scala-cli to write a Scala 3 script, you can just do:

for i ← 10 to 0 by -1 do println(i)

And it should work.

Thanks for leading me in the right path. The above works at the command line, but the body of the for loop required parentheses.

Now I need an explanation of what sort of statements are “top level”. It’s not mentioned in Scala for the Impatient

1 Like

I don’t even know, but with Scala 2 it just works except for the fancy arrow

➜  snips scala -Xlint illegal-top.scala
illegal-top.scala:4: warning: The unicode arrow `←` is deprecated, use `<-` instead. If you still wish to display it as one character, consider using a font with programming ligatures such as Fira Code. [quickfixable]
for (i ← 10 to 0 by -1) println(i)
       ^
10
9
8
7
[snip]

yet

➜  snips scala-cli --server=false --scala 2.13.13 illegal-top.scala
.../illegal-top.scala:4: error: expected class or object definition
for (i ← 10 to 0 by -1) println(i)
^
1 error
Compilation failed

and similarly (same for dotty runner)

➜  snips scala-cli --server=false --scala 3.4.1 illegal-top.scala
-- [E103] Syntax Error: .../illegal-top.scala:4:0 ---------------
4 |for (i ← 10 to 0 by -1) println(i)
  |^^^
  |Illegal start of toplevel definition
  |
  | longer explanation available when compiling with `-explain`
there was 1 deprecation warning; re-run with -deprecation for details
1 warning found
1 error found
Compilation failed

Maybe you can tell me what works, but why do I have to guess?

I think computers can figure out how to run it.

You must be more patient for that.

I joke, but this is pretty fundamental for “running as a program” vs “REPL snippet”.

I think it should just work in whatever environment.

The details of how it is compiled and run might differ in ways that probably don’t matter to you.

But it should not be a puzzler.

Welcome!

If you are using VS Code, you can use worksheets that end with the .worksheet.sc file extension.

In these files, top-level bare expressions are allowed. They are just evaluated inside the editor directly whenever you press Ctrl+S to save the file. So it’s like a “multi-line REPL”. Here is a Scastie example: Scastie - An interactive playground for Scala. Notice I’m using Scala 3 syntax with for ... do ....

Outside of worksheets, in other words, files that end with .sc only, or with .scala, top-level bare expressions are not allowed. This means that, your expressions either have to be bound to a val or var or def declaration, or they have to be inside a class / trait or object (basically inside a scope of some kind).

A few more tips:

  • Use Scastie to share your problematic code examples, that way we can help much more easily. (On Scastie, it is possible to turn-off the worksheet mode and still “run” the file, by the way.)
  • Which version of “Scala for the Impatient” are you using? Is it the old one, or the 2023 one? Code running has changed significantly in Scala since the old days (when a lot of books used the Eclipse IDE). I am looking at the 2023 version and it’s using the REPL on the Terminal, and worksheets in VS Codium.
  • If you have more questions consider joining Scala Discord server where you can chat more easily and get faster feedback.
1 Like

I was using the Impatient 2012 version, but will switch to the latest 2023 version when it arrives from my friend, Amazon.
I appreciate your comments even if I don’t quite understand them

1 Like

Oh yeah the 2012 version is ancient at this point.
Feel free to ask anything else!
Remember Scastie is your friend.

What is Scastie?

I clicked the link in your message for the discord server. It then asks me to sign in and I do have an ID/PW for discord. When I enter it, discord tells me that email is already registered. I don’t get it!!

https://scastie.scala-lang.org – an online website that allows you to experiment easily with small Scala programs, without needing to install or run anything locally. It’s generally the easiest way to play around with the language in small ways.

(If you go to “Build Settings” there, you can specify the version of Scala, the libraries to include, and so on.)

2 Likes

Interesting development. I installed JDK 22, And now when I go to the scala shell (is that the correct terminology?), my typing does not show on the screen. I hit the keys and nothing happens. I found something called CLI (command line interface) and installed that. When I run it, I get the scala prompt and can enter commands. However, when I enter the readInt command, the computer just sits there and no response. If I hit return at this time, I get the sequence of error messages that I previously posted. I have, of course, tried reboot (the old Windows fallback), but that didn’t change anything. Maybe I should go back to JDK 14???

I did go back to jdk 14 and now it works again. I need some serious help!

readInt() is expecting user input. So you type an integer and hit Enter.

$ scala
Welcome to Scala 3.4.1 (21.0.2, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
                                                                                                                        
scala> import scala.io.StdIn.readInt // hit Enter
                                                                                                                        
scala> val x = readInt() // hit Enter
// now you have to type an integer, and hit Enter again
123 // Enter
val x: Int = 123
                                                                                                                        
scala> 

This is a bit confusing because there are two interactions going on.
First, we are interacting with the REPL ourselves.
Second, readInt() is also expecting interaction, which is happening inside our REPL interaction.

Normally we would not use readInt() in a REPL session. It would be used in a program that we write for someone else to use, so that we can get command line input from them.

But for some reason the book chose that as an example.

I believe Scala does not yet support Java 22.
Java 21 and lower should work. I’m using Java 21.

1 Like

I would stick to LTS versions of Java.
So either 21, 17, 11, 8 would be a good choice.

1 Like

I would definitely not recommend using Java version 8. I had problems with it a few months ago that cost me a week of spinning my wheels and finally got resolved when I upgraded to 21. I don’t even know what the underlying problem was, but I know it was resolved by upgrading. I would say stay with 17 or 21.

2 Likes