I got an idea of how to solve the age old issue of getting negative indices in ranges to work. We'd all like to do things like this:
foo = foo[..-2]; // Lose the last item.
But so far it hasn't worked because of cases like this:
foo = foo[..i-1] + foo[i+1..]; // Lose item i.
which should work even when i is zero.
My idea is to give the unary negation operator an additional literal meaning in the range operator. I.e. in the expression
foo[-a..-b]
both index operations takes place in the range -sizeof(foo)..-1 instead of the normal 0..sizeof(foo)-1. The expressions a and b are negated as usual. Thus, if they already contain the negative indices a double negation would be necessary:
foo[..- -b]
That's easily optimized away. Another example:
// Lose item i, where i is in the range -sizeof(foo)..-1. foo = foo[..- -(i-1)] + foo[- -(i+1)..];
There's a compatibility issue here, but I think it's minor. Only cases where range expressions are negated are affected. That means expressions that evaluate to values in the range 0 for the first element down to -sizeof(foo)+1 for the last, which I believe is fairly odd.
How to convey this to the range lfuns remains to be solved.
What do you say? Would it be too strange?
I think it would be less confusing to use something different from "-" to mean "count from the end". Besides that, it's an interesting idea.
/ Niels Möller (med röd bil)
Previous text:
2003-05-15 16:54: Subject: Negative ranges revisited
I got an idea of how to solve the age old issue of getting negative indices in ranges to work. We'd all like to do things like this:
foo = foo[..-2]; // Lose the last item.
But so far it hasn't worked because of cases like this:
foo = foo[..i-1] + foo[i+1..]; // Lose item i.
which should work even when i is zero.
My idea is to give the unary negation operator an additional literal meaning in the range operator. I.e. in the expression
foo[-a..-b]
both index operations takes place in the range -sizeof(foo)..-1 instead of the normal 0..sizeof(foo)-1. The expressions a and b are negated as usual. Thus, if they already contain the negative indices a double negation would be necessary:
foo[..- -b]
That's easily optimized away. Another example:
// Lose item i, where i is in the range -sizeof(foo)..-1. foo = foo[..- -(i-1)] + foo[- -(i+1)..];
There's a compatibility issue here, but I think it's minor. Only cases where range expressions are negated are affected. That means expressions that evaluate to values in the range 0 for the first element down to -sizeof(foo)+1 for the last, which I believe is fairly odd.
How to convey this to the range lfuns remains to be solved.
What do you say? Would it be too strange?
/ Martin Stjernholm, Roxen IS
Perhaps, but what would that syntax be? '-' has the advantage that e.g.
foo = foo[..-2]
would do what most people intuitively think it does. Otoh one could easily consider it bogus that the above isn't the same as:
int n = -2; foo = foo[..n];
/ Martin Stjernholm, Roxen IS
Previous text:
2003-05-15 17:14: Subject: Negative ranges revisited
I think it would be less confusing to use something different from "-" to mean "count from the end". Besides that, it's an interesting idea.
/ Niels Möller (med röd bil)
I don't have any obvious operator to propose (ideally, it should be something that can be associated with the end of the string), but for the syntax, you just add it before the index, either after the leading [ or after the ... (One could also have it before the .., if one likes that symmetry better).
As for negation, there are two choices. I think I'd prefer to say that 0 is the position after the end of the string, -1 the position before that, and so on. Say we make the random choise of % for the magic character (any binary operator could be reused, as could for example:, ;, ,, /, @, $).
Then "banan"[%-3..%-1] == "nan", "banan"[%-4..4] == "ana". The easiest way to understand it is to think of %, in this context, as a shorthand for "sizeof(the string or array in question) +".
Actually, $ might be a better choice than %, anyone familiar with regexps can easily associate it to "end". Then it's
"banan"[$-3..$-1]
And when talking about ranges, I still like the old idea of using (x..y), [x..y) etc to represent open and half open intervals ;-)
/ Niels Möller (med röd bil)
Previous text:
2003-05-15 21:17: Subject: Negative ranges revisited
Perhaps, but what would that syntax be? '-' has the advantage that e.g.
foo = foo[..-2]
would do what most people intuitively think it does. Otoh one could easily consider it bogus that the above isn't the same as:
int n = -2; foo = foo[..n];
/ Martin Stjernholm, Roxen IS
I think that represent-the-previous-expression is very nice syntactically. But how would it work internally?
/ Mirar
Previous text:
2003-05-15 22:23: Subject: Negative ranges revisited
I don't have any obvious operator to propose (ideally, it should be something that can be associated with the end of the string), but for the syntax, you just add it before the index, either after the leading [ or after the ... (One could also have it before the .., if one likes that symmetry better).
As for negation, there are two choices. I think I'd prefer to say that 0 is the position after the end of the string, -1 the position before that, and so on. Say we make the random choise of % for the magic character (any binary operator could be reused, as could for example:, ;, ,, /, @, $).
Then "banan"[%-3..%-1] == "nan", "banan"[%-4..4] == "ana". The easiest way to understand it is to think of %, in this context, as a shorthand for "sizeof(the string or array in question) +".
Actually, $ might be a better choice than %, anyone familiar with regexps can easily associate it to "end". Then it's
"banan"[$-3..$-1]
And when talking about ranges, I still like the old idea of using (x..y), [x..y) etc to represent open and half open intervals ;-)
/ Niels Möller (med röd bil)
I don't think about it as a general "previous expression" thing. It's just a special modifier for the indexing operation to tell it, unambigously, to count relative to the end of the array/string.
I haven't yet thought about how to map it to `[] calls.
/ Niels Möller (med röd bil)
Previous text:
2003-05-15 22:35: Subject: Negative ranges revisited
I think that represent-the-previous-expression is very nice syntactically. But how would it work internally?
/ Mirar
Looks good to me. The operator could imply the negation, so that it's only e.g. foo[$3..$1]. Maybe the negation is good for clarity, but otoh it could easily be taken for a binary substraction and that the $ is a term.
$ has a slight drawback in that it's often treated as a symbol building character, typically used in machine generated symbols.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-05-15 22:23: Subject: Negative ranges revisited
I don't have any obvious operator to propose (ideally, it should be something that can be associated with the end of the string), but for the syntax, you just add it before the index, either after the leading [ or after the ... (One could also have it before the .., if one likes that symmetry better).
As for negation, there are two choices. I think I'd prefer to say that 0 is the position after the end of the string, -1 the position before that, and so on. Say we make the random choise of % for the magic character (any binary operator could be reused, as could for example:, ;, ,, /, @, $).
Then "banan"[%-3..%-1] == "nan", "banan"[%-4..4] == "ana". The easiest way to understand it is to think of %, in this context, as a shorthand for "sizeof(the string or array in question) +".
Actually, $ might be a better choice than %, anyone familiar with regexps can easily associate it to "end". Then it's
"banan"[$-3..$-1]
And when talking about ranges, I still like the old idea of using (x..y), [x..y) etc to represent open and half open intervals ;-)
/ Niels Möller (med röd bil)
I think it's clearer to not have $ imply negation, so that $-x can really be thought of as the subtraction sizeof(the string) - x. But that's a question of taste, I guess.
/ Niels Möller (med röd bil)
Previous text:
2003-05-16 00:28: Subject: Negative ranges revisited
Looks good to me. The operator could imply the negation, so that it's only e.g. foo[$3..$1]. Maybe the negation is good for clarity, but otoh it could easily be taken for a binary substraction and that the $ is a term.
$ has a slight drawback in that it's often treated as a symbol building character, typically used in machine generated symbols.
/ Martin Stjernholm, Roxen IS
I think it is easier to just rip the python notation for ranges, foo[a:b] and have negative values count from the end. That is more or less the same as your suggestion, but with ":" instead of "..-", without compatibility impact (if it works with the grammar).
/ Martin Nilsson (lambda)
Previous text:
2003-05-15 16:54: Subject: Negative ranges revisited
I got an idea of how to solve the age old issue of getting negative indices in ranges to work. We'd all like to do things like this:
foo = foo[..-2]; // Lose the last item.
But so far it hasn't worked because of cases like this:
foo = foo[..i-1] + foo[i+1..]; // Lose item i.
which should work even when i is zero.
My idea is to give the unary negation operator an additional literal meaning in the range operator. I.e. in the expression
foo[-a..-b]
both index operations takes place in the range -sizeof(foo)..-1 instead of the normal 0..sizeof(foo)-1. The expressions a and b are negated as usual. Thus, if they already contain the negative indices a double negation would be necessary:
foo[..- -b]
That's easily optimized away. Another example:
// Lose item i, where i is in the range -sizeof(foo)..-1. foo = foo[..- -(i-1)] + foo[- -(i+1)..];
There's a compatibility issue here, but I think it's minor. Only cases where range expressions are negated are affected. That means expressions that evaluate to values in the range 0 for the first element down to -sizeof(foo)+1 for the last, which I believe is fairly odd.
How to convey this to the range lfuns remains to be solved.
What do you say? Would it be too strange?
/ Martin Stjernholm, Roxen IS
This would have been my suggestion.
/ David Hedbor
Previous text:
2003-05-15 21:24: Subject: Negative ranges revisited
I think it is easier to just rip the python notation for ranges, foo[a:b] and have negative values count from the end. That is more or less the same as your suggestion, but with ":" instead of "..-", without compatibility impact (if it works with the grammar).
/ Martin Nilsson (lambda)
A very good suggestion, IMO.
/ Johan Sundström (folkskådare)
Previous text:
2003-05-15 21:24: Subject: Negative ranges revisited
I think it is easier to just rip the python notation for ranges, foo[a:b] and have negative values count from the end. That is more or less the same as your suggestion, but with ":" instead of "..-", without compatibility impact (if it works with the grammar).
/ Martin Nilsson (lambda)
So should...
a[-1:-3] work and thus reverse the subset of the array? :)
/ David Hedbor
Previous text:
2003-05-15 21:24: Subject: Negative ranges revisited
I think it is easier to just rip the python notation for ranges, foo[a:b] and have negative values count from the end. That is more or less the same as your suggestion, but with ":" instead of "..-", without compatibility impact (if it works with the grammar).
/ Martin Nilsson (lambda)
No, it's not the same as my suggestion. I had a "[-" part too, which is independent of the "..-" part. Each one would select indexing in either the 0..sizeof(x)-1 interval or -sizeof(x)..1 but never both at the same time. I.e. the fencepost cases in x[..i-1]+x[i+1..] would still work as today.
It'd work to adopt python-style ranges. If we do it I think we should deprecate the syntax with ".." since it'd be ugly with two different syntaxes and semantics for this.
However, python slices have their problems too:
One is the x[:-0] case. Although I generally like the a <= x < b style ranges, that special case is bad. I think it's about as bad as our current problem with negative ranges.
The other is the fencepost case that Pike currently handles more conveniently.
I'm not overly enthusiastic about replacing one flawed system with another that also is flawed, but in different ways. A solution that would really work is to abandon the notion of negative indices and instead add a proper count-from-the-end operator. Granted, that operator should not be the same as unary negation.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-05-15 21:24: Subject: Negative ranges revisited
I think it is easier to just rip the python notation for ranges, foo[a:b] and have negative values count from the end. That is more or less the same as your suggestion, but with ":" instead of "..-", without compatibility impact (if it works with the grammar).
/ Martin Nilsson (lambda)
It'd work to adopt python-style ranges. If we do it I think we should deprecate the syntax with ".." since it'd be ugly with two different syntaxes and semantics for this.
I think backwards compatibility is more important than making it not ugly though. I'm stil annoyed when pike warns me about writing 'string *', even though I don't really like that syntax. Deprecating *anything* is often a hassle for the end user.
At least in Pike we can use #pike to maintain backwards compatibility if we really do get rid of the .. syntax, when other languages change, they just become unusuable...
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-05-15 21:59: Subject: Negative ranges revisited
No, it's not the same as my suggestion. I had a "[-" part too, which is independent of the "..-" part. Each one would select indexing in either the 0..sizeof(x)-1 interval or -sizeof(x)..1 but never both at the same time. I.e. the fencepost cases in x[..i-1]+x[i+1..] would still work as today.
It'd work to adopt python-style ranges. If we do it I think we should deprecate the syntax with ".." since it'd be ugly with two different syntaxes and semantics for this.
However, python slices have their problems too:
One is the x[:-0] case. Although I generally like the a <= x < b style ranges, that special case is bad. I think it's about as bad as our current problem with negative ranges.
The other is the fencepost case that Pike currently handles more conveniently.
I'm not overly enthusiastic about replacing one flawed system with another that also is flawed, but in different ways. A solution that would really work is to abandon the notion of negative indices and instead add a proper count-from-the-end operator. Granted, that operator should not be the same as unary negation.
/ Martin Stjernholm, Roxen IS
I'm not overly enthusiastic about replacing one flawed system with another that also is flawed, but in different ways.
But this is not a question of replacing a system, but to add other system, isn't it?
/ Hedda (Vad ska jag äta idag då?)
Previous text:
2003-05-15 21:59: Subject: Negative ranges revisited
No, it's not the same as my suggestion. I had a "[-" part too, which is independent of the "..-" part. Each one would select indexing in either the 0..sizeof(x)-1 interval or -sizeof(x)..1 but never both at the same time. I.e. the fencepost cases in x[..i-1]+x[i+1..] would still work as today.
It'd work to adopt python-style ranges. If we do it I think we should deprecate the syntax with ".." since it'd be ugly with two different syntaxes and semantics for this.
However, python slices have their problems too:
One is the x[:-0] case. Although I generally like the a <= x < b style ranges, that special case is bad. I think it's about as bad as our current problem with negative ranges.
The other is the fencepost case that Pike currently handles more conveniently.
I'm not overly enthusiastic about replacing one flawed system with another that also is flawed, but in different ways. A solution that would really work is to abandon the notion of negative indices and instead add a proper count-from-the-end operator. Granted, that operator should not be the same as unary negation.
/ Martin Stjernholm, Roxen IS
No.
/ Peter Bortas
Previous text:
2003-05-17 02:28: Subject: Negative ranges revisited
I'm not overly enthusiastic about replacing one flawed system with another that also is flawed, but in different ways.
But this is not a question of replacing a system, but to add other system, isn't it?
/ Hedda (Vad ska jag äta idag då?)
Yes.
/ Martin Nilsson (lambda)
Previous text:
2003-05-17 02:28: Subject: Negative ranges revisited
I'm not overly enthusiastic about replacing one flawed system with another that also is flawed, but in different ways.
But this is not a question of replacing a system, but to add other system, isn't it?
/ Hedda (Vad ska jag äta idag då?)
Perhaps, but having two systems that are flawed in different ways isn't very exciting either. I think Niels' suggestion for a count-from-the-end operator is much better.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-05-17 02:28: Subject: Negative ranges revisited
I'm not overly enthusiastic about replacing one flawed system with another that also is flawed, but in different ways.
But this is not a question of replacing a system, but to add other system, isn't it?
/ Hedda (Vad ska jag äta idag då?)
Two complementary flawed systems can be quite nice.
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-05-17 19:45: Subject: Negative ranges revisited
Perhaps, but having two systems that are flawed in different ways isn't very exciting either. I think Niels' suggestion for a count-from-the-end operator is much better.
/ Martin Stjernholm, Roxen IS
But python's ranges are also slightly broken, as Marcus pointed out in text 10155351.
/ Niels Möller (med röd bil)
Previous text:
2003-05-15 21:24: Subject: Negative ranges revisited
I think it is easier to just rip the python notation for ranges, foo[a:b] and have negative values count from the end. That is more or less the same as your suggestion, but with ":" instead of "..-", without compatibility impact (if it works with the grammar).
/ Martin Nilsson (lambda)
pike-devel@lists.lysator.liu.se