digitalmars.D - Why is array truth tied to .ptr?
- Bill Baxter (47/47) Dec 09 2007 Here's a little test program:
- Bill Baxter (5/5) Dec 09 2007 BTW, if someone does feel the current behavior is more rational or
- Janice Caron (13/17) Dec 10 2007 Personally, I'd prefer if(array) to fail to compile, because I don't
- Bill Baxter (10/32) Dec 10 2007 I also would prefer an error to the current behavior of doing something
- Bruce Adams (23/49) Dec 10 2007 e:
- Robert Fraser (3/8) Dec 10 2007 Optional warnings are also a planned feature for Descent. But that's the...
- Derek Parnell (25/32) Dec 09 2007 I'm guessing that this behaviour is due to the commonly used idiom for a...
- Daniel Keep (9/22) Dec 09 2007 I actually went and created a pseudo-property for just this purpose:
- Janice Caron (12/17) Dec 10 2007 What is relevant to this whole question is the fact the I recall
- Daniel Keep (20/40) Dec 10 2007 I never suggested z and nz as standard names; that would be a ridiculous
- Robert Fraser (3/5) Dec 10 2007 That gives me the answer to the Object.toString() vs. Object.toUtf8()
- Daniel Keep (10/16) Dec 10 2007 '?' is used for function that check a property of a type, '!' is used
- Leandro Lucarella (74/95) Dec 11 2007 One thing that I think Ruby doesn't have is automatic not-in-place
- renoX (15/117) Dec 11 2007 I like it but I think that the calls are a bit confusing:
- Robert DaSilva (5/59) Dec 11 2007 Don't you mean t.dup.sort(). t.sort.dup() would do a inplace sort and
- Leandro Lucarella (18/29) Dec 11 2007 Ok, good catch, maybe that syntax is not right but you missed the big
- Robert DaSilva (4/28) Dec 11 2007 I'm just saying that t.sort.dup() can *only* mean sort t then duplicate
- Leandro Lucarella (9/22) Dec 12 2007 I was talking about a new feature proposal. I know it doesn't work now.
- Robert DaSilva (6/22) Dec 12 2007 I'm say it could *NEVER* work because that already has a well defined
- Leandro Lucarella (12/39) Dec 13 2007 From my first e-mail:
- Oskar Linde (18/43) Dec 13 2007 One convention I have grown comfortable with is using the adjective form...
- Bill Baxter (6/26) Dec 10 2007 Agreed. I might be ok with "zero" and "nonzero" but I'd rather have it
- Bill Baxter (3/38) Dec 09 2007 I'm just too lazy to type that much. :-)
- 0ffh (9/17) Dec 09 2007 While I'm not used to this shorthand (as I don't regularly meddle in thi...
- Robert Fraser (2/65) Dec 09 2007 me too
Here's a little test program: void main() { void check(int[] l) { if (l) writef("%-10s","true"); else writef("%-10s","false"); writef("%-10s", (l is null)); writef("%-10s", (l.length==0)); writefln; } int[] list; writefln("%-10s%-10s%-10s%-10s", " ", "is true","is null","length==0"); writef("%-10s","initial"); check(list); list = new int[10]; list = null; writef("%-10s","nulled"); check(list); list = new int[10]; list.length = 0; writef("%-10s", "zeroed"); check(list); } and here's the table it generates: is true is null length==0 initial false true true nulled false true true zeroed true false true Question: which is the bit of information you are more likely interested in knowing: a) whether the array is currently empty. b) whether the array happens to have a buffer of some unknowable length allocated because of a previous history of operations on it. If you answered a) then we think alike. So why does the simplest check if(array) { ... } tell us b) ? In a nutshell, if(array) is synonymous with if(array.ptr) but I believe it makes much more sense for it to be synonymous with if(array.length) since that's the thing you want to be checking 99.9% of the time. A little while ago I realized I was making the mistake of checking if(array) all over my code. It makes a lot of sense to do that if you know Python, since that's how Python works. But I think Python's way makes a lot more sense than D's way. So it's hard to remember that the simple and clear if(array) is almost always a bug waiting to happen. --bb
Dec 09 2007
BTW, if someone does feel the current behavior is more rational or functional in some way, then I'd love to hear it. Perhaps it's my familiarity with Python, but I just don't get why you'd want if(array) to mean anything other than if(array.length). --bb
Dec 09 2007
On Dec 10, 2007 2:01 AM, Bill Baxter <dnewsgroup billbaxter.com> wrote:BTW, if someone does feel the current behavior is more rational or functional in some way, then I'd love to hear it. Perhaps it's my familiarity with Python, but I just don't get why you'd want if(array) to mean anything other than if(array.length).Personally, I'd prefer if(array) to fail to compile, because I don't like the idea of implicit conversions to bool. That would force you to say what you mean - i.e. either if (array.length == 0) or if (array is null) I suspect the current behaviour really means if (array.ptr == null && array.length == 0) which is not entirely unreasonable. Certainly, in the case of strings (as special type of array) the current behaviour allows one to distinguish between an unassigned string and an empty string - which is occasionally desirable.
Dec 10 2007
Janice Caron wrote:On Dec 10, 2007 2:01 AM, Bill Baxter <dnewsgroup billbaxter.com> wrote:I also would prefer an error to the current behavior of doing something unintuitive that looks like it works correctly but in fact does something slightly different.BTW, if someone does feel the current behavior is more rational or functional in some way, then I'd love to hear it. Perhaps it's my familiarity with Python, but I just don't get why you'd want if(array) to mean anything other than if(array.length).Personally, I'd prefer if(array) to fail to compile, because I don't like the idea of implicit conversions to bool. That would force you to say what you mean - i.e. either if (array.length == 0) or if (array is null)I suspect the current behaviour really means if (array.ptr == null && array.length == 0)I guess you are free to look at it it that way, however if you look at the truth table I posted in the original message, the array.length == 0 is redundant there. if array.ptr is null length is always zero.which is not entirely unreasonable. Certainly, in the case of strings (as special type of array) the current behaviour allows one to distinguish between an unassigned string and an empty string - which is occasionally desirable.If the default were changed to check array.length you could still achieve that by explicitly checking "if(array.ptr)" --bb
Dec 10 2007
On Mon, 10 Dec 2007 09:07:13 -0000, Bill Baxter = <dnewsgroup billbaxter.com> wrote:Janice Caron wrote:e:On Dec 10, 2007 2:01 AM, Bill Baxter <dnewsgroup billbaxter.com> wrot=y)BTW, if someone does feel the current behavior is more rational or functional in some way, then I'd love to hear it. Perhaps it's my familiarity with Python, but I just don't get why you'd want if(arra=to mean anything other than if(array.length).Personally, I'd prefer if(array) to fail to compile, because I don't=olike the idea of implicit conversions to bool. That would force you t=g =say what you mean - i.e. either if (array.length =3D=3D 0) or if (array is null)I also would prefer an error to the current behavior of doing somethin=unintuitive that looks like it works correctly but in fact does =something slightly different.I suspect you are moving into the realms of lint here. I would say it = should not even be a warning in the core language. In linted variant you are free to enforce stricter rules. I thought I saw a link to a dlint someti= me ago.=I suspect the current behaviour really means if (array.ptr =3D=3D null && array.length =3D=3D 0)I guess you are free to look at it it that way, however if you look at=the truth table I posted in the original message, the array.length =3D==3D 0 =is redundant there. if array.ptr is null length is always zero.I think her point was that its not redundant for the case of array.ptr != =3D 0 as in: foo[5] x; //not initialised if (x) { ... }which is not entirely unreasonable. Certainly, in the case of strings=(as special type of array) the current behaviour allows one to distinguish between an unassigned string and an empty string - which is occasionally desirable.If the default were changed to check array.length you could still =achieve that by explicitly checking "if(array.ptr)"True. The default should be what is most useful in practice.
Dec 10 2007
Bruce Adams wrote:I suspect you are moving into the realms of lint here. I would say it should not even be a warning in the core language. In linted variant you are free to enforce stricter rules. I thought I saw a link to a dlint sometime ago.Optional warnings are also a planned feature for Descent. But that's the future.
Dec 10 2007
On Mon, 10 Dec 2007 10:52:00 +0900, Bill Baxter wrote:In a nutshell, if(array) is synonymous with if(array.ptr) but I believe it makes much more sense for it to be synonymous with if(array.length) since that's the thing you want to be checking 99.9% of the time.I'm guessing that this behaviour is due to the commonly used idiom for all reference types, namely that the test is against the 'pointer' value rather than any other aspect of the item being referenced. class Foo {}; Foo f = new Foo(); Foo g; if (f) ... if (g) ... long *lp; if (lp) ... Personally, I regard this as a shorthand option that should be avoided on legibility grounds. I prefer the more explicit versions ... if (array.ptr !is null) if (array.length != 0) if (f !is null) if (lp !is null) only because this is harder to misunderstand. -- Derek (skype: derek.j.parnell) Melbourne, Australia 10/12/2007 2:17:38 PM
Dec 09 2007
Derek Parnell wrote:... Personally, I regard this as a shorthand option that should be avoided on legibility grounds. I prefer the more explicit versions ... if (array.ptr !is null) if (array.length != 0) if (f !is null) if (lp !is null) only because this is harder to misunderstand.I actually went and created a pseudo-property for just this purpose: /// Tests the array to see if it's of non-zero length. bool nz(T)(T arr) { return arr.length != 0; } /// Tests the array to see if it's of zero length. bool z(T)(T arr) { return arr.length == 0; } if( "foo".nz() || "bar".z() ) ... Much quicker to type, and more legible (at least, for me.) -- Daniel
Dec 09 2007
On Dec 10, 2007 4:21 AM, Daniel Keep <daniel.keep.lists gmail.com> wrote:I actually went and created a pseudo-property for just this purpose: /// Tests the array to see if it's of non-zero length. bool nz(T)(T arr) { return arr.length != 0; } /// Tests the array to see if it's of zero length. bool z(T)(T arr) { return arr.length == 0; }What is relevant to this whole question is the fact the I recall Walter saying he was thinking of changing the representation of an array from struct { ptr, length } to struct { ptr, end }. I suggested at that time that all arrays should be given an isEmpty property, because isEmpty() is just a sensible idea for collections in general. I have to say though, that I don't like the function names z() and nz(). I don't equate "zero" with "zero length". To me, the only meaning I could attribute to "is zero" would be "is full of zeroes". That is, I would expect the array [ 0, 0, 0, 0 ] to pass a test called z() and fail a test called nz(). That's why I'd suggest isEmpty() as the preferred name.
Dec 10 2007
Janice Caron wrote:On Dec 10, 2007 4:21 AM, Daniel Keep <daniel.keep.lists gmail.com> wrote:I never suggested z and nz as standard names; that would be a ridiculous proposition, as I doubt many people would be able to work out what they meant at first glance. I use them because a. they're shorter than isEmpty and !isEmpty, b. I'm lazy when it comes to typing and c. because they're actually named after jnz and jz from assembler, which I don't expect *anyone* to pick up on. I'm not a big fan of 'isEmpty' because I think it's too long, *and* it requires me to hit shift [1]. 'empty' would be OK, but then that's both a noun and a verb, which leads to ambiguity over exactly what it does. [2] All things considered, 'isEmpty' is probably the best choice for inclusion as a standard property. That said, I'll keep my lovely .z & .nz properties. :) -- Daniel [1] I realise the irony of this, in that .z and .nz require me to type a set of parens. None the less, I find typing '.z()' much faster and easier than '.isEmpty' due to the way my hands move as I type. [2] Sometimes, I really wish '?' and '!' were valid characters in identifiers, like in Ruby.I actually went and created a pseudo-property for just this purpose: /// Tests the array to see if it's of non-zero length. bool nz(T)(T arr) { return arr.length != 0; } /// Tests the array to see if it's of zero length. bool z(T)(T arr) { return arr.length == 0; }What is relevant to this whole question is the fact the I recall Walter saying he was thinking of changing the representation of an array from struct { ptr, length } to struct { ptr, end }. I suggested at that time that all arrays should be given an isEmpty property, because isEmpty() is just a sensible idea for collections in general. I have to say though, that I don't like the function names z() and nz(). I don't equate "zero" with "zero length". To me, the only meaning I could attribute to "is zero" would be "is full of zeroes". That is, I would expect the array [ 0, 0, 0, 0 ] to pass a test called z() and fail a test called nz(). That's why I'd suggest isEmpty() as the preferred name.
Dec 10 2007
Daniel Keep wrote:[2] Sometimes, I really wish '?' and '!' were valid characters in identifiers, like in Ruby.That gives me the answer to the Object.toString() vs. Object.toUtf8() problem posed before... just change it to Object.wtf?()
Dec 10 2007
Robert Fraser wrote:Daniel Keep wrote:'?' is used for function that check a property of a type, '!' is used for functions that perform in-place modification. if( "my string".empty? ) [3,1,2].sort --> int[] [3,1,2].sort! --> void Without "?", you can get away by putting "is" in front of everything, but "!" is a hard one, unless you come up with some sort of trailing sigil using normal characters (like _ip). -- Daniel[2] Sometimes, I really wish '?' and '!' were valid characters in identifiers, like in Ruby.That gives me the answer to the Object.toString() vs. Object.toUtf8() problem posed before... just change it to Object.wtf?()
Dec 10 2007
Daniel Keep, el 11 de diciembre a las 13:37 me escribiste:Robert Fraser wrote:One thing that I think Ruby doesn't have is automatic not-in-place function generation. I mean, if I have implemented SomeClass.sort! but not SomeClass.sort, the later can be created by copying the object, sorting the copy in-place and returning that copy. You can see it as a copy constructor in C++, which is generated by default by the compiler, if you don't provide one. In D it could be something like: class T { void sort() { // in-place sort implementation } T dupsort() // default compiler implementation { auto t = new T(this); t.sort(); return t; } } I think the regular name in D should be used for the in-place version, and dup<name> (or d<name> for short) could be used for the copying version, because there is also a well known .dup property (and I think it fits better in D the in-place because of it's high performance orientation). Maybe some syntactic sugar can be used too when using the dup version, something like: auto t = new T(); auto w = t.sort.dup(); // calls dupsort() You can see it as function were objects (like in Python, or Ruby AFAIK) which has a property "dup" =) Which makes me think that it could be defined as: class T { void sort() { // in-place sort implementation T dup() // default compiler implementation { auto t = new T(this); t.sort(); return t; } } } The dup() nested function could be not present (if the default implementation is enought(). I know we have a problem to access to dup() nested function because it needs a stack frame, but maybe the compiler can be aware of that and use it as a special case. Or maybe we can use the syntax for pre/post conditions: class T { void sort() body { // in-place sort implementation } dup // default compiler implementation { auto t = new T(this); t.sort(); return t; } } Again, you should only have to provide a dup function if the compilers default is not enought. Too much? =) -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Y tuve amores, que fue uno sólo El que me dejó de a pie y me enseñó todo...Daniel Keep wrote:'?' is used for function that check a property of a type, '!' is used for functions that perform in-place modification. if( "my string".empty? ) [3,1,2].sort --> int[] [3,1,2].sort! --> void Without "?", you can get away by putting "is" in front of everything, but "!" is a hard one, unless you come up with some sort of trailing sigil using normal characters (like _ip).[2] Sometimes, I really wish '?' and '!' were valid characters in identifiers, like in Ruby.That gives me the answer to the Object.toString() vs. Object.toUtf8() problem posed before... just change it to Object.wtf?()
Dec 11 2007
Leandro Lucarella a écrit :Daniel Keep, el 11 de diciembre a las 13:37 me escribiste:I like it but I think that the calls are a bit confusing: - t.dup.sort(): duplicate t then sort in-place the duplicate. - t.sort().dup: sort in-place t then duplicate it. - t.sort.dup(): by default duplicate t then sort in-place the duplicate, so it's the equivalent of t.dup.sort() except that it can be overloaded in the sort function to provide a faster implementation. OK, it all make sense when you look closely and it's D-ish but it's also a pitfall: "t.sort().dup" and "t.sort.dup()" do very different things yet look very very similar.. The ruby way is more concise and less risky IMHO (though a bit obscure for beginners/non-rubyist). I wish that D have copied more things from Ruby's syntax which I like very much.. renoXRobert Fraser wrote:One thing that I think Ruby doesn't have is automatic not-in-place function generation. I mean, if I have implemented SomeClass.sort! but not SomeClass.sort, the later can be created by copying the object, sorting the copy in-place and returning that copy. You can see it as a copy constructor in C++, which is generated by default by the compiler, if you don't provide one. In D it could be something like: class T { void sort() { // in-place sort implementation } T dupsort() // default compiler implementation { auto t = new T(this); t.sort(); return t; } } I think the regular name in D should be used for the in-place version, and dup<name> (or d<name> for short) could be used for the copying version, because there is also a well known .dup property (and I think it fits better in D the in-place because of it's high performance orientation). Maybe some syntactic sugar can be used too when using the dup version, something like: auto t = new T(); auto w = t.sort.dup(); // calls dupsort() You can see it as function were objects (like in Python, or Ruby AFAIK) which has a property "dup" =) Which makes me think that it could be defined as: class T { void sort() { // in-place sort implementation T dup() // default compiler implementation { auto t = new T(this); t.sort(); return t; } } } The dup() nested function could be not present (if the default implementation is enought(). I know we have a problem to access to dup() nested function because it needs a stack frame, but maybe the compiler can be aware of that and use it as a special case. Or maybe we can use the syntax for pre/post conditions: class T { void sort() body { // in-place sort implementation } dup // default compiler implementation { auto t = new T(this); t.sort(); return t; } } Again, you should only have to provide a dup function if the compilers default is not enought. Too much? =)Daniel Keep wrote:'?' is used for function that check a property of a type, '!' is used for functions that perform in-place modification. if( "my string".empty? ) [3,1,2].sort --> int[] [3,1,2].sort! --> void Without "?", you can get away by putting "is" in front of everything, but "!" is a hard one, unless you come up with some sort of trailing sigil using normal characters (like _ip).[2] Sometimes, I really wish '?' and '!' were valid characters in identifiers, like in Ruby.That gives me the answer to the Object.toString() vs. Object.toUtf8() problem posed before... just change it to Object.wtf?()
Dec 11 2007
Leandro Lucarella wrote:Daniel Keep, el 11 de diciembre a las 13:37 me escribiste:Don't you mean t.dup.sort(). t.sort.dup() would do a inplace sort and then duplicate it. (t.dup().sort and t.dup.sort() mean the *exact* same thing, the ending () are optional for *all* function that don't tack arguments.)Robert Fraser wrote:One thing that I think Ruby doesn't have is automatic not-in-place function generation. I mean, if I have implemented SomeClass.sort! but not SomeClass.sort, the later can be created by copying the object, sorting the copy in-place and returning that copy. You can see it as a copy constructor in C++, which is generated by default by the compiler, if you don't provide one. In D it could be something like: class T { void sort() { // in-place sort implementation } T dupsort() // default compiler implementation { auto t = new T(this); t.sort(); return t; } } I think the regular name in D should be used for the in-place version, and dup<name> (or d<name> for short) could be used for the copying version, because there is also a well known .dup property (and I think it fits better in D the in-place because of it's high performance orientation). Maybe some syntactic sugar can be used too when using the dup version, something like: auto t = new T(); auto w = t.sort.dup(); // calls dupsort()Daniel Keep wrote:'?' is used for function that check a property of a type, '!' is used for functions that perform in-place modification. if( "my string".empty? ) [3,1,2].sort --> int[] [3,1,2].sort! --> void Without "?", you can get away by putting "is" in front of everything, but "!" is a hard one, unless you come up with some sort of trailing sigil using normal characters (like _ip).[2] Sometimes, I really wish '?' and '!' were valid characters in identifiers, like in Ruby.That gives me the answer to the Object.toString() vs. Object.toUtf8() problem posed before... just change it to Object.wtf?()
Dec 11 2007
Robert DaSilva, el 11 de diciembre a las 19:26 me escribiste:No.Maybe some syntactic sugar can be used too when using the dup version, something like: auto t = new T(); auto w = t.sort.dup(); // calls dupsort()Don't you mean t.dup.sort().t.sort.dup() would do a inplace sort and then duplicate it. (t.dup().sort and t.dup.sort() mean the *exact* same thing, the ending () are optional for *all* function that don't tack arguments.)Ok, good catch, maybe that syntax is not right but you missed the big picture (a compiler generated default implementation for a copying function that can be overrideable). If you now write t.sort.dup(), you are exactly doing that: duplicating t and then sorting it (in-place I guess). If the implementor has a more eficient way to use the copy while sorting, you miss that, or you have to change the syntax (to t.dupsort() for example). -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- El discman vuelve locos a los controles, te lleva a cualquier lugar. Ajústense pronto los cinturones, nos vamos a estrellar. Evidentemente, no escuchaste el speech, que dio la azafata, antes de despegar.
Dec 11 2007
Leandro Lucarella wrote:Robert DaSilva, el 11 de diciembre a las 19:26 me escribiste:I'm just saying that t.sort.dup() can *only* mean sort t then duplicate what sort returns (an error as sort returns void); unless sort is a struck that overloads opCall, but it's not.No.Maybe some syntactic sugar can be used too when using the dup version, something like: auto t = new T(); auto w = t.sort.dup(); // calls dupsort()Don't you mean t.dup.sort().t.sort.dup() would do a inplace sort and then duplicate it. (t.dup().sort and t.dup.sort() mean the *exact* same thing, the ending () are optional for *all* function that don't tack arguments.)Ok, good catch, maybe that syntax is not right but you missed the big picture (a compiler generated default implementation for a copying function that can be overrideable). If you now write t.sort.dup(), you are exactly doing that: duplicating t and then sorting it (in-place I guess). If the implementor has a more eficient way to use the copy while sorting, you miss that, or you have to change the syntax (to t.dupsort() for example).
Dec 11 2007
Robert DaSilva, el 11 de diciembre a las 21:31 me escribiste:I was talking about a new feature proposal. I know it doesn't work now. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Hey you, dont help them to bury the light Don't give in without a fight.Ok, good catch, maybe that syntax is not right but you missed the big picture (a compiler generated default implementation for a copying function that can be overrideable). If you now write t.sort.dup(), you are exactly doing that: duplicating t and then sorting it (in-place I guess). If the implementor has a more eficient way to use the copy while sorting, you miss that, or you have to change the syntax (to t.dupsort() for example).I'm just saying that t.sort.dup() can *only* mean sort t then duplicate what sort returns (an error as sort returns void); unless sort is a struck that overloads opCall, but it's not.
Dec 12 2007
Leandro Lucarella wrote:Robert DaSilva, el 11 de diciembre a las 21:31 me escribiste:I'm say it could *NEVER* work because that already has a well defined behaver and a sub-function can only be called by it's direct parent function, it own sub-function or sibling sub functions and their sub-functions, because it *needs* a context pointer to it's parent functions' stack.I was talking about a new feature proposal. I know it doesn't work now.Ok, good catch, maybe that syntax is not right but you missed the big picture (a compiler generated default implementation for a copying function that can be overrideable). If you now write t.sort.dup(), you are exactly doing that: duplicating t and then sorting it (in-place I guess). If the implementor has a more eficient way to use the copy while sorting, you miss that, or you have to change the syntax (to t.dupsort() for example).I'm just saying that t.sort.dup() can *only* mean sort t then duplicate what sort returns (an error as sort returns void); unless sort is a struck that overloads opCall, but it's not.
Dec 12 2007
Robert DaSilva, el 12 de diciembre a las 21:23 me escribiste:Leandro Lucarella wrote:I don't like to repeat myself, but you force me :)Robert DaSilva, el 11 de diciembre a las 21:31 me escribiste:I was talking about a new feature proposal. I know it doesn't work now.Ok, good catch, maybe that syntax is not right but you missed the big picture (a compiler generated default implementation for a copying function that can be overrideable). If you now write t.sort.dup(), you are exactly doing that: duplicating t and then sorting it (in-place I guess). If the implementor has a more eficient way to use the copy while sorting, you miss that, or you have to change the syntax (to t.dupsort() for example).I'm just saying that t.sort.dup() can *only* mean sort t then duplicate what sort returns (an error as sort returns void); unless sort is a struck that overloads opCall, but it's not.I'm say it could *NEVER* work because that already has a well defined behaverOk, good catch, maybe that syntax is not right but you missed the big picture (a compiler generated default implementation for a copying function that can be overrideable).and a sub-function can only be called by it's direct parent function, it own sub-function or sibling sub functions and their sub-functions, because it *needs* a context pointer to it's parent functions' stack.From my first e-mail: "I know we have a problem to access to dup() nested function because it needs a stack frame, but ..." Are you even reading my e-mails? =) -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- aFR [afr my.farts.cause.nuclear.reaction.org] has quit IRC (Ping timeout)
Dec 13 2007
Leandro Lucarella wrote:Daniel Keep, el 11 de diciembre a las 13:37 me escribiste:One convention I have grown comfortable with is using the adjective form of the verb to define the non-in place versions: sort - sorted reverse - reversed transpose - transposed capitalize - capitalized strip - stripped rotate - rotated normalize - normalized project - projected But doesn't work in 100 % of the cases, and I would prefer if the in-place version wasn't the shortest form and stood out a bit more.Robert Fraser wrote:Daniel Keep wrote:'?' is used for function that check a property of a type, '!' is used for functions that perform in-place modification. if( "my string".empty? ) [3,1,2].sort --> int[] [3,1,2].sort! --> void Without "?", you can get away by putting "is" in front of everything, but "!" is a hard one, unless you come up with some sort of trailing sigil using normal characters (like _ip).[2] Sometimes, I really wish '?' and '!' were valid characters in identifiers, like in Ruby.That gives me the answer to the Object.toString() vs. Object.toUtf8() problem posed before... just change it to Object.wtf?()One thing that I think Ruby doesn't have is automatic not-in-place function generation. I mean, if I have implemented SomeClass.sort! but not SomeClass.sort, the later can be created by copying the object, sorting the copy in-place and returning that copy. You can see it as a copy constructor in C++, which is generated by default by the compiler, if you don't provide one.One problem here is that the functional version is the generic one. Not all algorithms have in-place versions and some that do are much more complicated. -- Oskar
Dec 13 2007
Janice Caron wrote:On Dec 10, 2007 4:21 AM, Daniel Keep <daniel.keep.lists gmail.com> wrote:Agreed. I might be ok with "zero" and "nonzero" but I'd rather have it be called empty() or isEmpty(). Anyway seems we agree there should be a default property like this. It's kind of STL 101 that you should always call a container's 'empty' rather than checking 'size==0'. --bbI actually went and created a pseudo-property for just this purpose: /// Tests the array to see if it's of non-zero length. bool nz(T)(T arr) { return arr.length != 0; } /// Tests the array to see if it's of zero length. bool z(T)(T arr) { return arr.length == 0; }What is relevant to this whole question is the fact the I recall Walter saying he was thinking of changing the representation of an array from struct { ptr, length } to struct { ptr, end }. I suggested at that time that all arrays should be given an isEmpty property, because isEmpty() is just a sensible idea for collections in general. I have to say though, that I don't like the function names z() and nz(). I don't equate "zero" with "zero length". To me, the only meaning I could attribute to "is zero" would be "is full of zeroes". That is, I would expect the array [ 0, 0, 0, 0 ] to pass a test called z() and fail a test called nz(). That's why I'd suggest isEmpty() as the preferred name.
Dec 10 2007
Derek Parnell wrote:On Mon, 10 Dec 2007 10:52:00 +0900, Bill Baxter wrote:I'm just too lazy to type that much. :-) --bbIn a nutshell, if(array) is synonymous with if(array.ptr) but I believe it makes much more sense for it to be synonymous with if(array.length) since that's the thing you want to be checking 99.9% of the time.I'm guessing that this behaviour is due to the commonly used idiom for all reference types, namely that the test is against the 'pointer' value rather than any other aspect of the item being referenced. class Foo {}; Foo f = new Foo(); Foo g; if (f) ... if (g) ... long *lp; if (lp) ... Personally, I regard this as a shorthand option that should be avoided on legibility grounds. I prefer the more explicit versions ... if (array.ptr !is null) if (array.length != 0) if (f !is null) if (lp !is null) only because this is harder to misunderstand.
Dec 09 2007
Bill Baxter wrote:Here's a little test program: [...] So why does the simplest check if(array) { ... } tell us b) ?Hmmm... bad luck?[...] But I think Python's way makes a lot more sense than D's way. So it's hard to remember that the simple and clear if(array) is almost always a bug waiting to happen.While I'm not used to this shorthand (as I don't regularly meddle in things Pythonic), I surely could get so quite quickly. I like it. ++votes I think D's current behaviour makes little sense indeed, as an array is not just another reference type or object, but something special. If there was a built-in type "set" in D, I'd expect it to be true when it's not empty. Same goes for the array type. regards, frank
Dec 09 2007
Bill Baxter wrote:Here's a little test program: void main() { void check(int[] l) { if (l) writef("%-10s","true"); else writef("%-10s","false"); writef("%-10s", (l is null)); writef("%-10s", (l.length==0)); writefln; } int[] list; writefln("%-10s%-10s%-10s%-10s", " ", "is true","is null","length==0"); writef("%-10s","initial"); check(list); list = new int[10]; list = null; writef("%-10s","nulled"); check(list); list = new int[10]; list.length = 0; writef("%-10s", "zeroed"); check(list); } and here's the table it generates: is true is null length==0 initial false true true nulled false true true zeroed true false true Question: which is the bit of information you are more likely interested in knowing: a) whether the array is currently empty. b) whether the array happens to have a buffer of some unknowable length allocated because of a previous history of operations on it. If you answered a) then we think alike. So why does the simplest check if(array) { ... } tell us b) ? In a nutshell, if(array) is synonymous with if(array.ptr) but I believe it makes much more sense for it to be synonymous with if(array.length) since that's the thing you want to be checking 99.9% of the time. A little while ago I realized I was making the mistake of checking if(array) all over my code. It makes a lot of sense to do that if you know Python, since that's how Python works. But I think Python's way makes a lot more sense than D's way. So it's hard to remember that the simple and clear if(array) is almost always a bug waiting to happen. --bbme too
Dec 09 2007