8

I am trying to understand the following code but can't.

it is supposed to create a child actor for an Event if it does not exist, otherwise says that the Event exist as it as an associated child actor.

context.child(name).fold(create())(_ => sender() ! EventExists)

But the fold here does not make sense to me. If the context.child is emtpty we get the creation and i understand that. However if there is children we are still going to create why ?

MaatDeamon
  • 9,532
  • 9
  • 60
  • 127

1 Answers1

9

Akka's child returns an Option

As you can see from Option's scaladoc:

fold[B](ifEmpty: ⇒ B)(f: (A) ⇒ B): B Returns the result of applying f to this scala.Option's value if the scala.Option is nonempty. Otherwise, evaluates expression ifEmpty.

Or making it more clear:

This (fold) is equivalent to scala.Option map f getOrElse ifEmpty.

So the first parameter of fold is lazy (call-by-name) and evaluates only if Option is empty. The second parameter (a function) is called only if Option is not empty.

Experiment:

scala> Some(0).fold({println("1");1}){_ => println("2"); 2}
2
res0: Int = 2

scala> None.fold({println("1");1}){_ => println("2"); 2}
1
res1: Int = 1

Here's some readings about:

https://kwangyulseo.com/2014/05/21/scala-option-fold-vs-option-mapgetorelse/

And some critics of that approach:

http://www.nurkiewicz.com/2014/06/optionfold-considered-unreadable.html

But in Option.fold() the contract is different: folding function takes just one parameter rather than two. If you read my previous article about folds you know that reducing function always takes two parameters: current element and accumulated value (initial value during first iteration). But Option.fold() takes just one parameter: current Option value! This breaks the consistency, especially when realizing Option.foldLeft() and Option.foldRight() have correct contract (but it doesn't mean they are more readable).

dk14
  • 22,206
  • 4
  • 51
  • 88
  • Thank you very much for the detail explanation. I resorted to build an explanation based on the laziness of the neutral argument, and given that it is not used in the function as it does not work on two parameter, i figure that it is never called. Which was close to what you, the truth is the function only take one parameter. It is good to know this difference thank you. – MaatDeamon May 02 '16 at 06:50