main method in intellij worksheet doesn't run? - scala

I am trying to use the worksheet functionality of Intellij. I have this simple code:
object Timer {
// this function takes another function as an argument.
// that function takes no args, and doesn't return anything.
def oncePerSecond(callback: () => Unit) {
while (true) { callback(); Thread.sleep(1000) }
}
// the function we'll pass in to oncePerSecond.
// this can be any function that takes no args and doesn't
// return anything.
def timeFlies() {
println("time flies like an arrow ...")
}
// the main() method, where we pass timeFlies into oncePerSecond.
def main(args: Array[String]): Unit = {
oncePerSecond(timeFlies)
}
}
Why doesn't it run? I don't see "time flies like an arrow" when it executes.

If you want to run this method inside worksheet you shouldn't put it in main method but:
oncePerSecond(timeFlies)
without anything. In this Timer object.
Edit:
If you want to run it from a console you can use scalac and scala:
scalac Timer.scala
scala Timer
Or you can create a simple sbt project or use another build tool.
Edit2: Previously I didn't see that you have one more question. Your code doesn't work because in practice you create a method main without using it. In a worksheet, you need to use a method to see the result. So if you put in object:
val a = 1
and you run this worksheet you can see that it's evaluated on the right side (in the right window).
The same situation is with a method. If you create some method you can see that method is created. To see the result you only need to use this method and run the worksheet.

Related

Scala methods with no argument evaluating on definition in zeppelin

I'm writing a method in zeppelin that will update several DataFrames, to be called as part of initializing my code.
The pattern we're following is to define all initialization methods in their own paragraphs, and then call them as part of a block.
def init(nc: NotebookContext) = {
method1()
method2()
}
However, for most definition signatures of methods without parameters, it appears that zeppelin is actually calling and evaluating the last method in a paragraph. This is a problem, because when the method is called later, it means the transformations have been applied to the DataFrame twice, which is not desired.
Is this a function of scala, or a quirk of zeppelin, or both? Why do some of these declarations evaluate immediately, while others wait to be called?
Assume the below methods are each defined in their own zeppelin paragraph
def runsAutomatically(): Unit = { println("test") }
//runsAutomatically: ()Unit
//test
def runsAutomatically2 = { println("test2") }
//runsAutomatically2: Unit
//test2
def waitsForDefinition= () => { println("test") }
//waitsForDefinition: () => Unit
I understand that there is a difference in scala between functions/methods with no parameter lists, and a single parameter list with no parameters, but I don't know why these different version would change when things get executed.
Finally if done in a single paragraph:
def runsAutomatically(): Unit = { println("test") }
def runsAutomatically2 = { println("test") }
//runsAutomatically: ()Unit
//runsAutomatically2: Unit
//test2
Is this just a quirk of zeppelins, or something about Scala I'm missing?
Because in scala, a def without an empty parameter list is a strict value; In the end it's actually just a val.
Scala is a strict language and not making the function a thunk by not adding an empty parameter list will actually be evaluated immediately.
You are right, none of these methods should get evaluated automatically. At least, not in pure Scala.
def runsAutomatically(): Unit = { println("test") }
def runsAutomatically2 = { println("test2") }
def waitsForDefinition= () => { println("test") }
You should blame Zeppelin for that then. What version of Zeppelin are you using? I don't see this problem in Zeppelin 0.9.0 - maybe an upgrade would be the option for you?

async before in scalatest for scalajs

In the code example below, how can I wait for ajaxCall() to finish before starting test 1 when using scalatest to test Scala.js code ? I cannot use await in Scala.js.
class ClientGetEntityDynTest
extends AsyncFunSuite
with Matchers
with BeforeAndAfter {
implicit override def executionContext =
scala.scalajs.concurrent.JSExecutionContext.Implicits.queue
before {
ajaxCall(...) // returns Future[...]
... // I would like to wait for ajaxCall to finish before starting test 1
}
test("test 1") {
...
getEntityDyn(...) // returns Future[Assertion]
}
}
This one year old issue seems to be related but not really resolved.
One simple possibility would be to make my own testWithBefore method... that calls test and waits for a Future to complete before calling test but maybe it is possible to do this without this workaround.
I suspect you need to restructure your tests, to not use BeforeAndAfter. I'm not sure of the best solution, but the fall-back would be to create your own higher-order function, called something like beforeAsync(fun: => Future[Any]), and manually use that in your tests.
I suspect it wouldn't be too hard to take BeforeAndAfter.scala, and create a variant BeforeAndAfterAsyc that has this beforeAsync() function in it, but I haven't tried doing so.

If-else without else causes recursive function to repeat

Why does the following produce the output "ayyayy" and not just "ayy" (once)?
def iftest(b: Boolean): Unit = {
if(b) iftest(false)
print("ayy")
}
I run it in REPL as iftest(true) which should cause it to fail on the first pass but succeed on the second (hence only one "ayy"). So why does it act like both succeed?
Is there some sort of recursive "backfolding" in scala that I don't know about?
Is there some sort of recursive "backfolding" in scala that I don't
know about?
No, the method operates as you've defined it. Lets analyze:
You call iftest(true) and invoke the method.
if(b) is true, so you call iftest(false) and start a new stack frame.
if(b) is now false, so we don't recursively call the method again.
The next line of code is print("ayy"), so it prints it out and the method completes
We go back up one frame, we now finished calling iftest(false) and the next line of code is println("ayy"), so it prints it out again
Method completes.
Perhaps what you want is:
def iftest(b: Boolean): Unit = {
if (b) {
iftest(false)
print("ayy")
}
}

Scala "is not a member of" when chaining method calls without periods and parameters

Continuation of my work in:
Scala "does not take parameters" when chaining method calls without periods
Given the accepted answer, this time I want to pass a parameter to one of the methods.
Original suggestion:
object and
class Greeter {
def hi(a: and.type) = { print("hi"); this }
def hello = { print("hello"); this }
}
new Greeter hi and hello
My new code:
object and
class Greeter {
def hi(name: String) = { print("hi" + name); this }
def hi(name: String, a: and.type): Greeter = hi(name)
def hello = { print("hello"); this }
}
but when I: new Greeter hi "Miguel" and
I get: error: value and is not a member of Greeter
putting the parentheses and comma works: new Greeter hi ("Miguel", and)
In Scala, there must always be parentheses around a parameter list with more than one parameter. Leaving those off is simply not possible.
new Greeter hi "Miguel" and is interpreted as (new Greeter).hi("Miguel").and, i.e. it's trying to invoke an and method on a Greeter object.
The compiler isn't always able to infer parantheses. My rule is simply that if it blows up without them I add them and move on. Usually, I'll later learn the language further and then come back and clean up my code in ways that removes them (if they are part of a DSL). But, i've found trying to do so upfront takes 20 times longer to find an answer. Could've released the software much sooner if I just accepted a couple mild blemishes.

why does this scala by-name parameter behave weirdly

OK the question might not say much, but here's the deal:
I'm learning scala and decided to make an utility class "FuncThread" with a method which receives a by-name parameter function (I guess its called that because it's a function but without a parameter list) and then starts a thread with a runable which in turn executes the passed function, I wrote such a class as follows:
class FuncThread
{
def runInThread( func: => Unit)
{
val thread = new Thread(new Runnable()
{
def run()
{
func
}
}
thread.start()
}
}
Then I wrote a junit test as follows:
#Test
def weirdBehaivorTest()
{
var executed = false
val util = new FuncThread()
util.runInThread
{
executed = true
}
//the next line makes the test pass....
//val nonSense : () => Unit = () => { Console println "???" }
assertTrue(executed)
}
If I uncomment the second commented line, the test passes but if it remains commented the test fails, is this the correct behaviour? how and when do by-name parameter functions get executed?
I know Scala has the actors library but I wanted to try this since I've always wanted to do this in Java
Is this just a race condition? runInThread starts the thread but your assertion tests 'executed' before the other thread sets it to true. Adding your extra line means more code (and so time) is executed before the test, making it more likely that 'executed' has been set to true
It's also worth noting that (as of Scala 2.8), the construct you were trying to write is available in the standard library
import scala.actors.Futures._
future{
executed = true
}
This construct is actually more powerful than what you're describing, the thread calculation can return a value, and which can be waited for.
import scala.actors.Futures._
//forks off expensive calculation
val expensiveToCalculateNumber:Future[Int] = future{
bigExpensiveCalculation()
}
// do a lot of other stuff
//print out the result of the expensive calculation if it's ready, otherwise wait until it is
println( expensiveToCalculateNumber());