July 14, 2004
Not sure you cover all the cases... we need something that returns a pair with the value(or a default) and a bool

lets assume a lookup is slow
and I have a map<int,int>

what if I want each and every integer to have a valid place in my map (i.e. there are no garbage values for data points)
but I would like to see if that integer is in my map
and if not then I would like to insert it at that place....
how would this be accomplished with your setup?

with a STL map I'd just do a upper bound find :-)
and then insert it with that value as a hint.

another situation that this does not cover:

I'd like to see if my int is in the map (hardly likely) (any int is valid), and if so, then I would like to get that value. to accomplish this I would have to do a contains, THEN a find!
and in that case if I did the getXyz() I would get an exception 99% of the time--that's hardly exceptional and would likely be a fair bit slower than desired. I guess I could cook up some unlikely default value...and in the event of the default value do a contains..but that's the kind of code I wouldn't want to have to write each time I just wish to do a find.

What's wrong with returning a pointer to the desired value again? :-) and null if it's gone... cus memory is certain to have an unused default value of 0 :-)

so my proposal is:

value_type* findXyx(key_type key)
 returns the ref of requested element
that way you can modify it as well

Matthew wrote:
> 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?
>>>
>>>
> 
> 
> 
July 14, 2004
"Sean Kelly" <sean@f4.ca> wrote in message news:cd40jp$2t8p$1@digitaldaemon.com...
> 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()

In DTL, I've used isEmpty() and clear(), but steered clear (arf, arf) of empty
entirely. I always - except where conforming to STL conventions - try to make
methods be verbs or questions.



July 14, 2004
On Wed, 14 Jul 2004 19:31:51 +0100, Stewart Gordon <smjg_1998@yahoo.com> wrote:

> 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)
>
> ....

Or opHas :) I think changing the order of the expression using contains or has is the best soln. eg.

if (arr has key)
if (arr contains key)

instead of

if (key in arr)

I don't think this can be extended to cover normal arrays as in a normal array there can be multiple identical values, this is also true for an AA, but not true for the keys of an AA which must be unique. This uniqueness is what makes this operator possible/sensible.

I think for finding a value in either an AA or normal array a template find function is the solution.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
July 14, 2004
In article <cd481o$adi$4@digitaldaemon.com>, Matthew says...
>
>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?

I don't like the new findXyz semantics.  The new function requires that I either set aside a potentially valid value to signal lookup failure, do two lookups (one for containsXyz and another for findXyz), or wrap getXyz in a try block. Another possibility would be to offer two versions of findXyz, one accepting a default and one returning a pointer?

Sean


July 14, 2004
"Andy Friesen" <andy@ikagames.com> wrote in message news:cd3muf$2cue$1@digitaldaemon.com...
> 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.


If I understand correctly, then my criticism of this is that it prevents one from cascading [], as in

    Node n = doc["D"]["PrettyPrinter"];

which is a big loss, IMO, when dealing with object models over structured content. If you care only that the totality of your required structure is there, or it's not, then you want to be able to cascade instances implementing opIndex. If we have to use the get(key, default), then we can't do that.






July 14, 2004
"Daniel Horn" <hellcatv@hotmail.com> wrote in message news:cd48u5$c2j$1@digitaldaemon.com...
> Not sure you cover all the cases... we need something that returns a pair with the value(or a default) and a bool
>
> lets assume a lookup is slow
> and I have a map<int,int>

Not to be a pedantic fop, but isn't one of the purposes of associative containers that they're efficient at lookup?

> what if I want each and every integer to have a valid place in my map
> (i.e. there are no garbage values for data points)
> but I would like to see if that integer is in my map
> and if not then I would like to insert it at that place....
> how would this be accomplished with your setup?
>
> with a STL map I'd just do a upper bound find :-)
> and then insert it with that value as a hint.
>
> another situation that this does not cover:
>
> I'd like to see if my int is in the map (hardly likely) (any int is
> valid), and if so, then I would like to get that value. to accomplish
> this I would have to do a contains, THEN a find!

For this kind of containment model, there's no reason why we could not provide a getOrCreate() method.

> and in that case if I did the getXyz() I would get an exception 99% of the time--that's hardly exceptional and would likely be a fair bit slower than desired. I guess I could cook up some unlikely default value...and in the event of the default value do a contains..but that's the kind of code I wouldn't want to have to write each time I just wish to do a find.

Agreed. I'm seeking to reduce unnecessary function calls. Basically, I'd like all the common cases covered by a single call.

But remember, I started this thread to ask about naming conventions for such things, not necessarily to debate their merits as functions. (That's not to say it's not fruitful to discuss such things, but I expect people are writing such methods anyway. Hence, it's getting the names write and consistent that I am most concerned with.)

>
> What's wrong with returning a pointer to the desired value again? :-) and null if it's gone... cus memory is certain to have an unused default value of 0 :-)

You'll disenfranchise anyone who's not conversant with, and a big fan of, C/C++'s pointer syntax.

It simply won't be acceptable to the D community.

> so my proposal is:
>
> value_type* findXyx(key_type key)
>   returns the ref of requested element
> that way you can modify it as well
>
> Matthew wrote:
> > 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?
> >>>
> >>>
> >
> >
> >


July 14, 2004
"Sean Kelly" <sean@f4.ca> wrote in message news:cd4dqj$m1f$1@digitaldaemon.com...
> In article <cd481o$adi$4@digitaldaemon.com>, Matthew says...
> >
> >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?
>
> I don't like the new findXyz semantics.  The new function requires that I
either
> set aside a potentially valid value to signal lookup failure, do two lookups (one for containsXyz and another for findXyz), or wrap getXyz in a try block. Another possibility would be to offer two versions of findXyz, one accepting a default and one returning a pointer?

Can you provide a quick sample of using a findXyz() that illustrates your
requirement?


Ok, assuming that everyone's on board with testing (by opIn and/or contains()
and/or containsXyz()) and getting (opIndex and/or get() and/or getXyz()), then
it's finding that's the trouble.

What are our requirements for finding:

        To be able to determine presence (testing) and retrieve the element in
the case of its being present.

To determine presence we must either return a boolean or sentinel value (e.g.
null). Given the dichotomy between null being a good (but not perfect) sentinel
for object types, and 0/NaN being a bad sentinel for built-in types, I'd now
suggest that we don't do that. Hence, presence should be indicated either by
return value, or by an out parameter.
Retrieval can similarly be return value or out parameter.

Thus, for finding, we have two options

1.  Return the value, pass the presence as an out parameter

    value_type findXyz(key_type key, out bool bPresent);

2. Return the presence, pass the value as an out parameter

    bool findXyz(key_type key, out value_type value);

I'd suggest here and now that neither of these are going to satisfy all circumstances. I'd further suggest, however, that we need to decide on one and stick to it.


btw, considering all this, it now seems to me that the above definition of findXyz(), incorporating a default value, is quite wrong. That should be called something else, findWithDefault[Xyz](), or something less ugly.


Leaving us with the following lookup "conventions":

    1. Testing - opIn and/or contains() and/or containsXyz() - returns a boolean
indicating presence or absence. (We might even say an int, returning the number
of items matching in non-unique containers!)
    2. Getting - opIndex and/or get() and/or getXyz() - always returns the
requested value. Throws InvalidKeyException otherwise
    3. Finding - find() or findXyz() - returns value and presence indicator to
caller.
    4. Defaulted Lookup - findWithDefault() or findWithDefaultXyz() (please send
in better suggestions! <g> - takes a key_type and a default value_type. Returns
the default if the key is not present.
    5. Creating Lookup - findOrInsert() or findOrInsertXyz() - takes key_type and
"new" value_type. Returns the existing one, or inserts the new one if none
existing.

So, how can we all live with that?



July 15, 2004
In article <cd4gnr$rp0$1@digitaldaemon.com>, Matthew says...
>
>
>"Sean Kelly" <sean@f4.ca> wrote in message news:cd4dqj$m1f$1@digitaldaemon.com...
>> In article <cd481o$adi$4@digitaldaemon.com>, Matthew says...
>
>> I don't like the new findXyz semantics.  The new function requires that I
>either
>> set aside a potentially valid value to signal lookup failure, do two lookups (one for containsXyz and another for findXyz), or wrap getXyz in a try block. Another possibility would be to offer two versions of findXyz, one accepting a default and one returning a pointer?
>
>Can you provide a quick sample of using a findXyz() that illustrates your
>requirement?

I don't have a concrete example offhand, except that I do this quite often in C++:

mymap::iterator i( m.find( "key" ) );
if( i != m.end() )
{
..
}

Now a case could definately be made for using getXyz here, except for the cost incurred when an exception is thrown, plus the additional coding it would require:

try
{
int i = m.getXyz( "key" );
..
}
catch( KeyNotFound e ) {}

I haven't quite embraced exceptions so much that I use them for this level of flow control.  I would likely just ignore the getXyz call and fake it using the others.

>To determine presence we must either return a boolean or sentinel value (e.g. null). Given the dichotomy between null being a good (but not perfect) sentinel for object types, and 0/NaN being a bad sentinel for built-in types, I'd now suggest that we don't do that.

Well, null could be returned for built-ins as well.  Always using pointers would allow for in-place modification of values.  But then pointers are potentially unsafe, so it's a tough issue.

>1.  Return the value, pass the presence as an out parameter
>
>    value_type findXyz(key_type key, out bool bPresent);
>
>2. Return the presence, pass the value as an out parameter
>
>    bool findXyz(key_type key, out value_type value);
>
>I'd suggest here and now that neither of these are going to satisfy all circumstances. I'd further suggest, however, that we need to decide on one and stick to it.

I agree.  I think that it would make more sense to return the bit value.  It would maintain syntactic consistency with a contains() call and allow us to find the value and check for success in a single expression.

>btw, considering all this, it now seems to me that the above definition of findXyz(), incorporating a default value, is quite wrong. That should be called something else, findWithDefault[Xyz](), or something less ugly.

I agree.  A defaulting version is great just so long as it's not the only option.

(more later, I think I'm being summoned to do more vacation stuff :)


Sean


July 15, 2004
On Thu, 15 Jul 2004 09:47:52 +1000, Matthew <admin@stlsoft.dot.dot.dot.dot.org> wrote:
> "Sean Kelly" <sean@f4.ca> wrote in message news:cd4dqj$m1f$1@digitaldaemon.com...
>> In article <cd481o$adi$4@digitaldaemon.com>, Matthew says...
>> >
>> >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?
>>
>> I don't like the new findXyz semantics.  The new function requires that I
> either
>> set aside a potentially valid value to signal lookup failure, do two lookups
>> (one for containsXyz and another for findXyz), or wrap getXyz in a try block.
>> Another possibility would be to offer two versions of findXyz, one accepting a
>> default and one returning a pointer?
>
> Can you provide a quick sample of using a findXyz() that illustrates your
> requirement?
>
>
> Ok, assuming that everyone's on board with testing (by opIn and/or contains()
> and/or containsXyz()) and getting (opIndex and/or get() and/or getXyz()), then
> it's finding that's the trouble.
>
> What are our requirements for finding:
>
>         To be able to determine presence (testing) and retrieve the element in
> the case of its being present.
>
> To determine presence we must either return a boolean or sentinel value (e.g.
> null). Given the dichotomy between null being a good (but not perfect) sentinel
> for object types, and 0/NaN being a bad sentinel for built-in types, I'd now
> suggest that we don't do that. Hence, presence should be indicated either by
> return value, or by an out parameter.
> Retrieval can similarly be return value or out parameter.
>
> Thus, for finding, we have two options
>
> 1.  Return the value, pass the presence as an out parameter
>
>     value_type findXyz(key_type key, out bool bPresent);
>
> 2. Return the presence, pass the value as an out parameter
>
>     bool findXyz(key_type key, out value_type value);

I like #2, it allows this...

if (findXyz("regan",value)) {
}

#1 would be

value = findXyz("regan",r);
if (r) {
}

> I'd suggest here and now that neither of these are going to satisfy all
> circumstances. I'd further suggest, however, that we need to decide on one and
> stick to it.

My vote is for #2 above.

> btw, considering all this, it now seems to me that the above definition of
> findXyz(), incorporating a default value, is quite wrong. That should be called
> something else, findWithDefault[Xyz](), or something less ugly.

True, having a default value requires being able to pass 'no default', which is the null/0/NaN problem all over again.

Do we need this at all, consider:

if (!findXyz("regan",value)) value = "default";
..use value here..

> Leaving us with the following lookup "conventions":
>
>     1. Testing - opIn and/or contains() and/or containsXyz() - returns a boolean
> indicating presence or absence. (We might even say an int, returning the number
> of items matching in non-unique containers!)
>     2. Getting - opIndex and/or get() and/or getXyz() - always returns the
> requested value. Throws InvalidKeyException otherwise
>     3. Finding - find() or findXyz() - returns value and presence indicator to
> caller.
>     4. Defaulted Lookup - findWithDefault() or findWithDefaultXyz() (please send
> in better suggestions! <g> - takes a key_type and a default value_type. Returns
> the default if the key is not present.

I don't think this is necessary (see above).

>     5. Creating Lookup - findOrInsert() or findOrInsertXyz() - takes key_type and
> "new" value_type. Returns the existing one, or inserts the new one if none
> existing.
>
> So, how can we all live with that?

Sounds good.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
July 15, 2004
"Sean Kelly" <sean@f4.ca> wrote in message news:cd4ik2$vg7$1@digitaldaemon.com...
> In article <cd4gnr$rp0$1@digitaldaemon.com>, Matthew says...
> >
> >
> >"Sean Kelly" <sean@f4.ca> wrote in message
news:cd4dqj$m1f$1@digitaldaemon.com...
> >> In article <cd481o$adi$4@digitaldaemon.com>, Matthew says...
> >
> >> I don't like the new findXyz semantics.  The new function requires that I
> >either
> >> set aside a potentially valid value to signal lookup failure, do two lookups (one for containsXyz and another for findXyz), or wrap getXyz in a try
block.
> >> Another possibility would be to offer two versions of findXyz, one accepting
a
> >> default and one returning a pointer?
> >
> >Can you provide a quick sample of using a findXyz() that illustrates your
> >requirement?
>
> I don't have a concrete example offhand, except that I do this quite often in C++:
>
> mymap::iterator i( m.find( "key" ) );
> if( i != m.end() )
> {
> ..
> }
>
> Now a case could definately be made for using getXyz here, except for the cost incurred when an exception is thrown, plus the additional coding it would require:
>
> try
> {
> int i = m.getXyz( "key" );
> ..
> }
> catch( KeyNotFound e ) {}
>
> I haven't quite embraced exceptions so much that I use them for this level of flow control.  I would likely just ignore the getXyz call and fake it using the others.

I wouldn't write a library that placed that burden on its users. Stuff like that is shit, plain and simple.

> >To determine presence we must either return a boolean or sentinel value (e.g.
> >null). Given the dichotomy between null being a good (but not perfect)
sentinel
> >for object types, and 0/NaN being a bad sentinel for built-in types, I'd now suggest that we don't do that.
>
> Well, null could be returned for built-ins as well.  Always using pointers
would
> allow for in-place modification of values.  But then pointers are potentially unsafe, so it's a tough issue.
>
> >1.  Return the value, pass the presence as an out parameter
> >
> >    value_type findXyz(key_type key, out bool bPresent);
> >
> >2. Return the presence, pass the value as an out parameter
> >
> >    bool findXyz(key_type key, out value_type value);
> >
> >I'd suggest here and now that neither of these are going to satisfy all circumstances. I'd further suggest, however, that we need to decide on one and stick to it.
>
> I agree.  I think that it would make more sense to return the bit value.  It would maintain syntactic consistency with a contains() call and allow us to
find
> the value and check for success in a single expression.
>
> >btw, considering all this, it now seems to me that the above definition of findXyz(), incorporating a default value, is quite wrong. That should be
called
> >something else, findWithDefault[Xyz](), or something less ugly.
>
> I agree.  A defaulting version is great just so long as it's not the only option.
>
> (more later, I think I'm being summoned to do more vacation stuff :)

Cool. Let me know what you think of my 5-member taxonomy of indexed access, in the reposted thread.