March 21, 2008 const debacle | ||||
---|---|---|---|---|
| ||||
This issue was just brought to my attention, and I wonder if the other const-proponents have a good solution for this. This is going to be very tough to deal with. How do you declare a function that takes an array, is not allowed to change the array, but returns a slice into the argument array, and the return type matches the argument type. For example, if I pass a mutable array to this function, I want it to pass me back a mutable slice into the array, but I also want a guarantee that the function will not modify the array. I can't declare the argument is const because then the return value must also be const, as it is a slice of the original array. How does one solve this problem? -Steve |
March 21, 2008 Re: const debacle | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote:
> This issue was just brought to my attention, and I wonder if the other const-proponents have a good solution for this. This is going to be very tough to deal with.
>
> How do you declare a function that takes an array, is not allowed to change the array, but returns a slice into the argument array, and the return type matches the argument type.
>
> For example, if I pass a mutable array to this function, I want it to pass me back a mutable slice into the array, but I also want a guarantee that the function will not modify the array. I can't declare the argument is const because then the return value must also be const, as it is a slice of the original array.
>
> How does one solve this problem?
>
> -Steve
>
>
IIRC Walter has something planed for this. Something to do with a "return" const type. It would do just that; "the function's return type has the same constness as one of it's arguments."
In short: Not yet.
|
March 21, 2008 Re: const debacle | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote:
> How do you declare a function that takes an array, is not allowed to change the array, but returns a slice into the argument array, and the return type matches the argument type.
The way to do it is with a function template, parameterizing the type in question.
|
March 21, 2008 Re: const debacle | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | "Walter Bright" wrote
> Steven Schveighoffer wrote:
>> How do you declare a function that takes an array, is not allowed to change the array, but returns a slice into the argument array, and the return type matches the argument type.
>
>
> The way to do it is with a function template, parameterizing the type in question.
So your answer essentially is, there is no way to specify that the function will not modify the parameter but returns the same type passed in?
Basically, I want a function like:
T[] foo(T)(in T[] source, in T[] pattern);
Where foo returns a slice of source that matches pattern, and promises not to modify source or pattern, but returns the same type as was passed in. Then the caller could modify the slice as necessary. It's kind of like a 'scoped' const, where the argument is only const within the function, but reverts to what it was passed in as once the function is exited.
What you're saying is, specify it like:
T[] foo(T)(T[] source, in T[] pattern);
Which means there is no check by the compiler to guarantee that source is not modified (unless T is const), and basically, the coder has to rely on the documentation to determine whether source will remain intact? I think this degrades the benefits of const in this context.
-Steve
|
March 21, 2008 Re: const debacle | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | "BCS" wrote
> Steven Schveighoffer wrote:
>> This issue was just brought to my attention, and I wonder if the other const-proponents have a good solution for this. This is going to be very tough to deal with.
>>
>> How do you declare a function that takes an array, is not allowed to change the array, but returns a slice into the argument array, and the return type matches the argument type.
>>
>> For example, if I pass a mutable array to this function, I want it to pass me back a mutable slice into the array, but I also want a guarantee that the function will not modify the array. I can't declare the argument is const because then the return value must also be const, as it is a slice of the original array.
>>
>> How does one solve this problem?
>>
>> -Steve
>
> IIRC Walter has something planed for this. Something to do with a "return" const type. It would do just that; "the function's return type has the same constness as one of it's arguments."
>
> In short: Not yet.
I remember that idea. I'm concerned however that in this mode, the compiler will not check the function itself for const-correctness (i.e. ensure it doesn't modify the input) because the argument will not be const. See my reply to Walter for my example. I want a way to specify "the function's return type has the same constness as one of it's arguments, and it promises not to modify that argument, and the compiler made sure of that."
-Steve
|
March 21, 2008 Re: const debacle | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | == Quote from Steven Schveighoffer (schveiguy@yahoo.com)'s article
> This issue was just brought to my attention, and I wonder if the other
> const-proponents have a good solution for this. This is going to be very
> tough to deal with.
> How do you declare a function that takes an array, is not allowed to change
> the array, but returns a slice into the argument array, and the return type
> matches the argument type.
> For example, if I pass a mutable array to this function, I want it to pass
> me back a mutable slice into the array, but I also want a guarantee that the
> function will not modify the array. I can't declare the argument is const
> because then the return value must also be const, as it is a slice of the
> original array.
> How does one solve this problem?
Use overloaded functions. In theory, I think this should work:
T[] func(T)( T[] buf ) { ... }
const T[] func(T)( const T[] buf ) { ... }
invariant T[] func(T)( invariant T[] buf ) { ... }
Even if D doesn't overload on const-ness (I seem to recall that it doesn't right now), I think the above set of functions won't conflict because one will be more specialized than the other, based on the supplied type. However, this aspect of D is fairly primitive so it's somewhat of a shot in the dark. Weren't templates in 2.0 eventually supposed to get some way to learn the const-ness of a parameter? I seem to recall that from Walter and Andrei's conference presentation.
Sean
|
March 21, 2008 Re: const debacle | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | == Quote from Steven Schveighoffer (schveiguy@yahoo.com)'s article
> "BCS" wrote
> >
> > IIRC Walter has something planed for this. Something to do with a "return" const type. It would do just that; "the function's return type has the same constness as one of it's arguments."
> >
> > In short: Not yet.
> I remember that idea. I'm concerned however that in this mode, the compiler will not check the function itself for const-correctness (i.e. ensure it doesn't modify the input) because the argument will not be const. See my reply to Walter for my example. I want a way to specify "the function's return type has the same constness as one of it's arguments, and it promises not to modify that argument, and the compiler made sure of that."
Oops, I'd forgotten about this while writing my post. In short, I don't think there's any way to do this automatically. You'd likely either have to supply the type manually or resort to some sort of proxy function to do this for you.
Sean
|
March 21, 2008 Re: const debacle | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | "Sean Kelly" wrote in message
> == Quote from Steven Schveighoffer
>> This issue was just brought to my attention, and I wonder if the other
>> const-proponents have a good solution for this. This is going to be very
>> tough to deal with.
>> How do you declare a function that takes an array, is not allowed to
>> change
>> the array, but returns a slice into the argument array, and the return
>> type
>> matches the argument type.
>> For example, if I pass a mutable array to this function, I want it to
>> pass
>> me back a mutable slice into the array, but I also want a guarantee that
>> the
>> function will not modify the array. I can't declare the argument is
>> const
>> because then the return value must also be const, as it is a slice of the
>> original array.
>> How does one solve this problem?
>
> Use overloaded functions. In theory, I think this should work:
>
> T[] func(T)( T[] buf ) { ... }
> const T[] func(T)( const T[] buf ) { ... }
> invariant T[] func(T)( invariant T[] buf ) { ... }
>
> Even if D doesn't overload on const-ness (I seem to recall that it doesn't
> right now), I think the above
> set of functions won't conflict because one will be more specialized than
> the other, based on the
> supplied type. However, this aspect of D is fairly primitive so it's
> somewhat of a shot in the dark.
> Weren't templates in 2.0 eventually supposed to get some way to learn the
> const-ness of a parameter? I
> seem to recall that from Walter and Andrei's conference presentation.
>
>
> Sean
Hm... can't you just do this like:
T[] func(T)(T[] buf) {...}
and T will be either const(T), invariant(T), or just T?
In any case, the crux of the problem is still there. For the version with just T, the compiler is not guaranteeing that func doesn't modify the input.
-Steve
|
March 21, 2008 Re: const debacle | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | == Quote from Steven Schveighoffer (schveiguy@yahoo.com)'s article
> Hm... can't you just do this like:
> T[] func(T)(T[] buf) {...}
> and T will be either const(T), invariant(T), or just T?
> In any case, the crux of the problem is still there. For the version with
> just T, the compiler is not guaranteeing that func doesn't modify the input.
You're right of course. Darn mornings.
Sean
|
March 21, 2008 Re: const debacle | ||||
---|---|---|---|---|
| ||||
On 21/03/2008, Janice Caron <caron800@googlemail.com> wrote:
> I really wish there was a better way of doing it though. Essentially,
> we want a way to auto-generate all three versions of
>
> K(T)[] func(T)(K(T)[] buf ) { ... }
Oh, and - as has been noted previously - the object code for all three versions could be byte-for-byte identical, and therefore the function only needs to be compiled once. The trick is to /allow/ it to compile, for each of the three cases.
|
Copyright © 1999-2021 by the D Language Foundation