0

I am trying to implement a control flow structure which can accept a variable number of by-name parameters.

See CalculateGroup method and its use.

I was trying to follow this post, but still have some issues

As I can see from the error, I suspect I need to define a type annotation predicate in CalculateGroup function?

Here is current code:

 def compare[T : Numeric](x: T)(y: T) : Boolean = implicitly[Numeric[T]].gt( x, y )

 val items = compare[Double](10) _

 val assertionsEnabled = true

 def Calculate( predicate: => Boolean ) =
     if (assertionsEnabled && !predicate)
       throw new AssertionError

 Calculate{
   items(5)
 }

  def CalculateGroup( list: (predicate: => Boolean) *) =
  {
    list.foreach( (p : (predicate: => Boolean) ) => {
      if (assertionsEnabled && !predicate)
        throw new AssertionError
    })
  }

  CalculateGroup{
    items(5),
    items(3),
    items(8)
  }

Error details:

scala ControlFlow.scala /Users/pavel/Documents/ControlFlow/ControlFlow.scala:36: error: ')' expected but ':' found. def CalculateGroup( list: (predicate: => Boolean) *) = ^ /Users/pavel/Documents/ControlFlow/ControlFlow.scala:68: error: ')' expected but '}' found. } ^ two errors found

Community
  • 1
  • 1
Pavel
  • 1,519
  • 21
  • 29

2 Answers2

1

You have a syntax problem... you are placing a colon in front of the word predicate in the signature of the method CalculateGroup and in the foreach. Just remove them and it should compile.

just remove it and know that the word predicate is not alias for a variable, but it should be the name of a class. So it's better if you capitalize it. Contrary to the case of your methods, which shouldn't be capitalized.

Update

To have multiple by-name parameters just do this:

def CalculateGroup( list: (=> Boolean) *) =
{
list.foreach( (p : (=> Boolean) ) => {
  if (assertionsEnabled && !p)
    throw new AssertionError
})
}
caeus
  • 3,084
  • 1
  • 22
  • 36
1

You cannot use by-name var args, you could use a lazy collection like Iterator or maybe Stream:

def compare[T : Numeric](x: T)(y: T) : Boolean = implicitly[Numeric[T]].gt( x, y )

  val items = compare[Double](10) _

  val assertionsEnabled = true

  def Calculate(predicate: => Boolean) =
    if (assertionsEnabled && !predicate)
      throw new AssertionError

  Calculate{
    items(5)
  }

  def CalculateGroup(list: Iterator[Boolean]) =
  {
    list.foreach { (p : Boolean ) =>
      if (assertionsEnabled && !p) {
        throw new AssertionError
      }
    }
  }

  CalculateGroup{Iterator(
    items(5),
    items(3),
    items(8)
  )}
Sascha Kolberg
  • 7,092
  • 1
  • 31
  • 37
  • Your code works fine. however, as I can see from the next post it possible. Thanks. http://stackoverflow.com/questions/13307418/scala-variable-argument-list-with-call-by-name-possible – Pavel Apr 08 '16 at 19:58
  • Oh .. I see. Looks like this is not supported: https://issues.scala-lang.org/browse/SI-5787 .. Accepted. Thanks! – Pavel Apr 08 '16 at 20:15