digitalmars.D - Why no cast between integral types and bit[]?
- Jarrett Billingsley (18/18) Aug 19 2005 This works just fine:
- Ben Hinkle (3/23) Aug 19 2005 What would cast(bit[])(1+2) do?
- Jarrett Billingsley (3/4) Aug 19 2005 Return a bit array 32 elements long with bits 0 and 1 set to 1?
- Ben Hinkle (5/9) Aug 19 2005 But a dynamic array is a pointer and length so I don't know where it is
- Jarrett Billingsley (29/32) Aug 19 2005 ..You know, that's a good point. Then again, nothing says that the resu...
- Ben Hinkle (19/52) Aug 19 2005 Not all expression evaluate to lvalues. For example there is no location...
- Jarrett Billingsley (9/26) Aug 19 2005 You also can't say 5=x, but that didn't seem to be what you were getting...
- Regan Heath (36/36) Aug 19 2005 I've often thought that the ability to slice any basic type would be qui...
- Jarrett Billingsley (7/43) Aug 20 2005 Right, that's kind of what I would like this for, twiddling bits in numb...
- Ben Hinkle (8/75) Aug 20 2005 The thing about a bit array is that it doesn't know about big-endian or
- Jarrett Billingsley (3/9) Aug 20 2005 Oof. Yeah, that's an issue.
- Regan Heath (5/85) Aug 20 2005 All the more reason to have the ability to slice basic types built-in an...
- Ben Hinkle (9/95) Aug 21 2005 I don't think the problems can be wished away with magic. The core issue...
- Regan Heath (34/48) Aug 21 2005 Almost irrelevant. eg. in an assignment:
- Ben Hinkle (41/90) Aug 21 2005 I thought you guys were looking for something general purpose. I agree i...
- Regan Heath (43/96) Aug 21 2005 The OP might have been. I wasn't.
- Ben Hinkle (17/29) Aug 21 2005 So I guess the proposal is:
- Regan Heath (33/68) Aug 21 2005 Yes.
- Ben Hinkle (17/43) Aug 21 2005 I say special case because it would be the only construct in D that take...
- Regan Heath (34/75) Aug 21 2005 I need a concrete example to understand the problem here.
- Regan Heath (35/46) Aug 21 2005 Are you saying that:
- Derek Parnell (9/69) Aug 21 2005 The more I see examples of your proposal, the more I like another way of
- Regan Heath (13/83) Aug 22 2005 The question is then, where does the problem lie, in the proposal or in ...
- Ben Hinkle (20/56) Aug 22 2005 There is a big difference between j[] = i[a..b] and j = i[a..b] no matte...
- Regan Heath (11/35) Aug 22 2005 You're right. I agree.
- Derek Parnell (24/43) Aug 21 2005 On Mon, 22 Aug 2005 13:14:39 +1200, Regan Heath wrote:
- Regan Heath (9/46) Aug 21 2005 But that's exactly what it is.
- Derek Parnell (33/63) Aug 21 2005 All data is a set of bits, but nearly all data is never used this way. D...
- Regan Heath (33/90) Aug 21 2005 I agree totally. When it 'conceptually' makes sense you will use [] and ...
- Derek Parnell (8/12) Aug 21 2005 The joke is that Walter's not going to do either anyway. ;-)
- Regan Heath (3/9) Aug 21 2005 We can but hope.
This works just fine: ubyte[] a=new ubyte[1]; a[0]=5; bit[] b=cast(bit[])a; But this doesn't: ubyte a=5; bit[] b=cast(bit[])a; I would think that adding support of casting integral types to bit arrays would be a trivial task, as it would be just like casting a single-element array. Then there's the inverse: static bit[8] b=[1,0,1,0,0,0,0,0]; ubyte[] a=cast(ubyte[])b; writefln(a); I can see how casting from bit[] to an integral type would be a little more difficult, but really, all that'd have to be done would be to increase the length of the bit array to the size of the integer if it's too small. How about it?
Aug 19 2005
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:de4rek$27i9$1 digitaldaemon.com...This works just fine: ubyte[] a=new ubyte[1]; a[0]=5; bit[] b=cast(bit[])a; But this doesn't: ubyte a=5; bit[] b=cast(bit[])a; I would think that adding support of casting integral types to bit arrays would be a trivial task, as it would be just like casting a single-element array.What would cast(bit[])(1+2) do?Then there's the inverse: static bit[8] b=[1,0,1,0,0,0,0,0]; ubyte[] a=cast(ubyte[])b; writefln(a); I can see how casting from bit[] to an integral type would be a little more difficult, but really, all that'd have to be done would be to increase the length of the bit array to the size of the integer if it's too small. How about it?
Aug 19 2005
"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:de4usa$2bas$1 digitaldaemon.com...What would cast(bit[])(1+2) do?Return a bit array 32 elements long with bits 0 and 1 set to 1?
Aug 19 2005
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:de578c$2iq7$1 digitaldaemon.com..."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:de4usa$2bas$1 digitaldaemon.com...But a dynamic array is a pointer and length so I don't know where it is getting the pointer from. I know bit[] is funny sometimes wrt array semantics but it needs a ptr.What would cast(bit[])(1+2) do?Return a bit array 32 elements long with bits 0 and 1 set to 1?
Aug 19 2005
"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:de58t4$2k80$1 digitaldaemon.com...But a dynamic array is a pointer and length so I don't know where it is getting the pointer from. I know bit[] is funny sometimes wrt array semantics but it needs a ptr...You know, that's a good point. Then again, nothing says that the result of a cast has to point to the location of the expression that was casted, so a cast to a bit array could return a new bit array. But if you really wanted the cast to point to the original number, the D compiler could force it to, doing something like: bit[]* intToBit(int* x) { struct arr { uint length; void* ptr; } arr* a=new arr; a.length=32; a.ptr=x; return cast(bit[]*)cast(void*)a; } void main() { int x=5; bit[] b=*intToBit(&x); // Writes 00000000000000000000000000000101 for(int i=31; i>=0; i--) writef(b[i] ? 1 : 0); } Of course, since the compiler has access to all the internals of the arrays, it wouldn't have to use a kludgy function like that.
Aug 19 2005
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:de5lla$2uci$1 digitaldaemon.com..."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:de58t4$2k80$1 digitaldaemon.com...Not all expression evaluate to lvalues. For example there is no location of the result of the expression (1+2). You can't say &(1+2).But a dynamic array is a pointer and length so I don't know where it is getting the pointer from. I know bit[] is funny sometimes wrt array semantics but it needs a ptr...You know, that's a good point. Then again, nothing says that the result of a cast has to point to the location of the expression that was casted,so a cast to a bit array could return a new bit array. But if you really wanted the cast to point to the original number, the D compiler could force it to, doing something like: bit[]* intToBit(int* x) { struct arr { uint length; void* ptr; } arr* a=new arr; a.length=32; a.ptr=x; return cast(bit[]*)cast(void*)a; }I'm not sure why you are allocating a new dynamic array reference from the GC. One can write intToBit as bit[] toBits(void* x, int len) { return cast(bit[])x[0..len]; } int main() { int x; bit[] b = toBits(&x,x.sizeof*8); b[3] = 1; printf("%d\n",x); return 0; } In any case one still has to supply a pointer to x. I think making more special cases for bit arrays is not worth it especially when a little helper like toBits can make the code more readable if that's the concern.void main() { int x=5; bit[] b=*intToBit(&x); // Writes 00000000000000000000000000000101 for(int i=31; i>=0; i--) writef(b[i] ? 1 : 0); } Of course, since the compiler has access to all the internals of the arrays, it wouldn't have to use a kludgy function like that.
Aug 19 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:de5pf8$3168$1 digitaldaemon.com...Not all expression evaluate to lvalues. For example there is no location of the result of the expression (1+2). You can't say &(1+2).You also can't say 5=x, but that didn't seem to be what you were getting at with your first reply.I'm not sure why you are allocating a new dynamic array reference from the GC. One can write intToBit as bit[] toBits(void* x, int len) { return cast(bit[])x[0..len]; } int main() { int x; bit[] b = toBits(&x,x.sizeof*8); b[3] = 1; printf("%d\n",x); return 0; }I wasn't aware that you could cast void[] to bit[], as I had tried casting void* to bit[] and it didn't seem to work; hence the bit[]* thing in mine.In any case one still has to supply a pointer to x. I think making more special cases for bit arrays is not worth it especially when a little helper like toBits can make the code more readable if that's the concern.Oh, have it your way then ;) I just always thought that it was odd that D supported arrays of consecutive bits, while it had no support for converting integers, which are consecutive arrays of bits, to bit arrays.
Aug 19 2005
I've often thought that the ability to slice any basic type would be quite nice, eg. ubyte b; uint i; long l; b[0] = 1; i[5] = 0; l[16..32] = 1; in other words slicing a basic type gives a bit[] or bit. Of course the big problem that rears it's head is how does this work: bit[] b; uint i; b = i[5..15]; A slice on non-byte boundaries... It seems it can't without copying or great internal hoop jumping. So, I would limit the feature to lvalue assignments instead, i.e. bit[10] b; uint i; i[5..15] = b[]; //would be fine, but b = i[5..15]; //would not perhaps, if we desire, we can allow: b[] = i[5..15]; or b = i[5..15].dup; i.e. a copy would be easier to implement. The reason I like this is that code that would read something like: variable |= 1<<16; or variable &= ~(1<<16) or whatever can now read: variable[16] = 1; or variable[16] = 0; (note I have not paid strict attention to the code above, it's probably wrong, but you should get the picture) Regan
Aug 19 2005
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsvr9dkx523k2f5 nrage.netwin.co.nz...I've often thought that the ability to slice any basic type would be quite nice, eg. ubyte b; uint i; long l; b[0] = 1; i[5] = 0; l[16..32] = 1; in other words slicing a basic type gives a bit[] or bit. Of course the big problem that rears it's head is how does this work: bit[] b; uint i; b = i[5..15]; A slice on non-byte boundaries... It seems it can't without copying or great internal hoop jumping. So, I would limit the feature to lvalue assignments instead, i.e. bit[10] b; uint i; i[5..15] = b[]; //would be fine, but b = i[5..15]; //would not perhaps, if we desire, we can allow: b[] = i[5..15]; or b = i[5..15].dup; i.e. a copy would be easier to implement. The reason I like this is that code that would read something like: variable |= 1<<16; or variable &= ~(1<<16) or whatever can now read: variable[16] = 1; or variable[16] = 0; (note I have not paid strict attention to the code above, it's probably wrong, but you should get the picture) ReganRight, that's kind of what I would like this for, twiddling bits in numbers. I was thinking about something to replace bitfields as well, as shifting and masking is just so much fun, but it'd be nice to do something like a[0..4]=6. Then again, for bitfields, you could use a union between a bit[32] and a uint.
Aug 20 2005
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:de7c77$17at$1 digitaldaemon.com..."Regan Heath" <regan netwin.co.nz> wrote in message news:opsvr9dkx523k2f5 nrage.netwin.co.nz...The thing about a bit array is that it doesn't know about big-endian or little-endian and the exact packing of the bit array into memory is compiler-dependent (see for example http://www.digitalmars.com/d/arrays.html#bitarrays). With shifting the compiler knows the size of the data being shifted and so you the coder don't have to worry about all the memory layout details.I've often thought that the ability to slice any basic type would be quite nice, eg. ubyte b; uint i; long l; b[0] = 1; i[5] = 0; l[16..32] = 1; in other words slicing a basic type gives a bit[] or bit. Of course the big problem that rears it's head is how does this work: bit[] b; uint i; b = i[5..15]; A slice on non-byte boundaries... It seems it can't without copying or great internal hoop jumping. So, I would limit the feature to lvalue assignments instead, i.e. bit[10] b; uint i; i[5..15] = b[]; //would be fine, but b = i[5..15]; //would not perhaps, if we desire, we can allow: b[] = i[5..15]; or b = i[5..15].dup; i.e. a copy would be easier to implement. The reason I like this is that code that would read something like: variable |= 1<<16; or variable &= ~(1<<16) or whatever can now read: variable[16] = 1; or variable[16] = 0; (note I have not paid strict attention to the code above, it's probably wrong, but you should get the picture) ReganRight, that's kind of what I would like this for, twiddling bits in numbers. I was thinking about something to replace bitfields as well, as shifting and masking is just so much fun, but it'd be nice to do something like a[0..4]=6. Then again, for bitfields, you could use a union between a bit[32] and a uint.
Aug 20 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:de7enn$1998$1 digitaldaemon.com...The thing about a bit array is that it doesn't know about big-endian or little-endian and the exact packing of the bit array into memory is compiler-dependent (see for example http://www.digitalmars.com/d/arrays.html#bitarrays). With shifting the compiler knows the size of the data being shifted and so you the coder don't have to worry about all the memory layout details.Oof. Yeah, that's an issue.
Aug 20 2005
On Sat, 20 Aug 2005 10:28:33 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:de7c77$17at$1 digitaldaemon.com...All the more reason to have the ability to slice basic types built-in and have the compiler work it's magic in the background. Regan"Regan Heath" <regan netwin.co.nz> wrote in message news:opsvr9dkx523k2f5 nrage.netwin.co.nz...The thing about a bit array is that it doesn't know about big-endian or little-endian and the exact packing of the bit array into memory is compiler-dependent (see for example http://www.digitalmars.com/d/arrays.html#bitarrays). With shifting the compiler knows the size of the data being shifted and so you the coder don't have to worry about all the memory layout details.I've often thought that the ability to slice any basic type would be quite nice, eg. ubyte b; uint i; long l; b[0] = 1; i[5] = 0; l[16..32] = 1; in other words slicing a basic type gives a bit[] or bit. Of course the big problem that rears it's head is how does this work: bit[] b; uint i; b = i[5..15]; A slice on non-byte boundaries... It seems it can't without copying or great internal hoop jumping. So, I would limit the feature to lvalue assignments instead, i.e. bit[10] b; uint i; i[5..15] = b[]; //would be fine, but b = i[5..15]; //would not perhaps, if we desire, we can allow: b[] = i[5..15]; or b = i[5..15].dup; i.e. a copy would be easier to implement. The reason I like this is that code that would read something like: variable |= 1<<16; or variable &= ~(1<<16) or whatever can now read: variable[16] = 1; or variable[16] = 0; (note I have not paid strict attention to the code above, it's probably wrong, but you should get the picture) ReganRight, that's kind of what I would like this for, twiddling bits in numbers. I was thinking about something to replace bitfields as well, as shifting and masking is just so much fun, but it'd be nice to do something like a[0..4]=6. Then again, for bitfields, you could use a union between a bit[32] and a uint.
Aug 20 2005
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsvtzskgc23k2f5 nrage.netwin.co.nz...On Sat, 20 Aug 2005 10:28:33 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:I don't think the problems can be wished away with magic. The core issue is that bit[] forgets the layout of the numeric types. What would the expression x[a .. b] actually return? I don't mean "it returns the bits from a to b". I mean what is the type of the result? It should't be bit[]. It's simpler (and well-defined) to use & and |. Besides to me x[a .. b] is array indexing not bit-twiddling so I'm not even sure I like the idea of abusing [] to slice numeric types."Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:de7c77$17at$1 digitaldaemon.com...All the more reason to have the ability to slice basic types built-in and have the compiler work it's magic in the background. Regan"Regan Heath" <regan netwin.co.nz> wrote in message news:opsvr9dkx523k2f5 nrage.netwin.co.nz...The thing about a bit array is that it doesn't know about big-endian or little-endian and the exact packing of the bit array into memory is compiler-dependent (see for example http://www.digitalmars.com/d/arrays.html#bitarrays). With shifting the compiler knows the size of the data being shifted and so you the coder don't have to worry about all the memory layout details.I've often thought that the ability to slice any basic type would be quite nice, eg. ubyte b; uint i; long l; b[0] = 1; i[5] = 0; l[16..32] = 1; in other words slicing a basic type gives a bit[] or bit. Of course the big problem that rears it's head is how does this work: bit[] b; uint i; b = i[5..15]; A slice on non-byte boundaries... It seems it can't without copying or great internal hoop jumping. So, I would limit the feature to lvalue assignments instead, i.e. bit[10] b; uint i; i[5..15] = b[]; //would be fine, but b = i[5..15]; //would not perhaps, if we desire, we can allow: b[] = i[5..15]; or b = i[5..15].dup; i.e. a copy would be easier to implement. The reason I like this is that code that would read something like: variable |= 1<<16; or variable &= ~(1<<16) or whatever can now read: variable[16] = 1; or variable[16] = 0; (note I have not paid strict attention to the code above, it's probably wrong, but you should get the picture) ReganRight, that's kind of what I would like this for, twiddling bits in numbers. I was thinking about something to replace bitfields as well, as shifting and masking is just so much fun, but it'd be nice to do something like a[0..4]=6. Then again, for bitfields, you could use a union between a bit[32] and a uint.
Aug 21 2005
On Sun, 21 Aug 2005 10:05:46 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:Almost irrelevant. eg. in an assignment: uint b; b[0..5] = 1; It doesn't matter, the compiler is doing it all in the background, the user never needs to know the type, or have one to store anything in, however.. (see next response)All the more reason to have the ability to slice basic types built-in and have the compiler work it's magic in the background.I don't think the problems can be wished away with magic. The core issue is that bit[] forgets the layout of the numeric types. What would the expression x[a .. b] actually return? I don't mean "it returns the bits from a to b". I mean what is the type of the result?It should't be bit[].Why not? I mean, if you actually want to copy bits, you might write: bit[5] a; uint b; a[] = b[0..5]; I don't think we need/want to remove the bit[] types I just think being able to slice basic types to get bit[] types would be very useful. I think we do want to restrict it to bit boundaries or require a copy (anything else seems quite complicated, though the compiler is the best place to handle that, if it was desired)It's simplerI disagree. After years of experience using & and | is easy (perhaps 'simple'), but, to a begginer it's not at all.(and well-defined) to use & and |.In C and other languages, yes. In D, c'mon we have bit[], surely it can make bit twiddling really nice and easy. It seems bizarre to say the least that we're not using bit[] for bit twiddling but instead using old techniques which are both harder to understand and use (until you're proficient with them).Besides to me x[a .. b] is array indexing not bit-twiddlingSure, until you add "= 1" or "= 0", then it's an assignment and thus bit twiddling .. obviously?so I'm not even sure I like the idea of abusing [] to slice numeric types."abusing" .. your opinion is obvious from your choice of words ;) IMO the idea of slicing a basic type to get bit[]: - Makes bit twiddling _much_ easier. - Makes bit twiddling _much_ simpler for begginers. - Makes more use of the bit[] type (we're not using it for bit twiddling, why?). Regan
Aug 21 2005
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsvvmcao123k2f5 nrage.netwin.co.nz...On Sun, 21 Aug 2005 10:05:46 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:I thought you guys were looking for something general purpose. I agree if the proposal is limited to indexed assignment statements that the return type doesn't matter because there is no return type. But that's not what the proposal is, I thought.Almost irrelevant. eg. in an assignment: uint b; b[0..5] = 1; It doesn't matter, the compiler is doing it all in the background, the user never needs to know the type, or have one to store anything in, however.. (see next response)All the more reason to have the ability to slice basic types built-in and have the compiler work it's magic in the background.I don't think the problems can be wished away with magic. The core issue is that bit[] forgets the layout of the numeric types. What would the expression x[a .. b] actually return? I don't mean "it returns the bits from a to b". I mean what is the type of the result?See http://en.wikipedia.org/wiki/Endian. On big-endian machines b[0..16], for example, would be the last two bytes of the memory range &b .. &b+4 in reverse order and for little endian machines is the first two bytes in incresing order. For longs and shorts it would behave similarly. The type bit[] is packed into compiler-dependent chunks in whatever ways it wants. I imagine it would take some non-trivial changes to bit[] to support slicing non-int sized types on big-endian machines.It should't be bit[].Why not?I mean, if you actually want to copy bits, you might write: bit[5] a; uint b; a[] = b[0..5];I understand.I don't think we need/want to remove the bit[] types I just think being able to slice basic types to get bit[] types would be very useful.I'm not aware of any post in this thread suggesting bit[] go away. I'm aware you think slicing basic types to get bit[] would be useful.I think we do want to restrict it to bit boundaries or require a copy (anything else seems quite complicated, though the compiler is the best place to handle that, if it was desired)I'm not sure what exactly you are referring to. Which bit boundaries and copying do you mean? By the way, I'm guessing as to exactly what the proposal is. My impression is that the proposal is to slice lvalues of numeric type to obtain bit[]. The only numeric type I can imagine it working for is the underlying numeric type used by bit[] (on big endian machines). For little endian machines bit[] can be used for any slice that starts at a multiple of the underlying bit-packing unit (eg int).Given that using bit[] will require lots of special cases to explain (see above) I think & and | is simpler. If that's too confusing for beginners one can write simple functions like template getbit(T) bit getbit(T x, int n){ return cast(bit)(x & ((cast(T)1) << n)); } } etcIt's simplerI disagree. After years of experience using & and | is easy (perhaps 'simple'), but, to a begginer it's not at all.I think a more detailed proposal would help show the trade-off and true impact of trying to extend bit[] to be used as a replacement for &|. I don't think it's a trivial as you assume. I view bit[] as only being a packed array of true/false values (ala Pascal and C++). The exact packing behavior is compiler-dependent.(and well-defined) to use & and |.In C and other languages, yes. In D, c'mon we have bit[], surely it can make bit twiddling really nice and easy. It seems bizarre to say the least that we're not using bit[] for bit twiddling but instead using old techniques which are both harder to understand and use (until you're proficient with them).Other languages have bit arrays - I'm thinking specifically of Pascal's packed arrays and STL's bit vectors but there could be others, too. I'm not aware of any that try to use bit arrays to do bit twiddling. They are meant to be memory efficient arrays of true/false values and that's it.Besides to me x[a .. b] is array indexing not bit-twiddlingSure, until you add "= 1" or "= 0", then it's an assignment and thus bit twiddling .. obviously?so I'm not even sure I like the idea of abusing [] to slice numeric types."abusing" .. your opinion is obvious from your choice of words ;) IMO the idea of slicing a basic type to get bit[]: - Makes bit twiddling _much_ easier. - Makes bit twiddling _much_ simpler for begginers. - Makes more use of the bit[] type (we're not using it for bit twiddling, why?). Regan
Aug 21 2005
On Sun, 21 Aug 2005 19:22:54 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:The OP might have been. I wasn't.It doesn't matter, the compiler is doing it all in the background, the user never needs to know the type, or have one to store anything in, however.. (see next response)I thought you guys were looking for something general purpose.I agree if the proposal is limited to indexed assignment statements that the return type doesn't matter because there is no return type.My proposal was 'limited' to it, with some exceptions i.e. allowing copying.See http://en.wikipedia.org/wiki/Endian. On big-endian machines b[0..16], for example, would be the last two bytes of the memory range &b .. &b+4 in reverse order and for little endian machines is the first two bytes in incresing order. For longs and shorts it would behave similarly.I understand big/little endian. I don't understand why it's a problem. Either: 1 - the compiler handles the big/little endian nature of the bits for us, guaranteeing a certain ordering 2 - the compiler does nothing and we have to handle/understand it ourselves. think? next response)The type bit[] is packed into compiler-dependent chunks in whatever ways it wants. I imagine it would take some non-trivial changes to bit[] to support slicing non-int sized types on big-endian machines.I understand, I think. However, if it's restricted to assignments and copying it simplifies things a bit, the compiler already has to know how to access the bits, all that is added is the ability to set them or copy them. I'm saying, slicing without copying or assigning is not allowed, thus the bit[] type does not need to handle the packing of the bits. Instead on assignment the compiler handles it by assigning to them as it finds them. When copying it makes new data, copying from the old data and no changes are required to bit[] to handle this case.Replace "bit" with "byte" above. I mean: uint a; bit[] b = a[2..12]; would not be possible because the slice crosses a byte boundary. but, a copy or assignment would be fine (reasons above) eg. uint a; bit[] b; b[] = a[2..12]; a[2..12] = 1;I think we do want to restrict it to bit boundaries or require a copy (anything else seems quite complicated, though the compiler is the best place to handle that, if it was desired)I'm not sure what exactly you are referring to. Which bit boundaries and copying do you mean?By the way, I'm guessing as to exactly what the proposal is. My impression is that the proposal is to slice lvalues of numeric type to obtain bit[].Correct.The only numeric type I can imagine it working for is the underlying numeric type used by bit[] (on big endian machines). For little endian machines bit[] can be used for any slice that starts at a multiple of the underlying bit-packing unit (eg int).above.No, I am trying to remove them, see above.Given that using bit[] will require lots of special cases to explain (see above)It's simplerI disagree. After years of experience using & and | is easy (perhaps 'simple'), but, to a begginer it's not at all.Ok. I must admit I haven't tried to formalise this idea as yet.I think a more detailed proposal would help show the trade-off and true impact of trying to extend bit[] to be used as a replacement for &|.(and well-defined) to use & and |.In C and other languages, yes. In D, c'mon we have bit[], surely it can make bit twiddling really nice and easy. It seems bizarre to say the least that we're not using bit[] for bit twiddling but instead using old techniques which are both harder to understand and use (until you're proficient with them).I don't think it's a trivial as you assume. I view bit[] as only being a packed array of true/false values (ala Pascal and C++). The exact packing behavior is compiler-dependent.I didn't first consider this but I don't see this as a problem, unless I am mistaken above.Other languages have bit arrays - I'm thinking specifically of Pascal's packed arrays and STL's bit vectors but there could be others, too. I'm not aware of any that try to use bit arrays to do bit twiddling. They are meant to be memory efficient arrays of true/false values and that's it.So they're not 'bit' arrays but 'bool' arrays ;) The argument "it hasn't been done before, it's a bad idea" is weak. Regan
Aug 21 2005
I'm saying, slicing without copying or assigning is not allowed, thus the bit[] type does not need to handle the packing of the bits. Instead on assignment the compiler handles it by assigning to them as it finds them. When copying it makes new data, copying from the old data and no changes are required to bit[] to handle this case.So I guess the proposal is: Statements of the form "<bit array slice> = var[a .. b];" or "var[a .. b] = <bit array slice>;" or "var[a .. b] = <bit-value>;" are allowed when var is an lvalue of numeric type. Restrictions on a and b to byte-boundaries may apply. No other use of slicing a numeric type is allowed. The type of "var[a .. b]" is not defined. Only allowing slicing in copying or assignment contexts is too restricted IMHO. I agree if that's the proposal then the compiler can figure out the endianness and other issues. Given that such constructs can easily be implemented using functions I don't think it's worth the weight of adding special cases to the language.I mentioned other languages because 1) bit arrays are old concepts 2) other languages don't use them for bit twiddling 3) D is alot like those other languages and I'm sure people have tried using bit arrays for bit twiddling in those other languages, too. It's not an unusual request to have bit[] help with twiddling.Other languages have bit arrays - I'm thinking specifically of Pascal's packed arrays and STL's bit vectors but there could be others, too. I'm not aware of any that try to use bit arrays to do bit twiddling. They are meant to be memory efficient arrays of true/false values and that's it.So they're not 'bit' arrays but 'bool' arrays ;) The argument "it hasn't been done before, it's a bad idea" is weak.
Aug 21 2005
On Sun, 21 Aug 2005 20:20:19 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:Yes.I'm saying, slicing without copying or assigning is not allowed, thus the bit[] type does not need to handle the packing of the bits. Instead on assignment the compiler handles it by assigning to them as it finds them. When copying it makes new data, copying from the old data and no changes are required to bit[] to handle this case.So I guess the proposal is: Statements of the form "<bit array slice> = var[a .. b];" or "var[a .. b] = <bit array slice>;" or "var[a .. b] = <bit-value>;" are allowed when var is an lvalue of numeric type.Restrictions on a and b to byte-boundaries may apply.Assuming "<bit array slice>" above means "b[x..y]" (or "b[]") and not simply "b" (reference to bit array) then, no. There need not be any restriction to byte-boundaries.No other use of slicing a numeric type is allowed. The type of "var[a .. b]" is not defined.Correct. Except that this type is implicitly castable to a <bit array slice>, eg. b[] = var[a..b]; b[a..b] = var[a..b];Only allowing slicing in copying or assignment contexts is too restricted IMHO. I agree if that's the proposal then the compiler can figure out the endianness and other issues. Given that such constructs can easily be implemented using functions I don't think it's worth the weight of adding special cases to the language.You're entitled to your own opinion, mine is: It wouldn't be a "special case", it would be the "standard"/"best way" to manipulate bits in the general case. It would be _much_ nicer than using functions as it would be allow shorter more concise yet more descriptive code. For example, a challenge: What would the following code look like using your proposed functions? //take certain bits from 3 different variables, build a new variable uint newVar; ubyte varOne; ushort varTwo; uint varThree; newVar[0..8] = varOne[3..11]; newVar[8..16] = varTwo[5..13]; newVar[16..32] = varThree[7..23]; I expect the code above to: - look nicer - be clearer - be more concise than anything you can come up with. However I am wary about you being able to come up with something ;)Sure, but it's still a weak argument IMO. ReganI mentioned other languages because 1) bit arrays are old concepts 2) other languages don't use them for bit twiddling 3) D is alot like those other languages and I'm sure people have tried using bit arrays for bit twiddling in those other languages, too. It's not an unusual request to have bit[] help with twiddling.Other languages have bit arrays - I'm thinking specifically of Pascal's packed arrays and STL's bit vectors but there could be others, too. I'm not aware of any that try to use bit arrays to do bit twiddling. They are meant to be memory efficient arrays of true/false values and that's it.So they're not 'bit' arrays but 'bool' arrays ;) The argument "it hasn't been done before, it's a bad idea" is weak.
Aug 21 2005
I say special case because it would be the only construct in D that takes an expression (the indexing and assignment expression) and forces them to appear in their special statement form. Other expressions in D have types and can be assigned to variables and passed to functions or used as subexpressions. Compared to other expressions and statements in D it is very special.Only allowing slicing in copying or assignment contexts is too restricted IMHO. I agree if that's the proposal then the compiler can figure out the endianness and other issues. Given that such constructs can easily be implemented using functions I don't think it's worth the weight of adding special cases to the language.You're entitled to your own opinion, mine is: It wouldn't be a "special case", it would be the "standard"/"best way" to manipulate bits in the general case.It would be _much_ nicer than using functions as it would be allow shorter more concise yet more descriptive code. For example, a challenge: What would the following code look like using your proposed functions? //take certain bits from 3 different variables, build a new variable uint newVar; ubyte varOne; ushort varTwo; uint varThree; newVar[0..8] = varOne[3..11]; newVar[8..16] = varTwo[5..13]; newVar[16..32] = varThree[7..23];The proposal written above didn't mention copying one var[a..b] to another var[a..b] so that's another case to add.I expect the code above to: - look nicer - be clearer - be more concisesigh. There's more to adding features than making a small set of user code "more concise".than anything you can come up with. However I am wary about you being able to come up with something ;)The most obvious API that comes to mind using a single function is copybits(newVar,0,8,varOne,3,11); The newVar is 'inout'. The varOne is 'in'. Seems like a trivial rewrite of your syntax to me. The benefits of these functions are: 1) no special case 2) users can immediately use them without having to learn a special syntax 3) no confusion with mistaking newVar and varOne with an array
Aug 21 2005
On Sun, 21 Aug 2005 21:45:44 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:I say special case because it would be the only construct in D that takes an expression (the indexing and assignment expression) and forces them to appear in their special statement form. Other expressions in D have types and can be assigned to variables and passed to functions or used as subexpressions. Compared to other expressions and statements in D it is very special.I need a concrete example to understand the problem here.It's just using 2 of the cases that were mentioned at the same time. How is it "another case to add"?It would be _much_ nicer than using functions as it would be allow shorter more concise yet more descriptive code. For example, a challenge: What would the following code look like using your proposed functions? //take certain bits from 3 different variables, build a new variable uint newVar; ubyte varOne; ushort varTwo; uint varThree; newVar[0..8] = varOne[3..11]; newVar[8..16] = varTwo[5..13]; newVar[16..32] = varThree[7..23];The proposal written above didn't mention copying one var[a..b] to another var[a..b] so that's another case to add.The goal of this suggestion is to make working with bits easier. Part of that is being able to do things without strange and/or complicated code. Part of that is then having a nice concise syntax. Part of that is having a syntax that is clear as to what it's doing. As you've already mentioned there are many pitfalls when dealing with bits eg. little/big endian byte ordering, packing, etc. Having the compiler (or functions) handle them is a huge bonus. Having the compiler handle it with a built-in syntax is a bit (no pun intended) nicer than using functions. I have yet to understand the problem with the "special case" you keep mentioning. The only special case I see so far is the fact that copying/assigning is required if slicing over byte boundaries.I expect the code above to: - look nicer - be clearer - be more concisesigh. There's more to adding features than making a small set of user code "more concise".Users either have to learn: - the existance of the module AND the function names AND what they do. - the fact that you can slice a basic type to obtain bits AND the restriction that you must copy or assign over byte boundaries The latter requires one or two sentences of explanation (assuming they know what slicing is, which they will or will need to in order to use D anyway).than anything you can come up with. However I am wary about you being able to come up with something ;)The most obvious API that comes to mind using a single function is copybits(newVar,0,8,varOne,3,11); The newVar is 'inout'. The varOne is 'in'. Seems like a trivial rewrite of your syntax to me. The benefits of these functions are: 1) no special case 2) users can immediately use them without having to learn a special syntax3) no confusion with mistaking newVar and varOne with an arrayI can't see how this is a problem at all. A variable _is_ (effectively) an array when you can slice it for bits. It's no different(*) to any other array (or class pretending to be an array). *the differences play no part when you're reading existing code rather than writing new code. Out of context you'll assume (correctly) that it's an array, no problem. In context you'll (correctly) see it as an array of bit[], again, no problem. Regan
Aug 21 2005
On Mon, 22 Aug 2005 14:54:43 +1200, Regan Heath <regan netwin.co.nz> wrote:On Sun, 21 Aug 2005 21:45:44 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:Are you saying that: uint i; cannot be assigned to a variable, eg. bit[] j = i[0..3]; cannot be a sub-expresion, eg. bit[] j = i[0..3] = 1; or passed to a function, eg. foo(i[0..3]); If so, you're quite correct about the assigned to a variable part. Due to byte boundary issues this: bit[] j = i[0..3]; is illegal, however: bit[3] j; j[] = i[0..3]; and: bit[] j; j.length = 3; j[] = i[0..3]; are both legal. That said, if the slice started on a byte boundary it would be _possible_ to allow it. I doubt many people would like/accept the inconsistency there however. As for the others, an expression like: bit[] j = i[0..3] = 1; is processed like any other expression, in 2 sub-expressions. The first sub-expression "i[0..3] = 1" sets the bits in the variable 'i' to 1. (as previously described) The seccond "j = i[0..3]" is illegal (as previously described). It could instead be written as: bit[3] j; j[] = i[0..3] = 1; The same applies to the function call it creates a bit[] or bit[3] on the stack copying the bits from the source and passing it to the function. ReganI say special case because it would be the only construct in D that takes an expression (the indexing and assignment expression) and forces them to appear in their special statement form. Other expressions in D have types and can be assigned to variables and passed to functions or used as subexpressions. Compared to other expressions and statements in D it is very special.I need a concrete example to understand the problem here.
Aug 21 2005
On Mon, 22 Aug 2005 17:23:11 +1200, Regan Heath wrote:On Mon, 22 Aug 2005 14:54:43 +1200, Regan Heath <regan netwin.co.nz> wrote:The more I see examples of your proposal, the more I like another way of doing it. Its just *too* misleading in my mind. I keep seeing arrays of integers and not arrays of bits ;-) -- Derek (skype: derek.j.parnell) Melbourne, Australia 22/08/2005 4:30:20 PMOn Sun, 21 Aug 2005 21:45:44 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:Are you saying that: uint i; cannot be assigned to a variable, eg. bit[] j = i[0..3]; cannot be a sub-expresion, eg. bit[] j = i[0..3] = 1; or passed to a function, eg. foo(i[0..3]); If so, you're quite correct about the assigned to a variable part. Due to byte boundary issues this: bit[] j = i[0..3]; is illegal, however: bit[3] j; j[] = i[0..3]; and: bit[] j; j.length = 3; j[] = i[0..3]; are both legal. That said, if the slice started on a byte boundary it would be _possible_ to allow it. I doubt many people would like/accept the inconsistency there however. As for the others, an expression like: bit[] j = i[0..3] = 1; is processed like any other expression, in 2 sub-expressions. The first sub-expression "i[0..3] = 1" sets the bits in the variable 'i' to 1. (as previously described) The seccond "j = i[0..3]" is illegal (as previously described). It could instead be written as: bit[3] j; j[] = i[0..3] = 1; The same applies to the function call it creates a bit[] or bit[3] on the stack copying the bits from the source and passing it to the function.I say special case because it would be the only construct in D that takes an expression (the indexing and assignment expression) and forces them to appear in their special statement form. Other expressions in D have types and can be assigned to variables and passed to functions or used as subexpressions. Compared to other expressions and statements in D it is very special.I need a concrete example to understand the problem here.
Aug 21 2005
On Mon, 22 Aug 2005 16:35:48 +1000, Derek Parnell <derek psych.ward> wrote:On Mon, 22 Aug 2005 17:23:11 +1200, Regan Heath wrote:The question is then, where does the problem lie, in the proposal or in your mind ;) I don't have the same problem with it, but then perhaps _I_ am strange. You're seeing arrays (correctly, because they are in this case) but you're assuming integers, so, if bit literals had some sort of suffix (I guess the binary suffix is it?) then you could, if you so chose, make it more obvious i.e. i[0..3] = 1b i[3..8] = 0b So, you could code like that, I could code without, both of us are happy (until you have to read my code perhaps) ReganOn Mon, 22 Aug 2005 14:54:43 +1200, Regan Heath <regan netwin.co.nz> wrote:The more I see examples of your proposal, the more I like another way of doing it. Its just *too* misleading in my mind. I keep seeing arrays of integers and not arrays of bits ;-)On Sun, 21 Aug 2005 21:45:44 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:Are you saying that: uint i; cannot be assigned to a variable, eg. bit[] j = i[0..3]; cannot be a sub-expresion, eg. bit[] j = i[0..3] = 1; or passed to a function, eg. foo(i[0..3]); If so, you're quite correct about the assigned to a variable part. Due to byte boundary issues this: bit[] j = i[0..3]; is illegal, however: bit[3] j; j[] = i[0..3]; and: bit[] j; j.length = 3; j[] = i[0..3]; are both legal. That said, if the slice started on a byte boundary it would be _possible_ to allow it. I doubt many people would like/accept the inconsistency there however. As for the others, an expression like: bit[] j = i[0..3] = 1; is processed like any other expression, in 2 sub-expressions. The first sub-expression "i[0..3] = 1" sets the bits in the variable 'i' to 1. (as previously described) The seccond "j = i[0..3]" is illegal (as previously described). It could instead be written as: bit[3] j; j[] = i[0..3] = 1; The same applies to the function call it creates a bit[] or bit[3] on the stack copying the bits from the source and passing it to the function.I say special case because it would be the only construct in D that takes an expression (the indexing and assignment expression) and forces them to appear in their special statement form. Other expressions in D have types and can be assigned to variables and passed to functions or used as subexpressions. Compared to other expressions and statements in D it is very special.I need a concrete example to understand the problem here.
Aug 22 2005
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsvv88xxi23k2f5 nrage.netwin.co.nz...On Mon, 22 Aug 2005 14:54:43 +1200, Regan Heath <regan netwin.co.nz> wrote:There is a big difference between j[] = i[a..b] and j = i[a..b] no matter what the byte boundaries are. Consider big-endian machines with trying to slice shorts and longs where the bit[] packing unit is a byte. Short is positioned in memory as 1 0 where the number "1" means that byte stores the data starting at bit 8*1. Long as 7 6 5 4 3 2 1 0 Assuming bit[] is made of a pointer and length with the pointer at the low memory value it is reverse of the endian order (bit[] is currently independent of endianness). Implementing bit[] with the pointer at the high byte and decreasing might work for setting bits but it wouldn't mesh with D's existing array semantics of increasing indices mapping to increasing memory locations. Plus resizing a bit[] with decreasing contents would be very different than resizing a standard array. That's why I think the most practical suggestion was your original restriction of only allowing the slicing if it is immediately copied and never exists as a bit[]. But then I think that's too large a restriction to be useful.On Sun, 21 Aug 2005 21:45:44 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:Are you saying that: uint i; cannot be assigned to a variable, eg. bit[] j = i[0..3]; cannot be a sub-expresion, eg. bit[] j = i[0..3] = 1; or passed to a function, eg. foo(i[0..3]); If so, you're quite correct about the assigned to a variable part. Due to byte boundary issues this: bit[] j = i[0..3]; is illegal, however: bit[3] j; j[] = i[0..3]; and: bit[] j; j.length = 3; j[] = i[0..3]; are both legal. That said, if the slice started on a byte boundary it would be _possible_ to allow it. I doubt many people would like/accept the inconsistency there however.I say special case because it would be the only construct in D that takes an expression (the indexing and assignment expression) and forces them to appear in their special statement form. Other expressions in D have types and can be assigned to variables and passed to functions or used as subexpressions. Compared to other expressions and statements in D it is very special.I need a concrete example to understand the problem here.
Aug 22 2005
On Mon, 22 Aug 2005 18:39:34 -0400, Ben Hinkle <bhinkle mathworks.com> wrote:You're right. I agree.That said, if the slice started on a byte boundary it would be _possible_ to allow it. I doubt many people would like/accept the inconsistency there however.There is a big difference between j[] = i[a..b] and j = i[a..b] no matter what the byte boundaries are. Consider big-endian machines with trying to slice shorts and longs where the bit[] packing unit is a byte. Short is positioned in memory as 1 0 where the number "1" means that byte stores the data starting at bit 8*1. Long as 7 6 5 4 3 2 1 0 Assuming bit[] is made of a pointer and length with the pointer at the low memory value it is reverse of the endian order (bit[] is currently independent of endianness). Implementing bit[] with the pointer at the high byte and decreasing might work for setting bits but it wouldn't mesh with D's existing array semantics of increasing indices mapping to increasing memory locations. Plus resizing a bit[] with decreasing contents would be very different than resizing a standard array. That's why I think the most practical suggestion was your original restriction of only allowing the slicing if it is immediately copied and never exists as a bit[].But then I think that's too large a restriction to be useful.It doesn't stop you twiddling bits and it doesn't stop you forming a new variable from a collection of bits via bit copying. So, it achieves the desired goals. It does stop you from referencing part of an existing variable then later twiddling or reading them, but then that wasn't what it was supposed to achieve, and it can be achieved with a pointer to the original variable and later slicing. Regan
Aug 22 2005
On Mon, 22 Aug 2005 13:14:39 +1200, Regan Heath wrote: [snip]What would the following code look like using your proposed functions? //take certain bits from 3 different variables, build a new variable uint newVar; ubyte varOne; ushort varTwo; uint varThree; newVar[0..8] = varOne[3..11]; newVar[8..16] = varTwo[5..13]; newVar[16..32] = varThree[7..23]; I expect the code above to: - look nicer - be clearer - be more concise than anything you can come up with. However I am wary about you being able to come up with something ;)My issue with this idea is that just by looking at 'newVar[0..8]' it gives the impression that newVar is an array. And I don't mean an array of bits ;-) Of course all data ultimately is stored as array(s) of bits so this syntax is a tad misleading. I can see a point to the argument that it would be useful to have the compiler help coders who need to access variables at the bit level. But it would need a different syntax to avoid ambiguities. Seeing that all data is ultimately a set of bits, and is thus intrinsic to the variable, maybe an in-built property of '.bits' might be a useful idea. newVar.bits[0..8] = varOne.bits[3..11]; newVar.bits[8..16] = varTwo.bits[5..13]; newVar.bits[16..32] = varThree.bits[7..23]; And the compiler can do the Endian transformations on the coder's behalf. D would just define that the .bits property is always used as if the data is really stored as Big Endian (ie. Motorola/IBM style and not Intel/VAX style). -- Derek (skype: derek.j.parnell) Melbourne, Australia 22/08/2005 11:51:58 AM
Aug 21 2005
On Mon, 22 Aug 2005 12:26:49 +1000, Derek Parnell <derek psych.ward> wrote:On Mon, 22 Aug 2005 13:14:39 +1200, Regan Heath wrote: [snip]And it is.What would the following code look like using your proposed functions? //take certain bits from 3 different variables, build a new variable uint newVar; ubyte varOne; ushort varTwo; uint varThree; newVar[0..8] = varOne[3..11]; newVar[8..16] = varTwo[5..13]; newVar[16..32] = varThree[7..23]; I expect the code above to: - look nicer - be clearer - be more concise than anything you can come up with. However I am wary about you being able to come up with something ;)My issue with this idea is that just by looking at 'newVar[0..8]' it gives the impression that newVar is an array.And I don't mean an array of bitsBut that's exactly what it is.;-) Of course all data ultimately is stored as array(s) of bits so this syntax is a tad misleading.What problems can you see it causing?I can see a point to the argument that it would be useful to have the compiler help coders who need to access variables at the bit level. But it would need a different syntax to avoid ambiguities.I don't yet see any problem with "ambiguities". A variable is a collection of bits.Seeing that all data is ultimately a set of bits, and is thus intrinsic to the variable, maybe an in-built property of '.bits' might be a useful idea. newVar.bits[0..8] = varOne.bits[3..11]; newVar.bits[8..16] = varTwo.bits[5..13]; newVar.bits[16..32] = varThree.bits[7..23];That's 4 more chars I have to type, for no gain. IMO.And the compiler can do the Endian transformations on the coder's behalf.That is a crucial part of the idea it makes bit manipulation much easier. Regan
Aug 21 2005
On Mon, 22 Aug 2005 15:00:45 +1200, Regan Heath wrote: [snip]All data is a set of bits, but nearly all data is never used this way. Data is used in conceptual ways rather than implementational ways. And therefore, assuming we give common usage better support than rare usage, we should use special syntax to indicate rare usage.My issue with this idea is that just by looking at 'newVar[0..8]' it gives the impression that newVar is an array.And it is.And I don't mean an array of bitsBut that's exactly what it is.;-) Of course all data ultimately is stored as array(s) of bits so this syntax is a tad misleading.What problems can you see it causing?Confusion. What is the mistake here ... uint newVar; newVar[0..8] = 255; Its hard to tell, no? I actually meant to code ... uint[8] newVar; newVar[0..8] = 255; Now how would the compiler know that? But consider this ... uint newVar; newVar.bits[0..8] = 255; Anyone see the ambiguity here? Neither can I.Yes, but its not as commonly thought of as that, is it? Sure, there are cases when one *has* to bit twiddle, but these are rare. As a code reader, if I saw 'RecordCount[0]' I would be thinking the it was referring to the first RecordCount value and not the first bit in the record count value. It is visually confusing, so why bother with it.I can see a point to the argument that it would be useful to have the compiler help coders who need to access variables at the bit level. But it would need a different syntax to avoid ambiguities.I don't yet see any problem with "ambiguities". A variable is a collection of bits.Legibility is a huge gain! Making code unambiguous and/or easier to read is saving maintenance costs. Code is read much more frequently than written, so the 'pain' of typing four characters is paid for many times over because people read it better.Seeing that all data is ultimately a set of bits, and is thus intrinsic to the variable, maybe an in-built property of '.bits' might be a useful idea. newVar.bits[0..8] = varOne.bits[3..11]; newVar.bits[8..16] = varTwo.bits[5..13]; newVar.bits[16..32] = varThree.bits[7..23];That's 4 more chars I have to type, for no gain. IMO.Yes! -- Derek (skype: derek.j.parnell) Melbourne, Australia 22/08/2005 1:03:59 PMAnd the compiler can do the Endian transformations on the coder's behalf.That is a crucial part of the idea it makes bit manipulation much easier.
Aug 21 2005
On Mon, 22 Aug 2005 13:19:13 +1000, Derek Parnell <derek psych.ward> wrote:I agree totally. When it 'conceptually' makes sense you will use [] and slice an int, otherwise you wont.All data is a set of bits, but nearly all data is never used this way. Data is used in conceptual ways rather than implementational ways.My issue with this idea is that just by looking at 'newVar[0..8]' it gives the impression that newVar is an array.And it is.And I don't mean an array of bitsBut that's exactly what it is.;-) Of course all data ultimately is stored as array(s) of bits so this syntax is a tad misleading.And therefore, assuming we give common usage better support than rare usage,We already do. 'a' is easier to use and type than 'a[x..y]'we should use special syntax to indicate rare usage.Sure, that's what I am suggesting. [] _is_ special syntax. It indicates slicing, which is exactly what we're doing.What is the context?What problems can you see it causing?Confusion. What is the mistake here ... uint newVar; newVar[0..8] = 255;Its hard to tell, no?Without context, yes.I actually meant to code ... uint[8] newVar; newVar[0..8] = 255; Now how would the compiler know that?It wont, nor is it supposed to. The compiler verifies the code is legal, in some situations it can provide additional help. This example, like _many_ others, is not one of them.But consider this ... uint newVar; newVar.bits[0..8] = 255; Anyone see the ambiguity here? Neither can I.A clunky syntax is unlikely to collide with any existing stuff by it's very nature ;) I understand your point, I just disagree that there is any(*) more likelihood of problems here than other features where a typo can and does mean something other than the programmer intended. *where 'any' is defined as some really small number/value.Sure, bit twiddling is rare.Yes, but its not as commonly thought of as that, is it? Sure, there are cases when one *has* to bit twiddle, but these are rare.I can see a point to the argument that it would be useful to have the compiler help coders who need to access variables at the bit level. But it would need a different syntax to avoid ambiguities.I don't yet see any problem with "ambiguities". A variable is a collection of bits.As a code reader, if I saw 'RecordCount[0]' I would be thinking the it was referring to the first RecordCount valueAnd you'd be correct. The 'value' is a bit and RecordCount is a collection of bits.and not the first bit in the record count value. It is visually confusing, so why bother with it.It's not visually confusing because it's idential to slicing any other sort of array, and further it will only occur in situations where it makes sense conceptually. In other words you're only going to be using it when you want to reference the bits of something. Thus the variable will be named appropriately i.e. 'fields' or 'rawData' or something and "if (fields[IS_BINARY])" would make perfect sense. You cannot ignore context.Sure, but, I still see 'no gain' in the above because I don't agree that it 'solves' any problem that the original syntax had. I believe the original syntax is as legible and unambiguous as any other instance of slicing. ReganLegibility is a huge gain! Making code unambiguous and/or easier to read is saving maintenance costs. Code is read much more frequently than written, so the 'pain' of typing four characters is paid for many times over because people read it better.Seeing that all data is ultimately a set of bits, and is thus intrinsic to the variable, maybe an in-built property of '.bits' might be a useful idea. newVar.bits[0..8] = varOne.bits[3..11]; newVar.bits[8..16] = varTwo.bits[5..13]; newVar.bits[16..32] = varThree.bits[7..23];That's 4 more chars I have to type, for no gain. IMO.
Aug 21 2005
On Mon, 22 Aug 2005 15:51:38 +1200, Regan Heath wrote:Sure, but, I still see 'no gain' in the above because I don't agree that it 'solves' any problem that the original syntax had. I believe the original syntax is as legible and unambiguous as any other instance of slicing.The joke is that Walter's not going to do either anyway. ;-) -- Derek (skype: derek.j.parnell) Melbourne, Australia 22/08/2005 2:23:18 PM
Aug 21 2005
On Mon, 22 Aug 2005 14:24:38 +1000, Derek Parnell <derek psych.ward> wrote:On Mon, 22 Aug 2005 15:51:38 +1200, Regan Heath wrote:We can but hope. ReganSure, but, I still see 'no gain' in the above because I don't agree that it 'solves' any problem that the original syntax had. I believe the original syntax is as legible and unambiguous as any other instance of slicing.The joke is that Walter's not going to do either anyway. ;-)
Aug 21 2005