| Thread overview | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
December 13, 2007 Re: constancy and template parameters in D2.009+ | ||||
|---|---|---|---|---|
| ||||
That said, it occurs to me that (U, T=const(U)) is itself not the best syntax, because it suggests that T is a constant version of U, which is not the intent. So maybe this is isn't the right syntax after all.
The problem is simply stated. We need (1) some notation which means
"with constancy preserved", and (2) some notation which means "with
head constancy removed"
I argue that (T:T) is not the most obvious way to state (1), and that
typeof(T) is not the most obvious way to state (2).
At the risk of overusing keywords, maybe we could reinterpret init? As in:
class A(init T)
{
to mean T preserves the complete original type of the callee parameter. And you could use a template for the second situation:
alias RemoveHeadConst!(T) U;
to mean U is T with head constancy removed (that is, const(int)
becomes just int).
I don't know if that's any better or not? Somehow (init T) seems a
little more suggestive than (T:T) (and also more expressive, because
you can distinguish between (T:T[]) and (init T:T[]); and also,
RemoveHeadConst!(T) seems a little more suggestive than typeof(T).
I think it's better than the idea in my previous post, anyway.
| ||||
December 13, 2007 Re: constancy and template parameters in D2.009+ | ||||
|---|---|---|---|---|
| ||||
On 12/13/07, Janice Caron <caron800@googlemail.com> wrote:
> And you could use a template for the second situation:
>
> alias RemoveHeadConst!(T) U;
>
> to mean U is T with head constancy removed (that is, const(int)
> becomes just int).
I think the template idea actually works. You could implement it in std.typecons as
template RemoveHeadConst(T) { alias T RemoveHeadConst; }
It ought to work because the parameter has been expressed as (T), not
(T:T), or my suggested (init T). If that works, one of the two
problems is solved without /any/ modification to the language.
That just leaves (1)...
| ||||
December 13, 2007 Re: constancy and template parameters in D2.009+ | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | Janice Caron wrote:
> I think the template idea actually works. You could implement it in
> std.typecons as
>
> template RemoveHeadConst(T) { alias T RemoveHeadConst; }
>
> It ought to work because the parameter has been expressed as (T), not
> (T:T), or my suggested (init T). If that works, one of the two
> problems is solved without /any/ modification to the language.
>
> That just leaves (1)...
Of course, if you say that the constness of parameters should always be preserved, you'd get:
template RemoveHeadConst(T) {
static if (is (T : const(U), U)) {
alias U RemoveHeadConst;
} else {
alias T RemoveHeadConst;
}
}
It's really just a matter of which case will be more common.
| |||
December 13, 2007 Re: constancy and template parameters in D2.009+ | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | On 12/13/07, Christopher Wright <dhasenan@gmail.com> wrote:
> Of course, if you say that the constness of parameters should always be preserved, you'd get:
>
> template RemoveHeadConst(T) {
> static if (is (T : const(U), U)) {
> alias U RemoveHeadConst;
> } else {
> alias T RemoveHeadConst;
> }
> }
Assuming that works, yes. It doesn't in D2.008, and I don't believe it did in D2.007 (although you'd imagine it should).
| |||
December 13, 2007 Re: constancy and template parameters in D2.009+ | ||||
|---|---|---|---|---|
| ||||
On 12/13/07, Janice Caron <caron800@googlemail.com> wrote:
> On 12/13/07, Christopher Wright <dhasenan@gmail.com> wrote:
> > Of course, if you say that the constness of parameters should always be preserved, you'd get:
> >
> > template RemoveHeadConst(T) {
> > static if (is (T : const(U), U)) {
> > alias U RemoveHeadConst;
> > } else {
> > alias T RemoveHeadConst;
> > }
> > }
>
> Assuming that works, yes. It doesn't in D2.008, and I don't believe it did in D2.007 (although you'd imagine it should).
No wait - I must correct myself - I posted without thinking it through.
That template will remove ALL const, not just head const. You need
something that transforms const(int[]) into const(int)[]. And it has
to work for invariant too. (And even for const pointer to invariant -
yes such things /are/ allowed to exist in D).
It's a much harder template to write than you might first assume.
...which is why I like D2.008's default, in every regard but the syntax (and the fact that it has some bugs which mean it doesn't actually work as advertised in all cases).
| ||||
December 14, 2007 Re: constancy and template parameters in D2.009+ | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | Janice Caron wrote: > That template will remove ALL const, not just head const. You need > something that transforms const(int[]) into const(int)[]. And it has > to work for invariant too. (And even for const pointer to invariant - > yes such things /are/ allowed to exist in D). > > It's a much harder template to write than you might first assume. > > ....which is why I like D2.008's default, in every regard but the > syntax (and the fact that it has some bugs which mean it doesn't > actually work as advertised in all cases). Well, in that case, you need some way of expressing const data but mutable reference (exists in 2.008, maybe a library solution in 2.009, right?), and you need some solution for structs (a library solution for 2.009 would take care of that). Then your RemoveHeadConst template would do what you expect with arrays and classes, but structs...? A const(Vector!(int)) would turn into a Vector!(int) rather than a Vector!(const(int)). Is that what should happen? I think that depends on the type involved. Library types will have to define ways to get head-mutable forms of things, I think. I also think it is a mess. The convention will probably be along the lines of: struct Name(Args...) { Name!(RemoveHeadConst!(Args[0]), Args[1], Args[2], ...) HeadMutable() { return typeof(return).init; } } That's more work than most people will want to put into it. | |||
December 14, 2007 Re: constancy and template parameters in D2.009+ | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | On 12/14/07, Christopher Wright <dhasenan@gmail.com> wrote:
> Well, in that case, you need some way of expressing const data but mutable reference (exists in 2.008, maybe a library solution in 2.009,
To be completely honest, the D2.008 solution doesn't work in all cases. I don't know what the algorithm is, but I've made Walter aware of some (fairly simple) source code which doesn't work, and he said not to worry about it because it's all changing (presumably in D2.009)
So when, in D2.008, you do
T!(Before)
to match
template T(After)
I am not actually completely 100% certain of what the algorithm is which transforms Before into After in D2.008. I only know that it transforms const(int) into int. Beyond that, it's anybody's guess.
Maybe D2.007 got it right after all. Maybe multiple instantiations is really not such a bad thing. Walter did suggest (in relation to a different query) that the linker could be improved so that identical functions are elided into a single function. If he could do that, you'd get bigger .obj files, but the .exe would still be small. Ultimately, that's probably the right way to go, so maybe we should forget these intermediate kludges?
You're certainly right about the fact that RemoveHeadConst! would be a furiously hard template to write though. (But Andrei could probably do it!)
| |||
December 14, 2007 Re: constancy and template parameters in D2.009+ | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | Janice Caron wrote: > Maybe D2.007 got it right after all. Maybe multiple instantiations is > really not such a bad thing. Walter did suggest (in relation to a > different query) that the linker could be improved so that identical > functions are elided into a single function. If he could do that, > you'd get bigger .obj files, but the .exe would still be small. > Ultimately, that's probably the right way to go, so maybe we should > forget these intermediate kludges? That does seem best. It could also combine other identical methods -- not a bad thing. > You're certainly right about the fact that RemoveHeadConst! would be a > furiously hard template to write though. (But Andrei could probably do > it!) I'm not saying that it'd be furiously hard. I'm saying it may be impossible to get something that works in the general case for structs. It's not obvious that a mapping for a const struct T(U, V, W, ...) would go to a struct T(const(U), const(V), const(W), ...). It may well be the case, but I'm uncertain. And even if that works, it does nothing for struct members that aren't associated with template parameters. So an expressive system would have keywords for 'tail-const' and 'this member is not const if this data type is tail-const'. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply