Skip to content

Lazy evaluation of function arguments #194

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
roman-vanesyan opened this issue Jan 24, 2019 · 4 comments
Open

Lazy evaluation of function arguments #194

roman-vanesyan opened this issue Jan 24, 2019 · 4 comments

Comments

@roman-vanesyan
Copy link

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

@lrhn
Copy link
Member

lrhn commented Jan 24, 2019

This would be an example of either "call-by-name" or actual lazy-evaluation of arguments (the difference is that the former evaluates the argument expression every time it's referenced, the latter only evaluates it the first time, then caches the value). Obviously, if you only reference a parameter once, there is no difference.

I think call-by-name is the more useful version because it allows the called function to evaluate the argument more than once for side-effects, if that's what it wants to do. Otherwise it can easily cache the value internally if it wants that.

Proper call-by-name, perhaps including passing statement blocks, would be a powerful feature that allows user-written control structures without introducing extra closures, like:

  void myWhile(lazy bool test, lazy void increment, void action()) {
     for (; test; increment) {
       action();
     }
  }
  myWhile(x < 10, x++, () { print(x); });

@roman-vanesyan
Copy link
Author

What can I do to push toward this topic discussion?

@lrhn
Copy link
Member

lrhn commented Jan 28, 2019

You can try to write a more precise definition of what the language feature should do, so there are details for people to discuss. Then hope other people are interested and want to discuss it.

You could focus either entirely on the debugging use-case, and see if there are ways to design a simpler function just for that, or go for the more general feature that can be used in multiple ways.
The former is harder to argue for, but possibly easier to add to the language.

You can look at other languages and see what they have done for the same use-cases, and compare how those features would work with Dart.

In the end, all you can do is try to drive a discussion, and then hope that other people are interested in discussing the feature, and perhaps even lobbying for it. If there is no interest, and no pressing use-cases where the feature would help, it's very unlikely that anything will happen.

@He-Pin
Copy link

He-Pin commented Dec 24, 2019

Scala's by name parameter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants