Have && short circuit with :| in expressions in ScalaCheck - scala

I am attempting to create a property-based test in a Scala Test FlatSpec that uses the ScalaCheck :| operator to give failure messages for different parts of the ending boolean expression.
However, I am running into an issue where the && operator does not short circuit. In this case the earlier part of the expression checks to see if the next part of the expression can be run, otherwise that later section would throw an exception.
Here is an example of what the issue looks like. If decoded is None, then the expression should short circuit on the && so that decoded.get is not run, as it would throw an exception.
val value: Array[Int] = Array.fill(2)(0)
val encoded = encode(value)
val decoded: Option[Array[Int]] = decode(value)
decoded.isDefined :| "decoded None" &&
value.sameElements(decoded.get)
When I write the boolean without using the :| operator to give a failure message, the test fails on the decoded.isDefined without throwing an exception.
val value: Array[Int] = Array.fill(2)(0)
val encoded = encode(value)
val decoded: Option[Array[Int]] = decode(value)
decoded.isDefined &&
value.sameElements(decoded.get)
However, when I include a failure message with :|, it fails with a NoSuchElementException on the value.sameElements(decoded.get) line and does not display the failure message for decoded.isDefined even though it would evaluate to false.
The imports and test class declaration I am using are the following:
import org.scalacheck.Prop._
import org.scalatest.prop.Checkers
import org.scalatest.{FlatSpec, Matchers}
class ByteRWTests extends FlatSpec with Matchers with Checkers {
I am writing property checks in the following manner:
it should "be equal" in {
check(
forAll { (int: Int) =>
int == int
}
)
}
Is there any way to get the short circuiting for && to work with expressions using :|, or is there a workaround for this issue?

Why you see the difference
The issue is that while the && for booleans is short-circuiting, the && method on Prop isn't, and whether or not you use a label determines where the implicit conversion from boolean to Prop happens. For example:
import org.scalacheck.Prop, Prop._
val value: Array[Int] = Array.fill(2)(0)
val decoded: Option[Array[Int]] = None
val p1: Prop = decoded.isDefined && value.sameElements(decoded.get)
val p2: Prop = decoded.isDefined :| "decoded None" && value.sameElements(decoded.get)
Here the p1 definition desugars to this:
Prop.propBoolean(decoded.isDefined && value.sameElements(decoded.get))
While p2 gives you this:
(Prop.propBoolean(decoded.isDefined) :| "decoded None").&&(
Prop.propBoolean(value.sameElements(decoded.get))
)
(For what it's worth this is another example of why I don't like fancy implicit-conversion-based DSLs.)
Workaround
Unfortunately it's just not possible to get the && method on Prop to do what you want here, but you can define your own version of conjunction that does:
def propAnd(p1: => Prop, p2: => Prop) = p1.flatMap { r =>
if (r.success) Prop.secure(p2) else Prop(_ => r)
}
And then:
scala> propAnd(decoded.isDefined :| "decoded None" , value.sameElements(decoded.get))
res1: org.scalacheck.Prop = Prop
scala> .check
! Falsified after 0 passed tests.
> Labels of failing property:
decoded None
This method actually exists in ScalaCheck, but it's not part of the public API. A comment on the implementation does note that it "(Should maybe be in Prop module)", so if you find you're doing this kind of thing a lot, you might try opening a pull request to move the method from Commands to Prop and make it public.
In the specific case you've given here, though, I'd probably suggest using something like exists on the Option instead of checking whether it's defined and then using get.

Related

Need help in solving type mismatch error (value is not a member of Double) in Scala

I am using Amazon Deequ Scala library for data quality check. The format for calling methods in Deequ library below
checks = hasDistinctness(Seq("column1","column2"), _ >= 0.70)
I was planning to pass the condition check(>= 0.70) from config file.
code:
val chk_val = config.getString("chk_val")
println(chk_val) // ">= 0.70"
checks = hasDistinctness(Seq("column1","column2"),_ chk_val)
Method definition in Deequ library:
def hasDistinctness(
columns: Seq[String], assertion: Double => Boolean,
hint: Option[String] = None)
: CheckWithLastConstraintFilterable = {
addFilterableConstraint { filter => distinctnessConstraint(columns, assertion, filter, hint) }
}
Error:
Error: value chk_val is not a member of Double
How to solve this issue?
_ >= 0.70 is a function that compares it's element with 0.70. desugaring the _ it would look like value => value >= o.70
Compiler understands _ chk_val as a postfix-notation call to chk_val on whatever is passed to the function. Desugared, it would look like value => value.chk_val
Obviously, there is no chk_val member on the Double - and that's exactly what compiler tells you.
So, _ is not a black magic - it doesn't just magically parse the string and turn it into executable code :) In order to get the condition from the config file, you'd need to parse it into a function - probably the most straightforward (and risky, and probably compiler will not type check it) is to use some sort of eval functionality (e.g. see this answer, or this question).
The faster, easier and more straightforward (but probably less flexible and less scalable) approach is to probably define a parser yourself. Something along the lines of:
def parseCondition(input: String): Double => Boolean = {
val splitInput = input.split(" ")
// You might want to add some validation - e.g. ">=0.7" will just throw here
val (operator, operand) = (splitInput.first, splitInput.last)
operator match {
case ">=": _ >= operand
case ">": _ > operand
case "<": _ < operand
...
}
}
Or maybe use Atto::
Atto homepage
article on how to use it

Scalastyle Boolean expression can be simplified

Scalastyle (intellij 2016.1 defaults) says this boolean expression can be simplified
val t = Option(true)
val f = Option(false)
if(t.contains(true) && f.contains(false)) {
println("booop")
}
I can get rid of this by changing the if to:
if(t.contains(true).&&(f.contains(false)))
Or by changing && to &
But not really seeing how this is simplifying it, could anyone explain what's going on?
Update
It doesn't appear to be related to if the vals are known at compile time, or them being locally defined. The following code also get's the warning that the expression can be simplfied:
object TestFoo {
def bar(t: Option[Boolean]) = {
val f = Option(scala.util.Random.nextBoolean)
if (t.contains(true) && f.contains(false)) println("booop")
}
def main(args: Array[String]) = bar(t = Option(scala.util.Random.nextBoolean))
}
I just don't get how I'm supposed to make that any simpler, is there some strange Option[Boolean] comparing I'm missing out on?
It seems to suggest you being consistent with the method call usage. Either everything in infix form:
(t contains true) && (f contains false)
Or everything in regular method call form:
t.contains(true).&&(f.contains(false))
With your values, t.contains(true).&&(f.contains(false)) always returns true. So you could simplify it by simply writing true, i.e by just executing the print without an if condition.

how do I build with scalac using Leon's library?

I am trying to compile my Leon code using scalac directly. Unfortunately, I was not able to properly build the Leon library on which the code depends.
For instance, I have run
scalac $(find ~/my-path/leon/library/ -name "*.scala" | xargs) Queue.scala
But this actually returns errors:
.../leon/library/collection/List.scala:81: error: missing parameter type for expanded function ((x$2) => x$2.size.$eq$eq(if (i.$less$eq(0))
BigInt(0)
else
if (i.$greater$eq(this.size))
this.size
else
i))
}} ensuring { _.size == (
^
What should be passed to scalac to avoid those errors in the library and ultimately compile my own source file?
Thank you!
First of all, I suspect that the attempt here was to execute Leon programs, if so, there is a new option called --eval which will evaluate all ground functions (you can filter it further through --functions as usual). This should prevent issues with skeleton implementations being non-executable.
About the compilation issue: it should now be fixed in https://github.com/epfl-lara/leon/commit/3d73c6447916516d0ad56806fe0febf7b30a71ad
This was due to type-inference not being able to track types from the declared return type, through the untyped ensuring, to the body of the function. This causes Nil() to be imprecisely typed in the body, which in turn causes the type-less closure to be rejected.
Why did this work within Leon? Leon inserts a phase in the Scala compiler pipeline before type-checking to inject hints that make this inference possible (and convenient), since the pattern
def foo(a: A): B = { a match {
case ..
case ..
}} ensuring { .. }
is so frequent in Leon programs.
Oddly enough, writing something like:
def take(i: BigInt): List[T] = { val res: List[T] = (this, i) match {
case (Nil(), _) => Nil()
case (Cons(h, t), i) =>
if (i <= BigInt(0)) {
Nil()
} else {
Cons(h, t.take(i-1))
}
}; res} ensuring { _.size == (
if (i <= 0) BigInt(0)
else if (i >= this.size) this.size
else i
)}
...makes it clearly explicit. Scalac was not able to infer the proper parameter type, but this makes the return type of the first block explicit enough. Note however that this is not a problem using Leon directly, and that is a common syntax used throughout the Leon library, not my code.
By changing all functions as explained above I was able to compile the Leon Library - but not to run the project using normal scala syntax, since the set implementation in https://github.com/epfl-lara/leon/blob/master/library/lang/Set.scala, which is somehow not used by Leon, is missing.
Following Etienne post:
That works, but we still need to implement sets in https://github.com/epfl-lara/leon/blob/master/library/lang/Set.scala. I did it that way:
package leon.lang
import leon.annotation._
import scala.collection.{ immutable => imm }
object Set {
#library
def empty[T] = Set[T]()
protected[Set] def apply[T](elems: imm.Set[T]): Set[T] = Set(elems.toSeq :_*)
}
#ignore
case class Set[T](elems: T*) {
def +(a: T): Set[T] = Set(elems.toSet + a)
def ++(a: Set[T]): Set[T] = Set(elems.toSet ++ a.elems.toSet) //Set.trim(elems ++ a.elems) //Set((elems.toSeq ++ a.elems.toSeq).toSet.toSeq :_*)
def -(a: T): Set[T] = Set(elems.toSet - a)
def --(a: Set[T]): Set[T] = Set(elems.toSet -- a.elems.toSet)
def contains(a: T): Boolean = elems.toSet.contains(a)
def isEmpty: Boolean = this == Set.empty
def subsetOf(b: Set[T]): Boolean = elems.toSet.forall(e => b.elems.toSet.contains(e))
def &(a: Set[T]): Set[T] = Set(elems.toSet & a.elems.toSet)
}
Unfortunately this cannot be used directly as is in Leon:
[ Error ] 8:31: Scala's Set API is no longer extracted. Make sure you import leon.lang.Set that defines supported Set operations.
protected[Set] def apply[T](elems: imm.Set[T]): Set[T] = Set(elems.toSeq :_*)
^^^^^^^^^^^^^^^^^
But it works fine for compiling with scalac and running with scala using:
scalac $(find ~/my-path/leon/library/ -name "*.scala" | xargs) Queue.scala
Anyway, if --eval does the trick, let's just use it!
Thank you!

How to test if a `Some[String]` contains some other string?

Say I have a value which is Some("aaabbbccc"), I want to test if the value inside the Some contain some other string.
I tried:
val myvalue = Some("aaabbbccc")
myvalue must beSome(contain("bbb"))
It can't compile, but I can't find out a working one.
How to write such an assertion?
You may run into such cases
None must be none
Some("foo") must beSome(contain("f"))
These two statements won't compile.
Compiler will complains
method apply in trait MatchResult cannot be accessed in org.specs2.matcher.MatchResult[Option[T]]
[error] None must be none
[error]
^
Just put a ; at the end of the first statement and everything will be fine
You could try using a custom matcher like the following, taken straight out of the documentation: http://www.scalatest.org/user_guide/matchers_quick_reference
val beOdd =
Matcher { (left: Int) =>
MatchResult(
left % 2 == 1,
left + " was not odd",
left + " was odd"
)
}
3 should beOdd
That said.. perhaps there is a nice scala way of expressing what you're after.
I just saw the string include matcher, but how it could work with an Option[String]..?
string should include ("seven")
Ok.. got it:
option.value should be < 7
Which in your case would be:
myvalue should be ('defined)
myvalue.value should include ("bbb")
scala> val myvalue = Some("aaabbbccc")
myvalue: Some[String] = Some(aaabbbccc)
scala> myvalue exists (_.contains("bbb"))
res0: Boolean = true
scala> myvalue exists (_.contains("abc"))
res1: Boolean = false
You can adapt this easily to specs2:
(myvalue exists (_.contains("bbb"))) must beTrue
The real choice is in how you want the test to react in case myValue happens to be None. If you want it to fail on None, use the above. If you want it to succeed, use this instead:
(myValue forall (_.contains("bbb"))) must beTrue
In both cases, it will do the test you want on Some.

How to write this three-liner as a one-liner?

I like the way, you can write one-liner-methods in Scala, e.g. with List(1, 2, 3).foreach(..).map(..).
But there is a certain situation, that sometimes comes up when writing Scala code, where things get a bit ugly. Example:
def foo(a: A): Int = {
// do something with 'a' which results in an integer
// e.g. 'val result = a.calculateImportantThings
// clean up object 'a'
// e.g. 'a.cleanUp'
// Return the result of the previous calculation
return result
}
In this situation we have to return a result, but can not return it directly after the calculation is done, because we have to do some clean up before returning.
I always have to write a three-liner. Is there also a possibility to write a one-liner to do this (without changing the class of A, because this may be a external library which can not be changed) ?
There are clearly side-effects involved here (otherwise the order of invocation of calculateImportantThings and cleanUp wouldn't matter) so you would be well advised to reconsider your design.
However, if that's not an option you could try something like,
scala> class A { def cleanUp {} ; def calculateImportantThings = 23 }
defined class A
scala> val a = new A
a: A = A#927eadd
scala> (a.calculateImportantThings, a.cleanUp)._1
res2: Int = 23
The tuple value (a, b) is equivalent to the application Tuple2(a, b) and the Scala specification guarantees that its arguments will be evaluated left to right, which is what you want here.
This is a perfect use-case for try/finally:
try a.calculateImportantThings finally a.cleanUp
This works because try/catch/finally is an expression in scala, meaning it returns a value, and even better, you get the cleanup whether or not the calculation throws an exception.
Example:
scala> val x = try 42 finally println("complete")
complete
x: Int = 42
There is, in fact, a Haskell operator for just such an occasion:
(<*) :: Applicative f => f a -> f b -> f a
For example:
ghci> getLine <* putStrLn "Thanks for the input!"
asdf
Thanks for the input!
"asdf"
All that remains then is to discover the same operator in scalaz, since scalaz usually replicates everything that Haskell has. You can wrap values in Identity, since Scala doesn't have IO to classify effects. The result would look something like this:
import scalaz._
import Scalaz._
def foo(a: A): Int =
(a.calculateImportantThings.pure[Identity] <* a.cleanup.pure[Identity]).value
This is rather obnoxious, though, since we have to explicitly wrap the side-effecting computations in Identity. Well the truth is, scalaz does some magic that implicitly converts to and from the Identity container, so you can just write:
def foo(a: A): Int = Identity(a.calculateImportantThings) <* a.cleanup()
You do need to hint to the compiler somehow that the leftmost thing is in the Identity monad. The above was the shortest way I could think of. Another possibility is to use Identity() *> foo <* bar, which will invoke the effects of foo and bar in that order, and then produce the value of foo.
To return to the ghci example:
scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._
scala> val x : String = Identity(readLine) <* println("Thanks for the input!")
<< input asdf and press enter >>
Thanks for the input!
x: String = asdf
Maybe you want to use a kestrel combinator? It is defined as follows:
Kxy = x
So you call it with the value you want to return and some side-effecting operation you want to execute.
You could implement it as follows:
def kestrel[A](x: A)(f: A => Unit): A = { f(x); x }
... and use it in this way:
kestrel(result)(result => a.cleanUp)
More information can be found here: debasish gosh blog.
[UPDATE] As Yaroslav correctly points out, this is not the best application of the kestrel combinator. But it should be no problem to define a similar combinator using a function without arguments, so instead:
f: A => Unit
someone could use:
f: () => Unit
class Test {
def cleanUp() {}
def getResult = 1
}
def autoCleanup[A <: Test, T](a: A)(x: => T) = {
try { x } finally { a.cleanUp }
}
def foo[A <: Test](a:A): Int = autoCleanup(a) { a.getResult }
foo(new Test)
You can take a look at scala-arm project for type class based solution.
Starting Scala 2.13, the chaining operation tap can be used to apply a side effect (in this case the cleanup of A) on any value while returning the original value untouched:
def tap[U](f: (A) => U): A
import util.chaining._
// class A { def cleanUp { println("clean up") } ; def calculateImportantThings = 23 }
// val a = new A
val x = a.calculateImportantThings.tap(_ => a.cleanUp)
// clean up
// x: Int = 23
In this case tap is a bit abused since we don't even use the value it's applied on (a.calculateImportantThings (23)) to perform the side effect (a.cleanUp).