equivariant functions
Steven Schveighoffer
schveiguy at yahoo.com
Tue Oct 14 18:13:41 PDT 2008
"Bill Baxter" wrote
> I'm looking at all these funky syntaxes with their many unusual
> implicit assumptions that they require a user to keep in mind, and
> thinking it would all be a lot simpler if you could just declare some
> template-like meta-variables in a preamble to the function.
>
> I also don't like the looks of using a symbol in the return type that
> doesn't get declared till you see the parameter list.
>
> So how about introducing a "typedef block" where you can introduce
> metatypes and give them constraints.
>
> For constness:
>
> typedef { Const : const } // in this case means any kind of const
> Const(int) someFunc(Const(int) z) { ... }
>
> For Objects:
>
> class BaseClass {}
> class DerivedClass : BaseClass {}
>
> typedef { DType : BaseClass } // DType is anything passing is(DType :
> BaseClass)
> DType someFunc(DType input)
>
> For both:
>
> typedef {
> DType : BaseClass;
> Const : const
> }
> Const(DType) someFunc(Const(DType) input)
>
> And with something like this you can also come up with some solution
> to the min problem
> typedef{
> ConstA : const;
> ConstB : const;
> ConstC = maxConst!(ConstA,ConstB)
> }
> ConstC(Type) max(ConstA(Type), ConstB(Type))
>
> maxConst would be some template-like thing func to take the "more
> const" of the two qualifiers. Not sure how you'd implement that.
>
> Lots o hole's there, but the basic idea I'm suggesting is to declare
> the types and qualifiers that can vary in some sort of a preamble
> block. To me this looks like it will be much more readable and easier
> to maintain than any of these funky syntaxes with lots of implicit
> rules to remember.
I'm not a fan of complexity where it is not required.
You have outlined pretty much exactly the only use cases for this feature.
So why do you want to continually write large typedefs that are identical in
front of all your functions, when you can do so with a succinct syntax?
To put the use cases in more english descriptions:
1. I want the constancy of my return to be dependent on the constancy of the
argument at the call site.
2. I want the constancy of my return to be the greatest common constancy of
multiple arguments at the call site.
3. The return type will be exactly the same value that I passed in to the
function, so I can use it for call chaining. So it's OK to auto cast to the
most derived type.
4. I want 1 and 3
Where greatest common constancy is defined as const if any arguments differ
in constancy. If they don't differ it is defined as the constancy of the
arguments.
My biggest concern is 1 and 2, since otherwise for 1, we are left with 3
different versions of the same function, and for 2, we are left with 3^n
different versions.
3 (and 4) are of mild concern, because you are only forced to redefine once
per class, and it's not as common a problem, since not all classes require
handling of call chaining, whereas all classes should be const-aware.
I'll reiterate my proposal:
inout(X) f(inout(Y) y, inout(Z) z)
where inout means 'the greatest common constancy of all variables that are
declared inout'. Again, not in love with inout, but inout kind of reads
'you get out what you put in', and it is a 'free' keyword.
and for 3:
X f(return X x);
where return means 'this function will return x'. The return statements in
this function are all required to return the value of x. (x cannot be
rebindable inside the function).
-Steve
More information about the Digitalmars-d
mailing list