Generic programming ramifications of const by default

Bill Baxter dnewsgroup at billbaxter.com
Sun Jun 10 17:58:33 PDT 2007


Walter Bright wrote:
> Bill Baxter wrote:
>> * "having same type defaults is better for generics"
>>   (maybe...but I'm not convinced. If you have powerful enough 
>> metaprogramming it shouldn't be hard to strip const from a type tuple, 
>> or add it.  And people do far more programming than meta-programming.)
> 
> This is a good point. With const-by-default, you have function type 
> declarations behaving *fundamentally* different from other declarations. 
> Given the metaprogramming ability to use tuples to declare parameters, 
> doing function template type deduction for parameters, and type 
> inference on parameters, making this fundamentally different may wind up 
> really screwing things up.

Yes, it's a good point (it's David Held's point), but again your 
argument is "may wind up really screwing things up".  On the other hand 
it may wind up *not* screwing things up.  Gut feelings are great, but 
neither you nor David have given any concrete examples.

So let's look at a callback library like std.signals.

With std.signals we do something like:

     mixin Signal!(char[], int);

And the call signature for slots becomes

     void delegate(char[],int).

To get only requires a simple variadic tuple parameter:

template Signal(T1...)
{
     alias void delegate(T1) slot_t;
     . . .
}

With const default it will be a little more annoying because it doesn't 
make sense to have const be the default for template paramters.  So the 
user would need to say something like:
     mixin Signal!(in char[], in int);
But if the only transformation is stickig 'in' on everything a template 
can be made to do that. So just something like...
     mixin Signal!(ParameterTuple(char[], int));

But what if the user actually wants some parameter to be mutable? Like a 
ref int instead of an int.  There would have to be some keyword to mean 
'make it mutable' in any event for const default.  So just make our 
ParameterTuple metafunction smart enough not to override that.  Maybe 
keep inout for this:
     mixin Signal!(ParameterTuple(char[], inout int));

And rememeber that signals are *used* much more frequently than they are 
defined.  Users of the signal won't have to think about it, they'll just 
write their function:
     void cb(char[], inout int) { . . . }
and it'll work.

So that's a realistic case of wanting to take a regular tuple, and 
needing it to be a parameter tuple.  And it doesn't look like it would 
really screw things up so far.


But how about the other way?  Say now we extract a parameter tuple from 
a function and we want to make a value tuple out of it we can use to 
call the function.
void call(slot_t someslot) {
    alias  std.traits.ParameterTypeTuple(slot_t) ArgTup;
    ArgTup args;
    args[0] = "Hi there";
    args[1] = 5;
    someslot(args);
}

That won't work if slot_t's argument type tuple is all "constipated".
But this should be doable too, I would think.  Just something like a 
ValueTypeTuple(ArgTup).

But even if that's not possible, you're going to have the _exact_ same 
problem with any form of const when trying to convert an argument tuple 
into a tuple you can make a variable out of.  So it's hardly a strike 
against const by default.

Any comments?

--bb



More information about the Digitalmars-d mailing list