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

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}).

Related

Cake pattern for deep function call chain ( threading dependency along as extra parameter)

Question on simple example:
Assume we have :
1) 3 functions:
f(d:Dependency), g(d:Dependency), h(d:Dependency)
and
2) the following function call graph : f calls g, g calls h
QUESTION: In h I would like to use the d passed to f, is there a way to use the cake pattern to get access to d from h? If yes, how ?
Question on real-world example:
In the code below I manually need to thread the Handler parameter from
// TOP LEVEL , INJECTION POINT
to
//USAGE OF Handler
Is it possible to use the cake pattern instead of the manual threading? If yes, how ?
package Demo
import interop.wrappers.EditableText.EditableText
import interop.wrappers.react_sortable_hoc.SortableContainer.Props
import japgolly.scalajs.react.ReactComponentC.ReqProps
import japgolly.scalajs.react._
import japgolly.scalajs.react.vdom.prefix_<^._
import interop.wrappers.react_sortable_hoc.{SortableContainer, SortableElement}
object EditableSortableListDemo {
trait Action
type Handler=Action=>Unit
object CompWithState {
case class UpdateElement(s:String) extends Action
class Backend($: BackendScope[Unit, String],r:Handler) {
def handler(s: String): Unit =
{
println("handler:"+s)
$.setState(s)
//USAGE OF Handler <<<<<=======================================
}
def render(s:String) = {
println("state:"+s)
<.div(<.span(s),EditableText(s, handler _)())
}
}
val Component = (f:Handler)=>(s:String)=>
ReactComponentB[Unit]("EditableText with state").initialState(s).backend(new Backend(_,f))
.renderBackend.build
}
// Equivalent of ({value}) => <li>{value}</li> in original demo
val itemView: Handler=>ReqProps[String, Unit, Unit, TopNode] = (f:Handler)=> ReactComponentB[String]("liView")
.render(d => {
<.div(
<.span(s"uhh ${d.props}"),
CompWithState.Component(f)("vazzeg:"+d.props)()
)
})
.build
// As in original demo
val sortableItem = (f:Handler)=>SortableElement.wrap(itemView(f))
val listView = (f:Handler)=>ReactComponentB[List[String]]("listView")
.render(d => {
<.div(
d.props.zipWithIndex.map {
case (value, index) =>
sortableItem(f)(SortableElement.Props(index = index))(value)
}
)
})
.build
// As in original demo
val sortableList: (Handler) => (Props) => (List[String]) => ReactComponentU_ =
(f:Handler)=>SortableContainer.wrap(listView(f))
// As in original SortableComponent
class Backend(scope: BackendScope[Unit, List[String]]) {
def render(props: Unit, items: List[String]) = {
def handler = ???
// TOP LEVEL , INJECTION POINT<<<<<<========================================
sortableList(handler)(
SortableContainer.Props(
onSortEnd = p => scope.modState( l => p.updatedList(l) ),
useDragHandle = false,
helperClass = "react-sortable-handler"
)
)(items)
}
}
val defaultItems = Range(0, 10).map("Item " + _).toList
val c = ReactComponentB[Unit]("SortableContainerDemo")
.initialState(defaultItems)
.backend(new Backend(_))
.render(s => s.backend.render(s.props, s.state))
.build
}

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.

catch a string in boolean option

How do I prevent error when someone does not choose one of the options in scala. This is using Map to get options and I tried to implement Try and catch blocks in case options but it does not work. I'm not sure if this is the right way to do it, if there is any other way let me know. The error is Exception in thread "main" java.lang.NumberFormatException: For input string: "e".
object main extends menu {
def main(args: Array[String]): Unit = {
var opt = 0
do { opt = readOption }
while (menu(opt))
}
}
class menu extends database {
def menu(option: Int): Boolean = try {
actionMap.get(option) match {
case Some(a) => a()
case None => println("That didn't work.")
false
}
} catch {
case _: NumberFormatException => true
}
val actionMap = Map[Int, () => Boolean](1 -> cWords, 2 -> cCharacters, 3 -> exit)
def readOption: Int = {
println(
"""|Please select one of the following:
| 1 - Count Words
| 2 - Count Characters in words
| 3 - quit""".stripMargin)
StdIn.readInt()
}
Use scala.util.Try on readInt(),
import scala.io._
import scala.util._
Try(StdIn.readInt()).toOption
// returns Some(123) for input 123
Try(StdIn.readInt()).toOption
// returns None for input 1a3
Thus readOption delivers Option[Int]. Then
def menu(option: Option[Int]): Boolean = option match {
case Some(a) => actionMap(a)()
case None => println("Try again..."); false
}
Note
A more concise version of main,
def main(args: Array[String]): Unit = while (menu(readOption)) ()
Namely, while menu is true do Unit (or () ).
Here is some working implementation:
import scala.io.StdIn
import scala.util.Try
object Main extends Menu with App {
while (menu(readChoice)) ()
}
class Menu {
val actionMap = Map[Int, () => Boolean](1 -> (() => true), 2 -> (() => true), 3 -> (() => false))
def menu(choice: Option[Int]): Boolean = {
choice.flatMap(actionMap.get)
.map(action => action())
.getOrElse({ println("That didn't work."); false })
}
def readChoice: Option[Int] = {
println(
"""|Please select one of the following:
| 1 - Count Words
| 2 - Count Characters in words
| 3 - quit""".stripMargin)
Try(StdIn.readInt).toOption
}
}
For the first, you can mixin App trait to skip main method boilerplate.
You can simplify your do while loop like this, it has to do nothing inside so you either need some expression or block. A Unit value can be your expression that does nothing.
In scala we name classes using camel case, starting with capital letter.
As readInt throws whenever input is wrong you can catch that using Try, that will return Success(result) of Failure(exception) and change this result to an Option to discard the exception.
what happens in menu is shorthand for
choice match {
case Some(number) =>
actionMap.get(number) match {
case Some(action) =>
action()
case None =>
println("That didn't work.")
false
}
case None =>
println("That didn't work.")
false
}
And could be as well written with for
(for {
number <- choice
action <- actionMap.get(number)
} yield {
action()
}) getOrElse {
println("That didn't work.")
false
}
On as sidenote, you named choice of user an "option" which unfortunately is also a scala class used here extensively, I renamed the variables to avoid confusion.
I would make readOption return a Try[Int], (a Try surrounding StdIn.readInt()), then deal with the possible cases in the menu function

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

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

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.