Thread overview
Bragging about Unix and D
Aug 23, 2006
Georg Wrede
Aug 23, 2006
BCS
Aug 24, 2006
Tom S
Aug 24, 2006
Sean Kelly
Aug 24, 2006
Oskar Linde
Aug 24, 2006
Sean Kelly
Aug 24, 2006
Tom S
Aug 24, 2006
Bruno Medeiros
August 23, 2006
I just came to town. I had an interesting debate with somebody who didn't appreciate Unix (or Linux) or D enough. So I showed to him that interacting with a Unix machine is discussing, and that when you're good at it, you talk with sentences, not single commands (as in DOS). He demanded examples, and one I gave him was to ask the machine for a multiplication table. I conjured up the following sentence:

$ for a in {0..9};do for b in {0..9};do echo -ne `dc -e"$a $b *pq"`"\011";done;echo;done

which gave a nice table:

0     0     0     0     0     0     0     0     0     0
0     1     2     3     4     5     6     7     8     9
0     2     4     6     8     10    12    14    16    18
0     3     6     9     12    15    18    21    24    27
0     4     8     12    16    20    24    28    32    36
0     5     10    15    20    25    30    35    40    45
0     6     12    18    24    30    36    42    48    54
0     7     14    21    28    35    42    49    56    63
0     8     16    24    32    40    48    56    64    72
0     9     18    27    36    45    54    63    72    81

Now, I wanted to do the same thing with DMD, but I failed miserably.

What I tried to do was some kind of template magic (a la Don) that prints something like this at compile time, without even creating an executable.

-- Sigh, can't win 'em all.
August 23, 2006
Georg Wrede wrote:
> I just came to town. I had an interesting debate with somebody who didn't appreciate Unix (or Linux) or D enough. So I showed to him that interacting with a Unix machine is discussing, and that when you're good at it, you talk with sentences, not single commands (as in DOS). He demanded examples, and one I gave him was to ask the machine for a multiplication table. I conjured up the following sentence:
> 
> $ for a in {0..9};do for b in {0..9};do echo -ne `dc -e"$a $b *pq"`"\011";done;echo;done
> 
> which gave a nice table:
> 
> 0     0     0     0     0     0     0     0     0     0
> 0     1     2     3     4     5     6     7     8     9
> 0     2     4     6     8     10    12    14    16    18
> 0     3     6     9     12    15    18    21    24    27
> 0     4     8     12    16    20    24    28    32    36
> 0     5     10    15    20    25    30    35    40    45
> 0     6     12    18    24    30    36    42    48    54
> 0     7     14    21    28    35    42    49    56    63
> 0     8     16    24    32    40    48    56    64    72
> 0     9     18    27    36    45    54    63    72    81
> 
> Now, I wanted to do the same thing with DMD, but I failed miserably.
> 
> What I tried to do was some kind of template magic (a la Don) that prints something like this at compile time, without even creating an executable.
> 
> -- Sigh, can't win 'em all.


Crud, now I'm going to have to try that!
August 24, 2006
Georg Wrede wrote:
> What I tried to do was some kind of template magic (a la Don) that prints something like this at compile time, without even creating an executable.
> 
> -- Sigh, can't win 'em all.

Not hard at all...



const int numWidth = 6;
const int width   = 10;
const int height  = 10;


template itoa(int i) {
	static if (i < 10) {
		const char[] itoa = "" ~ "0123456789"[i];
	} else {
		const char[] itoa = itoa!(i/10) ~ "0123456789"[i%10];
	}
}


template nspaces(int n) {
	static if (n > 0) {
		const char[] nspaces = " " ~ nspaces!(n - 1);
	} else {
		const char[] nspaces = "";
	}
}


template itoa_pad(int i) {
	const char[] itoa_pad = itoa!(i) ~ nspaces!(numWidth - itoa!(i).length);
}


template row(int hpos, int i = 0) {
	static if (i+1 < width) {
		const char[] row = itoa_pad!(i*hpos) ~ row!(hpos, i+1);
	} else {
		const char[] row = itoa_pad!(i*hpos);
	}
}


template table(int i = 0) {
	pragma (msg, row!(i));

	static if (i+1 < height) {
		mixin .table!(i+1) table;
	} else {
		alias void table;
	}
}


alias table!() draw;



--
Tomasz Stachowiak
August 24, 2006
Tom S wrote:
> 
> template table(int i = 0) {
>     pragma (msg, row!(i));
> 
>     static if (i+1 < height) {
>         mixin .table!(i+1) table;
>     } else {
>         alias void table;
>     }
> }

Huh, now there's a use for mixin I can appreciate.  Nice work.


Sean
August 24, 2006
Sean Kelly wrote:
> Tom S wrote:
>>
>> template table(int i = 0) {
>>     pragma (msg, row!(i));
>>
>>     static if (i+1 < height) {
>>         mixin .table!(i+1) table;
>>     } else {
>>         alias void table;
>>     }
>> }
> 
> Huh, now there's a use for mixin I can appreciate.  Nice work.

but s/mixin/alias/ will work just as well. :)
August 24, 2006
Oskar Linde wrote:
> Sean Kelly wrote:
>> Tom S wrote:
>>>
>>> template table(int i = 0) {
>>>     pragma (msg, row!(i));
>>>
>>>     static if (i+1 < height) {
>>>         mixin .table!(i+1) table;
>>>     } else {
>>>         alias void table;
>>>     }
>>> }
>>
>> Huh, now there's a use for mixin I can appreciate.  Nice work.
> 
> but s/mixin/alias/ will work just as well. :)

True :-)  Though this got me thinking again about iterative code generation in D--I've been too occupied with other things to get fancy with template programming recently.  Working arount ITI limitations is about the extent of it.


Sean
August 24, 2006
Oskar Linde wrote:
> Sean Kelly wrote:
>> Tom S wrote:
>>>
>>> template table(int i = 0) {
>>>     pragma (msg, row!(i));
>>>
>>>     static if (i+1 < height) {
>>>         mixin .table!(i+1) table;
>>>     } else {
>>>         alias void table;
>>>     }
>>> }
>>
>> Huh, now there's a use for mixin I can appreciate.  Nice work.
> 
> but s/mixin/alias/ will work just as well. :)

Well, it's a typo, it was supposed to be an alias :D
August 24, 2006
Oskar Linde wrote:
> Sean Kelly wrote:
>> Tom S wrote:
>>>
>>> template table(int i = 0) {
>>>     pragma (msg, row!(i));
>>>
>>>     static if (i+1 < height) {
>>>         mixin .table!(i+1) table;
>>>     } else {
>>>         alias void table;
>>>     }
>>> }
>>
>> Huh, now there's a use for mixin I can appreciate.  Nice work.
> 
> but s/mixin/alias/ will work just as well. :)

Here it does, but in the general case it doesn't work as well. First since the mixin creates a (unique) new template instance, that might differ significantly if such template has run-time members. Second, you can't use a mixin in an instruction block, and an alias can (and I've used that).
So that's not a good use for mixin, use alias for instantiating dummy template instances. :)
Also the
  ... else {
     alias void table;
  }
is not necessary. ;)