The Scala programming language has a neat feature, called pass by name arguments, that allows some arguments to only be evaluated if required.
For example, it's possible to write a while
loop using a curried method such as the following:
// This is Scala code. A simulated while loop
@scala.annotation.tailrec
def myWhile(condition: => Boolean)(actions: => Unit): Unit = {
if(condition) {
actions
myWhile(condition)(actions)
}
}
This method can be used like a regular while
loop, thanks to Scala's syntactic sugar, closures and—of particular interest here—the ability to pass expressions as function arguments, which are evaluated when referenced (as indicated by the : => type
argument declaration).
For example, the following prints "Hello!" to the console ten times:
var i = 0
myWhile(i < 10) {
println("Hello!")
i = 1
}
For those who need to understand what is happening, the expression i < 10
is evaluated each time condition
appears inside the if(...)
statement inside the method, similarly, println("Hello!"); i = 1
is evaluated each time actions
appears in the body of the method. When recursively calling myWhile
for the next iteration, the expressions are passed as is, since the method requires expressions, not values. Scala terms these pass by name arguments.
If these arguments were passed by value instead, then i < 10
would be passed to myWhile
as false
, while "Hello!" would be printed exactly once, i
would be incremented once, and the loop would execute infinitely.
(Scala is primarily a functional language, and this code is not even close to being FP, but it's a simple example.)
My question is, is there a way to pass arguments in this way to a C# function? Also note that I'm restricted to using C# 7.3. :-(
CodePudding user response:
It sounds like you can get somewhat close with Func`1
and Action
:
void MyWhile(Func<bool> condition, Action action) {
while (condition()) {
action();
}
}
and calling as:
int i = 0;
MyWhile(() => i < 10, () => {
Console.WriteLine("Hello!");
i;
});
The syntax is a bit different, but the idea is similar.