const debacle
Davidson Corry
davidsoncorry at comcasst.net
Wed Mar 26 11:19:50 PDT 2008
Janice Caron wrote:
> On 26/03/2008, Davidson Corry <davidsoncorry at comcasst.net> wrote:
>> idem(x) foo(const T x, const U y); // first promise
>> idem(y) bar(T x const, U y const); // second promise
>>
>> Does this make any sense? Or have I said something silly, or resurrected
>> an old and discarded idea, or otherwise taken a pratfall on my maiden sally?
>
> It makes sense, and you're spot on. I think the problem is well
> understood now. All we're lacking a good syntax to recommend. And it
> seems to me that no one's come up with anything better than Walter's
>
> U bar(const(T) x, return const(U) y)
>
> although actually I still think it should be
>
> const(U) bar(const(T) x, return const(U) y)
>
> because inside the function body, every return statement is going to
> be returning a const(U), not a U.
>
> Your "bar" example doesn't make complete sense to me. If the function
> can only return a U (as indicated by your idem(y) - which incidently
> is similar to my earlier sliceof(y) suggestion), then why does x also
> have the "returnable" parameter declaration syntax? Was that a typo or
> am I missing something?
>
> Walter's syntax is not as expressive as we might like, but it does
> have the benefit of being simple. By contrast, making a distinction
> between const-on-the-left and const-on-the-right is potentially
> confusing - and also, no more expressive that Walter's idea, so
> there's nothing to be gained by it.
Thank you. I was trying to suggest a few more things without burdening
the message with too much extra explanation; in doing so I was unclear.
I apologise.
There are two things going on here. First, I wanted to show that you
could choose ANY of the function parameters as the basis for the
returned type. You're not constrained to use the first parameter, nor
the "first parameter that has one of these tricky annotations". <grin>
Second, these annotations are not necessarily tied to returns. They can
be applied to any parameter(s) in the function, and each one makes a
separate "promise".
The "promise" is actually two parts:
"I promise not to mutate the data underlying the X that you passed me,
whether you think it's mutable or not. And IF I RETURN SOMETHING TO YOU
BASED ON THOSE DATA, I won't constrain you to treat it as const even
though I did. (If the return data are not referenced through X, the
second part of the promise is irrelevant.)"
Imagine a signature like
void foo(T t const, U u invariant, const V v)
Since the "return" is void, obviously NONE of the input parameters are
participating in it. Nevertheless, we might have good reason to make the
promises "I will treat your t as if it were const, your u as if it were
invariant, and if you try to pass me a non-const v, I will cast it to
const". In THIS example, there's not much difference between
"const V v" and "V v const" for the third parameter -- but if the return
type were derived from v, the compiler would reject an attempt to return
a NON-const reference to it. (Whereas the compiler would ALLOW non-const
return types based on t or u.)
That is, the annotations participate in matching signatures for
overloaded function names. As a secondary issue, they MAY also support
automatic inference of a return type as well, but that's not part of
signature matching. (In C++, you can't overload on return type. Correct
me if I'm wrong, but I believe that this is true in D as well.)
Since what I'm talking about does not (necessarily) affect return, the
"return (type) x" syntax is inappropriate, IMHO. Particularly since you
could only mark ONE parameter as "return (Type) x", whereas here you
could mark any or all parameters as "as-if-const".
I agree with you that
const-on-the-left-const-on-the-right-stand-up-sit-down-fight-fight-fight
<grin> is potentially confusing. I just haven't thought of a better way
to express the notion "I will treat this parameter as if it were const,
but I won't require that YOU promise to treat it the same way".
I think of "const on the left" as being part of the type: (const T)
whereas "const on the right" is an additional assurance from the
function, part of its contract if you will: (plain T, possibly mutable,
but I will not change it).
Does that make things clearer?
-- Dai
More information about the Digitalmars-d
mailing list