Closed p5pRT closed 16 years ago
Resubmitting a bug report of mine back from February; this time through the proper channel (perlbug\, not p5p).
[paste]
While editing my Damn Book I re-remembered that couple of months back I ran into an anomaly in the handling of bitvectors.
Fiction: you have a bitvector which you want to shift.
The current (5.005_03-MT5) fact:
perl -wle '$b = ""; vec($b\, 0\, 1) = 1;print unpack("b*"\, $b);$b\<\<=1;print unpack("b*"\, $b)' 10000000 00001100
Huh? Adding -w tells more\, as usual: Argument "^A" isn't numeric in left_shift at -e line 1.
So left_shift assumes that the argument to shift is a number\, but "^A" isn't\, so it gets converted to string zero "0" (48\, 0x30\, 0b0000110).
I consider this behaviour to be rather broken. I think
$b \<\<= 1
should shift the whole bitvector left by one position and
vec($b\, 2\, 8) >>= 2
should shift the bits 16..23 right by two positions (of course not leaking into bits 8..15).
Back then I asked Larry whether the current behaviour is by design or something else.
larry: I suppose \<\< and >> ought to be made to work. There's a little more larry: chance of breaking things than with & and | because you can only larry: guess based on the stringiness of the first argument. But that's larry: no worse than ~\, I guess. larry: larry: Still\, there may be some programs out there that expect to be larry: able to coerce a string to integer and then shift it. Maybe we larry: should pre-deprecate it.
P.S. My original problem can be recoded with "use integer"\, but the original point was to demonstrate the similarity of bit vectors and integers vectors by coding the same algorithm using the two approaches. Now I found out that there are not similar enough. Besides\, the original formulation of the algorithm does not use integers\, it uses bit vectors. Sigh. I think I will drop the bitvector approach from the book.
-- $jhi++; # http://www.iki.fi/jhi/ # There is this special biologist word we use for 'stable'. # It is 'dead'. -- Jack Cohen
I can confirm this is present in @18374.
Still present in 5.8.5 and blead@22511
Resubmitting a bug report of mine back from February; this time through the proper channel (perlbug\, not p5p).
[paste]
While editing my Damn Book I re-remembered that couple of months back I ran into an anomaly in the handling of bitvectors.
Fiction: you have a bitvector which you want to shift.
The current (5.005_03-MT5) fact:
perl -wle '$b = ""; vec($b\, 0\, 1) = 1;print unpack("b*"\, $b);$b\<\<=1;print unpack("b*"\, $b)' 10000000 00001100
Huh? Adding -w tells more\, as usual: Argument "^A" isn't numeric in left_shift at -e line 1.
So left_shift assumes that the argument to shift is a number\, but "^A" isn't\, so it gets converted to string zero "0" (48\, 0x30\, 0b0000110).
I consider this behaviour to be rather broken. I think
$b \<\<= 1
should shift the whole bitvector left by one position and
vec\($b\, 2\, 8\) >>= 2
should shift the bits 16..23 right by two positions (of course not leaking into bits 8..15).
Just so we're clear\, and to add a proper TODO test case\, what would you consider the proper output to be?
On Wed\, Jul 20\, 2005 at 05:56:12AM -0700\, Steve Peters via RT wrote:
Resubmitting a bug report of mine back from February; this time through the proper channel (perlbug\, not p5p).
[paste]
While editing my Damn Book I re-remembered that couple of months back I ran into an anomaly in the handling of bitvectors.
Fiction: you have a bitvector which you want to shift.
The current (5.005_03-MT5) fact:
perl -wle '$b = ""; vec($b\, 0\, 1) = 1;print unpack("b*"\, $b);$b\<\<=1;print unpack("b*"\, $b)' 10000000 00001100
Huh? Adding -w tells more\, as usual: Argument "^A" isn't numeric in left_shift at -e line 1.
So left_shift assumes that the argument to shift is a number\, but "^A" isn't\, so it gets converted to string zero "0" (48\, 0x30\, 0b0000110).
I consider this behaviour to be rather broken. I think
$b \<\<= 1
should shift the whole bitvector left by one position and
vec\($b\, 2\, 8\) >>= 2
should shift the bits 16..23 right by two positions (of course not leaking into bits 8..15).
Just so we're clear\, and to add a proper TODO test case\, what would you consider the proper output to be?
I am opposed to such a change in behaviour.
\<\<= operates on numeric values\, while vec operates on strings.
vec($b\,0\,1) = 1
is just the same as
$b = "\x0\x0\x0\x01"
(ignoring endianess and int size complications)
If the \<\< and >> operators were to take any string as a bit pattern\, then it would break code like:
$b="1"; $b \<\<= 2; print $b
which should print 4\, not "\xc4".
-- The Enterprise is captured by a vastly superior alien intelligence which does not put them on trial. -- Things That Never Happen in "Star Trek" #10
Just so we're clear\, and to add a proper TODO test case\, what would you consider the proper output to be?
I am opposed to such a change in behaviour.
Rest peacefully\, so is Larry\, I once cornered him on this :-)
\<\<= operates on numeric values\, while vec operates on strings.
vec\($b\,0\,1\) = 1
is just the same as
$b = "\\x0\\x0\\x0\\x01"
(ignoring endianess and int size complications)
If the \<\< and >> operators were to take any string as a bit pattern\, then it would break code like:
$b="1"; $b \<\<= 2; print $b
which should print 4\, not "\xc4".
But on the other hand Larry could see the argumentation my way too\, that it should be possible to use \<\<= and >>= as bit shifters (looking at it from the C heritage it is strange that & | ~ ^ operate on strings as they were bitvectors\, but the shift ops don't). So an unfortunate murky corner of the dual (strings and numbers)\, err\, trefoil (strings and bitvectors and numbers)\, err\, quatrefoil (byte strings and Unicode strings and bitvectors and numbers) nature of Perl strings.
How to solve this\, if this is to be solved? *I* see as an ugly asymmetry blemish\, but since enraged hordes of people have not ascended upon yes over all these years\, I think I am in a minority\, and I can live with it. *IF* someone wants to fix this\, maybe a pragma. Or maybe borgify Bit::Vector :-)
-- Jarkko Hietaniemi \jhi@​iki\.fi http://www.iki.fi/jhi/ "There is this special biologist word we use for 'stable'. It is 'dead'." -- Jack Cohen
But on the other hand Larry could see the argumentation my way too\, that it should be possible to use \<\<= and >>= as bit shifters (looking at it from the C heritage it is strange that & | ~ ^ operate on strings as they were bitvectors\, but the shift ops don't). So an unfortunate murky corner of the dual (strings and numbers)\, err\, trefoil (strings and bitvectors and numbers)\, err\, quatrefoil (byte strings and Unicode strings and bitvectors and numbers) nature of Perl strings.
How to solve this\, if this is to be solved? *I* see as an ugly asymmetry blemish\, but since enraged hordes of people have not ascended upon yes over all these years\, I think I am in a minority\, and I can live with it. *IF* someone wants to fix this\, maybe a pragma. Or maybe borgify Bit::Vector :-)
How is the fixing of lexical pragmas progressing? If there were a working solution for that\, I could implement a pragma for shifting of scalars as bitvecs.
-- Jarkko Hietaniemi \jhi@​iki\.fi http://www.iki.fi/jhi/ "There is this special biologist word we use for 'stable'. It is 'dead'." -- Jack Cohen
On 8/6/05\, Jarkko Hietaniemi \jhietaniemi@​gmail\.com wrote:
How is the fixing of lexical pragmas progressing? If there were a working solution for that\, I could implement a pragma for shifting of scalars as bitvecs.
I've an unfinished patch\, and I've planned to work on this after the next 5.9.x is released. (Development plans are to be explained in my OSCON talk slides\, which I've to put on line soon. Must wait to be home to do that\, though\, due to my server having crashed or something.)
[stmpeters - Wed Jul 20 05:56:11 2005]:
Resubmitting a bug report of mine back from February; this time through the proper channel (perlbug\, not p5p).
[paste]
While editing my Damn Book I re-remembered that couple of months back I ran into an anomaly in the handling of bitvectors.
Fiction: you have a bitvector which you want to shift.
The current (5.005_03-MT5) fact:
perl -wle '$b = ""; vec($b\, 0\, 1) = 1;print unpack("b*"\, $b);$b\<\<=1;print unpack("b*"\, $b)' 10000000 00001100
Huh? Adding -w tells more\, as usual: Argument "^A" isn't numeric in left_shift at -e line 1.
So left_shift assumes that the argument to shift is a number\, but "^A" isn't\, so it gets converted to string zero "0" (48\, 0x30\, 0b0000110).
I consider this behaviour to be rather broken. I think
$b \<\<= 1
should shift the whole bitvector left by one position and
vec\($b\, 2\, 8\) >>= 2
should shift the bits 16..23 right by two positions (of course not leaking into bits 8..15).
Just so we're clear\, and to add a proper TODO test case\, what would you consider the proper output to be?
This thread sort of went off on a tangent. What should the expected results be?
Steve Peters via RT wrote:
[stmpeters - Wed Jul 20 05:56:11 2005]:
Resubmitting a bug report of mine back from February; this time through the proper channel (perlbug\, not p5p).
[paste]
While editing my Damn Book I re-remembered that couple of months back I ran into an anomaly in the handling of bitvectors.
Fiction: you have a bitvector which you want to shift.
The current (5.005_03-MT5) fact:
perl -wle '$b = ""; vec($b\, 0\, 1) = 1;print unpack("b*"\, $b);$b\<\<=1;print unpack("b*"\, $b)' 10000000 00001100
Huh? Adding -w tells more\, as usual: Argument "^A" isn't numeric in left_shift at -e line 1.
So left_shift assumes that the argument to shift is a number\, but "^A" isn't\, so it gets converted to string zero "0" (48\, 0x30\, 0b0000110).
I consider this behaviour to be rather broken. I think
$b \<\<= 1
should shift the whole bitvector left by one position and
vec\($b\, 2\, 8\) >>= 2
should shift the bits 16..23 right by two positions (of course not leaking into bits 8..15).
Just so we're clear\, and to add a proper TODO test case\, what would you consider the proper output to be?
This thread sort of went off on a tangent. What should the expected results be?
Well\, ASSUMING that there will be in future a way to make shifting of bitvecs to work as\, well\, shifting of bitvecs\, instead of the shift ops assuming their arguments are numbers (which must be kept as the default way of doing things because of hysterical raisins)... assuming this new pragma is called "bitvec":
perl -Mbitvec -wle '$b = ""; vec($b\, 0\, 1) = 1; print unpack("b*"\,$b); $b\<\<=1; print unpack("b*"\, $b)' 10000000 01000000
-- Jarkko Hietaniemi \jhi@​iki\.fi http://www.iki.fi/jhi/ "There is this special biologist word we use for 'stable'. It is 'dead'." -- Jack Cohen
On Wed\, Sep 28\, 2005 at 09:01:12AM +0300\, Jarkko Hietaniemi wrote:
Steve Peters via RT wrote:
This thread sort of went off on a tangent. What should the expected results be?
Well\, ASSUMING that there will be in future a way to make shifting of bitvecs to work as\, well\, shifting of bitvecs\, instead of the shift ops assuming their arguments are numbers (which must be kept as the default way of doing things because of hysterical raisins)... assuming this new pragma is called "bitvec":
perl -Mbitvec -wle '$b = ""; vec($b\, 0\, 1) = 1; print unpack("b*"\,$b); $b\<\<=1; print unpack("b*"\, $b)' 10000000 01000000
I'd rather see a pragma that allowed changing how &\,|\, etc. work also. Maybe: use bitvec auto => -shiftops;
to allow shifting as bitvecs if they've never been used in numeric context
use bitvec string => -shiftops;
to have the shift ops always shift as bitvecs\, and
use bitvec numeric => -shiftops;
being the default\, making the ops always assume numbers.
It would also allow affecting the bitwise ops (~\, &\, |\, ^) which would default to:
use bitvec auto => -bitwise;
And use bitvec default => -all;
would restore the defaults.
I know I'd use
use bitvec string => -all;
often in limited lexical scopes.
How about adding leftshift() and rightshift() as functions in a standard bitvec.pm\, rather than fiddling with the meaning of >> and \<\< ?
How about adding leftshift() and rightshift() as functions in a standard bitvec.pm\, rather than fiddling with the meaning of >> and \<\< ?
2008/11/14 Chip Salzenberg via RT \perlbug\-comment@​perl\.org:
How about adding leftshift() and rightshift() as functions in a standard bitvec.pm\, rather than fiddling with the meaning of >> and \<\< ?
Except the obligatory bikeshedding session on the new module name\, (which I like\, by the way)\, I think that's a good idea.
On Mon\, Nov 17\, 2008 at 09:36:07AM +0100\, Rafael Garcia-Suarez wrote:
2008/11/14 Chip Salzenberg via RT \perlbug\-comment@​perl\.org:
How about adding leftshift() and rightshift() as functions in a standard bitvec.pm\, rather than fiddling with the meaning of >> and \<\< ?
Except the obligatory bikeshedding session on the new module name\, (which I like\, by the way)\, I think that's a good idea.
I'm having a hard time deciding which way is "left". The convention for numbers holds the low bit at the right\, but the convention for bit vectors in Perl\, as strings. holds the low bit at the left. Perhaps we should call these functions "insert_low_bits" and "remove_low_bits". Awkward\, tho. -- Chip Salzenberg \chip@​pobox\.com
On Mon\, Nov 17\, 2008 at 09:36:07AM +0100\, Rafael Garcia-Suarez wrote:
2008/11/14 Chip Salzenberg via RT \perlbug\-comment@​perl\.org:
How about adding leftshift() and rightshift() as functions in a standard bitvec.pm\, rather than fiddling with the meaning of >> and \<\< ?
Except the obligatory bikeshedding session on the new module name\, (which I like\, by the way)\, I think that's a good idea.
Well ... does it count as bikeshedding if it's your own module? Here's a first cut at the 'vec' module. Please don't commit it just yet\, it needs review. So ... review\, please? (including the module name\, I suppose)
=item insert_low_bits STRING\, COUNT
Accept a bitvector STRING\, a la L\
=item remove_low_bits STRING\, COUNT
Accept a bitvector STRING\, a la L\
Chip Salzenberg \chip@​pobox\.com
2008/11/17 Chip Salzenberg \chip@​pobox\.com:
On Mon\, Nov 17\, 2008 at 09:36:07AM +0100\, Rafael Garcia-Suarez wrote:
2008/11/14 Chip Salzenberg via RT \perlbug\-comment@​perl\.org:
How about adding leftshift() and rightshift() as functions in a standard bitvec.pm\, rather than fiddling with the meaning of >> and \<\< ?
Except the obligatory bikeshedding session on the new module name\, (which I like\, by the way)\, I think that's a good idea.
Well ... does it count as bikeshedding if it's your own module? Here's a first cut at the 'vec' module. Please don't commit it just yet\, it needs review. So ... review\, please? (including the module name\, I suppose)
I expect this one will need to be dual-lived. At which point occurs the question\, is it really needed in the core...
Some minor nits:
=item insert_low_bits STRING\, COUNT
Accept a bitvector STRING\, a la L\
\, and an integral bit COUNT. Return a
à la L\<perlfunc/vec> (same link to be fixed in vec.pm)
new bitvector that is a copy of the original STRING but with COUNT zero bits inserted at the low end of the vector; that is\, at the front of the string. COUNT must be nonnegative.
=item remove_low_bits STRING\, COUNT
Accept a bitvector STRING\, a la L\
\, and an integral bit COUNT. Return a new bitvector that is a copy of the original STRING but with COUNT bits removed from the low end of the vector; that is\, from the front of the string.
What about "shift" and "unshift" instead of insert and remove ?
diff --git a/ext/vec/Makefile.PL b/ext/vec/Makefile.PL new file mode 100644 index 0000000..ff8910a --- /dev/null +++ b/ext/vec/Makefile.PL @@ -0\,0 +1\,7 @@ +use ExtUtils::MakeMaker; + +WriteMakefile( + VERSION_FROM => "vec.pm"\, + NAME => "vec"\, + OPTIMIZE => '-g'\,
Add to that C\<MAN3PODS => {}> (to avoid converting the manpage needlessly) if $ENV{PERL_CORE} is true.
diff --git a/ext/vec/t/vec.t b/ext/vec/t/vec.t new file mode 100644 index 0000000..57a21b2 --- /dev/null +++ b/ext/vec/t/vec.t
Maybe add some tests with strings flagged as utf8 ? Just to be sure it won't break ?
diff --git a/ext/vec/vec.xs b/ext/vec/vec.xs new file mode 100644 index 0000000..41d45e8 --- /dev/null +++ b/ext/vec/vec.xs @@ -0\,0 +1\,83 @@ +/* Copyright (c) 2008 Graham Barr \chip@​pobox\.com. All rights reserved.
You're Graham Barr in disguise ? :)
Quoth chip@pobox.com (Chip Salzenberg):
On Mon\, Nov 17\, 2008 at 09:36:07AM +0100\, Rafael Garcia-Suarez wrote:
2008/11/14 Chip Salzenberg via RT \perlbug\-comment@​perl\.org:
How about adding leftshift() and rightshift() as functions in a standard bitvec.pm\, rather than fiddling with the meaning of >> and \<\< ?
Except the obligatory bikeshedding session on the new module name\, (which I like\, by the way)\, I think that's a good idea.
I'm having a hard time deciding which way is "left". The convention for numbers holds the low bit at the right\, but the convention for bit vectors in Perl\, as strings. holds the low bit at the left. Perhaps we should call these functions "insert_low_bits" and "remove_low_bits". Awkward\, tho.
"shiftdown" and "shiftup"? Although\, given that it only works on strings\, I think 'left' and 'right' are pretty clear. Indeed\, for strings I think 'left' is clearer than 'low' to mean the (textually) first bit in the string.
Ben
On Mon\, Nov 17\, 2008 at 03:21:29AM -0800\, Chip Salzenberg wrote:
On Mon\, Nov 17\, 2008 at 09:36:07AM +0100\, Rafael Garcia-Suarez wrote:
2008/11/14 Chip Salzenberg via RT \perlbug\-comment@​perl\.org:
How about adding leftshift() and rightshift() as functions in a standard bitvec.pm\, rather than fiddling with the meaning of >> and \<\< ?
Except the obligatory bikeshedding session on the new module name\, (which I like\, by the way)\, I think that's a good idea.
Well ... does it count as bikeshedding if it's your own module? Here's a first cut at the 'vec' module. Please don't commit it just yet\, it needs review. So ... review\, please? (including the module name\, I suppose)
=item insert\_low\_bits STRING\, COUNT
The function name makes me think I can supply the bits that will be inserted.
Instead of focussing on just these two shift operations I wonder if an analogy with arrays of bits\, or strings of bits\, could be developed into a more general interface. Like a splicebits() analogous with splice() or subbits() analogous with substr().
splicebits VEC\,OFFSET\,LENGTH\,LIST splicebits VEC\,OFFSET\,LENGTH splicebits VEC\,OFFSET splicebits VEC
subbits VEC\,OFFSET\,LENGTH\,REPLACEMENT subbits VEC\,OFFSET\,LENGTH subbits VEC\,OFFSET
With more specialized functions implemented\, or at least specified\, in terms of the general one.
Just a thought.
Tim.
Instead of focussing on just these two shift operations I wonder if an analogy with arrays of bits\, or strings of bits\, could be developed into a more general interface. Like a splicebits() analogous with splice() or subbits() analogous with substr().
With more specialized functions implemented\, or at least specified\, in terms of the general one.
Just a thought.
Tim.
I concur. When I was writing Scalar::Vec::Util\, I felt like the atomic operation for vec strings really was the copy of bits\, from an arbitrary position to another. Shifting\, unshifting\, splicing and such then seem to be more or less compositions of those.
Vincent.
On Mon\, Nov 17\, 2008 at 12:43:39PM +0100\, Rafael Garcia-Suarez wrote:
I expect this one will need to be dual-lived. At which point occurs the question\, is it really needed in the core...
Yes\, this was my thought too. If it exists\, and it's not the default\, and you know that you need to use it\, what is wrong with CPAN?
Nicholas Clark
On Mon\, Nov 17\, 2008 at 02:27:17PM +0100\, Vincent Pit wrote:
When I was writing Scalar::Vec::Util\, I felt like the atomic operation for vec strings really was the copy of bits\, from an arbitrary position to another. Shifting\, unshifting\, splicing and such then seem to be more or less compositions of those.
Your Calar::Vec::Util::vcopy method ... does it work with overlapping ranges? I ass_u_med not ... but if so\, then I'll just mark the bug fixed with a pointer to your module. -- Chip Salzenberg \chip@​pobox\.com
On Mon\, Nov 17\, 2008 at 01:31:11PM +0000\, Nicholas Clark wrote:
Yes\, this was my thought too. If it exists\, and it's not the default\, and you know that you need to use it\, what is wrong with CPAN?
I agree. Since the original reporter was Jarkko\, and he asked for a language feature ... well\, I figured I'd at least _start_ with a core module. But it seems to me now that this is better handled via CPAN. -- Chip Salzenberg \chip@​pobox\.com
On Mon\, Nov 17\, 2008 at 09:04:12AM -0800\, Chip Salzenberg wrote:
On Mon\, Nov 17\, 2008 at 02:27:17PM +0100\, Vincent Pit wrote:
When I was writing Scalar::Vec::Util\, I felt like the atomic operation for vec strings really was the copy of bits\, from an arbitrary position to another. Shifting\, unshifting\, splicing and such then seem to be more or less compositions of those.
Your Calar::Vec::Util::vcopy method ... does it work with overlapping ranges? I ass_u_med not ... but if so\, then I'll just mark the bug fixed with a pointer to your module.
Silly me\, RTFM:
vcopy $t\, 10\, $t\, 20\, 30; # Overalapping areas DWIM.
OK\, I'm calling the bug closed. Thanks\, Vincent. -- Chip Salzenberg \chip@​pobox\.com
@chipdude - Status changed from 'open' to 'resolved'
Migrated from rt.perl.org#969 (status was 'resolved')
Searchable as RT969$