On Mon, 15 Feb 2010 18:46:52 -0500, grauzone <n...@example.net> wrote:

Steven Schveighoffer wrote:
On Sun, 14 Feb 2010 18:28:38 -0500, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:

Denis Koroskin wrote:
On Mon, 15 Feb 2010 00:31:29 +0300, Walter Bright <newshou...@digitalmars.com> wrote:

Right now, mixins are defined and used as:

    template foo(T) { declarations... }

    mixin foo!(int) handle;

The proposal is to switch it around:

    mixin template foo(T) { declarations... }

    foo!(int) handle;

to follow the notion that mixin templates are very different from regular templates, and that should be reflected in their definition rather than use.

What do you think?
I support the change, expect that I believe mixing in the mixin template should involve the "mixin" keyword.
[snip previous proposal]

The hope with the proposed change is to leverage existing mixin implementation into a solid and useful facility that could actually obviate the need for macros. I reckon there is a lot of value in the current mixin template idea, but it's just packaged the wrong way. Requiring mixin on the call side (something that many have complained about) would, in my opinion, keep the feature packaged the wrong way.

As an example of where we want to take this, consider an interpolation facility. The expression:

interp!"a = $a and b = $b\n"

expands into:

"a = ", a, " and b = ", b, "\n"

which you can writeln, pass to text or whatnot.
 could you use this to avoid lazy arguments for logging?
One of the huge uses I see for a macro is to do logging (and things like
assert) without requiring lazy evaluation.
 For example, in Tango from what I remember, logging is done like this:
 log.logInfo("created object " ~ obj.toString);
 where you may not want to execute obj.toString unless the info log is
enabled.  Solving this currently in Tango is done via lazy arguments.
However, this means making temporary functions, passing delegates, etc.
It's much more straightforward and generates smaller code to do:
 if(log.infoEnabled)
     log.log("created object " ~ obj.toString);
 This is the solution in log4j and it's plethora of clones.
A much better solution IMO is to use a macro where logInfo is a macro that
inserts the if statement at the call site.  You can do this with mixins,
but clearly it is not as attractive, plus since you are invariably dealing with strings in logging, you have to escape them when doing the mixin. It
would be awesome if macros can solve this problem by just making mixins
easier to use.
 i.e.
 class Log
{
     macro logInfo(s) mixin("if(this.infoEnabled) this.log(" ~ s ~ ")");
}

Eh.
How about

class Log
{
        void logInfo(char[] format, ...) {
                if (infoEnabled)
                        std.format.doFormat(&log, _arguments, _argptr);
        }
}

Log.logInfo("created object %s", obj);


Doesn't require new features, doesn't require lazy, doesn't require thousands of templates, works if Log is an interface.

That solves my example, yes. But it does not solve the generic case. If toString isn't the complex/time consuming part, then the thing that is toString'd will still be computed.

-Steve

Reply via email to