February 09, 2005
>Walter changed the language, so that "in" now returns a *pointer* (there are still a few bugs in the new implementation, but anyway)
>
>This means you can now do: if ((p = x in aa) != null) { y = *p; }
>which avoids the double-lookup, at the expense of readability...

Would it not be a better solution to have "in" return a bool, and instead have the compiler optimize away the double lookup?

I'm no expert, so I don't know if this is even possible. Is it?

Nick


February 09, 2005
Nick wrote:

>>Walter changed the language, so that "in" now returns a *pointer*
>>(there are still a few bugs in the new implementation, but anyway)
>>
>>This means you can now do: if ((p = x in aa) != null) { y = *p; }
>>which avoids the double-lookup, at the expense of readability...
> 
> Would it not be a better solution to have "in" return a bool,
> and instead have the compiler optimize away the double lookup?
> 
> I'm no expert, so I don't know if this is even possible. Is it?

That's how it worked before, although it can't optimize the double
lookup since it doesn't know that you are going to use it again...

*I* still believe that in most cases you could just have done a:
if ((y = aa[x) != y.init) { ... } and totally ignored the difference
of whether x was "in" or not ? (it doesn't work with .init entries)

You couldn't store "null" in in the old Java 1 class called Hashtable.
Can't say it was ever a big problem ? (Java 2 Map does permit null keys)

But you can't at the moment, since that will instead fill the hash up...
(you can't do if(y = aa[x)), since "'=' does not give a boolean result")


Which means that until the *bugs* has been addressed, you need to write:
val = key in hash ? hash[key] : val.init;

Instead of just:
val = hash[key];

--anders

February 09, 2005
Unknown W. Brackets wrote:

> I'm afraid that I, apparently unlike you, use associative arrays with many values in them - including some that are Type.init.

So use "in" to separate between them ? Works just fine.

Or do you mean you actually use hash[key] to set them ?

--anders
February 09, 2005
On Wed, 09 Feb 2005 11:04:29 +0100, Anders F Björklund <afb@algonet.se> wrote:
> Unknown W. Brackets wrote:
>
>> I'm afraid that I, apparently unlike you, use associative arrays with many values in them - including some that are Type.init.
>
> So use "in" to separate between them ? Works just fine.

Yes it works, but it's not 'nice'. You are relegated to using pointers for basic types, that seems contrary to the fact that they're 'basic' types.

> Or do you mean you actually use hash[key] to set them ?

I don't follow, why is this an issue?

Regan
February 09, 2005
On Wed, 09 Feb 2005 11:01:17 +0100, Anders F Björklund <afb@algonet.se> wrote:
> Nick wrote:
>
>>> Walter changed the language, so that "in" now returns a *pointer*
>>> (there are still a few bugs in the new implementation, but anyway)
>>>
>>> This means you can now do: if ((p = x in aa) != null) { y = *p; }
>>> which avoids the double-lookup, at the expense of readability...
>>  Would it not be a better solution to have "in" return a bool,
>> and instead have the compiler optimize away the double lookup?
>>  I'm no expert, so I don't know if this is even possible. Is it?
>
> That's how it worked before, although it can't optimize the double
> lookup since it doesn't know that you are going to use it again...
>
> *I* still believe that in most cases you could just have done a:
> if ((y = aa[x) != y.init) { ... } and totally ignored the difference
> of whether x was "in" or not ? (it doesn't work with .init entries)

You can do this for all cases where init.value == 'non existant'. In other words when you do not need to treat non existant as different to the init.value.

That might be 'most' cases for you, it might not be for someone else.

> You couldn't store "null" in in the old Java 1 class called Hashtable.
> Can't say it was ever a big problem ?

What did it do/return when you requested a non existant element?

> (Java 2 Map does permit null keys)

null keys? or null values?

> But you can't at the moment, since that will instead fill the hash up...
> (you can't do if(y = aa[x)), since "'=' does not give a boolean result")
>
>
> Which means that until the *bugs* has been addressed, you need to write:
> val = key in hash ? hash[key] : val.init;
>
> Instead of just:
> val = hash[key];

Are you talking about java above, or D?

Regan
February 09, 2005
Regan Heath wrote:

>>> I'm afraid that I, apparently unlike you, use associative arrays with  many values in them - including some that are Type.init.
>>
>> So use "in" to separate between them ? Works just fine.
> 
> Yes it works, but it's not 'nice'. You are relegated to using pointers for  basic types, that seems contrary to the fact that they're 'basic' types.

You can still use "in" like in a so called boolean expression,
like before. Won't matter that it's a pointer now and not bit ?

And then use hash[key] to retrieve it. Avoids the pointer,
but does mean a double lookup on the hash key is being made.

If you want the fast route, just use the pointer for both.

>> Or do you mean you actually use hash[key] to set them ?
> 
> I don't follow, why is this an issue?

The bug we're talking about is that when you read hash[key],
the value gets set to .init - and unless someone is actually
using this "feature", it should be removed from the language.

Since it's really confusing and annoying to everyone else...

--anders
February 09, 2005
Regan Heath wrote:

>> *I* still believe that in most cases you could just have done a:
>> if ((y = aa[x) != y.init) { ... } and totally ignored the difference
>> of whether x was "in" or not ? (it doesn't work with .init entries)
> 
> You can do this for all cases where init.value == 'non existant'. In other  words when you do not need to treat non existant as different to the  init.value.
> 
> That might be 'most' cases for you, it might not be for someone else.

And they can just use the "in" logic first, and avoid getting .init ?

Or if they do get a .init (0 or null or whatever), they can check
with "in" if it existed as .init or if it didn't exist in the hash.
But reading a value should not just create and store a blank one.

>> You couldn't store "null" in in the old Java 1 class called Hashtable.
>> Can't say it was ever a big problem ?
> 
> What did it do/return when you requested a non existant element?

It returned null. If you used null keys, it threw NullPointerExceptions

Java 1:
> Returns:
>     the value to which the key is mapped in this hashtable;
>     null if the key is not mapped to any value in this hashtable. 
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.html


>> (Java 2 Map does permit null keys)
> 
> null keys? or null values?

Both, I believe ? But they reworked the whole Java Collections a *lot*.

Java 2:
> Returns the value to which the specified key is mapped in this
> identity hash map, or null if the map contains no mapping for
> this key. A return value of null does not necessarily indicate
> that the map contains no mapping for the key; it is also possible
> that the map explicitly maps the key to null. The containsKey
> method may be used to distinguish these two cases.
http://java.sun.com/j2se/1.4.2/docs/api/java/util/HashMap.html

>> Which means that until the *bugs* has been addressed, you need to write:
>> val = key in hash ? hash[key] : val.init;
>>
>> Instead of just:
>> val = hash[key];
> 
> Are you talking about java above, or D?

Back in D land, again. :-) No primitive hashes in Java, objects there.

And in the current D implementation, reading a nonexisting key
will create a new value of .init for the key, and return that.
Thus, the need to use "in" - to avoid creating dummy hash entries.

I fail to see why one wants a dummy new value or an exception.
Maybe someone can give some example code that relies on either ?

--anders
February 09, 2005
In article <opslx7arol23k2f5@ally>, Regan Heath says...
>
>> You couldn't store "null" in in the old Java 1 class called Hashtable. Can't say it was ever a big problem ?
>
>What did it do/return when you requested a non existant element?

The Java Hashtable isn't really a good model to follow. It can only store objects, not basic types. To store an integer you would have to use the ugly Integer(3) wrapper class.

Nick


February 09, 2005
On Wed, 09 Feb 2005 23:21:30 +0100, Anders F Björklund <afb@algonet.se> wrote:
> Regan Heath wrote:
>
>>> *I* still believe that in most cases you could just have done a:
>>> if ((y = aa[x) != y.init) { ... } and totally ignored the difference
>>> of whether x was "in" or not ? (it doesn't work with .init entries)
>>  You can do this for all cases where init.value == 'non existant'. In other  words when you do not need to treat non existant as different to the  init.value.
>>  That might be 'most' cases for you, it might not be for someone else.
>
> And they can just use the "in" logic first, and avoid getting .init ?

Yes, but then they have a double lookup.

> Or if they do get a .init (0 or null or whatever), they can check
> with "in" if it existed as .init or if it didn't exist in the hash.

A double lookup.

> But reading a value should not just create and store a blank one.

I agree totally, I'm not arguing 'for' this behaviour at all. :)
Sorry if I missled.

>>> You couldn't store "null" in in the old Java 1 class called Hashtable.
>>> Can't say it was ever a big problem ?
>>  What did it do/return when you requested a non existant element?
>
> It returned null.

Could it store basic types i.e. 'int'?

> If you used null keys, it threw NullPointerExceptions

Sure, I can't really see a point in a null key.

> Java 1:
>> Returns:
>>     the value to which the key is mapped in this hashtable;
>>     null if the key is not mapped to any value in this hashtable.
> http://java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.html

Thanks.

>>> (Java 2 Map does permit null keys)
>>  null keys? or null values?
>
> Both, I believe ? But they reworked the whole Java Collections a *lot*.

I can understand null values, why do you want/need null keys?

> Java 2:
>> Returns the value to which the specified key is mapped in this
>> identity hash map, or null if the map contains no mapping for
>> this key. A return value of null does not necessarily indicate
>> that the map contains no mapping for the key; it is also possible
>> that the map explicitly maps the key to null. The containsKey
>> method may be used to distinguish these two cases.
> http://java.sun.com/j2se/1.4.2/docs/api/java/util/HashMap.html

Thanks.

>>> Which means that until the *bugs* has been addressed, you need to write:
>>> val = key in hash ? hash[key] : val.init;
>>>
>>> Instead of just:
>>> val = hash[key];
>>  Are you talking about java above, or D?
>
> Back in D land, again. :-) No primitive hashes in Java, objects there.
>
> And in the current D implementation, reading a nonexisting key
> will create a new value of .init for the key, and return that.

I know, I disagree with this behaviour.

> Thus, the need to use "in" - to avoid creating dummy hash entries.

Sure.

> I fail to see why one wants a dummy new value or an exception.

I don't want the former, I don't want the latter, however if they were our only choices I'd choose the latter.

As you've said we have other choices:
 - use 'in' and pointers.

To me that seems contrary to the idea that a basic type is just that basic, eg.

int[char[]] aa;
int *p;
int v;

//here we are trying to get the value of "fred" out of the aa without a double lookup.
p = ("fred" in aa);
v = *p;

//not too bad I admit, less verbose than
try {
  v = aa["fred"];
} catch(Exception e) {
}

Ahhh well, I guess all I'm saying is that:

- I dislike the behaviour of v = aa["fred"] when "fred" does not exist, it seems to be the greater of the evils.

- I dislike the soln we have to use to avoid a double lookup, but it appears to be the lesser of the evils.

> Maybe someone can give some example code that relies on either ?

Not I.

Regan

February 09, 2005
Regan Heath wrote:

>> But reading a value should not just create and store a blank one.
> 
> I agree totally, I'm not arguing 'for' this behaviour at all. :)
> Sorry if I missled.

<phew>

>>>> You couldn't store "null" in in the old Java 1 class called Hashtable.
>>>> Can't say it was ever a big problem ?
>>>
>>>  What did it do/return when you requested a non existant element?
>>
>> It returned null.
> 
> Could it store basic types i.e. 'int'?

Nope, like all collections in Java it can *only* handle Objects.

That's why they have all the wrapper object types for primitives:
Integer, Byte, Short, Long, Character, Float, Double, etc.

And of course the String class is the default, for doing strings
(doesn't really matter, since char[] is also an object in  Java!)


For the JDBC interface, they do a double approach: there is one
Object-returning method, and one for each of the primitive types -
including a boolean "wasNull" function to check for null values.

http://java.sun.com/j2se/1.4.2/docs/api/java/sql/ResultSet.html


Quite different. (D does *not* want such wrapper classes/methods)

>> I fail to see why one wants a dummy new value or an exception.
> 
> I don't want the former, I don't want the latter, however if they were our  only choices I'd choose the latter.

"None of the above". :-)

> As you've said we have other choices:
>  - use 'in' and pointers.

Pointers are optional.

> To me that seems contrary to the idea that a basic type is just that  basic, eg.
> 
> int[char[]] aa;
> int *p;
> int v;
> 
> //here we are trying to get the value of "fred" out of the aa without a  double lookup.
> p = ("fred" in aa);
> v = *p;
> 
> //not too bad I admit, less verbose than
> try {
>   v = aa["fred"];
> } catch(Exception e) {
> }

It doesn't work for all types of p, though. e.g. function delegates.

> Ahhh well, I guess all I'm saying is that:
> 
> - I dislike the behaviour of v = aa["fred"] when "fred" does not exist, it  seems to be the greater of the evils.

Mother of all evils.

> - I dislike the soln we have to use to avoid a double lookup, but it  appears to be the lesser of the evils.

For e.g. hashes of strings and Objects, just returning null is fine

And that doesn't require a double lookup either... (except for "in")

alias char[] str;

str[str] aa;
str v = aa["fred"];

--anders