Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
December 31, 2013 Why do associative arrays throw an Error (RangeError) on value not found? | ||||
---|---|---|---|---|
| ||||
Why do associative arrays throw an Error (RangeError) on value not found? This seems like it would be inefficient to check for, so a recoverable Exception (ItemNotFoundException?) would seem to be more appropriate. Or is Array[Key] with a key that is not in the array and bounds checking disabled undefined behavior? |
December 31, 2013 Re: Why do associative arrays throw an Error (RangeError) on value not found? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Supernova | On 2013-12-31 13:42, Supernova wrote: > Why do associative arrays throw an Error (RangeError) on value not found? > > This seems like it would be inefficient to check for, so a recoverable > Exception (ItemNotFoundException?) would seem to be more appropriate. How would ItemNotFoundException be any more efficient? The idea is that the error should not be recoverable. If you get an RangeError in your code you have made a logical error. You need to explicitly check if a key is available in the associative array before accessing it, something like this: if (auto value = key in aa) writefln("key %s was found with the value %s", key, value); else writefln("key %s was not found", key); -- /Jacob Carlborg |
December 31, 2013 Re: Why do associative arrays throw an Error (RangeError) on value not found? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Tuesday, 31 December 2013 at 12:55:59 UTC, Jacob Carlborg wrote:
> On 2013-12-31 13:42, Supernova wrote:
>> Why do associative arrays throw an Error (RangeError) on value not found?
>>
>> This seems like it would be inefficient to check for, so a recoverable
>> Exception (ItemNotFoundException?) would seem to be more appropriate.
>
> How would ItemNotFoundException be any more efficient? The idea is that the error should not be recoverable. If you get an RangeError in your code you have made a logical error.
>
> You need to explicitly check if a key is available in the associative array before accessing it, something like this:
>
> if (auto value = key in aa)
> writefln("key %s was found with the value %s", key, value);
>
> else
> writefln("key %s was not found", key);
Doesn't that duplicate the work of discovering whether the key is there or not? I guess it would depend on the implementation.
|
December 31, 2013 Re: Why do associative arrays throw an Error (RangeError) on value not found? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Supernova | On Tuesday, 31 December 2013 at 12:42:33 UTC, Supernova wrote:
> Why do associative arrays throw an Error (RangeError) on value not found?
>
> This seems like it would be inefficient to check for, so a recoverable Exception (ItemNotFoundException?) would seem to be more appropriate.
>
> Or is Array[Key] with a key that is not in the array and bounds checking disabled undefined behavior?
It seems to me like it's more or less an artifact from earlier D, maybe even back to D1. It's possible that it was designed like that so AAs behave the same way on accessing a non-existent index as normal arrays, for simplicity I suppose (though anyone that's used an AA in another language would probably find this behaviour weird). Item not found is not really a logic error, and not really deserving of a RangeError (who wants their program to crash when something as simple as an AA lookup fails?), but it's not too hard to get around. You have both `value in AA`, which returns a pointer that's null if the value is not found, and `AA.get(value, default)`, which returns `default` if `value` is not found.
|
December 31, 2013 Re: Why do associative arrays throw an Error (RangeError) on value not found? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | John Colvin:
> Doesn't that duplicate the work of discovering whether the key is there or not? I guess it would depend on the implementation.
If you compile the code with ldc2, the compiler in most cases is able to perform the associative array lookup only once. Elsewhere I suggested to add the same optimization to dmd.
With dmd currently you can avoid the double lookup manually because "key in aa" doesn't return a boolean as logic and good practice suggests, it returns a pointer that is null when the key is not found, and it points to the value when the key is present. So storing and dereferencing this pointer you can avoid the double lookup.
Bye,
bearophile
|
December 31, 2013 Re: Why do associative arrays throw an Error (RangeError) on value not found? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Tuesday, December 31, 2013 13:39:25 John Colvin wrote:
> On Tuesday, 31 December 2013 at 12:55:59 UTC, Jacob Carlborg
>
> wrote:
> > On 2013-12-31 13:42, Supernova wrote:
> >> Why do associative arrays throw an Error (RangeError) on value
> >> not found?
> >>
> >> This seems like it would be inefficient to check for, so a
> >> recoverable
> >> Exception (ItemNotFoundException?) would seem to be more
> >> appropriate.
> >
> > How would ItemNotFoundException be any more efficient? The idea is that the error should not be recoverable. If you get an RangeError in your code you have made a logical error.
> >
> > You need to explicitly check if a key is available in the associative array before accessing it, something like this:
> >
> > if (auto value = key in aa)
> >
> > writefln("key %s was found with the value %s", key, value);
> >
> > else
> >
> > writefln("key %s was not found", key);
>
> Doesn't that duplicate the work of discovering whether the key is there or not? I guess it would depend on the implementation.
Not really. If you don't know whether it's there or not, use the in operator. If you know that it's there, then use the subscript operator.
auto value = key in aa; //Maybe it's there, maybe not
auto value2 = aa[key2]; //It's definitely there and is a bug if it's not
You'd get a double lookup if the in operator returned a bool and then had to use the subscript operator to fetch it, but fortunately, in returns a pointer to the value (or null if it's not there), which is more efficient and a lot more useful.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation