November 13, 2013
On 11/13/2013 4:25 AM, Jacob Carlborg wrote:
> On 2013-11-13 09:38, Walter Bright wrote:
>
>> What's special about it was its use of expression templates. It made for
>> a nice demo of how to do such.
>
> Is there an actual point in doing that, except a nice exercise in expression
> templates?

It actually generated a very fast regex engine, though Dmitry's work has since eclipsed it.

November 13, 2013
On 11/13/2013 1:15 AM, deadalnix wrote:
> On Wednesday, 13 November 2013 at 08:45:13 UTC, Walter Bright wrote:
>> On 11/13/2013 12:03 AM, Jacob Carlborg wrote:
>>> Again, operator overloading in D is too limiting to implement something Linq
>>> like.
>>
>> Ok, let's set aside the opEquals and opCmp issue for the moment.
>>
>> Can AST macros do anything that expression templates cannot?
>
> Yes, they can reflect the ast provided and act accordingly.

The reflection ability is not something specific to an AST, it could be added so that any expression node can be reflected. We already do much of that with __traits.
November 13, 2013
On 11/13/2013 1:08 AM, Don wrote:
> On Wednesday, 13 November 2013 at 08:45:13 UTC, Walter Bright wrote:
>> On 11/13/2013 12:03 AM, Jacob Carlborg wrote:
>>> Again, operator overloading in D is too limiting to implement something Linq
>>> like.
>>
>> Ok, let's set aside the opEquals and opCmp issue for the moment.
>>
>> Can AST macros do anything that expression templates cannot?
>
> With an expression template you still can't create a statement. It has to
> revolve to a declaration.

Actually, there is a way to do this. I wrote an article years back on how to write "statement" workalikes using lazy function parameters. I suppose I should dig that up if I can find it.


> But as I said before, it's primarily syntax sugar. Expression templates are just
> a mass of boilerplate code. I came to the conclusion that the code for
> expression templates was no less ugly than for string mixins.
>
> What is true, though, is everything an AST macro can do, can already be done
> with a string mixin. The syntax is just ugly.
>
>                   calling syntax power  implementation
> string mixin       ugly         high      ugly
> expr template       ok          low       ugly
> AST macro          good          ?         ?

This implies to me that we ought to explore the limits of expression templates, which already exist, in preference to creating a wholesale new feature.

November 13, 2013
On 11/13/2013 11:24 AM, Walter Bright wrote:
> Actually, there is a way to do this. I wrote an article years back on how to
> write "statement" workalikes using lazy function parameters. I suppose I should
> dig that up if I can find it.

Ah, found the code:

void ifthen(bool cond, lazy void dg)
{
    if (cond)
        dg();
}

void ifthen(bool cond, lazy void dgthen, lazy void dgelse)
{
    if (cond)
        dgthen();
    else
        dgelse();
}

void dotimes(int i, lazy int dg)
{
    for (int j = 0; j < i; j++)
        dg();
}

void switcher(bool delegate()[] cases...)
{
    foreach (c; cases)
    {
        if (c())
            break;
    }
}

bool scase(bool b, lazy void dg)
{
    if (b)
    {
        dg();
        return true;
    }
    return false;
}

bool sdefault(lazy void dg)
{
    dg();
    return true;
}

void whiler(lazy bool cond, lazy void bdy)
{
    while (cond())
        bdy();
}

void test1()
{
    int x = 3;
    dotimes(5, printf("%d\n", ++x));

    ifthen(true, printf("yes\n"));
    ifthen(false, printf("no\n"));

    ifthen(true, printf("yes\n"), printf("no\n"));
    ifthen(false, printf("yes\n"), printf("no\n"));

    int v = 2;
    switcher(
        scase(v == 1, printf("it is 1\n")),
        scase(v == 2, printf("it is 2\n")),
        scase(v == 3, printf("it is 3\n")),
        sdefault( printf("it is default\n"))
    );

    whiler( x < 100,
        (printf("%d\n", x), x *= 2)
    );
}
November 13, 2013
13-Nov-2013 12:15, luka8088 пишет:
> On 10.11.2013. 22:20, Jacob Carlborg wrote:
[snip]
> foo {
>    writeln("foo");
>    writeln("foo again");
> }
>
> I would have to write:
>
> mixin(foo!(q{
>    writeln("foo");
>    writeln("foo again");
> }));
>

Actually even now it's can be just
foo!q{
 ...
};

For instance this is compilable:
{
 import std.regex;
 auto r =  ctRegex!"how do you think that works?";
}

See ctRegex template in std.regex.

-- 
Dmitry Olshansky
November 13, 2013
13-Nov-2013 01:16, Dicebot пишет:
> On Tuesday, 12 November 2013 at 20:56:34 UTC, Dmitry Olshansky wrote:
>> If we just had:
>>
>> //this would invoke compiler's parser at CTFE
>> auto ast = "x = y;".astof
>>
>> and have it work at CTFE to return sensible AST (a big if btw).
>>
>> And then (after some manipulations):
>> ast.toString() //get back a string of D code
>>
>> It may help code generation of D --> DSL.
>
> Add there "foo.codeof" in the toolset and it will pretty much give core
> needed stuff.
>
> However, it will destroy compilation times if not coupled with compiler
> internal parsing/semantic phase.

For me it feels a lot like implementing something as a soft-core or emulator in software vs producing a bare-metal chip. It's a good idea to test waters and prototype a soft-thingy before getting dirty. When it comes to manufacture ASICs the idea should be well tested and could be actually sold as is already ;)

If we consider that compiler is sort of "hardware" accelerator for getting ast's of strings and functions alike. Ditto with toString of ast. Then if somebody comes up with soft-core implementation of "macros" and shows:
a) Cool benefits of manipulating on ASTs compared to cracking some strings
b) Limitations of this implementation (unhyginic is one)
c) Quantify obvious performance problems
d) Prepare a solid file of use cases

Then we might get people to manufacture ASICs (pay costs, implement in compiler/spec).

Paraphrasing somebody from C++ ISO committee (I think Herb):

Boost C++ Lambda is a prime reason we had to add lambdas as a core feature in C++11. If it took these top-notch experts that much of coding to get only this far and it's still brittle, limited and etc.
... we have no choice but to add it to the language.

> Actual "macro" keyword syntax sugar is hardly important to me.


-- 
Dmitry Olshansky
November 13, 2013
On 11/13/2013 08:25 PM, Walter Bright wrote:
>>
>
> Ah, found the code:
>
> void ifthen(bool cond, lazy void dg)
> {
>      if (cond)
>          dg();
> }

int foo(int x){
    ifthen(!x, return 2); // uh oh
    return 3;
}
November 13, 2013
On 11/13/2013 12:50 PM, Timon Gehr wrote:
> On 11/13/2013 08:25 PM, Walter Bright wrote:
>>>
>>
>> Ah, found the code:
>>
>> void ifthen(bool cond, lazy void dg)
>> {
>>      if (cond)
>>          dg();
>> }
>
> int foo(int x){
>      ifthen(!x, return 2); // uh oh
>      return 3;
> }

This approach definitely hews to the single-entry/single-exit paradigm.
November 13, 2013
On Wednesday, 13 November 2013 at 17:13:11 UTC, Chris Nicholson-Sauls wrote:

> Is this in any way better than the basic Ruby
>
>   where( name: 'John', address: 'Main street' )
>
> ?  Or was it just something quick and contrived to show the behavior, and not the utility, of the plugin?  Just curious.

It was mostly to show what happens when the you have limited operator overloading.

It has it advantages over the hash-syntax. You can do much more, not equal, less then, greater then, like and so on.

--
/Jacob Carlborg
November 13, 2013
On Wednesday, 13 November 2013 at 19:19:32 UTC, Walter Bright wrote:
> The reflection ability is not something specific to an AST, it could be added so that any expression node can be reflected. We already do much of that with __traits.

Yes, that is why Dicebot was mentioning the parallel with compile time reflection.