digitalmars.D - Get vs Test method naming convention
- Matthew (27/27) Jul 14 2004 I'd like to solicit opinion on method naming conventions.
- Stewart Gordon (20/35) Jul 14 2004 At the moment, associative arrays return the value or the value type's
- Ivan Senji (18/53) Jul 14 2004 opIn would be really great (although it is now a part of an expression a...
- Matthew (17/77) Jul 14 2004 I like opIn, but that's only useful when a given "container" can contain...
- Stewart Gordon (16/33) Jul 14 2004 What do you mean by this?
- Ivan Senji (23/63) Jul 14 2004 and
- Stewart Gordon (34/55) Jul 14 2004 Similarly
- Ivan Senji (29/84) Jul 14 2004 Ignore this! I said something stupid :)
- Stewart Gordon (24/28) Jul 14 2004 AAs store values too.
- Regan Heath (17/40) Jul 14 2004 Or opHas :) I think changing the order of the expression using contains ...
- Andy Friesen (9/31) Jul 14 2004 It may be contradictory, but the meaning is completely clear and it's
- Sean Kelly (5/10) Jul 14 2004 I wouldn't mind having better support for hash sets in D. I ended up us...
- Arcane Jill (7/8) Jul 14 2004 what on Earth is wrong with
- Matthew (7/15) Jul 14 2004 Is this a genuine, considered response, or are you just seeking to waste...
- Arcane Jill (16/25) Jul 14 2004 Is this a genuine, considered question, or are you just in a bad mood fo...
- Matthew (28/53) Jul 14 2004 Not in a bad mood. Short on time. Short on patience.
- Sean Kelly (6/9) Jul 14 2004 Darn, and I like the C++ naming scheme. I suppose empty() is an odd cas...
- Matthew (8/17) Jul 14 2004 and
- Andy Friesen (13/51) Jul 14 2004 I think Python really nailed this one on the head. It does pretty much
- Matthew (16/66) Jul 14 2004 or
- Andy Friesen (4/13) Jul 14 2004 errrr sorry. Python does precisely what you suggested with respect to
- Daniel Horn (9/49) Jul 14 2004 I, for one, will be storing builtin types much (over 50%) of the time.
- Matthew (21/70) Jul 14 2004 Fair point
- Daniel Horn (29/127) Jul 14 2004 Not sure you cover all the cases... we need something that returns a
- Matthew (25/152) Jul 14 2004 Not to be a pedantic fop, but isn't one of the purposes of associative c...
- Sean Kelly (7/19) Jul 14 2004 I don't like the new findXyz semantics. The new function requires that ...
- Matthew (46/69) Jul 14 2004 presence
- Sean Kelly (30/54) Jul 14 2004 I don't have a concrete example offhand, except that I do this quite oft...
- Regan Heath (20/116) Jul 14 2004 I like #2, it allows this...
- Matthew (8/134) Jul 14 2004 Ok, but remember, my purpose here is to establish naming conventions. I ...
- Sean Kelly (11/25) Jul 15 2004 I never asked this, but what's with the Xyz bit? Why not just contains,...
- Matthew (38/65) Jul 15 2004 boolean
- Sean Kelly (13/29) Jul 14 2004 Perhaps a bit off-topic, but why no iterators in D? How else are we goi...
- Matthew (12/35) Jul 14 2004 or
- Daniel Horn (11/57) Jul 15 2004 can't you just use the typeof operator in the function "name"
- Matthew (16/74) Jul 15 2004 have
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?
Jul 14 2004
Matthew wrote: <snip>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.At the moment, associative arrays return the value or the value type's .init, which is of course null for classes. But in general, a value can itself be null, and sometimes it's useful to be able to distinguish between the two cases. But yes, I guess it can be useful to have null indicating absence of the element. But AAs versus LAs are already inconsistent here, and you could say we're stuck with this now. Guess it's a matter of remembering to documenting your class....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.<snip> C. the approach you suggested further down. We ought to have an opIn. But because it's really the RHS type of such an expression that wants to control the behaviour, there are complications with naming/priority. Meanwhile, mine uses contains. 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.
Jul 14 2004
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:cd32i7$1af9$1 digitaldaemon.com...Matthew wrote: <snip>opIn would be really great (although it is now a part of an expression and not an operator) 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. I use contains also :)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.At the moment, associative arrays return the value or the value type's .init, which is of course null for classes. But in general, a value can itself be null, and sometimes it's useful to be able to distinguish between the two cases. But yes, I guess it can be useful to have null indicating absence of the element. But AAs versus LAs are already inconsistent here, and you could say we're stuck with this now. Guess it's a matter of remembering to documenting your class....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.<snip> C. the approach you suggested further down. We ought to have an opIn. But because it's really the RHS type of such an expression that wants to control the behaviour, there are complications with naming/priority. Meanwhile, mine uses contains.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.
Jul 14 2004
I like opIn, but that's only useful when a given "container" can contain only one type of element. I'm currently working on a mapping to D of my Open-RJ library (shortly to be released on SF, under BSD) which is an implementation of the Record-Jar format. (And only 5KB!) A database contains records, and records contains fields. However, it's also useful to be able to treat a database as a collection of fields. Hence, the Database class allows access to Fields and/or to Records. As such, opIn (or contains) would only work for Record (since record is the value_type of Database). When wanting to to deduce whether a given field was in the database, I'm suggesting I'd the findField() syntax. I'm just as happy to call it containsField() as findField(), in fact I like that a bit better. The point I want to discuss is that we have an identified convention for the two forms of index/key based retrieval: return null-value on failure, and throw-exception on failure. "Ivan Senji" <ivan.senji public.srce.hr> wrote in message news:cd34m0$1e01$1 digitaldaemon.com..."Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:cd32i7$1af9$1 digitaldaemon.com...Matthew wrote: <snip>opIn would be really great (although it is now a part of an expression and not an operator) 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. I use contains also :)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.At the moment, associative arrays return the value or the value type's .init, which is of course null for classes. But in general, a value can itself be null, and sometimes it's useful to be able to distinguish between the two cases. But yes, I guess it can be useful to have null indicating absence of the element. But AAs versus LAs are already inconsistent here, and you could say we're stuck with this now. Guess it's a matter of remembering to documenting your class....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.<snip> C. the approach you suggested further down. We ought to have an opIn. But because it's really the RHS type of such an expression that wants to control the behaviour, there are complications with naming/priority. Meanwhile, mine uses contains.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.
Jul 14 2004
Ivan Senji wrote: <snip>opIn would be really great (although it is now a part of an expression and not an operator)What do you mean by this?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. You are referred back to http://www.digitalmars.com/drn-bin/wwwnews?D/24177 http://www.digitalmars.com/drn-bin/wwwnews?D/24217 And anyway, that has nothing to do with the OP's question. 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.
Jul 14 2004
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:cd3930$1lhc$1 digitaldaemon.com...Ivan Senji wrote: <snip>andopIn would be really great (although it is now a part of an expressionI 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.not an operator)What do you mean by this?theAnd 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 thatI 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. 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.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. You are referred back to http://www.digitalmars.com/drn-bin/wwwnews?D/24177 http://www.digitalmars.com/drn-bin/wwwnews?D/24217Yes i remember those posts.char [] x = "a string"; if ( "string" in x ) puts("matched");I agree that this makes no sence, but i don't agree that if it was defined for normal arrays that it would have to check for the index bounds. Mathew posted then:char [] x = "a string"; if ( ' ' in x ) { puts("matched"); }And this is what i would like. Associative arrays are for storing the key type, and normal arrays are for storing the type of array.And anyway, that has nothing to do with the OP's question.Whose question? :)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.
Jul 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>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.You've just contradicted yourself. In AAs, it works by checking if aI 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.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.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.And anyway, that has nothing to do with the OP's question.Whose question? :)
Jul 14 2004
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:cd3kj2$28hd$1 digitaldaemon.com...Ivan Senji wrote: <snip>Ignore this! I said something stupid :)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>itYou've just contradicted yourself. In AAs, it works by checking if aI don't think i have. You use associative arrays to store the keys, soI 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.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] == XExactly :)This is an inconsistency up with which plenty of us (not to mention generic programmers) will not put.It isn't completelly different, AAs store keys, and normal arrays store values. In is for testing is an element contained in an array.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>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?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.OP = Original Poster. The person who started the thread.And anyway, that has nothing to do with the OP's question.Whose question? :)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.
Jul 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.
Jul 14 2004
On Wed, 14 Jul 2004 19:31:51 +0100, Stewart Gordon <smjg_1998 yahoo.com> wrote:Ivan Senji wrote: <snip>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/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) ....
Jul 14 2004
Stewart Gordon wrote: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) { ... } -- andyAnd 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.
Jul 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
Jul 14 2004
In article <cd30iv$17m8$1 digitaldaemon.com>, Matthew says...Responses?what on Earth is wrong with ?
Jul 14 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cd34as$1dct$1 digitaldaemon.com...In article <cd30iv$17m8$1 digitaldaemon.com>, Matthew says...Is this a genuine, considered response, or are you just seeking to waste my eye-time? I take it you feel built-in associative arrays represent the totality of associative containers we'll ever consider for D. I disagree, and am hoping to get some useful feedback in that regard.Responses?what on Earth is wrong with ?
Jul 14 2004
In article <cd359e$1f32$1 digitaldaemon.com>, Matthew says...Is this a genuine, considered response, or are you just seeking to waste my eye-time?Is this a genuine, considered question, or are you just in a bad mood for some reason? I assume you don't SERIOUSLY imagine that I would deliberately seek to waste your "eye-time". If you do imagine that, you must be a very paranoid individual. Why on /Earth/ would I do that? I've never even met you. Chill out, man. Go and have a cup of tea and stop taking everything so seriously.I take it you feel built-in associative arrays represent the totality of associative containers we'll ever consider for D.No you don't. You just said that to be sarcastic. R-e-l-a-x. When I said:what on Earth is wrong withperhaps I should have said, what on Earth is wrong with but it's the same difference. Now come on, be nice to me... Jill
Jul 14 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cd37j6$1j7b$1 digitaldaemon.com...In article <cd359e$1f32$1 digitaldaemon.com>, Matthew says...Not in a bad mood. Short on time. Short on patience. Your response smacked of being half-considered, and more rejoinder for rejoinder's sake. It still seems like that now.Is this a genuine, considered response, or are you just seeking to waste my eye-time?Is this a genuine, considered question, or are you just in a bad mood for some reason?I assume you don't SERIOUSLY imagine that I would deliberately seek to waste your "eye-time". If you do imagine that, you must be a very paranoidindividual.Why on /Earth/ would I do that? I've never even met you. Chill out, man. Go and have a cup of tea and stop taking everything so seriously.Well, it was a sarcastic way of saying "what an ill-considered response". I guess I was being gutless in doing the former, rather than saying the latter. I've girded my loins, and told you what I think. No longer gutless smartass. Now patronising prig. Which do you prefer?PerhapsI take it you feel built-in associative arrays represent the totality of associative containers we'll ever consider for D.No you don't. You just said that to be sarcastic. R-e-l-a-x. When I said:what on Earth is wrong withperhaps I should have said, what on Earth is wrong withbut it's the same difference. Now come on, be nice to me...This is nice. :) But you've still jumped straight in without considering my point. The in / contains returns a boolean. That's nice, and a useful feature. But I was talking about a syntactic convention for differentiating between two different value-returning types. In one case, we want an exception to be thrown, so we can write client code to not have to care about missing elements. In the other, we want a get-existing-or-return-null semantic. I do like opIn, and I do like the contains method. But I want comment on the naming for two value-returning types. I suggested getXyz and opIndex for the get-existing-or-throw-exception type, and findXyz (could be testXyz instead) for the get-existing-or-return-null type. This is what I'm interested in everyone's thoughts about. 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()" !! Hence, concensus is important. Thoughts everyone?
Jul 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
Jul 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...andThe reason I case is that such a thing can only be a convention, not a "law","empty()I want to avoid the crappy naming mess that is the C++ standard library:suppose=> 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 Iempty() 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.
Jul 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
Jul 14 2004
"Andy Friesen" <andy ikagames.com> wrote in message news:cd3muf$2cue$1 digitaldaemon.com...Matthew wrote:orI'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,end()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 thetheiterator 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 haverequested? postfix. I'd like to suggest a simple convention: - opIndex, where appropriate never returns null. Always returns thetestelement, 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 tomostexistence 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 inalsocases. However, there are some cases where they are used, so maybe we shouldIf 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.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.
Jul 14 2004
Matthew wrote: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.errrr sorry. Python does precisely what you suggested with respect to opIndex, so I didn't bother to mention it. -- andy
Jul 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?
Jul 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:orI'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,end()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 thetheiterator 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 haverequested? postfix. I'd like to suggest a simple convention: - opIndex, where appropriate never returns null. Always returns thetestelement, 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 tomostexistence 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 inalsocases. However, there are some cases where they are used, so maybe we shouldinclude a hasXyz() method, which returns a boolean indicator. Responses?
Jul 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:orI'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,end()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 thetheiterator 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 haverequested? postfix. I'd like to suggest a simple convention: - opIndex, where appropriate never returns null. Always returns thetestelement, 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 tomostexistence 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 inalsocases. However, there are some cases where they are used, so maybe we shouldinclude a hasXyz() method, which returns a boolean indicator. Responses?
Jul 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:throwFair point What about: - value_type getXyz(key_type key) returns the requested element, orpresenceInvalidKeyException - bool containsXyz(key_type key) returns true/false, indicatingtheof element - value_type findXyx(key_type key, value_type defaultValue) returnssinglerequested element, or the given default - opIndex() is a synonym for getXyz where the container has only asecondaryvalue_type, or its primary value_type is obviously delineated from anykey,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 givenhaveorend()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 theiterator 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'taddresstherequested? postfix. I'd like to suggest a simple convention: - opIndex, where appropriate never returns null. Always returns thetestelement, 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 toexistence 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 wethisthis now, by adopting a common convention. 2. We can't return a null-value for built-in types. I would suggest thatmostisn't a problem for most cases, since we aren't storing built-in types inalsocases. However, there are some cases where they are used, so maybe we shouldinclude a hasXyz() method, which returns a boolean indicator. Responses?
Jul 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
Jul 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...throwFair point What about: - value_type getXyz(key_type key) returns the requested element, orpresenceInvalidKeyException - bool containsXyz(key_type key) returns true/false, indicatingsingleof 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 asecondaryvalue_type, or its primary value_type is obviously delineated from anyeithervalue_types. I'm pretty happy with this picture. Votes?I don't like the new findXyz semantics. The new function requires that Iset 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?
Jul 14 2004
In article <cd4gnr$rp0$1 digitaldaemon.com>, Matthew says..."Sean Kelly" <sean f4.ca> wrote in message news:cd4dqj$m1f$1 digitaldaemon.com...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.In article <cd481o$adi$4 digitaldaemon.com>, Matthew says...I don't like the new findXyz semantics. The new function requires that Ieitherset 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?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
Jul 14 2004
"Sean Kelly" <sean f4.ca> wrote in message news:cd4ik2$vg7$1 digitaldaemon.com...In article <cd4gnr$rp0$1 digitaldaemon.com>, Matthew says...news:cd4dqj$m1f$1 digitaldaemon.com..."Sean Kelly" <sean f4.ca> wrote in messageblock.In article <cd481o$adi$4 digitaldaemon.com>, Matthew says...I don't like the new findXyz semantics. The new function requires that Ieitherset aside a potentially valid value to signal lookup failure, do two lookups (one for containsXyz and another for findXyz), or wrap getXyz in a tryaAnother possibility would be to offer two versions of findXyz, one acceptingI wouldn't write a library that placed that burden on its users. Stuff like that is shit, plain and simple.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.default and one returning a pointer?Can you provide a quick sample of using a findXyz() that illustrates your requirement?sentinelTo 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)wouldfor 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 pointersallow for in-place modification of values. But then pointers are potentially unsafe, so it's a tough issue.find1. 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 tothe value and check for success in a single expression.calledbtw, considering all this, it now seems to me that the above definition of findXyz(), incorporating a default value, is quite wrong. That should beCool. Let me know what you think of my 5-member taxonomy of indexed access, in the reposted thread.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 :)
Jul 14 2004
"Sean Kelly" <sean f4.ca> wrote in message news:cd4ik2$vg7$1 digitaldaemon.com...In article <cd4gnr$rp0$1 digitaldaemon.com>, Matthew says...news:cd4dqj$m1f$1 digitaldaemon.com..."Sean Kelly" <sean f4.ca> wrote in messageblock.In article <cd481o$adi$4 digitaldaemon.com>, Matthew says...I don't like the new findXyz semantics. The new function requires that Ieitherset aside a potentially valid value to signal lookup failure, do two lookups (one for containsXyz and another for findXyz), or wrap getXyz in a tryaAnother possibility would be to offer two versions of findXyz, one acceptingI wouldn't write a library that placed that burden on its users. Stuff like that is shit, plain and simple.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.default and one returning a pointer?Can you provide a quick sample of using a findXyz() that illustrates your requirement?sentinelTo 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)wouldfor 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 pointersallow for in-place modification of values. But then pointers are potentially unsafe, so it's a tough issue.find1. 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 tothe value and check for success in a single expression.calledbtw, considering all this, it now seems to me that the above definition of findXyz(), incorporating a default value, is quite wrong. That should beCool. Let me know what you think of my 5-member taxonomy of indexed accesssomething 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 :)
Jul 14 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...if (findXyz("regan",value)) { } value = findXyz("regan",r); if (r) { }In article <cd481o$adi$4 digitaldaemon.com>, Matthew says...throwFair point What about: - value_type getXyz(key_type key) returns the requestedelement, orpresenceInvalidKeyException - bool containsXyz(key_type key) returns true/false, indicatingsingleof element - value_type findXyx(key_type key, value_type defaultValue)returns therequested element, or the given default - opIndex() is a synonym for getXyz where the container hasonly asecondaryvalue_type, or its primary value_type is obviously delineated from anyeithervalue_types. I'm pretty happy with this picture. Votes?I don't like the new findXyz semantics. The new function requires that Iset 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.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/
Jul 14 2004
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsa5kr4zf5a2sq9 digitalmars.com...On Thu, 15 Jul 2004 09:47:52 +1000, Matthew <admin stlsoft.dot.dot.dot.dot.org> wrote:Ok, but remember, my purpose here is to establish naming conventions. I am not concerned with whether or not a given container should have all of the above types of methods."Sean Kelly" <sean f4.ca> wrote in message news:cd4dqj$m1f$1 digitaldaemon.com...if (findXyz("regan",value)) { } value = findXyz("regan",r); if (r) { }In article <cd481o$adi$4 digitaldaemon.com>, Matthew says...throwFair point What about: - value_type getXyz(key_type key) returns the requestedelement, orpresenceInvalidKeyException - bool containsXyz(key_type key) returns true/false, indicatingsingleof element - value_type findXyx(key_type key, value_type defaultValue)returns therequested element, or the given default - opIndex() is a synonym for getXyz where the container hasonly asecondaryvalue_type, or its primary value_type is obviously delineated from anyeithervalue_types. I'm pretty happy with this picture. Votes?I don't like the new findXyz semantics. The new function requires that Iset 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.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).Cool. Unless I get strong objections to the contrary, or, heaven forfend, and opinion from big-W, I'll proceed on these lines over the next few days. (I can always search and replace later ... <g>)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.
Jul 14 2004
In article <cd4gnr$rp0$1 digitaldaemon.com>, Matthew says...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.I never asked this, but what's with the Xyz bit? Why not just contains, get, etc? Otherwise... 1. Sounds good 2. Agreed... this seems consistent with (the revised version of) C++ vectors anyway. An alternative would be to have range checking done using DBC and additionally throw exceptions in the release version. 3. Yes 4. Agreed. Se could really use find() for both because of overloading rules, but perhaps a different name would be clearer? Sean
Jul 15 2004
"Sean Kelly" <sean f4.ca> wrote in message news:cd6ehj$29hh$1 digitaldaemon.com...In article <cd4gnr$rp0$1 digitaldaemon.com>, Matthew says...booleanLeaving us with the following lookup "conventions": 1. Testing - opIn and/or contains() and/or containsXyz() - returns anumberindicating presence or absence. (We might even say an int, returning thesendof 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() (pleaseReturnsin better suggestions! <g> - takes a key_type and a default value_type.andthe default if the key is not present. 5. Creating Lookup - findOrInsert() or findOrInsertXyz() - takes key_typeBecause sometimes a container might be able to provide different types of things. The Open-RJ project (have a little look at http://gregpeet.com/_orj/ for a sneak at it; it'll soon be available at openrj.org) is just such a thing. A database consists of records, which are consisted of fields. A field is a name + optional value. An example Open-RJ file would be: %% Arturius Compiler Multiplexer Processor Configuration %% Updated: 22nd June 2004 ProcessorType: Script ScriptType: Ruby ProcessorPath: ruby %% ProcessorType: Script ScriptType: Python ProcessorPath: python %% ProcessorType: Script ScriptType: Perl ProcessorPath: perl %% The value_type of the Database class is Record. So its contains(), get(), find() methods would talk Record. However, it's also possible to just deal with all the fields in the database, without considering what records they're in. So it's also got containsField(), getField(), findFiled() etc."new" value_type. Returns the existing one, or inserts the new one if none existing.I never asked this, but what's with the Xyz bit? Why not just contains, get, etc? Otherwise...1. Sounds good 2. Agreed... this seems consistent with (the revised version of) C++ vectors anyway. An alternative would be to have range checking done using DBC and additionally throw exceptions in the release version.This is an interesting one. If it was C++, and the lookup was only on index (i.e. subscripting), I'd probably go for DbC and crashing, putting the onus on client code to ensure a valid index. But because we're talking generally, and might lookup by name, and might want to support docRoot["Blah"]["Waffle"] style coding, exception is necessary for some cases. IMO its better for all containers to be consistent, so I think all should throw exceptions3. Yes 4. Agreed. Se could really use find() for both because of overloading rules, but perhaps a different name would be clearer?I think that's important, yes. :) Thanks for the feedback. I think we've got a pretty clear convention here.
Jul 15 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
Jul 14 2004
"Sean Kelly" <sean f4.ca> wrote in message news:cd413g$2u54$1 digitaldaemon.com...In article <cd30iv$17m8$1 digitaldaemon.com>, Matthew says...orI'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,end()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 thetheiterator 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 haveAs I'm finding, and will want to discuss publicly soon, algorithms are seeming pretty darn near impossible without implicit instantiation. So we can create iterators quite nicely, but getting compile-time selection of type is not possible, at least not so far as I've thought about it (which, admittedly, is not terribly far). I'm going to start a discussion on this on the dtl ng in the next couple of days. For now, I want to get some basic parts of DTL moving and out there for criticism.? 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).
Jul 14 2004
Matthew wrote:"Sean Kelly" <sean f4.ca> wrote in message news:cd413g$2u54$1 digitaldaemon.com...can't you just use the typeof operator in the function "name" instead of doing sort (a.begin(),a.end()); do sort!(typeof(a.begin()),typeof(a.end())) (a.begin(),a.end()) this really sounds like a case where having a preprocessor would be nice! (gcc -E) #define sort (a,b) sort_template!(typeof(a),typeof(b))(a,b) with macros we could do autoinstantiation... this possible with mixins?...I can't think of a wayIn article <cd30iv$17m8$1 digitaldaemon.com>, Matthew says...orI'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,end()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 thetheiterator 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 haveAs I'm finding, and will want to discuss publicly soon, algorithms are seeming pretty darn near impossible without implicit instantiation. So we can create iterators quite nicely, but getting compile-time selection of type is not possible, at least not so far as I've thought about it (which, admittedly, is not terribly far). I'm going to start a discussion on this on the dtl ng in the next couple of days. For now, I want to get some basic parts of DTL moving and out there for criticism.? 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).
Jul 15 2004
"Daniel Horn" <hellcatv hotmail.com> wrote in message news:cd6fh8$29s0$1 digitaldaemon.com...Matthew wrote:have"Sean Kelly" <sean f4.ca> wrote in message news:cd413g$2u54$1 digitaldaemon.com...In article <cd30iv$17m8$1 digitaldaemon.com>, Matthew says...orI'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,end()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 theiterator 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'tusethe? 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 toofbecause all template arguments must be explicitly specified (the one featureseemingD that makes me occasionally gnash my teeth in frustration).As I'm finding, and will want to discuss publicly soon, algorithms arenotpretty darn near impossible without implicit instantiation. So we can create iterators quite nicely, but getting compile-time selection of type is not possible, at least not so far as I've thought about it (which, admittedly, isnextterribly far). I'm going to start a discussion on this on the dtl ng in theThat's an interesting one. Of course, we'd only need the one typeof, since iterators should be of the same type. I'll bear it in mind. Actually, I'm working on alternative approaches to iterators at the moment. I don't see iterators as being anywhere near as relevant in D as they are in C++. My plan is to hack away a couple more days, and then release what I have for use/criticism. Hopefully then I can enjoy the benefit of everyone's wisdom in the areas I've not explored, or have failed to explore adequately. More soon ...couple of days. For now, I want to get some basic parts of DTL moving and out there for criticism.can't you just use the typeof operator in the function "name" instead of doing sort (a.begin(),a.end()); do sort!(typeof(a.begin()),typeof(a.end())) (a.begin(),a.end()) this really sounds like a case where having a preprocessor would be nice! (gcc -E) #define sort (a,b) sort_template!(typeof(a),typeof(b))(a,b) with macros we could do autoinstantiation... this possible with mixins?...I can't think of a way
Jul 15 2004