tags:

views:

147

answers:

4

Hi,

I'll give some C-style "bracket" pseudo-code to show what I'd like to express in another way:

for (int i = 0; i < n; i++) {
    if (i == 3 || i == 5 || i == 982) {
        assertTrue( isCromulent(i) );      
    } else {
        assertFalse( isCromulent(i) );
    }
}

The for loop is not very important, that is not the point of my question: I'd like to know how I could rewrite what is inside the loop using Scala.

My goal is not to have the shortest code possible: it's because I'd like to understand what kind of manipulation can be done on method names (?) in Scala.

Can you do something like the following in Scala (following is still some kind of pseudo-code, not Scala code):

assert((i==3 || i==5 || i==982)?True:False)(isCromulent(i))

Or even something like this:

assertTrue( ((i==3 || i==5 || i==982) ?  : ! ) isCromulent(i) )

Basically I'd like to know if the result of the test (i==3 || i==5 || i==982) can be used to dispatch between two methods or to add a "not" before an expression.

I don't know if it makes sense so please be kind (look my profile) :)

+8  A: 
assertTrue(isCromulent(i) == (i==3||i==5||i==982))
pelotom
+1 Well done! I was thinking about such a complicated solution. Always, nice to see, that some problems are so easy to express.
Nils Schmidt
@pelotom: +1 and great but actually I was trying to come up with an example looking for an answer like the one Alexey gave :) so +1 to you but I'll accept Alexey's answer :)
NoozNooz42
+5  A: 

Within the Scala type system, it isn't possible to dynamically create a method name based on a condition.

But it isn't at all necessary in this case.

val condition = i == 3 || i == 5 || i == 982
assertEquals(condition, isCromulent(i))
retronym
@retronym: nice too!
NoozNooz42
+10  A: 

While pelotom's solution is much better for this case, you can also do this (which is a bit closer to what you asked originally):

(if (i==3||i==5||i==982) assertTrue else assertFalse)(isCromulent(i))

Constructing names dynamically can be done via reflection, but this certainly won't be concise.

Alexey Romanov
@Alexey Romanov: oh that is great! This is exactly what I was looking for. I'll come up with more questions about Scala probably, now I'm getting really exited! :)
NoozNooz42
+1 for getting at the spirit of the question :)
pelotom
But, likely, you need `(assertTrue _)` and `(assertFalse _)` instead.
Daniel
Right, depending on whether `assertTrue` and `assertFalse` are methods or functions.
Alexey Romanov
+2  A: 

I hope nobody minds this response, which is an aside rather than a direct answer.

I found the question and the answers so far very interesting and spent a while looking for a pattern matching based alternative.

The following is an attempt to generalise on this (very specific) category of testing:

class MatchSet(s: Set[Int]) {def unapply(i: Int) = s.contains(i)}
object MatchSet {def apply(s: Int*) = new MatchSet(Set(s:_*))}


val cromulentSet = MatchSet(3, 5, 982)

0 until n foreach {
  case i @ cromulentSet() => assertTrue(isCromulent(i))
  case i                  => assertFalse(isCromulent(i))
}

The idea is to create ranges of values contained in MatchSet instances rather than use explicit matches.

Don Mackenzie