Scala setup issue?


#1

Sample code -
object Fibonacci {

  def fib(n: Int): Int = {
    var count = 2
    @annotation.tailrec
    def go(a: Int, b: Int): Int = {
      count += 1
      val c = a + b
      if (n==0) 0
      if (n==1) 1
      if (count==n) c
      else go(b, c)
    }
    go(0, 1)
  }

  def main(args: Array[String]): Unit = {
    print(fib(8))
  }

}

When running this via Intellij IDEA Community, it works as it is meant to.

When trying to run it from the command line as scala fibonacci.scala (fibonacci.scala is the name of the file), I get the following error-

reik@reik-msi ~/Projects/FPiS/src $ scala fibonacci.scala
java.net.UnknownHostException: reik-msi: reik-msi: Name or service not known
	at java.net.InetAddress.getLocalHost(InetAddress.java:1506)
	at scala.tools.nsc.io.Socket$.localhost(Socket.scala:28)
	at scala.tools.nsc.CompileSocket.getsock$1(CompileSocket.scala:164)
	at scala.tools.nsc.CompileSocket.getOrCreateSocket(CompileSocket.scala:179)
	at scala.tools.nsc.ScriptRunner.compileWithDaemon(ScriptRunner.scala:71)
	at scala.tools.nsc.ScriptRunner.compile$1(ScriptRunner.scala:114)
	at scala.tools.nsc.ScriptRunner.$anonfun$withCompiledScript$2(ScriptRunner.scala:159)
	at scala.runtime.java8.JFunction0$mcZ$sp.apply(JFunction0$mcZ$sp.java:12)
	at scala.tools.nsc.util.package$.trackingThreads(package.scala:43)
	at scala.tools.nsc.util.package$.waitingForThreads(package.scala:27)
	at scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:127)
	at scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:190)
	at scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:203)
	at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:70)
	at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:85)
	at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
	at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:101)
	at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Caused by: java.net.UnknownHostException: reik-msi: Name or service not known
	at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
	at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:929)
	at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1324)
	at java.net.InetAddress.getLocalHost(InetAddress.java:1501)
	... 17 more

I think this might be an issue with my setup.
I set it up on my Gentoo system using emerge scala.


#2

I only run scala -nc to mean “no compilation daemon process”. -nc is now the default.

Besides your local config, it avoids bugs with resident compilation.


#3

Thanks! That worked.
But why didn’t scala filename.scala work?


#4

Off topic, since you didn’t ask about the code, but since it is here. :wink:

Since your go method has side effects (it changes count), it is not pure FP. I’m not saying it needs to be pure FP, but I guess you want it to be and that’s why you made it recursive. If you end up using shared counters, then a loop is probably the better alternative.

Pure FP solutions for Fibonacci numbers exist. The naive approach is is very inefficient, i.e.

def fib(n): Int = n match {

case 0 => 0

case 1 => 1

case _ => fib(n-1) + fib(n-2)

}

For example, for n=10, it calls f(9) and f(8) directly, which calls f(8) twice total, and f(7) three times and so on.

One approach would be to use caching, i.e. store values already calculated. That’s side-effecting, but still returns the same result for every method call, so it’s usually considered OK in FP.

The probably better approach is to use a helper method that can recurse with only one call by using the last two Fibonacci numbers:

def fib(n: Int): Int = {

val (_, f) = fib2(n)

f

}

def fib2(n: Int): (Int, Int) = n match {

case 0 => (0, 0)

case 1 => (0, 1)

case _ =>

val (a, b) = fib2(n-1)

(b, a+b)

}