Skip to content

Lazy evaluation of function arguments #194

@segfaultmedaddy

Description

@segfaultmedaddy

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 locs and breaks DRY idiom.

We even make the message argument of the debug dynamically 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions