a more consistent const syntax
Reiner Pope
some at address.com
Tue Aug 7 23:57:48 PDT 2007
Bill Baxter wrote:
> Or maybe just allow alias to use either syntax:
>
> alias x = 1;
> alias 1 x;
> alias myInt = some_complex_expr_to_compute_a_type!(int);
> alias some_complex_expr_to_compute_a_type!(int) myInt;
>
> In my opinion it's a lot easier to read the assignment syntax (alias
> sym=thing) than the current alias syntax (alias thing sym). Mainly
> because, as you see above, often the 'thing' is really long, but usually
> the 'sym' is something very short. It makes it easier to see the thing
> you care about in the end which is the sym that comes out of the
> statement that you'll be using in subsequent code.
>
> --bb
I think that would be just great. I hate having to write two templates,
one for values and one for aliases. It's quite un-generic. A good
example is the identity function that Andrei is keen on. It's a fair bit
of work to write with templates, so that it works with types, values,
and expression aliases:
template Identity(T...)
{
static if (!is(T[0]))
const Identity = T[0];
else
alias T[0] Identity;
}
// testing
static assert(is(Identity!(int) == int));
static assert(Identity!(5) == 5);
int x;
void main()
{
Identity!(x) = Identity!(5);
assert(x == 5);
}
This currently works, but I'm not sure why[1], and it is annoying to
require that. I would like to be able to write
template Identity(T...)
{
alias T[0] Identity;
}
but that currently doesn't work when T[0] is a value parameter.
This does actually cause problems with writing compile-time util
templates, like FoldR:
template FoldR(alias Fn, T...)
{
static if (T.length == 0)
static assert(false, "Must have starting case for FoldR");
else static if (T.length == 1)
{
static if (is(T[0]))
alias T[0] FoldR;
else
const FoldR = T[0];
}
else
{
// I have to repeat this ugly recursive instantiation 3 times
// because I can't keep the result -- do I alias it or use const?
static if (is(FoldR!(Fn, Fn!(T[0], T[1]).val, T[2..$])))
alias FoldR!(Fn, Fn!(T[0], T[1]).val, T[2..$]) FoldR;
else
const FoldR = FoldR!(Fn, Fn!(T[0], T[1]).val, T[2..$]);
}
}
So I think having alias work for values as well as types/symbols would
be great. I'm not so fussed either way about
alias x = int;
I can see it reads better in some situations, though, and I don't see it
causing any problems if both were allowed.
-- Reiner
[1] Here's what's confusing me (I expect it's a bug). In the first code
snippet I posted, the !is(T[0]) means that types are aliased, which is
good, but the call to Identity!(x) doesn't use the alias, it uses the
const Identity = T[0]; part. So what is happening is effectively this:
// in the instantiation of Identity!(x)
const Identity = x;
// in main()
Identity!(x).Identity = 5;
We're reassigning a constant -- how does that work? -- but somehow that
causes x to change... it's oddly doing the alias itself...
More information about the Digitalmars-d
mailing list