www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - array[length] bug

reply "Vathix" <vathixSpamFix dprogramming.com> writes:
I've been putting off upgrading my DMD because I was afraid the new length
feature would quietly break some of my code. Well, today I finally decided
to upgrade because of the new stream.d fixes. I recompile one of my projects
to find a very strange runtime error message:
   Error: file 'D:\foo

It's due to std.file.getcwd() leaving on a null byte! getcwd() was bitten by
this feature in the code:
   dir[0 .. length]
which used to refer to the local variable named length, but now is
implicitly dir.length, which is leaving the null byte in the array.

I think it should be an error to declare something with the name length, so
that you catch these mistakes easily. length is a popular name.

--
Christopher E. Miller
Aug 31 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"Vathix" <vathixSpamFix dprogramming.com> wrote in message
news:ch22pr$qvq$1 digitaldaemon.com...
 I've been putting off upgrading my DMD because I was afraid the new length
 feature would quietly break some of my code. Well, today I finally decided
 to upgrade because of the new stream.d fixes. I recompile one of my

 to find a very strange runtime error message:
    Error: file 'D:\foo

 It's due to std.file.getcwd() leaving on a null byte! getcwd() was bitten

 this feature in the code:
    dir[0 .. length]
 which used to refer to the local variable named length, but now is
 implicitly dir.length, which is leaving the null byte in the array.

 I think it should be an error to declare something with the name length,

 that you catch these mistakes easily. length is a popular name.

I was bitten by that in recompiling Phobos, too. But I'm a bit reluctant to make it a keyword as it is popular.
Aug 31 2004
parent reply "Vathix" <vathixSpamFix dprogramming.com> writes:
 I think it should be an error to declare something with the name length,

 that you catch these mistakes easily. length is a popular name.

I was bitten by that in recompiling Phobos, too. But I'm a bit reluctant

 make it a keyword as it is popular.

I actually don't really like this feature. Allowing with(array) makes more sense to me. It explicitly lets you specify which array you want length to refer to, and it's not just for length. How about a vote? 1) Leave it how it is now; having all these silent bugs and possible future misunderstandings. 2) Make it an error to declare something with the name 'length'. 3) Replace the feature with: with(array)statement
Aug 31 2004
next sibling parent reply "antiAlias" <fu bar.com> writes:
Mango was bitten by it too. The silent bugs are a glaring minefield, so
something has to change. Frankly, there was nothing wrong with how it was
before; e.g.

char[] substring = text [index .. text.length];

What's wrong with being explicit about where the 'length' property is coming
from? Introducing this new 'special case' within the bounds of a [] pair
provides no tangible value to the programmer, and is an impediment to
catching subtle bugs.

Permit me to ask the obvious question: why was this changed in the first
place?



"Vathix" <vathixSpamFix dprogramming.com> wrote in message
news:ch2deu$10tu$1 digitaldaemon.com...
 I think it should be an error to declare something with the name



 so
 that you catch these mistakes easily. length is a popular name.

I was bitten by that in recompiling Phobos, too. But I'm a bit reluctant

 make it a keyword as it is popular.

I actually don't really like this feature. Allowing with(array) makes more sense to me. It explicitly lets you specify which array you want length to refer to, and it's not just for length. How about a vote? 1) Leave it how it is now; having all these silent bugs and possible future misunderstandings. 2) Make it an error to declare something with the name 'length'. 3) Replace the feature with: with(array)statement

Aug 31 2004
next sibling parent "Ivan Senji" <ivan.senji public.srce.hr> writes:
"antiAlias" <fu bar.com> wrote in message
news:ch2fml$126h$1 digitaldaemon.com...
 Mango was bitten by it too. The silent bugs are a glaring minefield, so
 something has to change. Frankly, there was nothing wrong with how it was
 before; e.g.

 char[] substring = text [index .. text.length];

 What's wrong with being explicit about where the 'length' property is

 from? Introducing this new 'special case' within the bounds of a [] pair
 provides no tangible value to the programmer, and is an impediment to
 catching subtle bugs.

 Permit me to ask the obvious question: why was this changed in the first
 place?

Probably because of things like: blaBla.foo!(int).bar.getSomething.subSomething[0..blaBla.foo!(int).bar.getSo mething.subSomething]; vs blaBla.foo!(int).bar.getSomething.subSomething[0..length]; :)
 "Vathix" <vathixSpamFix dprogramming.com> wrote in message
 news:ch2deu$10tu$1 digitaldaemon.com...
 I think it should be an error to declare something with the name



 so
 that you catch these mistakes easily. length is a popular name.

I was bitten by that in recompiling Phobos, too. But I'm a bit



 to
 make it a keyword as it is popular.

I actually don't really like this feature. Allowing with(array) makes


 sense to me. It explicitly lets you specify which array you want length


 refer to, and it's not just for length.

 How about a vote?
    1) Leave it how it is now; having all these silent bugs and possible
 future misunderstandings.
    2) Make it an error to declare something with the name 'length'.
    3) Replace the feature with:  with(array)statement


Aug 31 2004
prev sibling next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"antiAlias" <fu bar.com> wrote in message
news:ch2fml$126h$1 digitaldaemon.com...
 Mango was bitten by it too. The silent bugs are a glaring minefield, so
 something has to change. Frankly, there was nothing wrong with how it was
 before; e.g.

 char[] substring = text [index .. text.length];

 What's wrong with being explicit about where the 'length' property is

 from? Introducing this new 'special case' within the bounds of a [] pair
 provides no tangible value to the programmer, and is an impediment to
 catching subtle bugs.

 Permit me to ask the obvious question: why was this changed in the first
 place?

It's a problem for things like: e[0..e.length] when e is an arbitrarilly complex expression with side effects. For example, e could be a function returning an array. Or a template instantiation. Or a combination of the two.
Aug 31 2004
next sibling parent "antiAlias" <fu bar.com> writes:
"Walter" <newshound digitalmars.com> wrote in message
news:ch2hmr$138t$1 digitaldaemon.com...

"antiAlias" <fu bar.com> wrote in message
news:ch2fml$126h$1 digitaldaemon.com...
 Mango was bitten by it too. The silent bugs are a glaring minefield, so
 something has to change. Frankly, there was nothing wrong with how it was
 before; e.g.

 char[] substring = text [index .. text.length];

 What's wrong with being explicit about where the 'length' property is

 from? Introducing this new 'special case' within the bounds of a [] pair
 provides no tangible value to the programmer, and is an impediment to
 catching subtle bugs.

 Permit me to ask the obvious question: why was this changed in the first
 place?

It's a problem for things like: e[0..e.length] when e is an arbitrarilly complex expression with side effects. For example, e could be a function returning an array. Or a template instantiation. Or a combination of the two. =========================== Right. Thanks for the clarification. However, you've added a special-case for array lengths which does not help in any fundamental manner with the general-case. Further, this special-case open the door to subtle and nasty bugs; in both existing and new code. The problem here is trying to do too much within a single expression. There's good reason why constructors are really intended to /construct/ only; rather than perform some arbitrarily complex functionality. Might I suggest coming up with a way to handle the general-case, rather than introducing a special-case for arrays only? That way, you'll have helped the language evolve systematically, and avoided making it rather fragile at the same time. For example: expression 'e' might be held in a temporary, and made available as a keyword?
Aug 31 2004
prev sibling next sibling parent reply "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 It's a problem for things like:

    e[0..e.length]

 when e is an arbitrarilly complex expression with side effects. For 
 example,
 e could be a function returning an array. Or a template instantiation. Or 
 a
 combination of the two.

Is it possible with something obvious like e[k..] meaning e[k..e.length] or is that problematic? No keyword needed, no name clash, shorter expression. Perhaps the expression syntax suffers.
Aug 31 2004
parent reply Andy Friesen <andy ikagames.com> writes:
Bent Rasmussen wrote:
It's a problem for things like:

   e[0..e.length]

when e is an arbitrarilly complex expression with side effects. For 
example,
e could be a function returning an array. Or a template instantiation. Or 
a
combination of the two.

Is it possible with something obvious like e[k..] meaning e[k..e.length] or is that problematic? No keyword needed, no name clash, shorter expression. Perhaps the expression syntax suffers.

Nice, but it doesn't scale as well. The 'length' keyword lets us do things like e[length - 4 .. length] Python evades this problem by shamelessly disregarding runtime performance and interpreting negative subscripts as being taken from the end. D doesn't have that option. :) -- andy
Aug 31 2004
parent reply "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 Nice, but it doesn't scale as well.  The 'length' keyword lets us do 
 things like

     e[length - 4 .. length]

 Python evades this problem by shamelessly disregarding runtime performance 
 and interpreting negative subscripts as being taken from the end.  D 
 doesn't have that option. :)

I see and that argument ties in with Walters argument. If it were not for that argument I would say that it is no big deal because it doesn't have to scale, as far as I can see; but that's a matter of oppinion. Its also possible to do the other way around, although with near no benefit except symmetry (I'm a sucker for that though) e[i..] e[..j] e[i..j] It boils down to having something short that stands for length. It could be some special symbol of course, but who wants to sacrifice $ for such a purpose e[..$] e[..$-c]
Aug 31 2004
next sibling parent reply "antiAlias" <fu bar.com> writes:
"Bent Rasmussen" <exo bent-rasmussen.info> wrote in message
news:ch2qm2$186l$1 digitaldaemon.com...
 Nice, but it doesn't scale as well.  The 'length' keyword lets us do
 things like

     e[length - 4 .. length]

 Python evades this problem by shamelessly disregarding runtime performance
 and interpreting negative subscripts as being taken from the end.  D
 doesn't have that option. :)

I see and that argument ties in with Walters argument. If it were not for that argument I would say that it is no big deal because it doesn't have to scale, as far as I can see; but that's a matter of oppinion. Its also possible to do the other way around, although with near no benefit except symmetry (I'm a sucker for that though) e[i..] e[..j] e[i..j] It boils down to having something short that stands for length. It could be some special symbol of course, but who wants to sacrifice $ for such a purpose e[..$] e[..$-c] ================================= But all of this is strictly for array lengths. What happens, for example, if you need to apply the other properties of array? Say, .sort, or .sizeof ? Now you've got to start exposing all of these names in the same manner as the [length] thing we're discussing. Not good. And again, this is only for expressions returning arrays. What about all the other kinds of expressions you might wish to handle in the general case? You still have to do things the original way (with all the potential for side-effects) for each of those. If there were a means of rewriting: # e[length - 4 .. length] as # tmp = e # tmp [tmp.length-4 .. tmp.length] then this special-case 'length' scenario would go away, and the whole thing would become more powerful (and symmetrical), since you could handle all the other non-array cases in the same manner. Trying to do too much in a single expression is unwieldly and error-prone. Perhaps that's why functions and subroutines were invented :-) Makes you wonder whether literal functions could take care of this instead ...
Aug 31 2004
next sibling parent Sean Kelly <sean f4.ca> writes:
In article <ch2rt3$18um$1 digitaldaemon.com>, antiAlias says...
But all of this is strictly for array lengths. What happens, for example, if
you need to apply the other properties of array? Say, .sort, or .sizeof ?
Now you've got to start exposing all of these names in the same manner as
the [length] thing we're discussing. Not good.

Perhaps all parameters of a type should be implicitly accessible in the subscript expression? The only issue then becomes visibility of other variables. It would mean another keyword, but you could do something like this: # void func() # { # int length; # char[] array; # array[0..length]; // references array.length # array[0..local.length]; // references int length # } I'll admit it's kind of ugly and I don't like the keyword I've chosen, but if the goal truly is to simplify expressions with anonymous types then it seems a reasonable approach. Sean
Aug 31 2004
prev sibling next sibling parent reply Regan Heath <regan netwin.co.nz> writes:
On Tue, 31 Aug 2004 14:54:55 -0700, antiAlias <fu bar.com> wrote:

<snip>

 If there were a means of rewriting:

 # e[length - 4 .. length]

 as

 # tmp = e
 # tmp [tmp.length-4 .. tmp.length]

Isn't that what 'with' is for? I quote... http://www.digitalmars.com/d/statement.html#with "The with statement with (expression) { ... ident; } is semantically equivalent to: { Object tmp; tmp = expression; ... tmp.ident; }" Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 31 2004
next sibling parent Sean Kelly <sean f4.ca> writes:
In article <opsdmc4bd65a2sq9 digitalmars.com>, Regan Heath says...
On Tue, 31 Aug 2004 14:54:55 -0700, antiAlias <fu bar.com> wrote:

<snip>

 If there were a means of rewriting:

 # e[length - 4 .. length]

 as

 # tmp = e
 # tmp [tmp.length-4 .. tmp.length]

Isn't that what 'with' is for? I quote... http://www.digitalmars.com/d/statement.html#with

Egads, I'd totally forgotten that D already had this feature. In light of that, I think the special case for length should probably be removed. Sean
Aug 31 2004
prev sibling parent reply Ben Hinkle <bhinkle4 juno.com> writes:
Regan Heath wrote:

 On Tue, 31 Aug 2004 14:54:55 -0700, antiAlias <fu bar.com> wrote:
 
 <snip>
 
 If there were a means of rewriting:

 # e[length - 4 .. length]

 as

 # tmp = e
 # tmp [tmp.length-4 .. tmp.length]

Isn't that what 'with' is for? I quote... http://www.digitalmars.com/d/statement.html#with "The with statement with (expression) { ... ident; } is semantically equivalent to: { Object tmp; tmp = expression; ... tmp.ident; }" Regan

The key difference is that "with" is a statement and we need it in an expression. Maybe there is some way to make "with" useful in expressions. Thinking off the top of my head we could use "with" as similar to "this": e[with.length-4 .. with.length] In other words inside an expression "with" evaluates to the containing array, class or struct reference. The second two uses come in handy for handling overloaded indexing and slicing expressions. For example if some_long_expression evaluates to an object reference "ref", then some_long_expression[0 .. with.length] is equivalent to ref.opSlice(0,ref.length) I don't know if parsing "with.foo" expressions conflicts with parsing "with{}" statements but if not it could be a fairly general construct. -Ben
Aug 31 2004
parent reply Regan Heath <regan netwin.co.nz> writes:
On Tue, 31 Aug 2004 20:02:01 -0400, Ben Hinkle <bhinkle4 juno.com> wrote:
 Regan Heath wrote:

 On Tue, 31 Aug 2004 14:54:55 -0700, antiAlias <fu bar.com> wrote:

 <snip>

 If there were a means of rewriting:

 # e[length - 4 .. length]

 as

 # tmp = e
 # tmp [tmp.length-4 .. tmp.length]

Isn't that what 'with' is for? I quote... http://www.digitalmars.com/d/statement.html#with "The with statement with (expression) { ... ident; } is semantically equivalent to: { Object tmp; tmp = expression; ... tmp.ident; }" Regan

The key difference is that "with" is a statement and we need it in an expression.

Do we? can you give me an example?
 Maybe there is some way to make "with" useful in expressions.
 Thinking off the top of my head we could use "with" as similar to "this":
  e[with.length-4 .. with.length]

 In other words inside an expression "with" evaluates to the containing
 array, class or struct reference. The second two uses come in handy for
 handling overloaded indexing and slicing expressions. For example if
 some_long_expression evaluates to an object reference "ref", then
  some_long_expression[0 .. with.length]
 is equivalent to
  ref.opSlice(0,ref.length)

 I don't know if parsing "with.foo" expressions conflicts with parsing
 "with{}" statements but if not it could be a fairly general construct.

Not a bad idea.. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 31 2004
parent reply Ben Hinkle <bhinkle4 juno.com> writes:
 The key difference is that "with" is a statement and we need it in an
 expression.

Do we? can you give me an example?

the things inside the brackets must be expressions. For example in e[length - 4 .. length] both "length-4" and "length" are expressions. You can't put a statement where D expects an expression. Since that slice expression might appear deep inside another expression it can be slightly painful to rewrite it all into a with statement. I was surprised that Walter added this "length" sugar but it did generate some excitement before.
Aug 31 2004
parent Regan Heath <regan netwin.co.nz> writes:
On Tue, 31 Aug 2004 21:45:23 -0400, Ben Hinkle <bhinkle4 juno.com> wrote:
 The key difference is that "with" is a statement and we need it in an
 expression.

Do we? can you give me an example?

the things inside the brackets must be expressions. For example in e[length - 4 .. length] both "length-4" and "length" are expressions. You can't put a statement where D expects an expression.

I see where you're coming from. I was not suggesting adding 'with' inside the [].
 Since that slice expression might appear deep inside another expression 
 it can be slightly painful to rewrite it all into a with statement.

Example, example, example.. please :) I think using 'with' will not only work, it will give cleaner code too.
 I was surprised that Walter added this "length" sugar but it did generate
 some excitement before.

Me too. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 31 2004
prev sibling parent reply "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 But all of this is strictly for array lengths. What happens, for example, 
 if
 you need to apply the other properties of array? Say, .sort, or .sizeof ?
 Now you've got to start exposing all of these names in the same manner as
 the [length] thing we're discussing. Not good.

That assumes you want to do that; I wouldn't. I don't see the problem with a temporal for such things; in fact I'd prefer the e[i..] and e[..i] syntax without any implicit temporal generation. The general syntax should be okay for most cases but its a matter of preference where to draw the line here. But just because something can be generalized doesn't mean it should be.
 And again, this is only for expressions returning arrays. What about all 
 the
 other kinds of expressions you might wish to handle in the general case? 
 You
 still have to do things the original way (with all the potential for
 side-effects) for each of those.

 If there were a means of rewriting:

 # e[length - 4 .. length]

 as

 # tmp = e
 # tmp [tmp.length-4 .. tmp.length]

temporal(e)[length - 4 .. length] // semi-yuck
 then this special-case 'length' scenario would go away, and the whole 
 thing
 would become more powerful (and symmetrical), since you could handle all 
 the
 other non-array cases in the same manner. Trying to do too much in a 
 single
 expression is unwieldly and error-prone. Perhaps that's why functions and
 subroutines were invented :-)

I don't think e.g. e[i..] is unwieldly, nor e[0..length-5] although I almost prefer not having length get special treatment (as per the current implementation) because of name confusion and as you say/imply, the old explicit syntax/semantics can be more readable; again though, I see e[i..] as quite readable. But I definitely would not like to have the current practice of implicit qualification of length expanded/generalized to other properties/functions. Perhaps its an unjustified worry, but it doesn't feel that "clean" to me.
 Makes you wonder whether literal functions could take care of this instead

Let's not get carried away here; unless you have something cool up your sleeve. :-)
 ...

Aug 31 2004
parent Regan Heath <regan netwin.co.nz> writes:
On Wed, 1 Sep 2004 01:55:45 +0200, Bent Rasmussen 
<exo bent-rasmussen.info> wrote:
 But all of this is strictly for array lengths. What happens, for 
 example,
 if
 you need to apply the other properties of array? Say, .sort, or .sizeof 
 ?
 Now you've got to start exposing all of these names in the same manner 
 as
 the [length] thing we're discussing. Not good.

That assumes you want to do that; I wouldn't. I don't see the problem with a temporal for such things; in fact I'd prefer the e[i..] and e[..i] syntax without any implicit temporal generation.

I think this is less immediately clear than a 'with' construct would be.
 The general syntax should be okay for most cases but its a matter of
 preference where to draw the line here. But just because something can be
 generalized doesn't mean it should be.

I think if you can generalise at no cost, then why not. After all no-one can think of everything someone is going to want to do. I'd draw the line if you're creating several ways to do the same thing, as I think that is a bad thing.
 And again, this is only for expressions returning arrays. What about all
 the
 other kinds of expressions you might wish to handle in the general case?
 You
 still have to do things the original way (with all the potential for
 side-effects) for each of those.

 If there were a means of rewriting:

 # e[length - 4 .. length]

 as

 # tmp = e
 # tmp [tmp.length-4 .. tmp.length]

temporal(e)[length - 4 .. length] // semi-yuck

with(e) { ..do stuff with e, reference e with 'this'.. }
 then this special-case 'length' scenario would go away, and the whole
 thing
 would become more powerful (and symmetrical), since you could handle all
 the
 other non-array cases in the same manner. Trying to do too much in a
 single
 expression is unwieldly and error-prone. Perhaps that's why functions 
 and
 subroutines were invented :-)

I don't think e.g. e[i..] is unwieldly, nor e[0..length-5] although I almost prefer not having length get special treatment (as per the current implementation) because of name confusion and as you say/imply, the old explicit syntax/semantics can be more readable; again though, I see e[i..] as quite readable.

even if 'e' is a really long templated expression, or a method call or function returning an array?
 But I definitely would not like to have the current practice of implicit
 qualification of length expanded/generalized to other 
 properties/functions.
 Perhaps its an unjustified worry, but it doesn't feel that "clean" to me.

I agree.
 Makes you wonder whether literal functions could take care of this 
 instead

Let's not get carried away here; unless you have something cool up your sleeve. :-)
 ...


I'd like to hear this idea too. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 31 2004
prev sibling next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 31 Aug 2004 23:30:46 +0200, Bent Rasmussen wrote:

 Nice, but it doesn't scale as well.  The 'length' keyword lets us do 
 things like

     e[length - 4 .. length]

 Python evades this problem by shamelessly disregarding runtime performance 
 and interpreting negative subscripts as being taken from the end.  D 
 doesn't have that option. :)

I see and that argument ties in with Walters argument. If it were not for that argument I would say that it is no big deal because it doesn't have to scale, as far as I can see; but that's a matter of oppinion. Its also possible to do the other way around, although with near no benefit except symmetry (I'm a sucker for that though) e[i..] e[..j] e[i..j] It boils down to having something short that stands for length. It could be some special symbol of course, but who wants to sacrifice $ for such a purpose e[..$] e[..$-c]

Me. What sacrifice? We already have '*' for multiplication and pointers, depending on context. Its short. Its not currently used. It has precedence (regular expressions). It doesn't clash with used-defined identifiers. It only has this meaning within []. -- Derek Melbourne, Australia 1/Sep/04 9:55:25 AM
Aug 31 2004
parent "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 Me. What sacrifice? We already have '*' for multiplication and pointers,
 depending on context. Its short. Its not currently used. It has precedence
 (regular expressions). It doesn't clash with used-defined identifiers. It
 only has this meaning within [].

Just a general statement that using it for this purpose may preclude other uses for it. It is, after all, conceivable that more broad uses of it could be found. But as you say, it could have multiple meanings depending on context, if you like that.
Aug 31 2004
prev sibling parent reply pragma <pragma_member pathlink.com> writes:
In article <ch2qm2$186l$1 digitaldaemon.com>, Bent Rasmussen says...
I see and that argument ties in with Walters argument. If it were not for 
that argument I would say  that it is no big deal because it doesn't have to 
scale, as far as I can see; but that's a matter of oppinion. Its also 
possible to do the other way around, although with near no benefit except 
symmetry (I'm a sucker for that though)

e[i..]
e[..j]
e[i..j]

I, for one, love the above syntax simply because it cannot be confused for anything else but what its for. Also, the python-esque negative indicies would also work very well for further reducing the need for referencing 'length' in a slice operation. As nice a shortcut 'length' is in a slice, I have to put my $0.02 in that it hurts more than it helps in a lot of cases. It also leads to some very ambiguous code if 'length' is declared elsewhere in the same scope as the slice operation. :( Walter, thank you for making strides in adding all these great features to this language. With all due respect, I'm looking forward to V0.102. :) - Pragma EricAnderton at (sig[0..]) yahoo dot com
Aug 31 2004
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 1 Sep 2004 02:25:17 +0000 (UTC), pragma wrote:

 In article <ch2qm2$186l$1 digitaldaemon.com>, Bent Rasmussen says...
I see and that argument ties in with Walters argument. If it were not for 
that argument I would say  that it is no big deal because it doesn't have to 
scale, as far as I can see; but that's a matter of oppinion. Its also 
possible to do the other way around, although with near no benefit except 
symmetry (I'm a sucker for that though)

e[i..]
e[..j]
e[i..j]

I, for one, love the above syntax simply because it cannot be confused for anything else but what its for. Also, the python-esque negative indicies would also work very well for further reducing the need for referencing 'length' in a slice operation.

Using this scheme, how does one specify the 2nd last element, such as e[i..length-1]?
 As nice a shortcut 'length' is in a slice, I have to put my $0.02 in that it
 hurts more than it helps in a lot of cases.  It also leads to some very
 ambiguous code if 'length' is declared elsewhere in the same scope as the slice
 operation. :(

Agreed.
 Walter, thank you for making strides in adding all these great features to this
 language.

Agreed (with cherries on top).
  With all due respect, I'm looking forward to V0.102. :)

I'm looking forward to v1.0 ;-) -- Derek Melbourne, Australia 1/Sep/04 2:31:09 PM
Aug 31 2004
parent Sean Kelly <sean f4.ca> writes:
In article <ch3jgm$1mjq$1 digitaldaemon.com>, Derek Parnell says...
On Wed, 1 Sep 2004 02:25:17 +0000 (UTC), pragma wrote:

 In article <ch2qm2$186l$1 digitaldaemon.com>, Bent Rasmussen says...
I see and that argument ties in with Walters argument. If it were not for 
that argument I would say  that it is no big deal because it doesn't have to 
scale, as far as I can see; but that's a matter of oppinion. Its also 
possible to do the other way around, although with near no benefit except 
symmetry (I'm a sucker for that though)

e[i..]
e[..j]
e[i..j]


Using this scheme, how does one specify the 2nd last element, such as e[i..length-1]?

I think it would be: e[i..-1] Sean
Aug 31 2004
prev sibling next sibling parent Andy Friesen <andy ikagames.com> writes:
pragma wrote:
 In article <ch2qm2$186l$1 digitaldaemon.com>, Bent Rasmussen says...
 
I see and that argument ties in with Walters argument. If it were not for 
that argument I would say  that it is no big deal because it doesn't have to 
scale, as far as I can see; but that's a matter of oppinion. Its also 
possible to do the other way around, although with near no benefit except 
symmetry (I'm a sucker for that though)

e[i..]
e[..j]
e[i..j]

I, for one, love the above syntax simply because it cannot be confused for anything else but what its for. Also, the python-esque negative indicies would also work very well for further reducing the need for referencing 'length' in a slice operation. As nice a shortcut 'length' is in a slice, I have to put my $0.02 in that it hurts more than it helps in a lot of cases. It also leads to some very ambiguous code if 'length' is declared elsewhere in the same scope as the slice operation. :( Walter, thank you for making strides in adding all these great features to this language. With all due respect, I'm looking forward to V0.102. :)

I agree on all counts. I mourn the lack of a straightforward way to ask for the last n elements, but life will go on. Further, this syntax doesn't add any magic words to the language, which means that it doesn't close any doors for new syntax come 2.0 time. -- andy
Aug 31 2004
prev sibling parent reply Dave <Dave_member pathlink.com> writes:
In article <ch3bud$1h94$1 digitaldaemon.com>, pragma says...
In article <ch2qm2$186l$1 digitaldaemon.com>, Bent Rasmussen says...
I see and that argument ties in with Walters argument. If it were not for 
that argument I would say  that it is no big deal because it doesn't have to 
scale, as far as I can see; but that's a matter of oppinion. Its also 
possible to do the other way around, although with near no benefit except 
symmetry (I'm a sucker for that though)

e[i..]
e[..j]
e[i..j]

I, for one, love the above syntax simply because it cannot be confused for anything else but what its for. Also, the python-esque negative indicies would also work very well for further reducing the need for referencing 'length' in a slice operation. As nice a shortcut 'length' is in a slice, I have to put my $0.02 in that it hurts more than it helps in a lot of cases. It also leads to some very ambiguous code if 'length' is declared elsewhere in the same scope as the slice operation. :( Walter, thank you for making strides in adding all these great features to this language. With all due respect, I'm looking forward to V0.102. :) - Pragma EricAnderton at (sig[0..]) yahoo dot com

e[i...] e[...j] e[i..j] ?
Aug 31 2004
parent reply "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 e[i...]
 e[...j]
 e[i..j]

 ?

It means the same as e[i...e.length] e[0...j] I wohn't tell what the last one means. :-)
Sep 01 2004
next sibling parent reply Derek <derek psyc.ward> writes:
On Wed, 1 Sep 2004 14:20:17 +0200, Bent Rasmussen wrote:

 e[i...]
 e[...j]
 e[i..j]

 ?

It means the same as e[i...e.length] e[0...j] I wohn't tell what the last one means. :-)

Notice the three(3) dots, not just two? I think that Dave was suggesting that instead of e[i..] (with two dots) that we use e[i...] (with three dots). -- Derek Melbourne, Australia
Sep 01 2004
parent "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 Notice the three(3) dots, not just two?

No!
 I think that Dave was suggesting that instead of e[i..] (with two dots)
 that we use e[i...] (with three dots).

I didn't see that before, no. I don't see the point in that though, besides its also subtle.
Sep 01 2004
prev sibling parent Dave <Dave_member pathlink.com> writes:
In article <ch4epr$26lu$1 digitaldaemon.com>, Bent Rasmussen says...
 e[i...]
 e[...j]
 e[i..j]

 ?

It means the same as e[i...e.length] e[0...j] I wohn't tell what the last one means. :-)

Sorry - didn't see that someone responded to this. Yes - [i...] would be from i to length. [...j] would be from 0 to j. I think this is probably 'easy' to parse and lex in that context, and most importantly for me, easy to type <g>! Plus, the '...' I think is generally accepted as meaning 'from beginning' or 'to end' depending on context, as when paraphrasing. - Dave
Sep 13 2004
prev sibling parent reply Regan Heath <regan netwin.co.nz> writes:
On Tue, 31 Aug 2004 11:57:03 -0700, Walter <newshound digitalmars.com> 
wrote:
 "antiAlias" <fu bar.com> wrote in message
 news:ch2fml$126h$1 digitaldaemon.com...
 Mango was bitten by it too. The silent bugs are a glaring minefield, so
 something has to change. Frankly, there was nothing wrong with how it 
 was
 before; e.g.

 char[] substring = text [index .. text.length];

 What's wrong with being explicit about where the 'length' property is

 from? Introducing this new 'special case' within the bounds of a [] pair
 provides no tangible value to the programmer, and is an impediment to
 catching subtle bugs.

 Permit me to ask the obvious question: why was this changed in the first
 place?

It's a problem for things like: e[0..e.length] when e is an arbitrarilly complex expression with side effects. For example, e could be a function returning an array. Or a template instantiation. Or a combination of the two.

So isn't the 'with' idea the best solution eg. void foo() { with(methodReturningAnArray(..complex set of parameters..)) { this[1..length]; } } in the above 'this' is used to reference the array, as in a class method, 'length' refers to this.length. The same error checking which is used (I assume) for class methods, scope blocks, and normal with statements should be applied. eg void foo() { int length; with(methodReturningAnArray(..complex set of parameters..)) { this[1..length]; //error: this.length or outer 'int length'? } } Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 31 2004
parent reply Sean Kelly <sean f4.ca> writes:
In article <opsdmc1c065a2sq9 digitalmars.com>, Regan Heath says...
So isn't the 'with' idea the best solution eg.

void foo() {
   with(methodReturningAnArray(..complex set of parameters..)) {
     this[1..length];
   }
}

in the above 'this' is used to reference the array, as in a class method, 
'length' refers to this.length.

This is probably the best general solution, but I don't think the meaning of 'this' should be changed. I'm inclined to want to allow declarations inside a with block, but then the problem becomes how the type should be determined. Maybe the current solution isn't so bad after all... Sean
Aug 31 2004
parent Regan Heath <regan netwin.co.nz> writes:
On Tue, 31 Aug 2004 23:46:25 +0000 (UTC), Sean Kelly <sean f4.ca> wrote:
 In article <opsdmc1c065a2sq9 digitalmars.com>, Regan Heath says...
 So isn't the 'with' idea the best solution eg.

 void foo() {
   with(methodReturningAnArray(..complex set of parameters..)) {
     this[1..length];
   }
 }

 in the above 'this' is used to reference the array, as in a class 
 method,
 'length' refers to this.length.

This is probably the best general solution, but I don't think the meaning of 'this' should be changed. I'm inclined to want to allow declarations inside a with block, but then the problem becomes how the type should be determined. Maybe the current solution isn't so bad after all...

Currently this: class A { int i; this(int _i) { i = _i; } } void main() { A a = new A(5); int i; with(a) { printf("%d",i); } } compiles, runs and prints 5 (as you'd expect) but I would rather get a compile error saying "with(a) hides 'i' from enclosing scope" or something similar. To then have to either: - rename the 'int i' in the enclosing scope - rename the 'int i' in the class - explicitly reference the class 'i' as in: with(a) { printf("%d",this.i); } to solve it. The only problem being, what if you meant the i from the enclosing scope? maybe .main.with.i? what if you have a with within a with? .main.with.with.i? ... Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 31 2004
prev sibling parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <ch2fml$126h$1 digitaldaemon.com>, antiAlias says...

Permit me to ask the obvious question: why was this changed in the first
place?

Poor Walter. He can't win. :( I rather gather that this feature was introduced because enough people on this newsgroup asked for it, or at least for something similar. Further, this isn't a bug, since the feature works exactly as described in the manual. However, I'm all in favor of having the compiler help us to find user-bugs at compile time, and to this end, I do think there is room for manoeuvre here. So here are some (mutually exclusive) options - any one of them would solve the problem. They are listed in order of my preference (most preferred first): 1) It shall be considered a compile-time error for the new use of "length" to eclipse a local variable called "length". (This forces the user to rename their conflicting variable). 2) Use the symbol "$" instead of the identifier "length". (so "e[length-1..length]" becomes "e[$-1..$]"). Note that "$" is a good choice, as it already means "end of string" in a regular expression. 3) Leave things exactly as they are now. If you screw up, it's your problem. 4) Make "length" a reserved word. This prevents users from having variables of this name. 5) Allow the keyword "with" (or some other keyword) to refer to the array, when used within a subscript expression (so "e[length-1..length]" becomes "e[with.length-1..with.length]". 6) Remove the feature altogether There are probably others, but that list will do me. I vote for (1), with (2) as my second choice. Arcane Jill
Sep 01 2004
next sibling parent reply "Ivan Senji" <ivan.senji public.srce.hr> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:ch3uu3$1u3e$1 digitaldaemon.com...
 In article <ch2fml$126h$1 digitaldaemon.com>, antiAlias says...

Permit me to ask the obvious question: why was this changed in the first
place?

Poor Walter. He can't win. :( I rather gather that this feature was

 because enough people on this newsgroup asked for it, or at least for

 similar.

 Further, this isn't a bug, since the feature works exactly as described in

 manual.

 However, I'm all in favor of having the compiler help us to find user-bugs

 compile time, and to this end, I do think there is room for manoeuvre

 here are some (mutually exclusive) options - any one of them would solve

 problem. They are listed in order of my preference (most preferred first):


 1) It shall be considered a compile-time error for the new use of "length"

 eclipse a local variable called "length". (This forces the user to rename

 conflicting variable).

 2) Use the symbol "$" instead of the identifier "length". (so
 "e[length-1..length]" becomes "e[$-1..$]"). Note that "$" is a good

 it already means "end of string" in a regular expression.

 3) Leave things exactly as they are now. If you screw up, it's your

 4) Make "length" a reserved word. This prevents users from having

 this name.

 5) Allow the keyword "with" (or some other keyword) to refer to the array,

 used within a subscript expression (so "e[length-1..length]" becomes
 "e[with.length-1..with.length]".

I would go with the "with" because it is the most general solution e[e.length-5..e.length]; e.sort(); becomes with(e) { this[this.length-5..this.length]; this.sort(); //or instead of this something like "obj" }
 6) Remove the feature altogether

 There are probably others, but that list will do me. I vote for (1), with

 my second choice.

 Arcane Jill

Sep 01 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <ch44vg$21cd$1 digitaldaemon.com>, Ivan Senji says...

 5) Allow the keyword "with" (or some other keyword) to refer to the array,

 used within a subscript expression (so "e[length-1..length]" becomes
 "e[with.length-1..with.length]".

I would go with the "with" because it is the most general solution e[e.length-5..e.length]; e.sort(); becomes with(e) { this[this.length-5..this.length]; this.sort(); //or instead of this something like "obj" }

That is not what I suggested. Please read again. (In fact, I was merely re-iterating Ben's earlier suggestion there). Your suggestion appears to be very similar to the status quo. To recap the six options, all of which refer to the evaluation of a subscript or slice /expression/: 1) It shall be considered a compile-time error for the new use of "length" to eclipse a local variable called "length". (This forces the user to rename their conflicting variable). This is definitely my favorite. It means that this will compile normally: # { # int length = 5; # f(length); # } # { # ubyte[] array = new ubyte[10]; # array[length-1] = 3; # } but this will not: # { # int length = 5; # f(length); # ubyte[] array = new ubyte[10]; # array[length-1] = 3; // error - length eclipses local variable # } Easy. Same syntax as now. All errors found. If this can be done then further complications and changes of syntax can be completely avoided. For what it's worth, here are the other suggestions: 2) Use the symbol "$" instead of the identifier "length". (so "e[length-1..length]" becomes "e[$-1..$]"). Note that "$" is a good choice, as it already means "end of string" in a regular expression. 3) Leave things exactly as they are now. If you screw up, it's your problem. 4) Make "length" a reserved word. This prevents users from having variables of this name. 5) Allow the keyword "with" (or some other keyword) to refer to the array, when used within a subscript expression (so "e[length-1..length]" becomes "e[with.length-1..with.length]". 6) Remove the feature altogether I have to say, I don't like (6) at all. I would like to see this feature kept in some form. Jill
Sep 01 2004
next sibling parent "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 I have to say, I don't like (6) at all. I would like to see this feature 
 kept in
 some form.

(1) does look like the most pragmatic solution.
Sep 01 2004
prev sibling parent reply Nick <Nick_member pathlink.com> writes:
In article <ch4b7u$24sq$1 digitaldaemon.com>, Arcane Jill says...
1) It shall be considered a compile-time error for the new use of "length" to
eclipse a local variable called "length". (This forces the user to rename their
conflicting variable).

"length" might not be a local, it might be a class member or even global, and in some cases you can't change that. Personally I don't mind the way it works now, but perhaps a special symbol like $ would be safer. (OTOH I don't want my code to look like Perl ;-) Nick
Sep 01 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <ch4fht$2779$1 digitaldaemon.com>, Nick says...
In article <ch4b7u$24sq$1 digitaldaemon.com>, Arcane Jill says...
1) It shall be considered a compile-time error for the new use of "length" to
eclipse a local variable called "length". (This forces the user to rename their
conflicting variable).

"length" might not be a local, it might be a class member or even global, and in some cases you can't change that.

Yes, that's true. But class members can be referenced as "this.length", globals as ".length", and the array length as "<array>.length", so it is always possible to disambiguate in these cases. I don't think that being explicit in the event of ambiguity is a bad thing, given that this is just a convenience syntax. I can see that container classes might want to define a "length" member, but maybe an opLength() overload would be better anyway, so that this feature can be extended beyond just arrays.
Personally I don't mind the way it works now,

Nor do I, actually. I'm just thinking aloud.
but perhaps a special symbol like $ would be safer. (OTOH I don't want my code
to look like Perl ;-)

I'm with you on all counts there. ($ was my second choice). Jill
Sep 01 2004
parent reply "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 I can see that container classes might want to define a "length" member, 
 but
 maybe an opLength() overload would be better anyway, so that this feature 
 can be
 extended beyond just arrays.

This may be getting out of hand if we have to introduce an operator to facilitate this feature/sugar. Its also not a good thing if sugar one places gives us salt other places, so to speak.
Sep 01 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Bent Rasmussen wrote:

 I can see that container classes might want to define a "length" 
 member, but maybe an opLength() overload would be better anyway, so 
 that this  feature can be extended beyond just arrays.

This may be getting out of hand if we have to introduce an operator to facilitate this feature/sugar.

What about... T[] opSlice(int start = 0, int end = length); Is there any restriction on what can be a default argument, for that matter? And similarly, when opSliceAssign finally comes along T[] opSliceAssign(T value, int start = 0, int end = length); Of course, with current restrictions it would be possible to make the begin required and the end optional, but not vice versa. Even if we don't yet allow the syntax opSlice(, 42); I guess we can support the equivalent with array slices. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 01 2004
parent reply "Bent Rasmussen" <exo bent-rasmussen.info> writes:
     T[] opSlice(int start = 0, int end = length);

Interesting. That may be a nice feature. Perhaps even, int f(int x = g(h)) ... int g(int x) ... int h() ... So it becomes default expressions instead of default values. In order not to side-track this discussion further, I move on. with haste. :-)
 I guess we can support the equivalent with array slices.

I don't see why not.
Sep 01 2004
parent "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 Interesting. That may be a nice feature. Perhaps even,

Silly me. It allready works that way...
Sep 02 2004
prev sibling parent Regan Heath <regan netwin.co.nz> writes:
On Wed, 1 Sep 2004 07:49:23 +0000 (UTC), Arcane Jill 
<Arcane_member pathlink.com> wrote:
 In article <ch2fml$126h$1 digitaldaemon.com>, antiAlias says...

<snip>
 1) It shall be considered a compile-time error for the new use of 
 "length" to
 eclipse a local variable called "length". (This forces the user to 
 rename their
 conflicting variable).

 2) Use the symbol "$" instead of the identifier "length". (so
 "e[length-1..length]" becomes "e[$-1..$]"). Note that "$" is a good 
 choice, as
 it already means "end of string" in a regular expression.

 3) Leave things exactly as they are now. If you screw up, it's your 
 problem.

 4) Make "length" a reserved word. This prevents users from having 
 variables of
 this name.

 5) Allow the keyword "with" (or some other keyword) to refer to the 
 array, when
 used within a subscript expression (so "e[length-1..length]" becomes
 "e[with.length-1..with.length]".

 6) Remove the feature altogether

7) Extend the current 'with' to handle all native types, or at least all reference types, (currently it only works on classes) eg. char[] a; with(a) { printf("%d\n",length); } I think we want (1),(6) and (7). The reasons: - 'with' already exists and provides the 'feature' for an existing subset of types. - 'with' is more obvious at first glance about what is going on. I think (3),(4) and (5) are very bad options. I think (2) is a last resort option. Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Sep 01 2004
prev sibling next sibling parent Juanjo =?ISO-8859-15?Q?=C1lvarez?= <juanjuxNO SPAMyahoo.es> writes:
Vathix wrote:

 I think it should be an error to declare something with the name
 length,

 that you catch these mistakes easily. length is a popular name.

I was bitten by that in recompiling Phobos, too. But I'm a bit reluctant

 make it a keyword as it is popular.


I was the only one to grep for length in my code before upgrading?
 How about a vote?
    1) Leave it how it is now; having all these silent bugs and possible
 future misunderstandings.

name).
    2) Make it an error to declare something with the name 'length'.

Aug 31 2004
prev sibling next sibling parent reply Regan Heath <regan netwin.co.nz> writes:
On Tue, 31 Aug 2004 13:49:37 -0400, Vathix 
<vathixSpamFix dprogramming.com> wrote:
    3) Replace the feature with:  with(array)statement

This one, we *already* have this feature. :) Lets just remove the length feature. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 31 2004
parent reply "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 This one, we *already* have this feature. :)
 Lets just remove the length feature.

Will this work? with (array) { return this[0..3]; } But if part of the reason for this feature was to save keystrokes (which I gather since with could do the same), then its no replacement. Not that I particularly like the feature in its current form. :-)
Aug 31 2004
parent Regan Heath <regan netwin.co.nz> writes:
On Wed, 1 Sep 2004 02:02:23 +0200, Bent Rasmussen 
<exo bent-rasmussen.info> wrote:
 This one, we *already* have this feature. :)
 Lets just remove the length feature.

Will this work? with (array) { return this[0..3]; }

actually no, not currently, I get "with expressions must be class objects, not 'char[]'" but I cannot see the reason to restrict it like this, in fact why not: int i; with(i) { printf("%d",sizeof); }
 But if part of the reason for this feature was to save keystrokes (which 
 I gather since with could do the same), then its no replacement. Not 
 that I
 particularly like the feature in its current form. :-)

I think the reason was... <quote source="Walter"> It's a problem for things like: e[0..e.length] when e is an arbitrarilly complex expression with side effects. For example, e could be a function returning an array. Or a template instantiation. Or a combination of the two. </quote> Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 31 2004
prev sibling parent Charles <Charles_member pathlink.com> writes:
How about a vote?

3 , or just get rid of it altogether. Charlie. In article <ch2deu$10tu$1 digitaldaemon.com>, Vathix says...
 I think it should be an error to declare something with the name length,

 that you catch these mistakes easily. length is a popular name.

I was bitten by that in recompiling Phobos, too. But I'm a bit reluctant

 make it a keyword as it is popular.

I actually don't really like this feature. Allowing with(array) makes more sense to me. It explicitly lets you specify which array you want length to refer to, and it's not just for length. How about a vote? 1) Leave it how it is now; having all these silent bugs and possible future misunderstandings. 2) Make it an error to declare something with the name 'length'. 3) Replace the feature with: with(array)statement

Sep 01 2004