December 10, 2012
> If I'm not mistaken isn't the "code" I'm trying to generate still in a string?
>

Well, yes, but not when you mix it in. It's a string mixin in this case, not a template mixin.


>
> (you've unfortunately left out the most important part at `//build your
> code here`)
>


Because it's just simple string operations using the entire language/Phobos/whatever to get the code you want. And then, you mix it in.

Anonymous gave you http://dpaste.dzfl.pl/5d4cb742

With a string mixin, this gives:

http://dpaste.dzfl.pl/8fc32179

string genStruct(string stringname)
{
    return
    "struct " ~ stringname ~ "
    {
        //....
    }";
}

mixin(genStruct("s1"));
mixin(genStruct("s2"));

static assert(is(s1));
static assert(is(s2));

void main() {}


December 10, 2012
On Monday, 10 December 2012 at 20:17:41 UTC, Philippe Sigaud wrote:
>> If I'm not mistaken isn't the "code" I'm trying to generate still in a
>> string?
>>
>
> Well, yes, but not when you mix it in. It's a string mixin in this case,
> not a template mixin.
>

My whole point is not to use strings to insert code but to use code to insert code. (essentially I want to avoid having to wrap the code with " " as it disables highlighting and possibly other features(intellisense, etc...))

We went off on a tangent before as it doesn't really solve my problem. I want to generate a partial struct and global functions and have the user supply the rest of the struct.


December 10, 2012
On 12/10/2012 01:52 PM, js.mdnq wrote:

> I want to avoid having to wrap the code with "
> " as it disables highlighting and possibly other features(intellisense,
> etc...))

The q{} syntax is supposed to help with that issue. Emacs manages syntax highlighting correctly for the q{} strings:

import std.stdio;

void main()
{
    enum s = q{
        writeln("hello world");
    };

    mixin (s);  // <-- s is a string
}

Ali

December 11, 2012
On Monday, 10 December 2012 at 22:01:37 UTC, Ali Çehreli wrote:
> On 12/10/2012 01:52 PM, js.mdnq wrote:
>
> > I want to avoid having to wrap the code with "
> > " as it disables highlighting and possibly other
> features(intellisense,
> > etc...))
>
> The q{} syntax is supposed to help with that issue. Emacs manages syntax highlighting correctly for the q{} strings:
>
> import std.stdio;
>
> void main()
> {
>     enum s = q{
>         writeln("hello world");
>     };
>
>     mixin (s);  // <-- s is a string
> }
>
> Ali

Thanks, this is definitely a step up. In Visual D, highlighting and intellisense does not work correctly but it does seem to make it easier than using a string directly. (I imagine it is the fault of Visual D for treating the argument of q as different than code)

It should, though, let me do what I want easier than the other methods.

Thanks again!
December 13, 2012
On Monday, 10 December 2012 at 22:01:37 UTC, Ali Çehreli wrote:
> On 12/10/2012 01:52 PM, js.mdnq wrote:
>
> > I want to avoid having to wrap the code with "
> > " as it disables highlighting and possibly other
> features(intellisense,
> > etc...))
>
> The q{} syntax is supposed to help with that issue. Emacs manages syntax highlighting correctly for the q{} strings:
>
> import std.stdio;
>
> void main()
> {
>     enum s = q{
>         writeln("hello world");
>     };
>
>     mixin (s);  // <-- s is a string
> }
>
> Ali

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.

I can do

q{
   struct _name_
   {
      .... normal struct code ...
   }
} (but everything inside q is a string)

when I want to do

struct _name_
{
     .... normal struct code ...
}

in code. The first is in a string and the second isn't. The difference is that with q, I can parse the code and replace _name, for example, while in the second case I can't.

It makes it difficult to build up code by mixing stringified code and code. It's like, either you have to completely used stringified code or not use any at all.


For example, what if I mispell writeln? Sure I get an error but it's not at all the correct line number. But if I could use "actual code" that then the error should be normal.

>     enum s = q{
>         writelin("hello world");
>     };

in a large program, it could get confusing very quickly because essentially all errors will be pointing to oblivion.

This is why I want to all the user to supply actual code(and not stringified code) so that errors will show up properly.

December 13, 2012
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
December 13, 2012
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.








December 13, 2012
On 2012-12-09 11:42, js.mdnq wrote:
> How can I create mixes of stringified code and code itself?
>
> http://dlang.org/mixin.html
>
> explains how to create structs using strings. But what if I do not want
> to have to encode the whole struct as a string but only parts of it?
>
>
> mixin template GenStruct(stringname)
> {
>       struct stringname ~ "alpha"
>       {
>           ....
>       }
> }
>
>
> mixin GenStruct!("Helpme");
>
> would be equivalent to do the following
>
> struct Helpmealpha
> {
>      ....
> }

Sounds like someone wants AST-macros. Yes I know, we don't have a proposal.

-- 
/Jacob Carlborg
December 15, 2012
On 12/10/2012 01:43 AM, anonymous wrote:
> Maybe it helps if you see it in action: http://dpaste.dzfl.pl/5d4cb742

Here's a slightly modified version: http://dpaste.dzfl.pl/f2bd1428

regards,
r_m_r
December 15, 2012
On Saturday, 15 December 2012 at 15:15:21 UTC, r_m_r wrote:
> On 12/10/2012 01:43 AM, anonymous wrote:
>> Maybe it helps if you see it in action: http://dpaste.dzfl.pl/5d4cb742

Note that here s1alpha and s2alpha are distinct types.

> Here's a slightly modified version: http://dpaste.dzfl.pl/f2bd1428

Whereas here they are the same.