Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
November 22, 2010 Const foreach | ||||
---|---|---|---|---|
| ||||
If in a D2 program I have an array of mutable items I may want to iterate on them but not modify them, so I'd like the iteration variable to be const. This is possible, but it seems I lose type inference: void main() { int[3] array; // not const // foreach (const x; array) {} // Error // foreach (const auto x; array) {} // Error // foreach (const(int) x; array) {} // OK foreach (const(typeof(array[0])) x; array) {} // OK } Is something wrong in that code? Is this a known limitation, an inevitable one? Is this an enhancement request worth adding to Bugzilla? Bye and thank you, bearophile |
November 22, 2010 Re: Const foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | bearophile <bearophileHUGS@lycos.com> wrote: > If in a D2 program I have an array of mutable items I may want to iterate on them but not modify them, so I'd like the iteration variable to be const. This is possible, but it seems I lose type inference: > > > void main() { > int[3] array; // not const > // foreach (const x; array) {} // Error > // foreach (const auto x; array) {} // Error > // foreach (const(int) x; array) {} // OK > foreach (const(typeof(array[0])) x; array) {} // OK > } > > > Is something wrong in that code? Is this a known limitation, an inevitable one? Is this an enhancement request worth adding to Bugzilla? Definitely worth adding to bugzilla. I can't find the post now, but there is a good description of how foreach loops can be rewritten as for loops, with type inference. Further testing shows that 'auto' creates the same problems, so it seems foreach is simply magical. -- Simen |
November 22, 2010 Re: Const foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Sunday 21 November 2010 17:21:14 bearophile wrote:
> If in a D2 program I have an array of mutable items I may want to iterate on them but not modify them, so I'd like the iteration variable to be const. This is possible, but it seems I lose type inference:
>
>
> void main() {
> int[3] array; // not const
> // foreach (const x; array) {} // Error
> // foreach (const auto x; array) {} // Error
> // foreach (const(int) x; array) {} // OK
> foreach (const(typeof(array[0])) x; array) {} // OK
> }
>
>
> Is something wrong in that code? Is this a known limitation, an inevitable one? Is this an enhancement request worth adding to Bugzilla?
Actually, const is pointless in your example, since you're dealing with a value type. Where it would matter is if you were dealing with an element type which was a reference type or if you marked x as a ref. And unfortunately, I don't think that it works to use const ref in a foreach (I've never gotten it work anyway) - probably for the same reason that const ref won't take an lvalue (and I _really_ wish that it would). _That_ would likely be worth opening up an enhancement request for, and it's probably necessary to get foreach to work properly with const.
- Jonathan M Davis
|
November 22, 2010 Re: Const foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis: > Actually, const is pointless in your example, since you're dealing with a value type. A const value time is meaningful, it means that you are saying the D compiler that you don't want to modify it. Generally it's good to stick a const/immutable even when you use values inside your functions. > And unfortunately, I don't think that it works to use const ref in a foreach (I've never gotten it work anyway) I think it works (it has the same problems of the const alone, there is no type inference): void main() { int[3] array; foreach (ref const(int) x; array) {} } Bye, bearophile |
November 22, 2010 Re: Const foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Sunday 21 November 2010 18:37:01 bearophile wrote: > Jonathan M Davis: > > Actually, const is pointless in your example, since you're dealing with a value type. > > A const value time is meaningful, it means that you are saying the D compiler that you don't want to modify it. Generally it's good to stick a const/immutable even when you use values inside your functions. True. But it's really only to help the compiler optimize better and perhaps to stop yourself from accidentally mutating it if you don't want it to happen. If the compiler's good enough, it shouldn't matter at all. > > And unfortunately, I don't > > think that it works to use const ref in a foreach (I've never gotten it > > work anyway) > > I think it works (it has the same problems of the const alone, there is no > type inference): > > void main() { > int[3] array; > foreach (ref const(int) x; array) {} > } It never occurred to me to use ref const(T). I tried const ref T, and that didn't worked (or maybe I only tried const ref - I don't recall). In any case, I've never figured out how to get const ref to work for foreach, so if what you give there works, that's great. - Jonathan M Davis |
November 22, 2010 Re: Const foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Sun, 21 Nov 2010 20:21:14 -0500
bearophile <bearophileHUGS@lycos.com> wrote:
> If in a D2 program I have an array of mutable items I may want to iterate on them but not modify them, so I'd like the iteration variable to be const. This is possible, but it seems I lose type inference:
>
>
> void main() {
> int[3] array; // not const
> // foreach (const x; array) {} // Error
> // foreach (const auto x; array) {} // Error
> // foreach (const(int) x; array) {} // OK
> foreach (const(typeof(array[0])) x; array) {} // OK
> }
>
>
> Is something wrong in that code? Is this a known limitation, an inevitable one? Is this an enhancement request worth adding to Bugzilla?
>
> Bye and thank you,
> bearophile
Maybe you'll find it weird, but I would expect
foreach (const(auto) x; array) {};
to be the logical idiom for this. "auto" beeing a kind of placeholder for a type name.
Presently yields the error:
__trials__.d(25): basic type expected, not auto
denis
-- -- -- -- -- -- --
vit esse estrany ☣
spir.wikidot.com
|
November 22, 2010 Re: Const foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to spir | spir <denis.spir@gmail.com> wrote: > On Sun, 21 Nov 2010 20:21:14 -0500 > bearophile <bearophileHUGS@lycos.com> wrote: > >> If in a D2 program I have an array of mutable items I may want to iterate on them but not modify them, so I'd like the iteration variable to be const. This is possible, but it seems I lose type inference: >> >> >> void main() { >> int[3] array; // not const >> // foreach (const x; array) {} // Error >> // foreach (const auto x; array) {} // Error >> // foreach (const(int) x; array) {} // OK >> foreach (const(typeof(array[0])) x; array) {} // OK >> } >> >> >> Is something wrong in that code? Is this a known limitation, an inevitable one? Is this an enhancement request worth adding to Bugzilla? >> >> Bye and thank you, >> bearophile > > Maybe you'll find it weird, but I would expect > foreach (const(auto) x; array) {}; > to be the logical idiom for this. "auto" beeing a kind of placeholder for a type name. 'auto' is not a placeholder for a type, but the default storage class. IOW, 'int n;' == 'auto int n;'. This does however not compile, complaining that it has no effect. Specifying just the storage class signals the compiler to use type inference. Try it: const x = 4; immutable y = 4; -- Simen |
November 22, 2010 Re: Const foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | On 11/22/2010 04:12 PM, Simen kjaeraas wrote:
> spir <denis.spir@gmail.com> wrote:
>
>> On Sun, 21 Nov 2010 20:21:14 -0500
>> bearophile <bearophileHUGS@lycos.com> wrote:
>>
>>> If in a D2 program I have an array of mutable items I may want to
>>> iterate on them but not modify them, so I'd like the iteration
>>> variable to be const. This is possible, but it seems I lose type
>>> inference:
>>>
>>>
>>> void main() {
>>> int[3] array; // not const
>>> // foreach (const x; array) {} // Error
>>> // foreach (const auto x; array) {} // Error
>>> // foreach (const(int) x; array) {} // OK
>>> foreach (const(typeof(array[0])) x; array) {} // OK
>>> }
>>>
>>>
>>> Is something wrong in that code? Is this a known limitation, an
>>> inevitable one? Is this an enhancement request worth adding to Bugzilla?
>>>
>>> Bye and thank you,
>>> bearophile
>>
>> Maybe you'll find it weird, but I would expect
>> foreach (const(auto) x; array) {};
>> to be the logical idiom for this. "auto" beeing a kind of placeholder
>> for a type name.
>
> 'auto' is not a placeholder for a type, but the default storage class.
> IOW, 'int n;' == 'auto int n;'. This does however not compile,
> complaining that it has no effect.
>
> Specifying just the storage class signals the compiler to use type
> inference. Try it:
>
> const x = 4;
> immutable y = 4;
>
I'm not sure you are correct:
const static auto x = 4;
|
November 22, 2010 Re: Const foreach | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pelle Månsson | Pelle Månsson <pelle.mansson@gmail.com> wrote: >> 'auto' is not a placeholder for a type, but the default storage class. >> IOW, 'int n;' == 'auto int n;'. This does however not compile, >> complaining that it has no effect. >> >> Specifying just the storage class signals the compiler to use type >> inference. Try it: >> >> const x = 4; >> immutable y = 4; >> > > I'm not sure you are correct: > > const static auto x = 4; I don't see how this contradicts anything I've said. You can safely remove auto from that statement, and the type will be inferred to the same. The fact that it compiles is a compiler bug, if we take the error message in the 'auto int x;' example to be representative. -- Simen |
Copyright © 1999-2021 by the D Language Foundation