July 14, 2004
Ivan Senji wrote:

<snip>
> I meant to say that having opIn would be great, but "in" is not
> an operator.
> 
> RelExpression -> RelExpression in ShiftExpression
> 
> It would be nice if it was an operator.

Similarly

AddExpression -> AddExpression + MulExpression

Straight to the point please - how is in different from an operator?

<snip>
>> You've just contradicted yourself.  In AAs, it works by checking if a
> 
> I don't think i have. You use associative arrays to store the keys, so it
> makes sence to check if a value of the key is in it or not.

No.  "Key" and "value" have specific meanings in this context.

	array[key] == value

OK, so a key may have a value, but it is different from the concept of a value in an AA.

For associative arrays,

	X in A

means that there exists a Y for which

	A[X] == Y

(well, strictly speaking that's true of elements that aren't in, but you get the idea)

You're suggesting that for linear arrays, it should mean the reverse: there exists a Y for which

	A[Y] == X

This is an inconsistency up with which plenty of us (not to mention generic programmers) will not put.

> int[char[]] AA1; //this stores char[]'s
> 
> And you use normal arrays to store that type:
> float[] normalArray; //i store a float here
> 
> I might wan't to know if a certain float is in the array.

Then invent a new operator with this meaning.  Don't overload operators to mean completely different things.

I might also "wan't" to know if a certain value occurs as a value in an AA.  The new operator would cover this case just as well.

<snip>
> Associative arrays are for storing the key type, and normal arrays
> are for storing the type of array.

AAs have two types declared: the key type and the value type.  Normal arrays only have the value type declared.

>> And anyway, that has nothing to do with the OP's question.
> 
> Whose question? :)

OP = Original Poster.  The person who started the thread.

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
July 14, 2004
Matthew wrote:
> I'd like to solicit opinion on method naming conventions.
> 
> In C++, std::map's entry access is via the following methods:
> 
>     - operator[] (key_type key) - this returns the element for the given key, or
> creates it if it does not exist. It never returns a "does-not-exist" value
>     - find(key_type key) - this returns an iterator for the element, or the end()
> iterator if it does not exist
> 
> In Ruby, we have the useful syntactic convention of ? for testing:
> 
>     - include?(val)
> 
> For D, we don't have iterators - of which more, later ... - and we don't have the
> ? postfix. I'd like to suggest a simple convention:
> 
>     - opIndex, where appropriate never returns null. Always returns the requested
> element, or throws an InvalidKeyException (or similar)
>     - getXyz() - same semantics as opIndex.
>     - findXyz() - tests the existence of the element, or returns null.
> 
> The alternatives to this are, IMO, far less attractive. We can either:
> 
> A. Only have the getXyz() version, which means the client code that wants to test
> existence has to have try-catch clutter
> B. Have getXyz(key_type key) and getXyz(key_type key, out bool bExists)
> overloads, which is confusing and also precludes the opIndex form.
> 
> There are two downsides to my proposed approach:
> 
> 1. People might get confused. That's the reason I'm proposing that we address
> this now, by adopting a common convention.
> 2. We can't return a null-value for built-in types. I would suggest that this
> isn't a problem for most cases, since we aren't storing built-in types in most
> cases. However, there are some cases where they are used, so maybe we should also
> include a hasXyz() method, which returns a boolean indicator.
> 
> Responses?

I think Python really nailed this one on the head.  It does pretty much the same thing, but goes a hair further:

get(key, default) - accepts a second argument, which is returned if the key sn't present. (this second argument defaults to None; T.init is as close to that as D gets)

setdefault(key, default) - same as get(), except it also assigns the value if the key isn't present. eg:

	if 'key' not in dict:
		dict['key'] = 'default'
	return dict['key']

contains(key) - tests for the existence of a key, returns a boolean.

 -- andy
July 14, 2004
Stewart Gordon wrote:
>> And having "in" work for arrays would be cool (just like it works for
>> associative arrays), it happens sometimes that you need to check
>> if something is in the array and i find my self rewriting something that the
>> compiler could do instead of me.
>>
>> bool found=false;
>> foreach(T t; array)
>> {
>>     if(myElem==t)}{found =true;break;}
>> }
>> if(found)...
>>
>> It would rally nice if i could just write:
>> if(myElem in array)
>> instead of the above.
> 
> <snip>
> 
> You've just contradicted yourself.  In AAs, it works by checking if a _key_ is in the array.  You've given a code snippet that checks if a _value_ is in the array.

It may be contradictory, but the meaning is completely clear and it's something that programmers need to do constantly.

If the inconsistency really is that troublesome, D could simply define the 'in' operator solely for arrays.  Programmers could instead write:

	char[][char[]] dict;
	if (x in dict.keys) { ... } // hot damn
	if (x in dict.values) { ... }

 -- andy
July 14, 2004
I, for one, will be storing builtin types much (over 50%) of the time.
or structs :-)
I mean how many of us have not at one point or another made a map from int to int, or from string to int even ... it's clearly a very common case...and I'm not a big fan of using a class Integer to wrap an int
not sure either structs or builtins can be null when returning

you probably want the findXyz to return a pointer if it's a builtin type (either using specialization or else always return a pointer)

Matthew wrote:
> I'd like to solicit opinion on method naming conventions.
> 
> In C++, std::map's entry access is via the following methods:
> 
>     - operator[] (key_type key) - this returns the element for the given key, or
> creates it if it does not exist. It never returns a "does-not-exist" value
>     - find(key_type key) - this returns an iterator for the element, or the end()
> iterator if it does not exist
> 
> In Ruby, we have the useful syntactic convention of ? for testing:
> 
>     - include?(val)
> 
> For D, we don't have iterators - of which more, later ... - and we don't have the
> ? postfix. I'd like to suggest a simple convention:
> 
>     - opIndex, where appropriate never returns null. Always returns the requested
> element, or throws an InvalidKeyException (or similar)
>     - getXyz() - same semantics as opIndex.
>     - findXyz() - tests the existence of the element, or returns null.
> 
> The alternatives to this are, IMO, far less attractive. We can either:
> 
> A. Only have the getXyz() version, which means the client code that wants to test
> existence has to have try-catch clutter
> B. Have getXyz(key_type key) and getXyz(key_type key, out bool bExists)
> overloads, which is confusing and also precludes the opIndex form.
> 
> There are two downsides to my proposed approach:
> 
> 1. People might get confused. That's the reason I'm proposing that we address
> this now, by adopting a common convention.
> 2. We can't return a null-value for built-in types. I would suggest that this
> isn't a problem for most cases, since we aren't storing built-in types in most
> cases. However, there are some cases where they are used, so maybe we should also
> include a hasXyz() method, which returns a boolean indicator.
> 
> Responses?
> 
> 
July 14, 2004
"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:cd3kj2$28hd$1@digitaldaemon.com...
> Ivan Senji wrote:
>
> <snip>
> > I meant to say that having opIn would be great, but "in" is not an operator.
> >
> > RelExpression -> RelExpression in ShiftExpression
> >
> > It would be nice if it was an operator.
>
> Similarly
>
> AddExpression -> AddExpression + MulExpression
>
> Straight to the point please - how is in different from an operator?

Ignore this! I said something stupid :)


> <snip>
> >> You've just contradicted yourself.  In AAs, it works by checking if a
> >
> > I don't think i have. You use associative arrays to store the keys, so
it
> > makes sence to check if a value of the key is in it or not.
>
> No.  "Key" and "value" have specific meanings in this context.
>
> array[key] == value
>
> OK, so a key may have a value, but it is different from the concept of a value in an AA.
>
> For associative arrays,
>
> X in A
>
> means that there exists a Y for which
>
> A[X] == Y

I don't see it that way. To me "X in A"
means:
For this X there is allready an Y so that
A[X]==Y

So if i do:
float[char[]] A;
A["string1"]=3.1;
A["string2"]=3.2;

And normally i can test:
"string1" in A == true;
"bla" in A == false;

We agree on this but this is the way i see normal arrays and in.

float[] A;
A~= 3.1;
A~=3.2;

3.1 in A == true;
4.0 in A == false;

This would be very usefull! I do agree that this is a little inconsistency but it is a one that makes sence.


> (well, strictly speaking that's true of elements that aren't in, but you
> get the idea)
>
> You're suggesting that for linear arrays, it should mean the reverse: there exists a Y for which
>
> A[Y] == X

Exactly :)

> This is an inconsistency up with which plenty of us (not to mention generic programmers) will not put.
> > int[char[]] AA1; //this stores char[]'s
> >
> > And you use normal arrays to store that type:
> > float[] normalArray; //i store a float here
> >
> > I might wan't to know if a certain float is in the array.
>
> Then invent a new operator with this meaning.  Don't overload operators to mean completely different things.

It isn't completelly different, AAs store keys, and normal arrays store values. In is for testing is an element contained in an array.

> I might also "wan't" to know if a certain value occurs as a value in an AA.  The new operator would cover this case just as well.
>
> <snip>
> > Associative arrays are for storing the key type, and normal arrays are for storing the type of array.
>
> AAs have two types declared: the key type and the value type.  Normal arrays only have the value type declared.
>
> >> And anyway, that has nothing to do with the OP's question.
> >
> > Whose question? :)
>
> OP = Original Poster.  The person who started the thread.

Thanks! I didn't know this one.

We obviouslly don't agree on in and normal arrays, but we do that having opIn would be usefull for container classes?

>
> Stewart.
>
> --
> My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.


July 14, 2004
Ivan Senji wrote:

<snip>
> It isn't completelly different, AAs store keys, and normal arrays store
> values. In is for testing is an element contained in an array.

AAs store values too.

<snip>
> We obviouslly don't agree on in and normal arrays, but we
> do that having opIn would be usefull for container classes?

Yes, though there is a complication.

Binary operators in general look first in the left-hand type to determine what to do.  But in really wants to be controlled by the right-hand type.  Consequently, if we kept to the usual mechanism of

	left.opIn(right)

or, if it's not there

	right.opIn_r(left)

then a type could define its own way of deciding if it is in a given container, and lead to confusion.

If OTOH, an exception were made so that either opIn_r takes priority, or the senses of opIn and opIn_r are reversed, then it would indeed be an exception, and I'm not sure if that would be the Right Thing.

The other possibility is to call it opContains, so that it's

	right.opContains(left)

....

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
July 14, 2004
In article <cd389r$1kg4$1@digitaldaemon.com>, Matthew says...
>
>The reason I case is that such a thing can only be a convention, not a "law", and
>I want to avoid the crappy naming mess that is the C++ standard library: "empty()
>=> is_empty?", "clear() => make_empty()" !!

Darn, and I like the C++ naming scheme.  I suppose empty() is an odd case
because it can be both a noun and a verb, but the meaning of clear() is, well,
clear :)  isEmpty() wouldn't be bad I suppose, though by that argument I suppose
empty() would replace clear()


Sean


July 14, 2004
In article <cd30iv$17m8$1@digitaldaemon.com>, Matthew says...
>
>I'd like to solicit opinion on method naming conventions.
>
>In C++, std::map's entry access is via the following methods:
>
>    - operator[] (key_type key) - this returns the element for the given key, or
>creates it if it does not exist. It never returns a "does-not-exist" value
>    - find(key_type key) - this returns an iterator for the element, or the end()
>iterator if it does not exist
>
>In Ruby, we have the useful syntactic convention of ? for testing:
>
>    - include?(val)
>
>For D, we don't have iterators - of which more, later ... - and we don't have the ? postfix.

Perhaps a bit off-topic, but why no iterators in D?  How else are we going to operate on the contents of a binary tree?  I suppose we could use foreach for such things, but that tosses the idea of C++-like algorithms, which I always kind of liked.  Though I suppose such algorithms would be more difficult to use because all template arguments must be explicitly specified (the one feature of D that makes me occasionally gnash my teeth in frustration).

>    - opIndex, where appropriate never returns null. Always returns the requested
>element, or throws an InvalidKeyException (or similar)

Seems reasonable, since a built-in container will throw an out of bounds error.

>    - getXyz() - same semantics as opIndex.
>    - findXyz() - tests the existence of the element, or returns null.

It's the returning null thing that gets me.  If I've found an element and want to iterate from there, can I?

>However, there are some cases where they are used, so maybe we should also include a hasXyz() method, which returns a boolean indicator.

Would be nice.  Checking for existence is very useful, and this is perhaps more concise than findXyz() == null.


Sean


July 14, 2004
In article <cd3mvn$2cue$2@digitaldaemon.com>, Andy Friesen says...
>
>If the inconsistency really is that troublesome, D could simply define the 'in' operator solely for arrays.  Programmers could instead write:
>
>	char[][char[]] dict;
>	if (x in dict.keys) { ... } // hot damn
>	if (x in dict.values) { ... }

I wouldn't mind having better support for hash sets in D.  I ended up using a map just to get the speed I wanted.  Maybe something like this?

void[char[]] set; // char[] key and no value type


Sean


July 14, 2004
Fair point

What about:

    -    value_type getXyz(key_type key) returns the requested element, or throw
InvalidKeyException
    -    bool containsXyz(key_type key) returns true/false, indicating presence
of element
    -    value_type findXyx(key_type key, value_type defaultValue) returns the
requested element, or the given default

    -    opIndex() is a synonym for getXyz where the container has only a single
value_type, or its primary value_type is obviously delineated from any secondary
value_types.

I'm pretty happy with this picture. Votes?



"Daniel Horn" <hellcatv@hotmail.com> wrote in message news:cd3qim$2iov$1@digitaldaemon.com...
> I, for one, will be storing builtin types much (over 50%) of the time.
> or structs :-)
> I mean how many of us have not at one point or another made a map from
> int to int, or from string to int even ... it's clearly a very common
> case...and I'm not a big fan of using a class Integer to wrap an int
> not sure either structs or builtins can be null when returning
>
> you probably want the findXyz to return a pointer if it's a builtin type (either using specialization or else always return a pointer)
>
> Matthew wrote:
> > I'd like to solicit opinion on method naming conventions.
> >
> > In C++, std::map's entry access is via the following methods:
> >
> >     - operator[] (key_type key) - this returns the element for the given key,
or
> > creates it if it does not exist. It never returns a "does-not-exist" value
> >     - find(key_type key) - this returns an iterator for the element, or the
end()
> > iterator if it does not exist
> >
> > In Ruby, we have the useful syntactic convention of ? for testing:
> >
> >     - include?(val)
> >
> > For D, we don't have iterators - of which more, later ... - and we don't have
the
> > ? postfix. I'd like to suggest a simple convention:
> >
> >     - opIndex, where appropriate never returns null. Always returns the
requested
> > element, or throws an InvalidKeyException (or similar)
> >     - getXyz() - same semantics as opIndex.
> >     - findXyz() - tests the existence of the element, or returns null.
> >
> > The alternatives to this are, IMO, far less attractive. We can either:
> >
> > A. Only have the getXyz() version, which means the client code that wants to
test
> > existence has to have try-catch clutter
> > B. Have getXyz(key_type key) and getXyz(key_type key, out bool bExists)
> > overloads, which is confusing and also precludes the opIndex form.
> >
> > There are two downsides to my proposed approach:
> >
> > 1. People might get confused. That's the reason I'm proposing that we address
> > this now, by adopting a common convention.
> > 2. We can't return a null-value for built-in types. I would suggest that this
> > isn't a problem for most cases, since we aren't storing built-in types in
most
> > cases. However, there are some cases where they are used, so maybe we should
also
> > include a hasXyz() method, which returns a boolean indicator.
> >
> > Responses?
> >
> >