November 02, 2010
On 11/2/10 3:16 PM, kenji hara wrote:
> And, I do not recommend following use of expand:
> writeline(mixin(expand!"take $n times."));
>
> The probrem is:
> - expand concatenates string by ~ operators, it is may cost than using
> appender(text, formatWrite, writefln...)
>
> I will remove ddoc example from github code.

Expand should have an option to expand with commas and without to!string, i.e. in order to make the code:

writeln(mixin(anotherexpand!"take $n times."));

identical 100% with the code

writeln("take ", n, " times.");

Not sure what's the best name for "anotherexpand".

Andrei
November 02, 2010
Is it just me, or does

writeln("take ", n, " times.");

not look so bad that we need to invent a function to do it with expansion?

I've used php for a while, and I love the variable expansion inside strings, but I don't know if it's worth defining a library function to do it.

-Steve



----- Original Message ----
> From: Andrei Alexandrescu <andrei at erdani.com>
> 
> On 11/2/10 3:16 PM, kenji hara wrote:
> > And, I do not recommend following  use of expand:
> > writeline(mixin(expand!"take $n  times."));
> >
> > The probrem is:
> > - expand concatenates string  by ~ operators, it is may cost than using
> > appender(text, formatWrite,  writefln...)
> >
> > I will remove ddoc example from github  code.
> 
> Expand should have an option to expand with commas and without to!string, i.e. in order to make the  code:
> 
> writeln(mixin(anotherexpand!"take $n times."));
> 
> identical  100% with the code
> 
> writeln("take ", n, " times.");
> 
> Not sure what's  the best name for  "anotherexpand".
> 
> Andrei
> _______________________________________________
> phobos  mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
> 



November 02, 2010
I think it would be great if we didn't have to write mixin(blah(stuff)). With that... it's almost just as annoying :o).

Andrei

On 11/2/10 3:49 PM, Steve Schveighoffer wrote:
> Is it just me, or does
>
> writeln("take ", n, " times.");
>
> not look so bad that we need to invent a function to do it with expansion?
>
> I've used php for a while, and I love the variable expansion inside strings, but I don't know if it's worth defining a library function to do it.
>
> -Steve
>
>
>
> ----- Original Message ----
>> From: Andrei Alexandrescu<andrei at erdani.com>
>>
>> On 11/2/10 3:16 PM, kenji hara wrote:
>>> And, I do not recommend following  use of expand:
>>> writeline(mixin(expand!"take $n  times."));
>>>
>>> The probrem is:
>>> - expand concatenates string  by ~ operators, it is may cost than using
>>> appender(text, formatWrite,  writefln...)
>>>
>>> I will remove ddoc example from github  code.
>>
>> Expand should have an option to expand with commas and without to!string, i.e. in order to make the  code:
>>
>> writeln(mixin(anotherexpand!"take $n times."));
>>
>> identical  100% with the code
>>
>> writeln("take ", n, " times.");
>>
>> Not sure what's  the best name for  "anotherexpand".
>>
>> Andrei
>> _______________________________________________
>> phobos  mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>>
>
>
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
November 02, 2010
On Tue, Nov 2, 2010 at 3:30 PM, Andrei Alexandrescu <andrei at erdani.com>
 wrote:

> On 11/2/10 3:16 PM, kenji hara wrote:
>
>> And, I do not recommend following use of expand:
>> writeline(mixin(expand!"take $n times."));
>>
>> The probrem is:
>> - expand concatenates string by ~ operators, it is may cost than using
>> appender(text, formatWrite, writefln...)
>>
>> I will remove ddoc example from github code.
>>
>
> Expand should have an option to expand with commas and without to!string, i.e. in order to make the code:
>
> writeln(mixin(anotherexpand!"take $n times."));
>
> identical 100% with the code
>
> writeln("take ", n, " times.");
>
> Not sure what's the best name for "anotherexpand".
>
> Andrei
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
>
Something like expandsplit?
I'm thinking of that because Python has "one two three".split()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/phobos/attachments/20101102/5067499c/attachment.html>
November 02, 2010
What I mean is, when just passing a string to writeln (and not using mixin to generate code), why do we need to invent a new syntax to do that?  We have:

writefln("take %s times.", n);

and

writeln("take ", n, " times.");

Why do we also need

writeln(expandToTuple!"take $n times."); // s/expandToTuple/someOtherName/

???

If there was a php-like way to do it like:

writeln("take $n times.");

I'd be all for that :)  But I don't see it happening.  Maybe some other type of quoting?

-Steve



----- Original Message ----
> From: Andrei Alexandrescu <andrei at erdani.com>
> 
> I think it would be great if we didn't have to write mixin(blah(stuff)). With that... it's almost just as annoying :o).
> 
> Andrei
> 
> On  11/2/10 3:49 PM, Steve Schveighoffer wrote:
> > Is it just me, or  does
> >
> > writeln("take ", n, " times.");
> >
> > not look so  bad that we need to invent a function to do it with expansion?
> >
> >  I've used php for a while, and I love the variable expansion inside strings,
>but
> > I don't know if it's worth defining a library function to do  it.
> >
> > -Steve
> >
> >
> >
> > ----- Original  Message ----
> >> From: Andrei Alexandrescu<andrei at erdani.com>
> >>
> >>  On 11/2/10 3:16 PM, kenji hara wrote:
> >>> And, I do not recommend  following  use of expand:
> >>> writeline(mixin(expand!"take  $n  times."));
> >>>
> >>> The probrem  is:
> >>> - expand concatenates string  by ~ operators, it is may  cost than using
> >>> appender(text, formatWrite,   writefln...)
> >>>
> >>> I will remove ddoc example from  github  code.
> >>
> >> Expand should have an option to  expand with commas and without to!string, i.e. in order to make  the  code:
> >>
> >> writeln(mixin(anotherexpand!"take $n  times."));
> >>
> >> identical  100% with the  code
> >>
> >> writeln("take ", n, "  times.");
> >>
> >> Not sure what's  the best name for   "anotherexpand".
> >>
> >> Andrei
> >>  _______________________________________________
> >> phobos  mailing  list
> >> phobos at puremagic.com
> >>  http://lists.puremagic.com/mailman/listinfo/phobos
> >>
> >
> >
> >
> >  _______________________________________________
> > phobos mailing  list
> > phobos at puremagic.com
> > http://lists.puremagic.com/mailman/listinfo/phobos
> 



November 02, 2010
On Tue, 02 Nov 2010 16:08:11 -0400, kenji hara <k.hara.pg at gmail.com> wrote:
> The points of text vs expand are:
> - text is comma separated formatting, expand is inlined formatting.

Personally, I consider comma separated formatting to be inlined, or at least inline style, but I understand your point.

> - text is general formatting function, expand is mostly useful in compile-time, and specialized D code formatting for code generation.

And text is both general and works at compile time.

> - editor highlighting issue - my editor does not color q{}, so generating code are colored with normal syntax highlighting. If I use text and its formatting, code readability will be wrong. I don't like it.

I think this is the biggest advantage of it. Well, that and familiarity to
Perl, PHP, etc, users.
But the amount/size of code inside these strings need to be pretty large
before it gets really annoying. For me, your generateFun example (which is
the only use of expand in interfaces.d) is a two liner, and is simply not
big enough to start sweating about these issues to me. And most of my
large mixins for me are generated dynamically; my need for expanding
variables in long strings is pretty minimal. You wouldn't have/know of a
good example of a long explicit string mixin requiring non-trivial
expansion, would you?

I recognize the benefits of expand, but I'm just concerned about introducing yet-another string formating routine, particularly one that looks low-yield in terms of power and is rather complex, into phobos.

Part of this problem could be addressed with better documentation, which highlights the shell-like syntax and the differences between expand, text, Format and ~.


November 03, 2010
On Tue, 2 Nov 2010 14:09:29 -0700 (PDT)
Steve Schveighoffer <schveiguy at yahoo.com> wrote:

> If there was a php-like way to do it like:
> 
> writeln("take $n times.");

Cobra has "take [n] times.", IIRC.
what do we need to implement that in D? (I mean, something like reading var values by name in current scope?)

Denis
-- -- -- -- -- -- --
vit esse estrany ?

spir.wikidot.com

November 02, 2010
On Tue, Nov 2, 2010 at 6:41 PM, spir <denis.spir at gmail.com> wrote:

> On Tue, 2 Nov 2010 14:09:29 -0700 (PDT)
> Steve Schveighoffer <schveiguy at yahoo.com> wrote:
>
> > If there was a php-like way to do it like:
> >
> > writeln("take $n times.");
>
> Cobra has "take [n] times.", IIRC.
> what do we need to implement that in D? (I mean, something like reading var
> values by name in current scope?)
>
> Denis
> -- -- -- -- -- -- --
> vit esse estrany ?
>
> spir.wikidot.com
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>


That would be really nice.
I really like Cobra myself.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/phobos/attachments/20101102/92d99ab8/attachment.html>
November 03, 2010
Paste my old code which creates tagged-union.
Is this a example of strong argument?

----
class Exp
{
    mixin TagUnion!(
        "CONST",IntT,
        "NAME", Label,
        "ESEQ", Stm, Exp
    );
}
Exp e;
e = CONST(10);
e = LABEL(l)
e = ESEQ(s, e);

template TagUnion(T...)
{
  ...

  // tycon tags
    enum MakeTyconTags =
        "enum Tag:"~(LeastUnsignedType!TyconCnt).stringof~"{ "
            ~staticReduce!(q{A==""?B~"=0":A~", "~B}, "", TyconTags)~" "
        "}";

  // tycon types
    template MakeTyconTypeField(size_t N)
    {
        template MakeTyconTypeField(size_t I)
        {
            enum MakeTyconTypeField = ToLongString!(TyconSig!N[I])~"
_"~to!string(I);
        }
    }
    template MakeTyconType(size_t N)
    {
        enum MakeTyconType =
            "static struct "~TyconTag!N~"_T{ "
                "Tag tag; "
                ~staticReduce!(q{A==""?B:A~"; "~B}, "",
generateTuple!(0, TyconSig!N.length, MakeTyconTypeField!N))~"; "
            "}";
    }
    enum MakeTyconTypes =
        staticReduce!(q{A==""?B:A~"\n"~B}, "", generateTuple!(0,
TyconCnt, MakeTyconType));

  // tycon datas
    template MakeTyconData(size_t N)
    {
        enum MakeTyconData = TyconTag!N~"_T data"~to!string(N)~";";
    }
    enum MakeTyconDatas =
        "union{ "~
            "Tag tag; "
            ~staticReduce!(q{A==""?B:A~" "~B}, "", generateTuple!(0,
TyconCnt, MakeTyconData))~
        " }";

  // ctors
    template MakeCtor(size_t N){
        enum MakeCtor =
            "this(ref "~TyconTag!N~"_T data){ data"~to!string(N)~" = data; }";
    }
    enum MakeCtors =
        staticReduce!(q{A==""?B:A~"\n"~B}, "", generateTuple!(0,
TyconCnt, MakeCtor));

  // tycons
    template MakeTycon(size_t N){
        enum MakeTycon =
            `static auto `~TyconTag!N~`(U...)(U args){`
                                         "\n"
            `   static if (is(U == TypeTuple!(`
                        ~staticReduce!(q{A==""?B:A~", "~B}, "",
staticMap!(ToLongString, TyconSig!N))~  `)))`   "\n"
            `   {`
                                         "\n"
            `       return new
typeof(this)(`~TyconTag!N~`_T(Tag.`~TyconTag!N~`, args));`
          "\n"
            `   }`
                                         "\n"
            `   else static if (Tie!U.isMatchingTuple!(`
                        ~staticReduce!(q{A==""?B:A~", "~B}, "",
staticMap!(ToLongString, TyconSig!N))~  `))`    "\n"
            `   {`
                                         "\n"
            `       return tie(Tag.`~TyconTag!N~`, args);`
                                         "\n"
            `   }`
                                         "\n"
            `   else`
                                         "\n"
            `   {`
                                         "\n"
            `       static assert(0);`
                                         "\n"
            `   }`
                                         "\n"
            `}`;
    }
    enum MakeTycons =
        staticReduce!(q{A==""?B:A~"\n"~B}, "", generateTuple!(0,
TyconCnt, MakeTycon));

  // opTieMatch
    template MakeTieMatchCase(size_t N){
        enum MakeTieMatchCase =
            `   case Tag.`~TyconTag!N~`:`
                         "\n"
            `       static if (Tie!U.isMatchingTuple!(Tag,
TyconSig!`~to!string(N)~`))`         "\n"
            `       {`
                         "\n"
            `           return tie =
tuple(data`~to!string(N)~`.tupleof);`                      "\n"
            `       }`
            `       else`
                         "\n"
            `       {`
                         "\n"
            `           return false;`
                         "\n"
            `       }`;
    }
    template MakeTieMatchInstanceIf(size_t N)
    {
        enum MakeTieMatchInstanceIf =
            `Tie!U.isMatchingTuple!(Tag, TyconSig!`~to!string(N)~`)`;
    }
    enum MakeTieMatch =
        `bool opTieMatch(U...)(ref Tie!U tie){`
                         "\n"
        `   static if (!(`
                ~staticReduce!(q{A==""?""~B:A~" || "~B}, "",
generateTuple!(0, TyconCnt, MakeTieMatchInstanceIf))~
            `))`
                         "\n"
        `   {`
                         "\n"
        `       static assert(0);`
                         "\n"
        `   }`
                         "\n"
        "   \n"
        `   final switch( tag ){`
                         "\n"
        ~staticReduce!(q{A==""?B:A~"\n"~B}, "", generateTuple!(0,
TyconCnt, MakeTieMatchCase))~ "\n"
        `   }`
                         "\n"
        `}`;

  // export tycons out of class/struct
    enum MakeTyconAlias =
        `import meta;`
                                         "\n"
        `template MakeAlias(size_t N)`
                                         "\n"
        `{`
                                         "\n"
        `   enum MakeAlias =`
                                         "\n"
        `       "alias "`
                                         "\n"
        `           ~ToLongString!(typeof(this))~"."~`
                                         "\n"
        `
TypeTuple!(`~staticReduce!(q{A==""?"\""~B:A~"\", \""~B}, "",
TyconTags)~`")[N]`         "\n"
        `               ~" "~`
                                         "\n"
        `
TypeTuple!(`~staticReduce!(q{A==""?"\""~B:A~"\", \""~B}, "",
TyconTags)~`")[N]`         "\n"
        `           ~";";`
                                         "\n"
        `}`
                                         "\n"
        `template Tycons()`
                                         "\n"
        `{`
                                         "\n"
        `   enum Tycons =`
                                         "\n"
        `       staticReduce!(q{A==""?B:A~"\n"~B}, "",
generateTuple!(0, `~to!string(TyconCnt)~`, MakeAlias));` "\n"
        `}`;

private:
    mixin(MakeTyconTags);
    mixin(MakeTyconTypes);
    mixin(MakeTyconDatas);
    mixin(MakeTieMatch);
public:
    mixin(MakeCtors);
    mixin(MakeTycons);
    mixin(MakeTyconAlias);
}
----


2010/11/3 Robert Jacques <sandford at jhu.edu>:
> On Tue, 02 Nov 2010 14:27:28 -0400, kenji hara <k.hara.pg at gmail.com> wrote:
>
>>> enum code = text(q{ enum msg = "I call you "}, count, q{" times"} );
>>> enum code = text(` enum msg = "I call you `, count, ` times;` );
>>> enum code = ` enum msg = "I call you ` ~ count ~ ` times;`
>>> enum code = q{ enum msg = "I call you "} ~ count ~ q{" times"; }
>>
>> 1st and 4th does not generate intended code string, but generates invalid
>> one.
>> expand! generates 3rd code automatically cooperation with mixin.
>> (2nd is ... the code currently others want to generate for run-time
>> performance?)
>
> Opps. Sorry, I tested 2 & 3, but forgot to test 1 & 2. I also seemed to have forgotten a " after times in 2 & 3.
>
> Also, what do you mean by: (2nd is ... the code currently others want to generate for run-time performance?)
>
>>> I admit ${n} is slightly better than },n,q{, but it's by no means ugly.
>>> (And
>>> using `` instead of q{} makes it better: `,n,`)
>>
>> The advantage of expand! is that escapes string quotations and
>> concatenates correctly while keeping readability of our meta-code
>> well.
>> (In above 3rd, you escape q{} to `` and interpolate "count" *manually*.)
>
> Yes, manually escaping and concatenating, in all but the trivial cases, is really annoying. But my main point was that text is both CTFE-able and lets you cleanly do everything expand does naturally. Expand is more complex to use, isn't self-documenting (i.e. you have to remember to use a mixin), is mostly redundant and increases the radius of comprehension of phobos. However, it does allow you to escape a token strings inside a nested string in a nice in-lined way. So far, the examples don't seem to provide a strong argument for yet another text formater beyond text and Format. Also, if I recall correctly the plan is to get a large portion of both phobos and D CTFE compatible, which would eventually eliminate the need for the current metastrings.
>
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
November 03, 2010
On Wed, 03 Nov 2010 02:04:45 -0400, kenji hara <k.hara.pg at gmail.com> wrote:
> Paste my old code which creates tagged-union.
> Is this a example of strong argument?

Strong argument: no. Borderline argument: yes. Mainly it's ugly because it's an example from (I assume) a time before you knew strings could be multi-lined. Switch to using multi-line strings, and it cleans up rather nicely.

P.S. Does expansion of types work? i.e. q{$int} == "int".