D - Imagining lazy evaluation of function arguments
- "Richard Krehbiel" <rich kastle.com> Feb 13 2002
- "Martin York" <Martin.York veritas.com> Feb 13 2002
- "Richard Krehbiel" <rich kastle.com> Feb 13 2002
- "Juan Carlos Arevalo Baeza" <jcab JCABs-Rumblings.com> Feb 14 2002
- "Richard Krehbiel" <rich kastle.com> Feb 15 2002
- DrWhat? <DrWhat nospam.madscientist.co.uk> Feb 14 2002
- "Pavel Minayev" <evilone omen.ru> Feb 14 2002
- "Juan Carlos Arevalo Baeza" <jcab JCABs-Rumblings.com> Feb 14 2002
- "Pavel Minayev" <evilone omen.ru> Feb 15 2002
- "Richard Krehbiel" <rich kastle.com> Feb 15 2002
"Lazy evaluation" is when the value of a function argument isn't actually
computed until the called function uses it.
For example, I've got a diagnostic logging function roughly like this:
void diag_log(int level, char *string)
{
if(level <= diag_level)
{
fputs(string, logfile);
}
}
...and this program listens on a socket port where I can connect up and give
it "change diag_level" commands. So no compile-time tricks will help.
Now, each time my program calls diag_log, it evaluates the argument, and
that might include some pretty hairy computations (network traffic, database
retrievals). And it will *probably* be thrown away, because diag_level
isn't high enough to print.
In C I dealt with this by using a macro that inserts a test of diag_level
before calling diag_log. Oops - D has no macros; and an inline function be
obliged to evaluate unused arguments anyway, for their side-effects.
To do something like this in C, you might pass a function pointer, so the
callee can evaluate the argument at it's leisure, and as often as it likes.
But setting up the function (a callback) is a bit more tedious than just
coding arguments.
Perhaps D can just do this stuff itself when the caller says "lazy."
int diag_log(int level, lazy char *string) { ... }
And, well, okay, applying the "lazy" term to the programmer himself is
probably appropriate. :-)
In the caller, the compiler sets up a hidden function containing the code to
evaluate the argument, and passes it's address for "string". In diag_log,
reference to "string" invokes this function to obtain the value, as if you
had coded the function call "(*string)()".
Further details left as an exercise to the, um, implementor...
(Oh, just wait until I write up "threaded function arguments." I don't want
much, do I?)
--
Richard Krehbiel, Arlington, VA, USA
rich kastle.com (work) or krehbiel3 home.com (personal)
Feb 13 2002
Is this not what interfaces are for?
void diag_log(int level,messageInterface *data)
{
if (level <= diag_level)
{
fputs(data->getString(),logfile);
}
}
"Richard Krehbiel" <rich kastle.com> wrote in message
news:a4dto2$2abh$1 digitaldaemon.com...
"Lazy evaluation" is when the value of a function argument isn't actually
computed until the called function uses it.
For example, I've got a diagnostic logging function roughly like this:
void diag_log(int level, char *string)
{
if(level <= diag_level)
{
fputs(string, logfile);
}
}
...and this program listens on a socket port where I can connect up and
it "change diag_level" commands. So no compile-time tricks will help.
Now, each time my program calls diag_log, it evaluates the argument, and
that might include some pretty hairy computations (network traffic,
retrievals). And it will *probably* be thrown away, because diag_level
isn't high enough to print.
In C I dealt with this by using a macro that inserts a test of diag_level
before calling diag_log. Oops - D has no macros; and an inline function
obliged to evaluate unused arguments anyway, for their side-effects.
To do something like this in C, you might pass a function pointer, so the
callee can evaluate the argument at it's leisure, and as often as it
But setting up the function (a callback) is a bit more tedious than just
coding arguments.
Perhaps D can just do this stuff itself when the caller says "lazy."
int diag_log(int level, lazy char *string) { ... }
And, well, okay, applying the "lazy" term to the programmer himself is
probably appropriate. :-)
In the caller, the compiler sets up a hidden function containing the code
evaluate the argument, and passes it's address for "string". In diag_log,
reference to "string" invokes this function to obtain the value, as if you
had coded the function call "(*string)()".
Further details left as an exercise to the, um, implementor...
(Oh, just wait until I write up "threaded function arguments." I don't
much, do I?)
--
Richard Krehbiel, Arlington, VA, USA
rich kastle.com (work) or krehbiel3 home.com (personal)
Feb 13 2002
Sure, that'll work, and it means the caller of diag_log must prepare an object with the given interface before calling diag_log. If it's that cumbersome, the programmer won't do it. "Martin York" <Martin.York veritas.com> wrote in message news:a4duot$2aoj$1 digitaldaemon.com...Is this not what interfaces are for? void diag_log(int level,messageInterface *data) { if (level <= diag_level) { fputs(data->getString(),logfile); } } "Richard Krehbiel" <rich kastle.com> wrote in message news:a4dto2$2abh$1 digitaldaemon.com..."Lazy evaluation" is when the value of a function argument isn't
computed until the called function uses it. For example, I've got a diagnostic logging function roughly like this: void diag_log(int level, char *string) { if(level <= diag_level) { fputs(string, logfile); } } ...and this program listens on a socket port where I can connect up and
it "change diag_level" commands. So no compile-time tricks will help. Now, each time my program calls diag_log, it evaluates the argument, and that might include some pretty hairy computations (network traffic,
retrievals). And it will *probably* be thrown away, because diag_level isn't high enough to print. In C I dealt with this by using a macro that inserts a test of
before calling diag_log. Oops - D has no macros; and an inline function
obliged to evaluate unused arguments anyway, for their side-effects. To do something like this in C, you might pass a function pointer, so
callee can evaluate the argument at it's leisure, and as often as it
But setting up the function (a callback) is a bit more tedious than just coding arguments. Perhaps D can just do this stuff itself when the caller says "lazy." int diag_log(int level, lazy char *string) { ... } And, well, okay, applying the "lazy" term to the programmer himself is probably appropriate. :-) In the caller, the compiler sets up a hidden function containing the
toevaluate the argument, and passes it's address for "string". In
reference to "string" invokes this function to obtain the value, as if
had coded the function call "(*string)()". Further details left as an exercise to the, um, implementor... (Oh, just wait until I write up "threaded function arguments." I don't
much, do I?)
-- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 home.com (personal)
Feb 13 2002
"Martin York" <Martin.York veritas.com> wrote in message news:a4duot$2aoj$1 digitaldaemon.com...Is this not what interfaces are for? void diag_log(int level,messageInterface *data) { if (level <= diag_level) { fputs(data->getString(),logfile); } }
And then comes the call: diag_log(3, new messageInterface(new concatStrings("Hello ", "World!")); That's the implementation. He was asking for a better syntax for this: diag_log(3, "Hello " + "World!"); Salutaciones, JCAB http://www.JCABs-Rumblings.com
Feb 14 2002
"Juan Carlos Arevalo Baeza" <jcab JCABs-Rumblings.com> wrote in message news:a4i8h3$19mk$1 digitaldaemon.com..."Martin York" <Martin.York veritas.com> wrote in message news:a4duot$2aoj$1 digitaldaemon.com...Is this not what interfaces are for? void diag_log(int level,messageInterface *data) { if (level <= diag_level) { fputs(data->getString(),logfile); } }
And then comes the call: diag_log(3, new messageInterface(new concatStrings("Hello ", "World!"));
...and before each call to diag_log, there's a call to "new concatStrings", whose result is passed to "new messageInterface", and *then* diag_log gets called with that result. I want those other calls *not* *to* *happen* unless diag_log tells them to.That's the implementation. He was asking for a better syntax for this: diag_log(3, "Hello " + "World!");
And yes, a simpler interface is better. (That's why printf still exists - despite being type-dangrous, it has a simple interface.)
Feb 15 2002
Richard Krehbiel wrote:"Lazy evaluation" is when the value of a function argument isn't actually computed until the called function uses it. For example, I've got a diagnostic logging function roughly like this: void diag_log(int level, char *string) { if(level <= diag_level) { fputs(string, logfile); } }
Why not just do a wrapper function ie. void diag_log(int level, char*string) { if( level <= diag_level ) { diag_log_wrapped(level,string) ;}} void diag_log_wrapped(int level,char*string) { /* hairy stuff */ ; fputs(string,logfile) ;} D should see the first function as "good to inline" and inline it in the calling procedure, that is if I read the specifications correctly. [Is there a way to tell D to always inline?] C 2002/2/15 [If the garbage collector truely worked then it would throw out most of my programmes!]
Feb 14 2002
"DrWhat?" <DrWhat nospam.madscientist.co.uk> wrote in message news:a4htc9$12he$1 digitaldaemon.com...[Is there a way to tell D to always inline?]
No. I believe it's because the compiler can determine whether to inline function or not better than programmer... just like the register variables in C that used to work in good old days but now mean nothing...[If the garbage collector truely worked then it would throw out most of my programmes!]
Why? =)
Feb 14 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a4i436$17ts$1 digitaldaemon.com..."DrWhat?" <DrWhat nospam.madscientist.co.uk> wrote in message news:a4htc9$12he$1 digitaldaemon.com...[Is there a way to tell D to always inline?]
No. I believe it's because the compiler can determine whether to inline function or not better than programmer... just like the register variables in C that used to work in good old days but now mean nothing...
That's, again, my old rant. I want (I need) to be able to let the compiler know that it has no choice in the matter, and that if it can't for any reason, it should halt compilation with an error. It doesn't change anything at the back-end at all. It just affects the decision of wether to inline or not and such.
Feb 14 2002
"Juan Carlos Arevalo Baeza" <jcab JCABs-Rumblings.com> wrote in message news:a4i8bu$19m3$1 digitaldaemon.com...That's, again, my old rant. I want (I need) to be able to let the compiler know that it has no choice in the matter, and that if it can't
any reason, it should halt compilation with an error.
A compiler switch (inline all functions, or inline function with name x) can be used for this purpose. In general, for you as a programmer, there's no difference. Program will work absolutely the same in both cases - output won't change. It's just the matter of speed. The language doesn't cover that, however - it is courtesy of the compiler.
Feb 15 2002
"DrWhat?" <DrWhat nospam.madscientist.co.uk> wrote in message news:a4htc9$12he$1 digitaldaemon.com...Why not just do a wrapper function ie. void diag_log(int level, char*string) { if( level <= diag_level ) { diag_log_wrapped(level,string) ;}} void diag_log_wrapped(int level,char*string) { /* hairy stuff */ ; fputs(string,logfile) ;} D should see the first function as "good to inline" and inline it in the calling procedure, that is if I read the specifications correctly.
No help. Function may or may not be inlined, and the program had better work exactly the same either way. Since it may have side-effects, then even if inlined, the string argument must be computed, even if it doesn't get used. I want it not to get computed if it's not used. -- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)
Feb 15 2002









"Richard Krehbiel" <rich kastle.com> 