-
Notifications
You must be signed in to change notification settings - Fork 218
Description
The primary use case of lazy evaluation of function arguments is to postpone initialization of arguments until the use of them in the function's body.
e.g.
void foo(Bar bar) {
// stuff...
bar.baz(); // bar is initialized here...
}
foo(new Bar()); // ...not here
Another use case is logging. It's common to print debug info in development and disable it in production.
// stuffs..
// Logger prints data base on severity level
class Logger {
void debug(String message) { /* ... */ }
bool isEnabledFor(Level level) { /* ... */ }
}
// `largeDataChunk` produces a large data, that involves heavy computation.
logger.debug('Data ${largeDataChunk()}');
We can set logger
's level to upper severity level and no output will be provided, but the string
still is processed and largeDataChunk
call occurs.
To prevent it, we can wrap the logger.debug
call into the if
statement, like:
// stuffs..
if (logger.isEnabledFor(Level.debug) logger.debug('Data {${largeDataChunk()}');
Until that it will give a huge number of additional boilerplate loc
s and breaks DRY idiom.
We even make the message
argument of the debug
dynamic
ally typed and accept lambda function
as argument.
class Logger {
void debug(dynamic message) {
if (isEnabledFor(Level.debug)) {
String result;
if (message is Function) {
result = message();
} else {
result = message;
}
// stuff...
}
}
}
In this case it breaks static typing.
I propose to add lazy evaluation of function arguments, something like in D:
https://dlang.org/articles/lazy-evaluation.html