3

I want to have a function that takes a variable number of functions, but I want them to not be evaluated until I actually used them. I could use the () => type syntax, but I would prefer to use the => type syntax, because it seems to be custom made for delaying evaluation.

When I try something like this:

  def functions(fns: => String*) = "OK"

I get the error:

error: ')' expected but identifier found.
  def functions(fns: => String*) = "OK"

Interestingly, it works fine when I change it to

def functions(fns: () => String*) = "OK"

What do I have to do to get my first function to work?

2 Answers 2

3

Since I submitted the issue:

https://issues.scala-lang.org/browse/SI-5787

It may yet happen.

Depending on your semantics, consider using Stream[String], which evaluates lazily.

  def foo(i: Int): String = { println(s"Numbering $i"); s"Number $i" }
  val invocations = foo(2) #:: foo(4) #:: foo(5) #:: foo(8) #:: Stream.empty

Edit: Then I thought, didn't someone just ask that? A couple of more answers here using implicits. I think my answer there should be up-voted just for "This used to happens first".

Sign up to request clarification or add additional context in comments.

3 Comments

Hmm, you're right, my SO-fu was weak. Should I just delete my question?
Since Rex pasted his answer, and one suspects he has hotkeys set up by now for the most-desired Rex wisdom, I think it's ok. Also, Typesafe ought to track SO questions in order to target features requiring simplification in 2.11. It's worth adding that I'd only just thought of using Streams for this use-case (because of recent Streams questions), so SO does actually drive if not innovation then clarification.
these are both good solutions, and I actually ended up going with a combination of both of them. I'm going to select this one though, because it links to issue where Martin Odersky points out that the spec says this doesn't work. Instead of streams, I used a view.
3

For now, you have to use () => X* for repeated parameters. This makes entering them a pain, so you may wish to

implicit def anything_to_function0[A](a: => A): () => A = () => a

scala> def functions(fns: () => String*) = fns.length
functions: (fns: () => String*)Int

scala> functions("salmon","cod")
res2: Int = 2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.