I'm trying to solve two ScalaCheck (+ specs2) problems:
Is there any way to change the number of cases that ScalaCheck generates?
How can I generate strings that contain some Unicode characters?
For example, I'd like to generate about 10 random strings that include both alphanumeric and Unicode characters. This code, however, always generates 100 random strings, and they are strictly alpha character based:
"make a random string" in {
def stringGenerator = Gen.alphaStr.suchThat(_.length < 40)
implicit def randomString: Arbitrary[String] = Arbitrary(stringGenerator)
"the string" ! prop { (s: String) => (s.length > 20 && s.length < 40) ==> { println(s); success; } }.setArbitrary(randomString)
}
Edit
I just realized there's another problem:
Frequently, ScalaCheck gives up without generating 100 test cases
Granted I don't want 100, but apparently my code is trying to generate an overly complex set of rules. The last time it ran, I saw "gave up after 47 tests."
The "gave up after 47 tests" error means that your conditions (which include both the suchThat predicate and the ==> part) are too restrictive. Fortunately it's often not too hard to bake these into your generator, and in your case you can write something like this (which also addresses the issue of picking arbitrary characters, not just alphanumeric ones):
val stringGen: Gen[String] = Gen.chooseNum(21, 40).flatMap { n =>
Gen.buildableOfN[String, Char](n, arbitrary[Char])
}
Here we pick an arbitrary length in the desired range and then pick that number of arbitrary characters and concatenate them into a string.
You could also increase the maxDiscardRatio parameter:
import org.specs2.scalacheck.Parameters
implicit val params: Parameters = Parameters(maxDiscardRatio = 1024)
But that's typically not a good idea—if you're throwing away most of your generated values your tests will take longer, and refactoring your generator is generally a lot cleaner and faster.
You can also decrease the number of test cases by setting the appropriate parameter:
implicit val params: Parameters = Parameters(minTestsOk = 10)
But again, unless you have a good reason to do this, I'd suggest trusting the defaults.
Related
The following simple code converts an Integer value to a string value and logs it.
module Main where
import Effect (Effect)
import Effect.Console (log)
import Prelude ((<>), Unit, discard)
import Data.Int (toStringAs, radix)
type CustomerFeedback = {
customerServiceScore :: Int,
productQualityScore :: Int,
onTimeDeliveryScore :: Int
}
feedback :: CustomerFeedback
feedback = {
customerServiceScore : 4,
productQualityScore : 2,
onTimeDeliveryScore : 6
}
stringifyCustomerFeedback :: CustomerFeedback -> String
stringifyCustomerFeedback feedback = "Service: " <> toStringAs (radix 10) feedback.customerServiceScore
main ∷ Effect Unit
main = do
log (stringifyCustomerFeedback(feedback))
However, running this code produces the following error:
Could not match type
Maybe Radix
with type
Radix
while checking that type Maybe Radix
is at least as general as type Radix
while checking that expression radix 10
has type Radix
in value declaration stringifyCustomerFeedback
Questions would be as follows:
How do you change the code above so it outputs a string as expected and not an error?
What's the point of a Maybe Radix type if using it where you would use a Radix causes an error? How do you use a Maybe value?
The idea of the radix function is that you give it a number and it creates a Radix from it. But not every number constitutes a valid Radix. For example, if you give it -5, it shouldn't work. And neither should 0 or 1 for example. For some technical reasons, radices above 32 are also deemed invalid.
So that's why it returns Maybe: it would be Nothing in case the number you gave it wasn't a "valid" radix.
And the use case for that function is when you don't actually know the number ahead of time. Like if you get it from the user. Or from some sort of config file or whatnot. In that case, if you get a Nothing, you would interpret that as "invalid user input" or "corrupted config file" and report an error accordingly. And you won't even get as far as calling toStringAs. This is one of the big selling points of static types: applied properly, they can force you to write a correct, reliable program, without ignoring edge cases.
However, in case you already know that you're interested in decimal radix, just use decimal. It's a Maybe-free constant provided by the library, along with some other frequently used ones, such as binary and octal.
stringifyCustomerFeedback feedback = "Service: " <> toStringAs decimal feedback.customerServiceScore
I have the following cython function.
01:
+02: cdef int count_char_in_x(unicode x,Py_UCS4 c):
03: cdef:
+04: int count = 0
05: Py_UCS4 x_k
06:
+07: for x_k in x: ## Yellow
+08: if x_k == c:
+09: count+=1
10:
+11: return count
Line 07 is not properly optimized.
The annotated HTML code is expanded as:
+07: for x_k in x: ## Yellow
if (unlikely(__pyx_v_x == Py_None)) {
PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
__PYX_ERR(0, 8, __pyx_L1_error)
}
__Pyx_INCREF(__pyx_v_x);
__pyx_t_1 = __pyx_v_x;
__pyx_t_6 = __Pyx_init_unicode_iteration(__pyx_t_1, (&__pyx_t_3), (&__pyx_t_4), (&__pyx_t_5)); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(0, 8, __pyx_L1_error)
for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_3; __pyx_t_7++) {
__pyx_t_2 = __pyx_t_7;
__pyx_v_x_k = __Pyx_PyUnicode_READ(__pyx_t_5, __pyx_t_4, __pyx_t_2);
Any tips on how could this be improved?
I think it is possible to write a cdef/cpdef function that at runtime completly avoids Python None type checks. Any idea on how this could be done?
The generated C code looks pretty good to me. The loop overall is a int-iterated for loop (i.e. it's not relying on calling the Python methods __iter__ and __next__).
__Pyx_PyUnicode_READ is translated pretty directly to PyUnicode_READ (depending slightly on the Python version you're using). PyUnicode_READ is a C macro which is as close to a direct array access as you can get.
This is probably as good as it's getting. You might get a small improvement by using bytes rather than unicode (provided you're dealing with ASCII characters). You might just consider whether it's really worth reimplementing unicode.count.
If it were a regular def function you could declare x as unicode not None to remove the None check before the loop. That might make a small difference. However, as #ead points out that isn't supported for cdef functions. It's likely the cost of a def function call will be slightly larger than the cost of a None-check, but you should time it if you care.
I have two questions. The first one: is code a pure expression?
lazy val code: Unit = {
// block of code
var s = "abc"
for (i <- 0 until 10) println(i)
s += s concat "def"
println(s)
}
And the second one: What does a pure expression mean? Is this a some code which does not return anything?
A pure expression is a computation that serves only to produce a resulting value - it has no side effects. In the case of your field code above, you make calls to print stuff to the console (println), which is considered a side effect, so it is not a pure expression. An example of a pure expression would be something like:
lazy val foo = 2 + 3
It does nothing apart from generate the final value for foo, and could safely be replaced by the result of the computation (5) without changing the outcome of the program in any way. If you made such a replacement in your code above:
lazy val code: Unit = ()
you would change the program - it no longer prints anything to the console.
Have a look here, for example, for more information about pure functions and pure expressions, and their significance in functional programming.
I have the following code, but I can't get it to work. As soon as I place a while loop inside the case, it's returning a unit, no matter what I change within the brackets.
case While(c, body) =>
while (true) {
eval(Num(1))
}
}
How can I make this while loop return a non-Unit type?
I tried adding brackets around my while condition, but still it doesn't do what it's supposed to.
Any pointers?
Update
A little more background information since I didn't really explain what the code should do, which seems to be handy if I want to receive some help;
I have defined a eval(exp : Exp). This will evaluate a function.
Exp is an abstract class. Extended by several classes like Plus, Minus (few more basic operations) and a IfThenElse(cond : Exp, then : Exp, else : Exp). Last but not least, there's the While(cond: Exp, body: Exp).
Example of how it should be used;
eval(Plus(Num(1),Num(4)) would result in NumValue(5). (Evaluation of Num(v : Value) results in NumValue(v). NumValue extends Value, which is another abstract class).
eval(While(Lt(Num(1),Var("n")), Plus(Num(1), Var("n"))))
Lt(a : Exp, b : Exp) returns NumValue(1) if a < b.
It's probably clear from the other answer that Scala while loops always return Unit. What's nice about Scala is that if it doesn't do what you want, you can always extend it.
Here is the definition of a while-like construct that returns the result of the last iteration (it will throw an exception if the loop is never entered):
def whiley[T](cond : =>Boolean)(body : =>T) : T = {
#scala.annotation.tailrec
def loop(previous : T) : T = if(cond) loop(body) else previous
if(cond) loop(body) else throw new Exception("Loop must be entered at least once.")
}
...and you can then use it as a while. (In fact, the #tailrec annotation will make it compile into the exact same thing as a while loop.)
var x = 10
val atExit = whiley(x > 0) {
val squared = x * x
println(x)
x -= 1
squared
}
println("The last time x was printed, its square was : " + atExit)
(Note that I'm not claiming the construct is useful.)
Which iteration would you expect this loop to return? If you want a Seq of the results of all iterations, use a for expression (also called for comprehension). If you want just the last one, create a var outside the loop, set its value on each iteration, and return that var after the loop. (Also look into other looping constructs that are implemented as functions on different types of collections, like foldLeft and foldRight, which have their own interesting behaviors as far as return value goes.) The Scala while loop returns Unit because there's no sensible one size fits all answer to this question.
(By the way, there's no way for the compiler to know this, but the loop you wrote will never return. If the compiler could theoretically be smart enough to figure out that while(true) never terminates, then the expected return type would be Nothing.)
The only purpose of a while loop is to execute a side-effect. Or put another way, it will always evaluate to Unit.
If you want something meaningful back, why don't you consider using an if-else-expression or a for-expression?
As everyone else and their mothers said, while loops do not return values in Scala. What no one seems to have mentioned is that there's a reason for that: performance.
Returning a value has an impact on performance, so the compiler would have to be smart about when you do need that return value, and when you don't. There are cases where that can be trivially done, but there are complex cases as well. The compiler would have to be smarter, which means it would be slower and more complex. The cost was deemed not worth the benefit.
Now, there are two looping constructs in Scala (all the others are based on these two): while loops and recursion. Scala can optimize tail recursion, and the result is often faster than while loops. Or, otherwise, you can use while loops and get the result back through side effects.
On compiling the following code with Scala 2.7.3,
package spoj
object Prime1 {
def main(args: Array[String]) {
def isPrime(n: Int) = (n != 1) && (2 to n/2 forall (n % _ != 0))
val read = new java.util.Scanner(System.in)
var nTests = read nextInt // [*]
while(nTests > 0) {
val (start, end) = (read nextInt, read nextInt)
start to end filter(isPrime(_)) foreach println
println
nTests -= 1
}
}
}
I get the following compile time error :
PRIME1.scala:8: error: illegal start of simple expression
while(nTests > 0) {
^
PRIME1.scala:14: error: block must end in result expression, not in definition
}
^
two errors found
When I add a semicolon at the end of the line commented as [*], the program compiles fine. Can anyone please explain why does Scala's semicolon inference fail to work on that particular line?
Is it because scala is assuming that you are using the syntax a foo b (equivalent to a.foo(b)) in your call to readInt. That is, it assumes that the while loop is the argument to readInt (recall that every expression has a type) and hence the last statement is a declaration:
var ntests = read nextInt x
wherex is your while block.
I must say that, as a point of preference, I've now returned to using the usual a.foo(b) syntax over a foo b unless specifically working with a DSL which was designed with that use in mind (like actors' a ! b). It makes things much clearer in general and you don't get bitten by weird stuff like this!
Additional comment to the answer by oxbow_lakes...
var ntests = read nextInt()
Should fix things for you as an alternative to the semicolon
To add a little more about the semicolon inference, Scala actually does this in two stages. First it infers a special token called nl by the language spec. The parser allows nl to be used as a statement separator, as well as semicolons. However, nl is also permitted in a few other places by the grammar. In particular, a single nl is allowed after infix operators when the first token on the next line can start an expression -- and while can start an expression, which is why it interprets it that way. Unfortunately, although while can start a expression, a while statement cannot be used in an infix expression, hence the error. Personally, it seems a rather quirky way for the parser to work, but there's quite plausibly a sane rationale behind it for all I know!
As yet another option to the others suggested, putting a blank newline between your [*] line and the while line will also fix the problem, because only a single nl is permitted after infix operators, so multiple nls forces a different interpretation by the parser.