On Thursday, 13 December 2012 at 06:26:15 UTC, dennis luehring wrote:
Am 13.12.2012 04:32, schrieb js.mdnq:
I think the issue I have with all this is that when you put code
inside a string you lose a lot of compile time features AFAICT.

your right - but...try to come up with an similar ("easy" to implement) powerfull solution that is not based on strings and you will see how hard it is to get it right - thats the reason for string based mixins

It's not that I do not want to use strings. I simply want to allow the user to insert their own code into places I want them too.

q{} helps make this easier but it still mangles the code.

My prototypical example for doing this is simply creating a struct with a "custom" name.

struct _name_
{
 ....
}

where _name_ is replaced with some user defined value(it can be generated at compile time based on various static settings.

In this case, though, we can't just generate the struct _name string and insert it because the mixin will be invalid. The user can't supply the block({ }) because there is no way to do so, well, unless they do it with a string or q{}, which breaks debugging, highlighting, and intellisense to some degree or another.

partial structs would work as well as partial mixins.

pmixin(GenStructTag("mystruct")) // (inserts struct "mystruct" at this line)
{
 ....
}

which, in this simple example would result in the exact same as if the user just did

struct mystruct
{
 ....
}

(BUT realize in both cases the code block {} are identical)

We could do this:

mixin(GenStructTag("mystruct",
q{
 ....
});

and this is a workable solution I suppose... it just doesn't seem to work that well in visual D(debugging stepping is broke, highlighting is different, etc...). It is better than using a string directly though.

There are many simple ways to solve the problem. Pre-processing is the easiest to implement but probably doesn't keep in line with D's approach. I think partial structs and classes will work in my case as I could generate the struct using mixin's then let the user add on to them with a partial struct.

Another approach would be possibly to let one pass a code block at compile time as a sort of lambda function. A compile time type "Code" could be created, which is real code passed to a template or mixin but stringified in the process. So:

mixin(GenStructTag("mystruct",
struct _name_
{
 ....
});

Where the 2nd argument is real code(possibly with "markup" or meta-tokens) that is stringified in the template mixin which can then be processed.

This creates little "pre-processor" like mixin that work on code blocks and lets one generate code at compile time.

It might not seem like one is gaining much from leaving out a q{} but I think it will make it much easier to debug such things as one can actually see the code and step through it, at least what is shown. The mixin might mangle the code.

q{} has no idea about code. It's not meant for code. The debugger does not know it it's real code or not. But having something like c{}, or a Code type, it knows that it's a real code block and not a set of arbitrary tokens... in any case q{} is close, but IMO, not close enough.








Reply via email to