February 16, 2007
Lionello Lunesu wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> Walter Bright wrote:
>>>
>>> I agree. I need a better example. Any ideas?
>>
>> Well we talked about:
>>
>> int a = foo();
>> char[] b = bar();
>> print("a is $a and b is $b, dammit\n");
>>
>> The interesting part is that this will also require you to screw in a couple of extra nuts & bolts (that were needed anyway).
> 
> 
> But add a "!" to the print, and it's already possible? What extra is needed, and is that just to get rid of the "!"?

You currently also need a mixin() around the print!().
February 16, 2007
Frits van Bommel wrote:
> Lionello Lunesu wrote:
>> Andrei Alexandrescu (See Website For Email) wrote:
>>> Walter Bright wrote:
>>>>
>>>> I agree. I need a better example. Any ideas?
>>>
>>> Well we talked about:
>>>
>>> int a = foo();
>>> char[] b = bar();
>>> print("a is $a and b is $b, dammit\n");
>>>
>>> The interesting part is that this will also require you to screw in a couple of extra nuts & bolts (that were needed anyway).
>>
>>
>> But add a "!" to the print, and it's already possible? What extra is needed, and is that just to get rid of the "!"?
> 
> You currently also need a mixin() around the print!().

Aha.. Or "before", right?

mixin print!("......");

L.
February 16, 2007
Lionello Lunesu wrote:
> Frits van Bommel wrote:
>> Lionello Lunesu wrote:
>>> Andrei Alexandrescu (See Website For Email) wrote:
>>>> Walter Bright wrote:
>>>>>
>>>>> I agree. I need a better example. Any ideas?
>>>>
>>>> Well we talked about:
>>>>
>>>> int a = foo();
>>>> char[] b = bar();
>>>> print("a is $a and b is $b, dammit\n");
>>>>
>>>> The interesting part is that this will also require you to screw in a couple of extra nuts & bolts (that were needed anyway).
>>>
>>>
>>> But add a "!" to the print, and it's already possible? What extra is needed, and is that just to get rid of the "!"?
>>
>> You currently also need a mixin() around the print!().
> 
> Aha.. Or "before", right?
> 
> mixin print!("......");

I think the example requires a string mixin statement, which according to the spec means parentheses are required[1].
Note that it needs to access variables whose names are specified in the string argument.


[1]: http://www.digitalmars.com/d/statement.html#MixinStatement
February 16, 2007
On Thu, 15 Feb 2007 13:02:40 -0800, Walter Bright <newshound@digitalmars.com> wrote:

>Gregor Richards wrote:
>> I see that I can't do this:
>> 
>> char[] someCompileTimeFunction()
>> {
>>     return "writefln(\"Wowza!\");";
>> }
>> 
>> int main()
>> {
>>     mixin(someCompileTimeFunction());
>>     return 0;
>> }
>> 
>> 
>> Any chance of compile-time code generation via this mechanism? Or are they simply handled in different, incompatible steps of compilation?
>> 
>>  - Gregor Richards
>> 
>> PS: Yes, I realize this is a terrible idea ^^
>
>That's a bug. I'll fix it.

The following must be a related bug. The compiler complains that the argument to the mixin is not a string and parse() cannot be evaliated at compile-time.

char[] parse(char[] src)
{
	return src;
}

class Test
{
	mixin(parse(import("guts.dspx")));
}

void main()
{

}

BTW, thanks for the awesome feature!
February 16, 2007
Walter Bright wrote:
> Russell Lewis wrote:
>> But here's my question: How do we have a compile-time switch which controls what to compile-time evaluate and what not?
> 
> It's not necessary. The context completely determines what to compile-time and what to run-time.

Please don't misunderstand me.  I understand how your design works. (And I think it's a pretty good one.)  But what I'm saying is that somebody might want to write code like this:

	int i;
	version(debug)
		i = eval!(MyFunc());
	else
		i = MyFunc();

Perhaps they want to do this because MyFunc() is still being debugged, or because MyFunc() takes a while to do compile-time function execution.

How would one write a cleaner syntax for this?  I'd like so see something like:

	int i = exec_compile_time_on_release_build!(MyFunc());

but I'm not sure how one would code it.
February 16, 2007
Derek Parnell wrote:
> On Thu, 15 Feb 2007 10:23:43 -0800, Walter Bright wrote:
> 
>> ... is now in DMD 1.006.
> 
> I guess its time I came clean and admitted that in spite of this being a
> huge technological advancement in the language, I can't see why I'd ever be
> needing it.
> 
> I mean, when it comes down to it, it's just a fancy way of getting the
> compiler to calculate/generate literals that can be done by myself anyway,
> no? These literals are values that can be determined prior to writing one's
> code, right?
> 
> This is not a troll posting, so can anyone enlighten me on how this ability
> will reduce the cost of maintaining code? I am very open to being educated.

It (sometimes) allows you to express things using the formulae that you used to derive them, which makes code more readable.  It also allows you to express mathematically things that might depend on implementation-dependent parameters, or versions, or whatever.

Say, like this:
	version(4K_PAGES)
		const int page_size = 4*1024;
	else
		const int page_size = 16*1024*1024;
	const int page_shift = eval!(log_base_2(page_size));

Sure, you could integrate page_shift into the version statement...but I think that the above is better.

P.S. I would prefer the template
	compile_time!(value)
over
	eval!(value)
for readability reasons.
February 16, 2007
Hi, GREAT new feature !

1) There is a bug with parentheses:
---------------------------------------------
import std.stdio;

template eval(A...) { alias A eval; }

char[] trimfirst(char[] s)
{
	int x = 0;
	foreach (char each; s) {
		if (each != ' ')
			return s[x .. $];
		x++;
	}
	return s;
}

void main()
{
	writefln(eval!(trimfirst("  test")));
	writefln(trimfirst("  test"));
}
---------------------------------------------
>  test
>test

So you see, the compile-time version doesn't work.


Now change line 9-10 to:
		if (each != ' ') {
			return s[x .. $];
		}

And voila ! Output is correct:
>test
>test


2) Would it be possible to make this working ?
writefln(eval!(std.string.stripl("  test")));

And all the other string functions from phobos, too ?


Daniel
February 16, 2007
Russell Lewis wrote:
> But what I'm saying is that somebody might want to write code like this:
> 
>     int i;
>     version(debug)
>         i = eval!(MyFunc());
>     else
>         i = MyFunc();
> 
> Perhaps they want to do this because MyFunc() is still being debugged, or because MyFunc() takes a while to do compile-time function execution.
> 
> How would one write a cleaner syntax for this?  I'd like so see something like:
> 
>     int i = exec_compile_time_on_release_build!(MyFunc());
> 
> but I'm not sure how one would code it.

That'll become possible once templates are extended to be able to take alias expressions as arguments.
February 16, 2007
Max Samukha wrote:
> The following must be a related bug. The compiler complains that the
> argument to the mixin is not a string and parse() cannot be evaliated
> at compile-time.

Yes, in the compiler source the mixin argument failed to be marked as "must interpret", so all these will fail. Fortunately, it's a trivial fix, and will go out in the next update.
February 16, 2007
Russell Lewis wrote:
> Say, like this:
>     version(4K_PAGES)
>         const int page_size = 4*1024;
>     else
>         const int page_size = 16*1024*1024;
>     const int page_shift = eval!(log_base_2(page_size));

Don't need eval!() for const declarations.

> Sure, you could integrate page_shift into the version statement...but I think that the above is better.
> 
> P.S. I would prefer the template
>     compile_time!(value)
> over
>     eval!(value)
> for readability reasons.

eval!() isn't even in the standard library! You can name it whatever you wish. In any case, I used the name "eval" simply because it was analogous to the eval function found in many scripting languages.