While browsing Reddit yesterday, I came across this thread on Perl’s Acme::Don't module. The Acme::Don't module is a joke module which adds support for “don't“, the opposite of the “do” command. The “don't” construct accepts a block of code and then DOESN’T execute it, no matter what. Now, lately I’ve been playing around with Scala and I know that thanks to its flexible syntax it’s possible to create functions which look and behave just like control structures. This got me thinking… could I implement a useful version of “don't“?
After a couple of minutes I came up with the following 2 use cases (in addition to the original standalone don’t block):
dont { ... }
dont { ... } unless (condition)
dont { ... } until (condition)
Implementing the dont { ... } part is easy. The only thing needed to make this work is a function which accepts a block of code and doesn’t do anything with it.
Adding support for the unles/until part is a bit trickier, but still easy. For this to work, the dont function must return an object which contains methods named unless and until. These methods then evaluate the condition passed to them and execute the original block of code if/when the condition is true.
It’s probably best if I just show you the code:
def dont(code: => Unit) = new {
def unless(condition: => Boolean) =
if (condition) code
def until(condition: => Boolean) = {
while (!condition) {}
code
}
}
(UPDATE 2010-12-28: Simplified the example above as per suggestion sent to me via email by Michael Lorton)
Now there’s nothing else left but to use it in an example:
/* This will never be executed */
dont {
println("Hello? Can anyone hear me?");
}
/* This will only be executed if the condition is true */
dont {
println("Yep, 2 really is greater than 1.")
} unless (2 > 1)
/* Just a helper function */
var number = 0;
def nextNumber() = {
number += 1
println(number)
number
}
/* This will not be printed until the condition is met. */
dont {
println("Done counting to 5!")
} until (nextNumber() == 5)
Runnig the above code should print:
Yep, 2 really is greater than 1.
1
2
3
4
5
Done counting to 5!

I like the resulting syntax.
What about nested dont?
dont {
dont {
println(“Hello? Can anyone hear me?”);
}
}
In math minus and minus gives plus. :)
That one is left as an exercise to the reader. ;-)
Actually, a simple
dont {dont {
println("Hello there!")
}
}
is perfectly doable by just adding an overloaded definition of dont, like this:
def dont(dontExecCode: DontCommand) = dontExecCode.unless(true)But this only works if the outer dont block doesn’t contain anything else than another dont block and there also can’t be any unless/until conditions.
Now implement “don’t”, like the original code? :)
@wolverian: Oh, that’s a tough one. I only managed to implement a more polite version, “please don’t”, by jumping through a couple of hoops:
object please {
def don(code: => Unit) = new DontCommand(code)
}
implicit def symbolExtender(s: Symbol) = new { def apply(r: Unit) = () }
please don't {
println("HEY HEY HEY!")
} unless (2 > 1)
Great article. This was a really simple explanation of how to write your own control structures in Scala. More please!