On Mon, 23 Nov 2009 12:49:01 -0500, Bill Baxter <wbax...@gmail.com> wrote:

On Mon, Nov 23, 2009 at 5:32 AM, Steven Schveighoffer
<schvei...@yahoo.com> wrote:
On Mon, 23 Nov 2009 07:38:32 -0500, Bill Baxter <wbax...@gmail.com> wrote:

On Mon, Nov 23, 2009 at 3:12 AM, Don <nos...@nospam.com> wrote:

This sounds like a job for better mixin syntax.
.
So let "template#(args)" be equivalent to "mixin(template!(args))".

Then you can do

auto statement = db.execute#(`select $visitcars.name from table where
$visitcars.id > 100 && $visitcars.surname Like "A*"`);

Yeah, something like that. Or it could mixin automatically. eg if
macro foo(args...)
foo(args) meant  mixin(foo(args)).

This is what I've been thinking too.
But we might want there to be more to a macro than that.  For instance
most macro parameters are strings and the '(string this, string that,
string theOther)', list of parameters doesn't look so great.  And
requiring the strings to be quoted on the calling side, also makes the
call side rather ugly.  It may be better to have arguments
automatically convert to some sort of AST type which supports some
introspection, and can be converted back to a string of code easily.

So I think jumping on just making macro mean "mixin automatically"
right now may limit our future choices too much.

What about this:

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=17853


Quoting from there:
"""
macro doit(x, y, z) mixin("x" ~ "y" ~ "z"); // allow easy syntax for
quoting parameters, since mixins are all about stringification.

doit(a, b, c) => mixin("abc");
"""

What happens if you want to have the string "x", just a plain x, in the mixin?

Don't name your parameter x. The author of the macro is charge of the names of its parameters, if you need a certain string, don't use it as a parameter name. I would say that I wouldn't expect a global search and replace, only matching symbols would be replaced, for example:

macro doit(x) mixin("xx = x;");

doit(hi);

would result in xx = hi;

Other than that, I think I don't know enough about the lessons to be
learned from Lisp, Scheme, and Nemerle.  I'd like to study more how
macros work in those systems before I'd feel comfortable committing to
any particular design.  For instance what's the best way to handle
hygene issues mentioned here:
http://en.wikipedia.org/wiki/Hygienic_macro .

There are probably some hygene issues there that should be considered
for template mixins too.  For instance it's a long-standing issue that
if you use a mixin from a library, you must import all the modules
that mixin depends on, which breaks a kind of encapsulation of the
mixin.  Mixins are probably also subject to the kind of environmental
hygene problem described on that page, where a common function
redefined in the current scope alters the intended behavior of the
mixin.


Yes, my scheme would suffer from those issues also. For those who are interested in a problem case, here is the first one identified on that page written in the proposed form:

macro INCI(i) mixin("{int a = 0; i++;}");

void main()
{
  int a = 0;
  int b = 0;
  INCI(a); // translates to {int a = 0; a++;}
  INCI(b); // translates to {int a = 0; b++;}
}

Now a won't be incremented as expected because the local a declared by the macro shadows the behavior.

I'll put it this way -- any problem that mixins suffer from, macros would suffer from as well. If we can fix those problems in mixins, then macros also become fixed. I don't see it worthwhile to propose a fixed macro system when mixins still suffer from the same issue.


I think Walter had intended template mixins to take the place of
macros.  They offer some features of macros but not all.  So once real
macros exist, I wonder if there will be any real reason for them to
continue existing.

The thing I think macros give you over mixins is their usage is simple and looks like part of the API. Other than that, I don't think mixins are any less powerful.

For example, instead of writing:

log.logError("bad error occurred with object: " ~ expensiveObjectStringification(obj));

I can do the correct thing via a mixin with:

mixin(doLog("log", "error", "\"bad error occurred with object: \" ~ expensiveObjectStringification(obj))"));

Where doLog is a CTFE function that rewrites the code as the macro does.

But the first looks *sooo* much better :)

-Steve

Reply via email to