user4955663 user4955663 - 2 months ago 21
Scala Question

Why Ammonite script fails while REPL runs same code just fine?

I installed ammonite using this:
http://www.lihaoyi.com/Ammonite/#Ammonite-Shell

~/.ammonite/predef.sc is as it was after install.

interp.load.ivy("com.lihaoyi" %% "ammonite-shell" % ammonite.Constants.version)
@
val shellSession = ammonite.shell.ShellSession()
import shellSession._
import ammonite.shell.PPrints._
import ammonite.ops._
import ammonite.shell._
ammonite.shell.Configure(repl, wd)


Ammonite Repl is v 0.7.7 with Scala 2.11.8 Java 1.8.0_101

I tried very simple ammonite script:

ammtest.sc is

/*
This is ammonite script file.
*/

import ammonite._
import ammonite.ops._
import ammonite.ops.ImplicitWd._

println("Hello World")

import java.util._
val date = new Date()
println(date)

val dir = ls!
println(dir)


When I compile it I get following error:

$ amm ammtest.sc
Compiling ammtest.sc
ammtest.sc:17: recursive value dir needs type
println(dir)
^
ammtest.sc:17: type mismatch;
found : Unit
required: ammonite.ops.Path
println(dir)
^
Compilation Failed


On the other hand when I copy/paste the same code (without imports in the beginning) to the ammonite REPL:

println("Hello World")

import java.util._
val date = new Date()
println(date)

val dir = ls!
println(dir)


it runs OK without any errors.

1) Do I need to import something more into the script to get it running like in REPL or what's the problem with it?
(I know that the script runs OK if changed e.g. val dir = ls! pwd )

2) What does "recursive value dir needs type" mean?

3) What's the meaning of the single "@" in the predef.sc?

Answer
val dir = ls!
println(dir)

is taken as

val dir = ls.!(println(dir))

That's why postfix operators are confusing.

You can add a blank line to get the intended meaning.

REPL parsing is line-by-line.