December 18, 2004
It is very convinient that assosiative array returns a default value when a
non-existing key is adressed.
I mainly use char [][char[]]  type arrays. Most time it is only the value that
it is interesting and it is very good that  (not set)=""
When I really whant to know if the value is not set or set to "" then I use the
in clause. But now reading spoils it.

I THINK THAT READING MUST NOT CREATE A NEW KEY.
READING IS READING WRITING IS WRITING.

My suggestion is that reading should still return a default value but writing
should not create the new key!
What do you think?




In article <cq1343$1duk$1@digitaldaemon.com>, novice2 says...
>
>IMHO access to not existing items in associative array should throw exception
>"Out of bounds", like to access to not existing items in normal arrays.
>IMHO auto creating not existing items is confuse. It is bad side effect.
>
>For me disabling autocreating will have no pros (?) and some cons (better error
>detection).
>
>good luck
>novice2.
>
>In article <cpuuir$2e66$1@digitaldaemon.com>, Ben Hinkle says...
>>
>>
>>"novice2" <novice2_member@pathlink.com> wrote in message news:cput9j$2cu8$1@digitaldaemon.com...
>>> Hi.
>>>
>>> Associative array automatically add items, if it not existed but was
>>accessed.
>>> Small example:
>>>
>>> /**************************/
>>> alias char[] string;
>>>
>>> void main()
>>> {
>>> string[string] arr;
>>>
>>> if("key" in arr)
>>> printf("key exist\n");
>>> else
>>> printf("key not exist\n");
>>>
>>> printf("arr[key]=%.*s\n", arr["key"]);
>>>
>>> if("key" in arr)
>>> printf("key exist\n");
>>> else
>>> printf("key not exist\n");
>>> }
>>> /**************************/
>>>
>>> For DMD 0.109 this program print:
>>>
>>> key not exist
>>> arr[key]=
>>> key exist
>>>
>>> Item auto inserted after access to it.
>>> Is it feature or bug?
>>> If it is feature - it is very inconveniently.
>>> So i can't trust to 'in' operator.
>>>
>>> Sorry, if a missed something.
>>>
>>>
>>
>>This is how it is documented to work. The precedent is C++'s map class. The alternative is to throw an exception and my guess for why it doesn't is that maybe having a function that sometimes throws is slower than always inserting. It does seem a little wierd but it isn't unreasonable.
>>
>>-Ben
>>
>>
>
>


December 18, 2004
>My suggestion is that reading should still return a default value but writing should not create the new key!

Yes. I will be good, IMHO.
I use char[char[]] too, and after first debug printf i loose information about
was originally key exist or it was autoinserted.

>What do you think?

IMHO autoinserting should be disabled.
About result of read non existed key:
for me, any of two variants appropriate: return default value or throw
exception.




December 18, 2004
On 2004-12-17, Stewart Gordon <smjg_1998@yahoo.com> wrote:
> Martin wrote:
>> This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!

Can you please explain what are the cons of this behavior? I've listened to the "if it can throw an exception it's slower" argument but I don't think that's a good one (against the cons, more difficult to understand, more dificult to debug, unwanted side effects for sure, not logical...)
December 18, 2004
My point was, that exeption throwing is NOT nessesary or desirable. For example if you have a file with words, you count the words and keep the result in an associative  array. Let's say there was word 'fox' five times. Then array["fox"] equels 5. But let's say there was no word rabbit. Then array["rabbit"] equals 0. It's logical. Most of the time 0 means none. Most of the cases when I use associative arrays are such cases. (Mostly for me, not existing means "" and that is what it should be).

PROGRAM.CONF:
NAME="My program"
MESSAGE=""
VERSION="1.95"

or

PROGRAM.CONF:
NAME="My program"
VERSION="1.95"

are the same. And my associative array CONF, the element CONF["MESSAGE"] should
be "". Why should I count all the empty strings.
eg

PROGRAM.CONF:
NAME="My program"
MESSAGE=""
MESSAGE1=""
MESSAGE2=""
MESSAGE3=""
MESSAGE4=""
MESSAGE5="something"
MESSAGE6=""
MESSAGE7=""
VERSION="1.95"

should be

PROGRAM.CONF:
NAME="My program"
MESSAGE5="something"
VERSION="1.95"

And when an action occurs in my program, for example the user logs out then I do
printf("%.*s",CONF["MESSAGE5"]);
If this is specified then the user gets the message, if it isn't then  the user
gets nothing. (Ok here I could write the in check, but there are lots of
situations that its very time consuming and makes code much uglyer.)
Most of the time (not given)=(default value). This way I can program much faster
and cleaner.

But sometimes I need to know if the value was actually given or not. Then I use if("MESSAGE5" in CONF). But now, if I had done printf("%.*s",CONF["MESSAGE5"]); then everything is spoiled. I need to keep CONF and CONF_original where I do the 'in' clause only in CONF_original, but this is absurd!!!

There is no need that the reading does create the key. There are opIndex and opIndexAssign. First I thought that maybe it is not possible to read on element without creating it. It is possible in D. So Walter please change it.

CAN ANYONE TELL ME atleast one good reaseon why the reading of an element should create it?


If for some reason Walter does not want to change it then I want to create my own associative arrays. I can use opIndex and opIndexAssign. But tell me, can I use something to overload 'in' for example if("string" in myArray). And how can I overload foreach?

Thanks,

Martin


In article <cq1mtr$1vh1$1@digita ldaemon.com>, Juanjo =?iso-8859-1?Q?=C1lvarez?= says...
>
>On 2004-12-17, Stewart Gordon <smjg_1998@yahoo.com> wrote:
>> Martin wrote:
>>> This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!
>
>Can you please explain what are the cons of this behavior? I've listened to the "if it can throw an exception it's slower" argument but I don't think that's a good one (against the cons, more difficult to understand, more dificult to debug, unwanted side effects for sure, not logical...)


December 19, 2004
Ben Hinkle wrote:

>>Associative array automatically add items,
>>if it not existed but was accessed.
> 
> This is how it is documented to work. The precedent is C++'s map class. The
> alternative is to throw an exception and my guess for why it doesn't is that
> maybe having a function that sometimes throws is slower than always
> inserting. It does seem a little wierd but it isn't unreasonable.

It just looks like a bug in the D compiler ?

> import std.stdio;
> void main()
> {
>   char[][char[]] hash;
> 
>   hash["this"];
>   hash["looks"];
>   hash["like"];
>   hash["a"];
>   hash["bug"];
> 
>   foreach(char[] str; hash.keys)
>     writefln(str);
> }

I don't think that it should output anything ?


Surely it is not intended that I need to write:

> ("key" in hash ? hash["key"] : "")

just to avoid accidently setting it when reading ?


I'm fine with it *returning* a zero/null value.
Since arrays are always being initialized with
the default initializer, it actually makes sense.
Just don't think that it should be *adding* one ?

Like someone suggested, maybe it should be treated
as out of bounds ? Throw exceptions in -debug mode ?
(just as with the regular indexed arrays, that is:
ArrayBoundsError exceptions being thrown at runtime)

--anders
December 19, 2004
The question was: is it possible to owerload the 'in' operator and the foreach one?

Does anybody know?

Thanks!

In article <cq2etq$2m9v$1@digitaldaemon.com>, Martin says...
>
>
>My point was, that exeption throwing is NOT nessesary or desirable. For example if you have a file with words, you count the words and keep the result in an associative  array. Let's say there was word 'fox' five times. Then array["fox"] equels 5. But let's say there was no word rabbit. Then array["rabbit"] equals 0. It's logical. Most of the time 0 means none. Most of the cases when I use associative arrays are such cases. (Mostly for me, not existing means "" and that is what it should be).
>
>PROGRAM.CONF:
>NAME="My program"
>MESSAGE=""
>VERSION="1.95"
>
>or
>
>PROGRAM.CONF:
>NAME="My program"
>VERSION="1.95"
>
>are the same. And my associative array CONF, the element CONF["MESSAGE"] should
>be "". Why should I count all the empty strings.
>eg
>
>PROGRAM.CONF:
>NAME="My program"
>MESSAGE=""
>MESSAGE1=""
>MESSAGE2=""
>MESSAGE3=""
>MESSAGE4=""
>MESSAGE5="something"
>MESSAGE6=""
>MESSAGE7=""
>VERSION="1.95"
>
>should be
>
>PROGRAM.CONF:
>NAME="My program"
>MESSAGE5="something"
>VERSION="1.95"
>
>And when an action occurs in my program, for example the user logs out then I do
>printf("%.*s",CONF["MESSAGE5"]);
>If this is specified then the user gets the message, if it isn't then  the user
>gets nothing. (Ok here I could write the in check, but there are lots of
>situations that its very time consuming and makes code much uglyer.)
>Most of the time (not given)=(default value). This way I can program much faster
>and cleaner.
>
>But sometimes I need to know if the value was actually given or not. Then I use if("MESSAGE5" in CONF). But now, if I had done printf("%.*s",CONF["MESSAGE5"]); then everything is spoiled. I need to keep CONF and CONF_original where I do the 'in' clause only in CONF_original, but this is absurd!!!
>
>There is no need that the reading does create the key. There are opIndex and opIndexAssign. First I thought that maybe it is not possible to read on element without creating it. It is possible in D. So Walter please change it.
>
>CAN ANYONE TELL ME atleast one good reaseon why the reading of an element should create it?
>
>
>If for some reason Walter does not want to change it then I want to create my own associative arrays. I can use opIndex and opIndexAssign. But tell me, can I use something to overload 'in' for example if("string" in myArray). And how can I overload foreach?
>
>Thanks,
>
>Martin
>
>
>In article <cq1mtr$1vh1$1@digita ldaemon.com>, Juanjo =?iso-8859-1?Q?=C1lvarez?= says...
>>
>>On 2004-12-17, Stewart Gordon <smjg_1998@yahoo.com> wrote:
>>> Martin wrote:
>>>> This is a very bad behavior and should be corrected. I know it is a feature, but a very bad one!
>>
>>Can you please explain what are the cons of this behavior? I've listened to the "if it can throw an exception it's slower" argument but I don't think that's a good one (against the cons, more difficult to understand, more dificult to debug, unwanted side effects for sure, not logical...)
>
>


December 19, 2004
>Like someone suggested, maybe it should be treated
>as out of bounds ? Throw exceptions in -debug mode ?

Yes but there should be a different switch for it. In most of my programs I relay on returning a default value, if element does not exist. But some people may need to test their programs so this option would be needed.

But this option sholdn't be default or else I still have to write ("key" in hash ? hash["key"] : "") just for avoining the exception.





In article <cq2h5u$2n99$1@digitaldaemon.com>, =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says...
>
>Ben Hinkle wrote:
>
>>>Associative array automatically add items,
>>>if it not existed but was accessed.
>> 
>> This is how it is documented to work. The precedent is C++'s map class. The alternative is to throw an exception and my guess for why it doesn't is that maybe having a function that sometimes throws is slower than always inserting. It does seem a little wierd but it isn't unreasonable.
>
>It just looks like a bug in the D compiler ?
>
>> import std.stdio;
>> void main()
>> {
>>   char[][char[]] hash;
>> 
>>   hash["this"];
>>   hash["looks"];
>>   hash["like"];
>>   hash["a"];
>>   hash["bug"];
>> 
>>   foreach(char[] str; hash.keys)
>>     writefln(str);
>> }
>
>I don't think that it should output anything ?
>
>
>Surely it is not intended that I need to write:
>
>> ("key" in hash ? hash["key"] : "")
>
>just to avoid accidently setting it when reading ?
>
>
>I'm fine with it *returning* a zero/null value.
>Since arrays are always being initialized with
>the default initializer, it actually makes sense.
>Just don't think that it should be *adding* one ?
>
>Like someone suggested, maybe it should be treated
>as out of bounds ? Throw exceptions in -debug mode ?
>(just as with the regular indexed arrays, that is:
>ArrayBoundsError exceptions being thrown at runtime)
>
>--anders


December 19, 2004
Think wrote:

>>Like someone suggested, maybe it should be treated
>>as out of bounds ? Throw exceptions in -debug mode ?
> 
> Yes but there should be a different switch for it. In most of my programs I
> relay on returning a default value, if element does not exist. But some people
> may need to test their programs so this option would be needed.
> 
> But this option sholdn't be default or else I still have to write ("key" in hash
> ? hash["key"] : "") just for avoining the exception.

On second thought, it should probably *not* throw exceptions.
An associative array doesn't really have any bounds per se...

Languages like Perl don't need to separate between the two,
since e.g. 0 and undef are different. But in D it's 0 and 0, (*)
so you still need "in" to check if it really was set to zero...
(in case you care about it, most programs wouldn't I suppose ?)

But having it throw exceptions is probably just as annoying as
having it write things to the A.A. when just reading, I agree.

--anders

*. For int[type] dictionaries, that is. (any non-reference AA)
December 19, 2004
On Fri, 17 Dec 2004 15:17:07 +0000 (UTC), novice2 <novice2_member@pathlink.com> wrote:
> Hi.
>
> Associative array automatically add items, if it not existed but was accessed.
> Small example:
>
> /**************************/
> alias char[] string;
>
> void main()
> {
> string[string] arr;
>
> if("key" in arr)
> printf("key exist\n");
> else
> printf("key not exist\n");
>
> printf("arr[key]=%.*s\n", arr["key"]);
>
> if("key" in arr)
> printf("key exist\n");
> else
> printf("key not exist\n");
> }
> /**************************/
>
> For DMD 0.109 this program print:
>
> key not exist
> arr[key]=
> key exist
>
> Item auto inserted after access to it.
> Is it feature or bug?
> If it is feature - it is very inconveniently.
> So i can't trust to 'in' operator.
>
> Sorry, if a missed something.

You can do this:

	item = "foo" in arr;

Regan
December 20, 2004
MMM wrote:
> The question was: is it possible to owerload the 'in' operator and the foreach
> one?
<snip top of upside-down reply>

in - not yet
foreach - look up opApply in the docs.

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.