www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Alias Arguments & Expressions

reply Xinok <xnknet gmail.com> writes:
I think aliases should be expanded to allow for arguments, and allow constant
expressions. The syntax that I used could be added to the language without
breaking any existing code.

-- Arguments
Like with functions and classes, the arguments could simply add a template to
the alias.
alias T* ptr(T);
would be the same as writing:
template ptr(T){ alias T* ptr; }

And they would be instantiated just like templates:
ptr!(int)


-- Expressions
alias 10 base;
alias (10*20) val;

Combine with arguments:
alias (a*b) mul(a, b);


I'm sure these ideas have been posted before, but I think they could really be
useful. For example, I once wrote an encryption algorithm which would encrypt
in 128k blocks (131072 bytes). I could have defined an alias to perform the
basic math for this:
alias (n * 131072) SizeofBlocks(n);
SizeofBlocks!(8);


To accomplish what alias expressions could do, you would have to write all of
this:
template mul(V...){
	const typeof(V[0] * V[1]) mul = V[0] * V[1];
}

Compared to:
alias (a*b) mul(a, b);

The syntax for aliases would be simpler and quicker. Plus, you wouldn't have to
guess the base type of the expression.
Jan 14 2007
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Xinok wrote:
 To accomplish what alias expressions could do, you would have to write all of
this:
 template mul(V...){
 	const typeof(V[0] * V[1]) mul = V[0] * V[1];
 }
 
 Compared to:
 alias (a*b) mul(a, b);

That typeof(...) is redundant. Remove that and it should default to automatic type deduction, which would do exactly the same.
Jan 14 2007
parent reply Xinok <xnknet gmail.com> writes:
Frits van Bommel Wrote:

 Xinok wrote:
 To accomplish what alias expressions could do, you would have to write all of
this:
 template mul(V...){
 	const typeof(V[0] * V[1]) mul = V[0] * V[1];
 }
 
 Compared to:
 alias (a*b) mul(a, b);

That typeof(...) is redundant. Remove that and it should default to automatic type deduction, which would do exactly the same.

Regardless, I think the extension to aliases would be a nice addition to D. template mul(V...){ const auto mul = V[0] * V[1]; } alias (a*b) mul(a, b); One of the problems with the template implementation is it uses a tuple. First off of course is the V[] syntax. Sure you could define aliases or constants for the arguments, but this only further pushes the problem: template mul(V...){ // This currently doesn't work due to bugs in the compiler: // alias V[0] a; alias V[1] b; // D doesn't allow this with the 'auto' type: // const auto a = V[0], b = V[1]; // This is the best you can do: const auto a = V[0]; const auto b = V[1]; // So you can create symbols for the tuple arguments: const auto mul = a * b; } void main(){ // Because 'a' and 'b' are members of the template, the compiler can't use the template implicitly: // writefln(mul!(15, 30)); // Defining 'a' and 'b' as private doesn't work either // So you have to manually specify the member 'mul': writefln(mul!(15, 30).mul); } The second problem is tuples aren't self-documenting. The user sees (V...), they'll have no idea what arguments they're supposed to pass. Alias arguments on the other hand can be named, giving the user a small idea what arguments must be provided for the expression.
Jan 14 2007
parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Xinok wrote:
 Frits van Bommel Wrote:
 
 Xinok wrote:
 To accomplish what alias expressions could do, you would have to write all of
this:
 template mul(V...){
 	const typeof(V[0] * V[1]) mul = V[0] * V[1];
 }

 Compared to:
 alias (a*b) mul(a, b);

automatic type deduction, which would do exactly the same.

Regardless, I think the extension to aliases would be a nice addition to D. template mul(V...){ const auto mul = V[0] * V[1]; } alias (a*b) mul(a, b); One of the problems with the template implementation is it uses a tuple. First off of course is the V[] syntax. Sure you could define aliases or constants for the arguments, but this only further pushes the problem: template mul(V...){ // This currently doesn't work due to bugs in the compiler: // alias V[0] a; alias V[1] b; // D doesn't allow this with the 'auto' type: // const auto a = V[0], b = V[1]; // This is the best you can do: const auto a = V[0]; const auto b = V[1]; // So you can create symbols for the tuple arguments: const auto mul = a * b; } void main(){ // Because 'a' and 'b' are members of the template, the compiler can't use the template implicitly: // writefln(mul!(15, 30)); // Defining 'a' and 'b' as private doesn't work either // So you have to manually specify the member 'mul': writefln(mul!(15, 30).mul); } The second problem is tuples aren't self-documenting. The user sees (V...), they'll have no idea what arguments they're supposed to pass. Alias arguments on the other hand can be named, giving the user a small idea what arguments must be provided for the expression.

First, I really don't think its a completely bad idea, although I might prefer the template parameters being on the alias keyword, even if it is a change from how its done with classes, structs, etc. Something like: alias(a, b) (a * b) mul; Second, I don't really comprehend what you are trying to do with the template above... it would just be: # template mul (a, b) { const mul = a * b; } # # void main () { # writefln(mul!(15, 30)); # } Which, IMHO, isn't so bad. (Note that 'auto' in this case isn't needed for type inferance, as any storage class without a specified type defaults to auto.) -- Chris Nicholson-Sauls
Jan 15 2007
parent reply Xinok <xnknet gmail.com> writes:
 Second, I don't really comprehend what you are trying to do with the template
above... it 
 would just be:
 # template mul (a, b) { const mul = a * b; }
 #
 # void main () {
 #   writefln(mul!(15, 30));
 # }

a and b are typenames, not variables. You can't use aliases either since they don't accept variables: template mul(alias a, alias b) The only thing that will work is a tuple: template mul(V...){ const mul = V[0] * V[1]; } And for a complex expression, that isn't very pleasing to the eye. You were right about not needing 'auto'. I didn't think D allowed that though.
Jan 16 2007
parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Xinok wrote:
 Second, I don't really comprehend what you are trying to do with the template
above... it 
 would just be:
 # template mul (a, b) { const mul = a * b; }
 #
 # void main () {
 #   writefln(mul!(15, 30));
 # }

a and b are typenames, not variables. You can't use aliases either since they don't accept variables: template mul(alias a, alias b) The only thing that will work is a tuple: template mul(V...){ const mul = V[0] * V[1]; } And for a complex expression, that isn't very pleasing to the eye. You were right about not needing 'auto'. I didn't think D allowed that though.

Ah okay, didn't realize a and b were supposed to be types. (What I get for reading just before bed.) -- Chris Nicholson-Sauls
Jan 16 2007