December 30, 2011
On 12/30/2011 3:21 PM, Timon Gehr wrote:
> 2. it picks up all symbols used in $(...) from the caller's context rather than
> the callee's context and there is no way to get rid of that default, because the
> macro is unscoped.

That's characteristic of how macros work, and people want it that way. Otherwise, they'd use functions or templates.
December 30, 2011
On 12/31/2011 12:34 AM, Walter Bright wrote:
> On 12/30/2011 3:21 PM, Timon Gehr wrote:
>> 2. it picks up all symbols used in $(...) from the caller's context
>> rather than
>> the callee's context and there is no way to get rid of that default,
>> because the
>> macro is unscoped.
>
> That's characteristic of how macros work, and people want it that way.
> Otherwise, they'd use functions or templates.

I don't think that is true. It's an undesirable characteristic. I don't think it works well together with a module system. Note that I use arbitrary CTFE inside @(...). That can be correcting the case of an identifier or any implementation detail. I don't want to require any module that expands the macro to import those implementation details publicly. If I actually want to pick up identifiers from the caller's scope, that is easy: I just embed another X template instantiation.

December 31, 2011
On 12/30/11 5:21 PM, Timon Gehr wrote:
> On 12/31/2011 12:02 AM, Andrei Alexandrescu wrote:
>> The library has a simple interface:
>>
>> enum myMacro = q{... $1 $2 $(anotherMacro($1))... };
>>
>> // To mixin
>> mixin(expand(myMacro, "argument one", "argument two"));
>>
>>
>> Andrei
>>
> I understand, but compared to how I solved the issue
>
> 1. it invents an (arguably inferior) parameter passing system, even
> though there is one in the language.
> 2. it picks up all symbols used in $(...) from the caller's context
> rather than the callee's context and there is no way to get rid of that
> default, because the macro is unscoped.

Fair enough. I think your idea of defining a mini-macro-expansion system based on CTFE and strings is genius. I also think at the present the semantics are very unprincipled, and should not be popularized in any form lest D mixins acquire reputation similar to C macros. Finally, I think you have the resources to work your idea into a wonderful system that will be principled, practical, and extremely powerful.

Good luck!

Andrei
December 31, 2011
On 12/31/2011 01:10 AM, Andrei Alexandrescu wrote:
> On 12/30/11 5:21 PM, Timon Gehr wrote:
>> On 12/31/2011 12:02 AM, Andrei Alexandrescu wrote:
>>> The library has a simple interface:
>>>
>>> enum myMacro = q{... $1 $2 $(anotherMacro($1))... };
>>>
>>> // To mixin
>>> mixin(expand(myMacro, "argument one", "argument two"));
>>>
>>>
>>> Andrei
>>>
>> I understand, but compared to how I solved the issue
>>
>> 1. it invents an (arguably inferior) parameter passing system, even
>> though there is one in the language.
>> 2. it picks up all symbols used in $(...) from the caller's context
>> rather than the callee's context and there is no way to get rid of that
>> default, because the macro is unscoped.
>
> Fair enough. I think your idea of defining a mini-macro-expansion system
> based on CTFE and strings is genius. I also think at the present the
> semantics are very unprincipled, and should not be popularized in any
> form lest D mixins acquire reputation similar to C macros.

I think what you propose is a lot closer to C macros than what I already use. Therefore I don't understand what qualifies its semantics as unprincipled.

> Finally, I think you have the resources to work your idea into a wonderful system
> that will be principled, practical, and extremely powerful.
>
> Good luck!
>
> Andrei

I'd be happy to extend the system, but currently I don't see it fall short any of the three requirements. Can you help me out?

December 31, 2011
On Fri, 30 Dec 2011 20:48:54 +0200, Walter Bright <newshound2@digitalmars.com> wrote:

> On 12/30/2011 7:06 AM, so wrote:
>> I agree @inline (which will probably be an extension) in D should mean
>> force-inline.
>> Ignoring the impossible-to-inline cases (which in time should get better),
>> adding @inline is a few minutes of editing.
>> It will just bypass the cost function and if it is not possible to inline, pop
>> error.
>
>
> Sure, but I think you'll be very disappointed in that it isn't going to deliver the goods.

dmd_inl -O -inline test.d
dmd_inl -O -inline test_inl.d
time ./test

real    0m4.686s
user    0m3.516s
sys     0m0.007s
time ./test_inl

real    0m1.900s
user    0m1.503s
sys     0m0.007s
time ./test

real    0m4.381s
user    0m3.520s
sys     0m0.010s
time ./test_inl

real    0m1.955s
user    0m1.473s
sys     0m0.037s
time ./test

real    0m4.473s
user    0m3.506s
sys     0m0.017s
time ./test_inl

real    0m1.836s
user    0m1.507s
sys     0m0.007s
time ./test

real    0m4.627s
user    0m3.523s
sys     0m0.003s
time ./test_inl

real    0m1.984s
user    0m1.480s
sys     0m0.030s

Just bypassing cost escape, I ll try some complex cases soon after i get phobos working.

int test() // test.d
int test() @inline // test_inl.d
{
	int i = 0;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	++i;
	return i;
}

void main()
{
	for(uint i=0; i<1_000_000_000; ++i)
		test();
}
December 31, 2011
On 31 December 2011 00:48, so <so@so.so> wrote:
> On Fri, 30 Dec 2011 20:48:54 +0200, Walter Bright <newshound2@digitalmars.com> wrote:
>
>> On 12/30/2011 7:06 AM, so wrote:
>>>
>>> I agree @inline (which will probably be an extension) in D should mean
>>> force-inline.
>>> Ignoring the impossible-to-inline cases (which in time should get
>>> better),
>>> adding @inline is a few minutes of editing.
>>> It will just bypass the cost function and if it is not possible to
>>> inline, pop
>>> error.
>>
>>
>>
>> Sure, but I think you'll be very disappointed in that it isn't going to deliver the goods.
>
>
> dmd_inl -O -inline test.d
> dmd_inl -O -inline test_inl.d
> time ./test
>
> real    0m4.686s
> user    0m3.516s
> sys     0m0.007s
> time ./test_inl
>
> real    0m1.900s
> user    0m1.503s
> sys     0m0.007s
> time ./test
>

*SNIP*

>
> void main()
> {
>        for(uint i=0; i<1_000_000_000; ++i)
>                test();
> }

A better compiler would see that the function 'test' has no side effects, and it's return value is unused, so elimates the call to it completely as dead code.

-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
December 31, 2011
On Sat, 31 Dec 2011 03:12:38 +0200, Iain Buclaw <ibuclaw@ubuntu.com> wrote:

> On 31 December 2011 00:48, so <so@so.so> wrote:
>> On Fri, 30 Dec 2011 20:48:54 +0200, Walter Bright
>> <newshound2@digitalmars.com> wrote:
>>
>>> On 12/30/2011 7:06 AM, so wrote:
>>>>
>>>> I agree @inline (which will probably be an extension) in D should mean
>>>> force-inline.
>>>> Ignoring the impossible-to-inline cases (which in time should get
>>>> better),
>>>> adding @inline is a few minutes of editing.
>>>> It will just bypass the cost function and if it is not possible to
>>>> inline, pop
>>>> error.
>>>
>>>
>>>
>>> Sure, but I think you'll be very disappointed in that it isn't going to
>>> deliver the goods.
>>
>>
>> dmd_inl -O -inline test.d
>> dmd_inl -O -inline test_inl.d
>> time ./test
>>
>> real    0m4.686s
>> user    0m3.516s
>> sys     0m0.007s
>> time ./test_inl
>>
>> real    0m1.900s
>> user    0m1.503s
>> sys     0m0.007s
>> time ./test
>>
>
> *SNIP*
>
>>
>> void main()
>> {
>>        for(uint i=0; i<1_000_000_000; ++i)
>>                test();
>> }
>
> A better compiler would see that the function 'test' has no side
> effects, and it's return value is unused, so elimates the call to it
> completely as dead code.

It is just a dummy function that dmd rejected to inline, send me a better one (which won't use any libraries) and i'll use it :)
December 31, 2011
On 31 December 2011 01:21, so <so@so.so> wrote:
> On Sat, 31 Dec 2011 03:12:38 +0200, Iain Buclaw <ibuclaw@ubuntu.com> wrote:
>
>> On 31 December 2011 00:48, so <so@so.so> wrote:
>>>
>>> On Fri, 30 Dec 2011 20:48:54 +0200, Walter Bright <newshound2@digitalmars.com> wrote:
>>>
>>>> On 12/30/2011 7:06 AM, so wrote:
>>>>>
>>>>>
>>>>> I agree @inline (which will probably be an extension) in D should mean
>>>>> force-inline.
>>>>> Ignoring the impossible-to-inline cases (which in time should get
>>>>> better),
>>>>> adding @inline is a few minutes of editing.
>>>>> It will just bypass the cost function and if it is not possible to
>>>>> inline, pop
>>>>> error.
>>>>
>>>>
>>>>
>>>>
>>>> Sure, but I think you'll be very disappointed in that it isn't going to deliver the goods.
>>>
>>>
>>>
>>> dmd_inl -O -inline test.d
>>> dmd_inl -O -inline test_inl.d
>>> time ./test
>>>
>>> real    0m4.686s
>>> user    0m3.516s
>>> sys     0m0.007s
>>> time ./test_inl
>>>
>>> real    0m1.900s
>>> user    0m1.503s
>>> sys     0m0.007s
>>> time ./test
>>>
>>
>> *SNIP*
>>
>>
>>>
>>> void main()
>>> {
>>>       for(uint i=0; i<1_000_000_000; ++i)
>>>               test();
>>> }
>>
>>
>> A better compiler would see that the function 'test' has no side effects, and it's return value is unused, so elimates the call to it completely as dead code.
>
>
> It is just a dummy function that dmd rejected to inline, send me a better
> one (which won't use any libraries) and i'll use it :)

Take a pick of any examples posted on this ML.  They are far better fit to use as a test bed.  Ideally one that does number crunching and can't be easily folded away.

Regards

-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
December 31, 2011
On Sat, 31 Dec 2011 03:40:43 +0200, Iain Buclaw <ibuclaw@ubuntu.com> wrote:

> Take a pick of any examples posted on this ML.  They are far better
> fit to use as a test bed.  Ideally one that does number crunching and
> can't be easily folded away.

Well not them but another dummy function, i didn't think it would differ this much.

time ./test_inl

real    0m0.013s
user    0m0.007s
sys     0m0.003s
time ./test

real    0m7.753s
user    0m5.966s
sys     0m0.013s
time ./test_inl

real    0m0.013s
user    0m0.010s
sys     0m0.000s
time ./test

real    0m7.391s
user    0m5.960s
sys     0m0.017s
time ./test_inl

real    0m0.014s
user    0m0.007s
sys     0m0.003s
time ./test

real    0m7.582s
user    0m5.950s
sys     0m0.030s


real test() // test.d
real test() @inline // test_inl.d
{
	real a=423123, b=432, c=10, d=100, e=4045, f=123;
	a = a / b * c / d + e - f;
	b = a / b * c / d + e - f;
	c = a / b * c / d + e - f;
	d = a / b * c / d + e - f;
	e = a / b * c / d + e - f;
	f = a / b * c / d + e - f;
	a = a / b * c / d + e - f;
	b = a / b * c / d + e - f;
	c = a / b * c / d + e - f;
	d = a / b * c / d + e - f;
	e = a / b * c / d + e - f;
	f = a / b * c / d + e - f;
	a = a / b * c / d + e - f;
	b = a / b * c / d + e - f;
	c = a / b * c / d + e - f;
	d = a / b * c / d + e - f;
	e = a / b * c / d + e - f;
	f = a / b * c / d + e - f;
	return f;
}

void main()
{
	for(uint i=0; i<1_000_000_0; ++i)
		test();
}
December 31, 2011
On 12/30/11 6:25 PM, Timon Gehr wrote:
> I'd be happy to extend the system, but currently I don't see it fall
> short any of the three requirements. Can you help me out?

I think it would be great to reproduce the expansion semantics of ddoc.

Andrei