Need help with Continuations-Error "found cps expression in non-cps position" - scala

I try building the following simple Generator using the Scala 2.8 Continuations-PlugIn.
Where does the following error come from?
None/None/Some((Unit,Unit))
GenTest.scala:8: error: found cps expression in non-cps position
yieldValue(1)
None/None/Some((Unit,Unit))
GenTest.scala:9: error: found cps expression in non-cps position
yieldValue(2)
None/None/Some((Unit,Unit))
GenTest.scala:10: error: found cps expression in non-cps position
yieldValue(3)
Code:
import scala.util.continuations._
object GenTest {
val gen = new Generator1[Int] {
yieldValue(1)
yieldValue(2)
yieldValue(3)
}
def main(args: Array[String]): Unit = {
for (v <- gen) {
println(v)
}
}
}
class Generator1[E](gen: => Unit #cps[Unit]) {
var loop: (E => Unit) = null
def foreach(f: => (E => Unit)): Unit = {
loop = f
reset[Unit,Unit]( gen )
}
def yieldValue(value: E): Unit #cps[Unit] =
shift { genK: (Unit => Unit) =>
loop( value )
genK( () )
()
}
}

Those yieldValue calls are happening inside gen's constructor, which is not allowed (I assume). Ah, I just noticed you intended them to be the constructor parameter. Well, unfortunately, that syntax only works with methods. I'm not sure you don't get another error as well here.

Related

Where does dut in Chisel Test get defined? (About Scala syntax)

I am trying to come up with a better title.
I am new in Chisel and Scala. Below there is a Chisel code defining and testing an module.
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
class DeviceUnderTest extends Module {
val io = IO(new Bundle {
val a = Input(UInt(2.W))
val b = Input(UInt(2.W))
val out = Output(UInt(2.W))
})
io.out := io.a & io.b
}
class WaveformTestWithIteration extends AnyFlatSpec with ChiselScalatestTester {
"WaveformIteration" should "pass" in {
test(new DeviceUnderTest)
.withAnnotations(Seq(WriteVcdAnnotation)) ( dut => // ???
{
for (a <- 0 until 4; b <- 0 until 4) {
dut.io.a.poke(a.U)
dut.io.b.poke(b.U)
dut.clock.step()
}
}
)
}
}
The code line with comments ??? is where I am quite puzzled. Where does the variable dut is defined? It seems an reference to instance gained by new DeviceUnderTest.
test(new DeviceUnderTest).withAnnotations(Seq(WriteVcdAnnotation)) return an TestBuilder[T] with apply method:
class TestBuilder[T <: Module](...) {
...
def apply(testFn: T => Unit): TestResult = {
runTest(defaults.createDefaultTester(dutGen, finalAnnos))(testFn)
}
...
}
So, dut => {...} is a function (T) => Unit? But it does not look like a standard lambda ((x:T) => {...})? Or it is something else?
What is this syntax in scala exactly?
Consider the following boiled-down version with a similar structure:
def test[A](testedThing: A)(testBody: A => Unit): Unit = testBody(testedThing)
What it's essentially doing is taking a value x: A and a function f: A => Unit, and applying f to x to obtain f(x).
Here is how you could use it:
test("foo"){ x =>
println(if x == "foo" then "Success" else "Failure")
} // Success
test("bar"){ x =>
println(if x == "baz" then "Success" else "Failure")
} // Failure
In both cases, the "string under test" is simply passed to the body of the "test".
Now, you could introduce a few more steps between the creation of the value under test and the specification of the body. For example, you could create a TestBuilder[A], which is essentially just a value a with some bells and whistles (in this case, list of "annotations" - plain strings in the following example):
type Annotation = String
case class TestOutcome(annotations: List[Annotation], successful: Boolean)
trait Test:
def run: TestOutcome
// This simply captures the value under test of type `A`
case class TestBuilder[A](
theThingUnderTest: A,
annotations: List[Annotation]
):
// Bells and whistles: adding some metadata
def withAnnotations(moreAnnotations: List[Annotation]): TestBuilder[A] =
TestBuilder(theThingUnderTest, annotations ++ moreAnnotations)
// Combining the value under test with the body of the test produces the
// actual test
def apply(testBody: A => Unit): Test = new Test:
def run =
try {
testBody(theThingUnderTest)
TestOutcome(annotations, true)
} catch {
case t: Throwable => TestOutcome(annotations, false)
}
// This constructs the thing that's being tested, and creates a TestBuilder around it
def test[A](thingUnderTest: A) = TestBuilder(thingUnderTest, Nil)
println(
test("hello")
.withAnnotations(List("size of hello should be 5")){ h =>
assert(h.size == 5)
}
.run
)
println(
test("hello")
.withAnnotations(List("size of hello should be 42")){ h =>
assert(h.size == 42)
}
.run
)
The principle remains the same: test(a) saves the tested value a, then TestBuilder adds some configuration, and once you add a body { thingUnderTest => /* assertStuff */ } to it, you get a full Test, which you can then run to obtain some results (TestOutcomes, in this case). Thus, the above snippet produces
TestOutcome(List(size of hello should be 5),true)
TestOutcome(List(size of hello should be 42),false)
I think I did not notice that sometimes we can omit type declaration in lambda.
class tester{
def apply( fn: (Int) => Int):Int = fn(5)
}
We can write (new tester)(x => {x+1}) instead of (new tester)((x:Int) => {x+1}).

Explanation on the error with for comprehension and co-variance

Question
Would like to get assistance to understand the cause of the error. The original is from Coursera Scala Design Functional Random Generators.
Task
With the factories for random int and random boolean, trying to implement a random tree factory.
trait Factory[+T] {
self => // alias of 'this'
def generate: T
def map[S](f: T => S): Factory[S] = new Factory[S] {
def generate = f(self.generate)
}
def flatMap[S](f: T => Factory[S]): Factory[S] = new Factory[S] {
def generate = f(self.generate).generate
}
}
val intFactory = new Factory[Int] {
val rand = new java.util.Random
def generate = rand.nextInt()
}
val boolFactory = intFactory.map(i => i > 0)
Problem
The implementation in the 1st block causes the error but if it changed into the 2nd block, it does not. I believe Factory[+T] meant that Factory[Inner] and Factory[Leaf] could be both treated as Factory[Tree].
I have no idea why the same if expression in for block is OK but it is not OK in yield block. I appreciate explanations.
trait Tree
case class Inner(left: Tree, right: Tree) extends Tree
case class Leaf(x: Int) extends Tree
def leafFactory: Factory[Leaf] = intFactory.map(i => new Leaf(i))
def innerFactory: Factory[Inner] = new Factory[Inner] {
def generate = new Inner(treeFactory.generate, treeFactory.generate)
}
def treeFactory: Factory[Tree] = for {
isLeaf <- boolFactory
} yield if (isLeaf) leafFactory else innerFactory
^^^^^^^^^^^ ^^^^^^^^^^^^
type mismatch; found : Factory[Inner] required: Tree
type mismatch; found : Factory[Leaf] required: Tree
However, below works.
def treeFactory: Factory[Tree] = for {
isLeaf <- boolFactory
tree <- if (isLeaf) leafFactory else innerFactory
} yield tree
I have no idea why the same if expression in for block is OK but it is
not OK in yield block
Because they are translated differently by the compiler. The former example is translated into:
boolFactory.flatMap((isLeaf: Boolean) => if (isLeaf) leafFactory else innerFactor)
Which yields the expected Factory[Tree], while the latter is being translated to:
boolFactory.map((isLeaf: Boolean) => if (isLeaf) leafFactory else innerFactory)
Which yields a Factory[Factory[Tree]], not a Factory[Tree], thus not conforming to your method signature. This isn't about covariance, but rather how for comprehension translates these statements differently.

How to pass a code block to function?

I am trying to create a try clause analogue which repeats code block if exception occurred inside this code block.
def retry(attempts: Int)(func: Unit => Unit) {
var attempt = 0
while (attempt < attempts) {
attempt += 1
try {
func()
} catch {
case _: Throwable =>
}
}
throw new Exception()
}
I expect that it can be used like this
retry(10) { // I would like to pass this block as function
val res = someNotReliableOp(); // <- exception may occur here
print(res)
}
But it doesn't work:
Operations.scala:27: error: type mismatch;
found : Unit
required: Unit => Unit
print(res)
^
one error found
What is the most concise way to pass custom block to my function?
You just need to change your method definition a tiny bit:
def retry(attempts: Int)(func: => Unit)
Unit => Unit means: a function that takes a parameter with a type of Unit and evaluates to Unit.
=> Unit means: a function that takes no parameters and evaluates to Unit. This is called call by name.
Consider
def retry(attempts: Int)(func: => Unit) {
for {
i <- Stream range (0, attempts)
v = Try (func()) toOption
if (v == None)
} ()
}
The for comprehension will invoke func up to an attempts number of times and will stop streaming if the invocation to func succeeds, namely if Try(func) toOption does not deliver None.
For each iteration in the for comprehension, the do-nothing () function is called.
If interested in details on each failure for func, consider replacing the Try in the comprehension with
v = Try(func()) match {
case Success(x) => Some(())
case Failure(x) => println(x) ; None
}
which preserves the semantics initially suggested, yet it extracts information on each failed attempt.

Implement transaction aspect in Scala

I would like to implement utility function/monad/aspect for managing hibernate transactions in scala, and looking for advice about best approach.
First I tried to create currying function like following:
def session() = sessionFactory.getCurrentSession()
def transaction() = session().getTransaction()
def tx[A, B](f: A => B)(a: A): B = {
try {
session().beginTransaction()
val r = f(a)
transaction().commit()
return r
} catch {
case e:
Throwable =>
transaction().rollback()
throw e
} finally {
session.close()
}
}
The idea was that I can do following with this function:
def saveMyEntity() {
session().save(new MyEntity)
}
tx(saveMyEntity)()
and saveMyEntity call will be wrapped into transaction.
Unfortunately I get following error with this code:
[error] found : () => Unit
[error] required: ? => ?
[error] tx(saveMyEntity)()
I still learning scala, and looking for advice to improve my approach. Maybe I can modify my function somehow to achieve better results? Or add another Unit type specific function? Or choose another path?
Any ideas?
Any scala canonical way to implement this?
Thanks.
Method tx accepts function of 1 argument as parameter and method saveMyEntity accepts no arguments, so you can't use it as A => B (function of 1 argument).
You are not using a and f separately, so there is no need in a. You could use by-name parameters here:
def tx[B](f: => B): B = {
If you want to use a saveMyEntity as Unit => Unit you should create function explicitly:
tx[Unit, Unit](_ => saveMyEntity)(())
I guess some changes may improve your code readability:
import util.control.Exception.allCatch
def withSession[T](f: Session => T):T = {
val session = ??? // start session here
allCatch.anfFinally{
session.close()
} apply { f(session) }
}
def inTransaction[T](f: => T): T =
withSession{ session =>
session().beginTransaction()
try {
val r = f(a)
transaction().commit()
r
} catch {
case e: Throwable =>
transaction().rollback()
throw e
}
}
inTransaction{saveMyEntity}
object TestTransaction
{
def executeInTransaction(f: => Unit)={
println("begin")
f
println("end")
}
executeInTransaction {
println("action!")
}
}
produces:
begin
action!
end

Why is a return statement required to allow this while statement to be evaluated properly?

Why is a return statement required to allow this while statement to be
evaluated properly? The following statement allows
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.io.BufferedReader
import java.io.InputStreamReader
trait Closeable {
def close ()
}
trait ManagedCloseable extends Closeable {
def use (code: () => Unit) {
try {
code()
}
finally {
this.close()
}
}
}
class CloseableInputStream (stream: InputStream)
extends InputStream with ManagedCloseable {
def read = stream.read
}
object autoclose extends App {
implicit def inputStreamToClosable (stream: InputStream):
CloseableInputStream = new CloseableInputStream(stream)
override
def main (args: Array[String]) {
val test = new FileInputStream(new File("test.txt"))
test use {
val reader = new BufferedReader(new InputStreamReader(test))
var input: String = reader.readLine
while (input != null) {
println(input)
input = reader.readLine
}
}
}
}
This produces the following error from scalac:
autoclose.scala:40: error: type mismatch;
found : Unit
required: () => Unit
while (input != null) {
^
one error found
It appears that it's attempting to treat the block following the use as an
inline statement rather than a lambda, but I'm not exactly sure why. Adding
return after the while alleviates the error:
test use {
val reader = new BufferedReader(new InputStreamReader(test))
var input: String = reader.readLine
while (input != null) {
println(input)
input = reader.readLine
}
return
}
And the application runs as expected. Can anyone describe to me what is going
on there exactly? This seems as though it should be a bug. It's been
persistent across many versions of Scala though (tested 2.8.0, 2.9.0, 2.9.1)
That's because it's use is declared as () => Unit, so the compiler expects the block you are giving use to return something that satisfies this signature.
It seems that what you want is to turn the entire block into a by-name parameter, to do so change def use (code : () => Unit) to def use (code : => Unit).
() => Unit is the type of a Function0 object, and you've required the use expression to be of that type, which it obviously isn't. => Unit is a by name parameter, which you should use instead.
You might find my answer to this question useful.
To go the heart of the matter, blocks are not lambdas. A block in Scala is a scope delimiter, nothing more.
If you had written
test use { () =>
val reader = new BufferedReader(new InputStreamReader(test))
var input: String = reader.readLine
while (input != null) {
println(input)
input = reader.readLine
}
}
Then you'd have a function (indicated by () =>) which is delimited by the block.
If use had been declared as
def use (code: => Unit) {
Then the syntax you used would work, but not because of any lambda thingy. That syntax indicates the parameter is passed by name, which, roughly speaking, means you'd take the whole expression passed as parameter (ie, the whole block), and substitute it for code inside the body of use. The type of code would be Unit, not a function, but the parameter would not be passed by value.
return or return expr has the type Nothing. You can substitute this for any type, as it never yields a value to the surrounding expression, instead it returns control to the caller.
In your program, it masquerades as the required type () => Unit.
Here's an occasionally convenient use for that (although you might be tarnished as unidiomatic if you use it too often, don't tell anyone you heard this from me!)
def foo(a: Option[Int]): Int = {
val aa: Int = a.getOrElse(return 0)
aa * 2
}
For the record, you should probably write:
def foo(a: Option[Int]): Int =
a.map(_ * 2).getOrElse(0)
You can get an insight into the mind of the compiler by checking the output of scala -Xprint:typer -e <one-liner>. Add -Ytyper-debug if you like sifting through the reams of output!
scala210 -Ytyper-debug -Xprint:typer -e 'def foo: Any = {val x: () => Any = { return }}'
... elided ...
typed return (): Nothing
adapted return (): Nothing to () => Any,