can't run .scala file from REPL? - scala

I'm newly at Scala.
I want to run function which is wrote at my file while.scala:
def whileLoop {
var i = 1
while(i <= 3) {
println(i)
i += 1
}
}
whileLoop
here is how it looks at REPL:
scala> scala /home/nazar/Downloads/while.scala
<console>:1: error: illegal start of simple expression
If I understood right from book. I need to specify .scala file location and run with:
scala /path/to/file.scala
Why it fails?
Here is snippet from book:
You can run the code like this:
batate$ scala code/scala/while.scala
1
2
3
UPDATE:
I tried options :load it works, but when I want to run another file for_loop.scala:
def forLoop {
println( "for loop using Java-style iteration" )
for(i <- 0 until args.length) {
println(args(i))
}
}
forLoop
it fails:
scala> :load /home/nazar/Downloads/for_loop.scala
Loading /home/nazar/Downloads/for_loop.scala...
<console>:9: error: not found: value args
for(i <- 0 until args.length) {
^
<console>:8: error: not found: value forLoop
forLoop
^
scala> :load /home/nazar/Downloads/for_loop.scala hello scala
That file does not exist
How to solve this trouble?

You do it like this, from the shell / command line, not from within the REPL (% is nominal shell prompt):
% scala MyScalaScriptName.scala
You did this:
% scala
scala> scala while.scala
<console>:1: error: illegal start of simple expression
The only thing known within the Scala REPL is Scala code itself and a few built-in special commands. However, one of them will do what you want:
% cd
% scala
scala> :load Downloads/while.scala
Loading Downloads/while.scala
1
2
3

In order to use command line arguments (via args) it is needed to extend App or more commonly to define a principal or main method in an object, namely a def main(args: Array[String]) method, which defines an entry point to the program. Consider for instance
object AnyName extends App {
def forLoop {
println( "for loop using Java-style iteration" )
for(i <- 0 until args.length) {
println(args(i))
}
}
forLoop
}
AnyName.main(Array("first","second"))
Try to load it from REPL. The other approach is thus,
object AnyName {
def main(args: Array[String]) {
println( "for loop using Java-style iteration" )
for(i <- 0 until args.length) {
println(args(i))
}
}
}
AnyName.main(Array("first","second"))
In this latter example, note the scope of args, bound to the parameter in main.

Related

Sum of list element in scala is not executable : error. How to fix?

I am not able to execute or **▶ button is not clickable in intelleiJ ** the sum function in following two ways. Please help me to identify the mistakes in both.
object Main{
def sum1(xs : List[Int]): Int = {
xs.filter(_ > 0).sum // am i missing return word here ?
}
def sum2(xs: List[Int]): Unit = {
val mx = xs.filter(_ > 0).sum // is it ok to have return in a variable ?
println(mx)
}
Main.sum1(List(1,2))
Main.sum2(List(1,2,3,4))
}
For Intellij, unless you code from within a Scala Worksheet where you can execute execute code without an entry point, in any normal application, you require an entry point to your application.
In Scala 2 you can do this in 2 ways. Either define the main method yourself inside an object definition, which is the conventional way:
object Main {
def main(args: Array[String]): Unit = {
// code here
}
}
Or - have your object definition extend the App trait, which provides the main method for you, so you can start writing code directly inside:
object Main extends App {
// code here
}
This is a bit cleaner, and one nested-levels less.
In Scala, statements are called expressions, because they generally return the value of the last expression, if the last expression is not an assignment. This code:
def sum1(xs: List[Int]): Int =
xs.filter(_ > 0).sum
Is a syntactic sugar for this:
def sum1(xs: List[Int]): Int = {
return xs.filter(_ > 0).sum
}
Because braces are optional if the code has only 1 expression, and will return the value of the last expression by default. So even though you can write code both ways, you'll get the warning Return keyword is redundant, because you'll never need to use it explicitly.
Also, you don't need to write Main.sum1(...) from within Main. You can omit the object:
object Main extends App {
def sum1(xs: List[Int]): Int =
xs.filter(_ > 0).sum
def sum2(xs: List[Int]): Unit = {
val mx = xs.filter(_ > 0).sum
println(mx) // 10
}
println(sum1(List(1, 2))) // 3
sum2(List(1, 2, 3, 4))
}
For Scala 3, things get simpler. The recommended way is to annotate a method with the #main annotation to mark it as the entry point in your program. This method ca either be defined at the top-level, or inside an object definition, and it's name does not matter anymore:
#main def hello() =
// code here
While Scala 3 still supports the App trait from Scala 2, it has now become deprecated and it's functionality has been limited, so if your program needs to cross-build between both Scala 2 and Scala 3 versions, it’s recommended to stick with the basic way of explicitly define a main method inside an object definition with an Array[String] argument instead:
object MyMain:
def main(args: Array[String]) =
// code here
Note, curly braces become optional in Scala 3 in favor of the cleaner Python-style indentation.

Scala lazy val interpretation

I am learning Scala basics. I just came across the lazy val concept. I have following code snippets which work without errors/warnings
Case 1
lazy val a = 10 + b
lazy val b = 5
println(a)
Case 2
lazy val a = 10 + b
val b = 5
println(a)
Case 3
val a = 10 + b
lazy val b = 5
println(a)
I understand how case 1 & 2 work. But I don't understand how the code in case 3 is working without error/warning. How is Scala able to evaluate the value of a when b is not yet defined?
EDIT
I am not running this code in Scala REPL. I have saved the code in case 3 in file called lazyVal.scala. I am executing it using scala lazyVal.scala. I think scala interprets the code in the file.
If I change the code in lazyVal.scala to
val a = 10 + b
val b = 5
println(a)
And execute it using scala lazyVal.scala I do get warning
/Users/varun.risbud/scalaRepo/src/Chapter1/lazyVal.scala:1: warning: Reference to uninitialized value b
val a = 10 + b
^
one warning found
10
Also If I change the code to create object and extend App it works
object lazyVal extends App {
val a = 10 + b
lazy val b = 5
println(a)
}
➜ Chapter1 scalac lazyVal.scala
➜ Chapter1 scala lazyVal
15
My scala version is 2.12.1 if that makes any difference.
Statements in a constructor execute in textual order, which is why you get a warning when the initialization of a refers to the uninitialized b. It's a common error to compose a class in a way that you don't even get the warning. (There's a FAQ tutorial about that.)
The same text is forbidden in a local sequence of statements:
scala> :pa
// Entering paste mode (ctrl-D to finish)
locally {
val a = 10 + b
lazy val b = 5
println(a)
}
// Exiting paste mode, now interpreting.
<console>:13: error: forward reference extends over definition of value a
val a = 10 + b
^
As members of a class or object, the lazy member is evaluated "on demand", when a is evaluated during construction.
scala> :pa
// Entering paste mode (ctrl-D to finish)
object X {
val a = 10 + b
lazy val b = 5
println(a)
}
// Exiting paste mode, now interpreting.
defined object X
scala> X
15
res1: X.type = X$#6a9344f5
The script runner packages your lines of code this way:
object X {
def main(args: Array[String]): Unit =
new AnyRef {
val a = 10 + b
lazy val b = 5
println(a)
}
}
If you give it an object with a main or that extends App, it won't wrap the code but just use it directly.
There are subtle differences between the three formulations. For example, the constructor of a top-level object is run as a static initializer; but an App is special-cased to run initializer code as main. (They're getting rid of App because it's confusing.)

In a scala macro called with an implicit def, how can I get the source statement of the caller to the implicit def as a string?

I'm trying to write an implicit def macro that captures the invoking statement (and preferably nothing else) as a string, that can hopefully be used just by having the desired output object as an implicit parameter. But I'm having some trouble getting it to work with multi line statements.
For example:
case class HowWasICalled(statement:String, lineNumber:Int)
object HowWasICalled {
implicit def generate: HowWasICalled = macro macro_impl
}
def callMe(something: Any)(implicit context: HowWasICalled)
// macro: c is the blackbox Context
def macro_impl(c: blackbox.Context): c.Expr[HowWasICalled] = { ... }
And the first attempt at implementing a method inside the macro that returns the invoking statement as a string:
def makeString:String = show(c.macroApplication)
But, this only returned "HowWasICalled.generate". I actually wanted the statement invoking callMe.
I was hoping the following would work, but it doesn't. The -Yrangepos compiler flag does not seem to result in range positions in def macros? :(
def makeString:String = {
if (c.enclosingPosition.isRange) {
new String(c.enclosingPosition.source.content.slice(
c.enclosingPosition.start,
c.enclosingPosition.end
))
}
}
The closest I got to any working implementation doesn't exactly capture just statement nor the entire statement, but at least I get the line of source invoking callMe.
def makeString:String = {
val lineNumber = c.enclosingPosition.line
val lineIndex = lineNumber-1
c.enclosingPosition.source.lineToString(lineIndex)
}
How can I improve the macro to handle the following case? It should ideally generate something like a HowIWasCalled("callMe( 1 + 2 )", 123) given the following input
0; 0; 0; val x = callMe(1 +
2)

When is code in Scala objects evaluated?

Could someone explain to me why given the object:
object HelloWord {
println("hello world")
var z = 1
z += {
println("adding 1 to z")
1
}
}
running the following code in the REPL gives:
import HelloWorld._
// no output
z
// hello world
// adding 1 to z
// res0: Int = 2
z
// res1: Int = 2
To clarify, I would like an explanation of the output for each line of code entered into the REPL.
Cheers
Scala objects are initialized lazily; their top-level code will be executed once when the object is first loaded and used.
Importing a class does not cause it to be loaded, so nothing happens.
Evaluating z in the REPL causes the object's class to be loaded and the initialization code to be executed. This will only happen once, just like a static initializer in Java.
Evaluating z again in the REPL prints out the value from the previous initialization. The initialization code is not run again, so neither of the println statements is executed.

Make a Scala interpreter oblivious between interpret calls

Is it possible to configure a Scala interpreter (tools.nsc.IMain) so that it "forgets" the previously executed code, whenever I run the next interpret() call?
Normally when it compiles the sources, it wraps them in nested objects, so all the previously defined variables, functions and bindings are available.
It would suffice to not generate the nested objects (or to throw them away), although I would prefer a solution which would even remove the previously compiled classes from the class loader again.
Is there a setting, or a method, or something I can overwrite, or an alternative to IMain that would accomplish this? I need to be able to still access the resulting objects / classes from the host VM.
Basically I want to isolate subsequent interpret() calls without something as heavy weight as creating a new IMain for each iteration.
Here is one possible answer. Basically there is method reset() which calls the following things (mostly private, so either you buy the whole package or not):
clearExecutionWrapper()
resetClassLoader()
resetAllCreators()
prevRequests.clear()
referencedNameMap.clear()
definedNameMap.clear()
virtualDirectory.clear()
In my case, I am using a custom execution wrapper, so that needs to be set up again, and also imports are handled through a regular interpret cycle, so either add them again, or—better—just prepend them with the execution wrapper.
I would like to keep my bindings, they are also gone:
import tools.nsc._
import interpreter.IMain
object Test {
private final class Intp(cset: nsc.Settings)
extends IMain(cset, new NewLinePrintWriter(new ConsoleWriter, autoFlush = true)) {
override protected def parentClassLoader = Test.getClass.getClassLoader
}
object Foo {
def bar() { println("BAR" )}
}
def run() {
val cset = new nsc.Settings()
cset.classpath.value += java.io.File.pathSeparator + sys.props("java.class.path")
val i = new Intp(cset)
i.initializeSynchronous()
i.bind[Foo.type]("foo", Foo)
val res0 = i.interpret("foo.bar(); val x = 33")
println(s"res0: $res0")
i.reset()
val res1 = i.interpret("println(x)")
println(s"res1: $res1")
i.reset()
val res2 = i.interpret("foo.bar()")
println(s"res2: $res2")
}
}
This will find Foo in the first iteration, correctly forget x in the second iteration, but then in the third iteration, it can be seen that the foo binding is also lost:
foo: Test.Foo.type = Test$Foo$#8bf223
BAR
x: Int = 33
res0: Success
<console>:8: error: not found: value x
println(x)
^
res1: Error
<console>:8: error: not found: value foo
foo.bar()
^
res2: Error
The following seems to be fine:
for(j <- 0 until 3) {
val user = "foo.bar()"
val synth = """import Test.{Foo => foo}
""".stripMargin + user
val res = i.interpret(synth)
println(s"res$j: $res")
i.reset()
}