Jump to page: 1 2 3
Thread overview
Imperfect D (A Rant About Bits)
Jun 05, 2004
Antti Sykäri
Jun 05, 2004
Matthew
Jun 05, 2004
Ivan Senji
Jun 05, 2004
Kevin Bealer
Jun 05, 2004
Sean Kelly
Jun 05, 2004
J Anderson
Jun 06, 2004
Kevin Bealer
Jun 06, 2004
Antti Sykäri
Jun 08, 2004
J Anderson
Jun 05, 2004
J Anderson
Jun 05, 2004
Arcane Jill
Jun 05, 2004
Lev Elbert
Jun 05, 2004
Sean Kelly
Jun 05, 2004
hellcatv
Jun 06, 2004
Benji Smith
Jun 06, 2004
Kevin Bealer
Jun 07, 2004
Antti Sykäri
Jun 07, 2004
Arcane Jill
bit: It was a good idea at the time, but it just didn't work out.
Jun 07, 2004
Arcane Jill
Re: It was a good idea at the time, but it just didn't work out.
Jun 07, 2004
Matthew
Jun 07, 2004
Andy Friesen
Jun 08, 2004
Norbert Nemec
Jun 08, 2004
Arcane Jill
Jun 05, 2004
Sean Kelly
Jun 06, 2004
Antti Sykäri
June 05, 2004
I've just finished reading a hundred-message thread about the boolean type that brought me to the following conclusion:

Boolean types are basic types and should be reasoned about in the same way as any other type. This includes doing things like:

void catastrophe1(inout bool y)
{
    if (y == false)
        y = true;
}

void catastrophe2(bool* y)
{
    if (*y == false)
        *y = true;
}

void main()
{
    bool[16] x;
    catastrophe1(x[5]);
    catastrophe2(&x[5]);

    bool* first_bool = &x[0];
    bool* second_bool = &x[1];
    assert(second_bool == first_bool + 1);
    assert(cast(int) second_bool = cast(int) first_bool + bool.size);
}

If you substitute int in place of bit, this works. But not as it is.

This is A Bad Thing, and violates several rules that I hold dear:

1) Keep It Simple, Stupid

  In current D, bit is not just a normal type for which the basic
  operations can implemented like for any other type. It is the
  nightmare of D language implementors. It doesn't leave many language
  features unaffected.  The implementation of pointers and references
  (as in inout and out parameters) has to be rewritten. Slices cannot be
  implemented that easily either, and I suspect they never will.

  A slight exaggeration is in place: the boolean type is to D what
  export is to C++.

2) Occam's Razor (which happens to be the underlying principle of Rule (1))

  To understand bool, you have to understand all of its special cases
  where it doesn't behave as a normal variable behaves. This means that
  you cannot explain nor understand bool fully without understanding
  pointers, parameter passing modes, arrays, bitarrays, integer
  representation, assembly language, etc. And I didn't even mention all
  of the thousands of different uses that 'bit' might have in templates,
  of which we don't even *know* yet. And which *will* be broken once we
  get there.

  This is a blatant violation of Occam's Razor, one real-life
  application of which is in learning:

  One should not increase, beyond what is necessary, the number of
  entities required to understand other entities.

3) The Rule of Least Surprise

  The number #1 rule in user interface design, one of the cornerstones
  of the Unix philosophy, this rule would be of utmost importance
  especially for the aspiring novice who first encounters the D
  language. He creates an integer, and lo, an integer is created. He
  passes it as inout reference, and rejoices of his success. Then,
  he proceeds to to create a boolean variable, which is fine also.
  Confidently and determinedly he tries to pass the variable as inout
  reference. The result: he is utterly disappointed, abandons the
  language, and turns to another, more logical languages, such as C++ or
  Scheme.

  [I could go on about the same thing between ints/structs and classes
  but everyone knows Java already so this would probably be in vain]

The only argument of having bit.size practically 0.125 is that you can use the array syntax to create arrays of bits. Too bad that it just conflicts with the very foundations of the language. *everything else* is byte-addressable, and this basic type is not, and just because a silly bit array.

Admit it, the idea of having a bit-sized boolean type was a bad idea. It might've been a clever-sounding trick when it was conceived but hey, in reality it doesn't provide that much value.

So let's move on and define a *real* boolean type, for example one of the same size as integer, or maybe a byte. If I were to implement it, it would probably be implemented as a 32-bit integer.  false would be 0 and true anything else. Checking for truth would be easy since processors tend to have these "jump if (not) zero" kind of instructions.  And testing for truth value (besides assignment) is the first and foremost use for bool.  Occasionally you need to convert it to int, and why not have an implicit conversion from false => 0 and true => 1. As easy as that. But nothing so silly as adding too booleans together or anything like that.

Heh, if you wanted a smaller bool (to consume less memory), maybe implement bool8 or even bool16 for that purpose. Wouldn't hurt anyone.

Besides, having bitarrays implemented as a language-level primitive is an insult to the D language itself. Is the language really so weak that you can't implement a bitset in the standard?

Surely you can!

The only reason _not_ to implement things in standard library is speed of compilation, which I don't think is a problem with the current D implementation, and optimization opportunities, which I believe can very well be done after the fact if the need arises.

So there.

-Antti

-- 
I will not be using Plan 9 in the creation of weapons of mass destruction to be used by nations other than the US.
June 05, 2004
From here on in I shall try my damndest to refrain from further comment, and if anyone asks my opinion, I shall simply refer them to this post.

I bow to your succinct wisdom.

Matthew



"Antti Sykäri" <jsykari@gamma.hut.fi> wrote in message news:slrncc26jr.n9h.jsykari@pulu.hut.fi...
> I've just finished reading a hundred-message thread about the boolean type that brought me to the following conclusion:
>
> Boolean types are basic types and should be reasoned about in the same way as any other type. This includes doing things like:
>
> void catastrophe1(inout bool y)
> {
>     if (y == false)
>         y = true;
> }
>
> void catastrophe2(bool* y)
> {
>     if (*y == false)
>         *y = true;
> }
>
> void main()
> {
>     bool[16] x;
>     catastrophe1(x[5]);
>     catastrophe2(&x[5]);
>
>     bool* first_bool = &x[0];
>     bool* second_bool = &x[1];
>     assert(second_bool == first_bool + 1);
>     assert(cast(int) second_bool = cast(int) first_bool + bool.size);
> }
>
> If you substitute int in place of bit, this works. But not as it is.
>
> This is A Bad Thing, and violates several rules that I hold dear:
>
> 1) Keep It Simple, Stupid
>
>   In current D, bit is not just a normal type for which the basic
>   operations can implemented like for any other type. It is the
>   nightmare of D language implementors. It doesn't leave many language
>   features unaffected.  The implementation of pointers and references
>   (as in inout and out parameters) has to be rewritten. Slices cannot be
>   implemented that easily either, and I suspect they never will.
>
>   A slight exaggeration is in place: the boolean type is to D what
>   export is to C++.
>
> 2) Occam's Razor (which happens to be the underlying principle of Rule (1))
>
>   To understand bool, you have to understand all of its special cases
>   where it doesn't behave as a normal variable behaves. This means that
>   you cannot explain nor understand bool fully without understanding
>   pointers, parameter passing modes, arrays, bitarrays, integer
>   representation, assembly language, etc. And I didn't even mention all
>   of the thousands of different uses that 'bit' might have in templates,
>   of which we don't even *know* yet. And which *will* be broken once we
>   get there.
>
>   This is a blatant violation of Occam's Razor, one real-life
>   application of which is in learning:
>
>   One should not increase, beyond what is necessary, the number of
>   entities required to understand other entities.
>
> 3) The Rule of Least Surprise
>
>   The number #1 rule in user interface design, one of the cornerstones
>   of the Unix philosophy, this rule would be of utmost importance
>   especially for the aspiring novice who first encounters the D
>   language. He creates an integer, and lo, an integer is created. He
>   passes it as inout reference, and rejoices of his success. Then,
>   he proceeds to to create a boolean variable, which is fine also.
>   Confidently and determinedly he tries to pass the variable as inout
>   reference. The result: he is utterly disappointed, abandons the
>   language, and turns to another, more logical languages, such as C++ or
>   Scheme.
>
>   [I could go on about the same thing between ints/structs and classes
>   but everyone knows Java already so this would probably be in vain]
>
> The only argument of having bit.size practically 0.125 is that you can use the array syntax to create arrays of bits. Too bad that it just conflicts with the very foundations of the language. *everything else* is byte-addressable, and this basic type is not, and just because a silly bit array.
>
> Admit it, the idea of having a bit-sized boolean type was a bad idea. It might've been a clever-sounding trick when it was conceived but hey, in reality it doesn't provide that much value.
>
> So let's move on and define a *real* boolean type, for example one of the same size as integer, or maybe a byte. If I were to implement it, it would probably be implemented as a 32-bit integer.  false would be 0 and true anything else. Checking for truth would be easy since processors tend to have these "jump if (not) zero" kind of instructions.  And testing for truth value (besides assignment) is the first and foremost use for bool.  Occasionally you need to convert it to int, and why not have an implicit conversion from false => 0 and true => 1. As easy as that. But nothing so silly as adding too booleans together or anything like that.
>
> Heh, if you wanted a smaller bool (to consume less memory), maybe implement bool8 or even bool16 for that purpose. Wouldn't hurt anyone.
>
> Besides, having bitarrays implemented as a language-level primitive is an insult to the D language itself. Is the language really so weak that you can't implement a bitset in the standard?
>
> Surely you can!
>
> The only reason _not_ to implement things in standard library is speed of compilation, which I don't think is a problem with the current D implementation, and optimization opportunities, which I believe can very well be done after the fact if the need arises.
>
> So there.
>
> -Antti
>
> -- 
> I will not be using Plan 9 in the creation of weapons of mass destruction to be used by nations other than the US.


June 05, 2004
"Antti Sykäri" <jsykari@gamma.hut.fi> wrote in message news:slrncc26jr.n9h.jsykari@pulu.hut.fi...
> I've just finished reading a hundred-message thread about the boolean type that brought me to the following conclusion:
>
> Boolean types are basic types and should be reasoned about in the same way as any other type. This includes doing things like:
>
> void catastrophe1(inout bool y)
> {
>     if (y == false)
>         y = true;
> }
>
> void catastrophe2(bool* y)
> {
>     if (*y == false)
>         *y = true;
> }
>
> void main()
> {
>     bool[16] x;
>     catastrophe1(x[5]);
>     catastrophe2(&x[5]);
>
>     bool* first_bool = &x[0];
>     bool* second_bool = &x[1];
>     assert(second_bool == first_bool + 1);
>     assert(cast(int) second_bool = cast(int) first_bool + bool.size);
> }
>
> If you substitute int in place of bit, this works. But not as it is.
>
> This is A Bad Thing, and violates several rules that I hold dear:
>
> 1) Keep It Simple, Stupid
>
>   In current D, bit is not just a normal type for which the basic
>   operations can implemented like for any other type. It is the
>   nightmare of D language implementors. It doesn't leave many language
>   features unaffected.  The implementation of pointers and references
>   (as in inout and out parameters) has to be rewritten. Slices cannot be
>   implemented that easily either, and I suspect they never will.
>
>   A slight exaggeration is in place: the boolean type is to D what
>   export is to C++.
>
> 2) Occam's Razor (which happens to be the underlying principle of Rule
(1))
>
>   To understand bool, you have to understand all of its special cases
>   where it doesn't behave as a normal variable behaves. This means that
>   you cannot explain nor understand bool fully without understanding
>   pointers, parameter passing modes, arrays, bitarrays, integer
>   representation, assembly language, etc. And I didn't even mention all
>   of the thousands of different uses that 'bit' might have in templates,
>   of which we don't even *know* yet. And which *will* be broken once we
>   get there.
>
>   This is a blatant violation of Occam's Razor, one real-life
>   application of which is in learning:
>
>   One should not increase, beyond what is necessary, the number of
>   entities required to understand other entities.
>
> 3) The Rule of Least Surprise
>
>   The number #1 rule in user interface design, one of the cornerstones
>   of the Unix philosophy, this rule would be of utmost importance
>   especially for the aspiring novice who first encounters the D
>   language. He creates an integer, and lo, an integer is created. He
>   passes it as inout reference, and rejoices of his success. Then,
>   he proceeds to to create a boolean variable, which is fine also.
>   Confidently and determinedly he tries to pass the variable as inout
>   reference. The result: he is utterly disappointed, abandons the
>   language, and turns to another, more logical languages, such as C++ or
>   Scheme.
>
>   [I could go on about the same thing between ints/structs and classes
>   but everyone knows Java already so this would probably be in vain]
>
> The only argument of having bit.size practically 0.125 is that you can use the array syntax to create arrays of bits. Too bad that it just conflicts with the very foundations of the language. *everything else* is byte-addressable, and this basic type is not, and just because a silly bit array.
>
> Admit it, the idea of having a bit-sized boolean type was a bad idea. It might've been a clever-sounding trick when it was conceived but hey, in reality it doesn't provide that much value.
>
> So let's move on and define a *real* boolean type, for example one of the same size as integer, or maybe a byte. If I were to implement it, it would probably be implemented as a 32-bit integer.  false would be 0 and true anything else. Checking for truth would be easy since processors tend to have these "jump if (not) zero" kind of instructions.  And testing for truth value (besides assignment) is the first and foremost use for bool.  Occasionally you need to convert it to int, and why not have an implicit conversion from false => 0 and true => 1. As easy as that. But nothing so silly as adding too booleans together or anything like that.
>
> Heh, if you wanted a smaller bool (to consume less memory), maybe implement bool8 or even bool16 for that purpose. Wouldn't hurt anyone.
>
> Besides, having bitarrays implemented as a language-level primitive is an insult to the D language itself. Is the language really so weak that you can't implement a bitset in the standard?
>
> Surely you can!
>
> The only reason _not_ to implement things in standard library is speed of compilation, which I don't think is a problem with the current D implementation, and optimization opportunities, which I believe can very well be done after the fact if the need arises.
>
> So there.

Wow. Well said! I agree with you on most of the points, except about
bitarrays. The only problem with them is that the current implementation
doesn't work (but it probabbly will soon), and that they are also used
as boolean value.
The only solution as i see it is to leave bit and bit arrays as they are
(only fix them), and add a new trully logical type bool.

I think there would be no problem where to use witch one:
use bit if you need "bit" as in 1/8 of byte
and use bool if you need true/false meaning logical true/false.
And then all opEquals == < > || and other operators would return
(as they should) a bool, and Walter could implement bool in a way he
thinks is best :)




> -Antti
>
> --
> I will not be using Plan 9 in the creation of weapons of mass destruction to be used by nations other than the US.


June 05, 2004
1. Your example fails to compile, and fails with a reasonable message, so there is no language bug there.

2. The bit/bit array objects are a *feature*.  All the behaviours that that you and the other anti-bit folks want in a boolean ARE ALREADY AVAILABLE in other types.  You can use typedef if you are afraid of automatic conversion.

3. You argue that it is hard to understand.  Well tough.

4. You argue that you don't need the bit ARRAY functionality.  Well then how can you possibly be upset that the example you give doesn't work the way you expect?

Go to a hardware store and buy a spray-bomb can of paint.  It's easy to use, and the results are okay for graffiti or stencils.  If you want to paint a car, you need a better tool.  It costs 400 dollars (USD), has at least a dozen adjustments, screws, filters, and levers.  It comes with a manual, and if you misuse it in any of 10 ways it will break permanently.  It's a power tool.  It's not expected to be easy.  It's as easy as they could make it WITHOUT sacrificing performance.

Bit arrays aren't needed everywhere.  Like C, C++, and the professional paint sprayer, they are a power tool.  If you want a simple tool with a different interface, don't use them.  But getting this functionality to run fast IS very important for a lot of applications, so it should be in the language, not a library.

Between enums, the dozens of integer types, and structures, the functionality you want is available.  You just have to accept that for "int" semantics, you want the int type.

In any case, functions calls like this:

AdjustWindow(100, 220, "window1", true, true, false, true);

.. Are considered bad form.  Don't use true to mean "yes I want beveled edges", instead have an enumerated type (i_Beveled, i_Squared).

In short, Walter gave very good reasons for the current behaviour, and none of the posts in these 101 threads has touched on those, except to say "can't the performance penalty just go away in the compiler" (the answer is, no it can't).

I find it particularly telling that the post ends in a vague discussion of "lets define a real type", but then mentions a dozen or so conflicting strategies, including multiple bool types of different sizes.  If Occam heard that, he would probably cut himself shaving.  Then it suggests adding booleans together is evil, which is done in the example code!

The reason posts like this wander from strategy to strategy at the end, is that each strategy has either performance issues, missing functionality issues, requires excessive casting, doesn't require enough casting, etc.  You're trying to find a solution to a problem, that everyone has a different "intuitively correct solution" to.  But you know that the solution you are proposing is broken (i.e. it can't solve all the problems) so you waffle and leave it open ended.  Then like a politician, everyone hears their own solution.

I want this discussion to end, because I have this bicycle shed I'm building and I'd like to ask everyone's advice on what color to make it...

Kevin

PS forgive me if this post was meant to be satire...




In article <slrncc26jr.n9h.jsykari@pulu.hut.fi>, Antti =?iso-8859-1?Q?Syk=E4ri?= says...
>
>I've just finished reading a hundred-message thread about the boolean type that brought me to the following conclusion:
>
>Boolean types are basic types and should be reasoned about in the same way as any other type. This includes doing things like:
>
>void catastrophe1(inout bool y)
>{
>    if (y == false)
>        y = true;
>}
>
>void catastrophe2(bool* y)
>{
>    if (*y == false)
>        *y = true;
>}
>
>void main()
>{
>    bool[16] x;
>    catastrophe1(x[5]);
>    catastrophe2(&x[5]);
>
>    bool* first_bool = &x[0];
>    bool* second_bool = &x[1];
>    assert(second_bool == first_bool + 1);
>    assert(cast(int) second_bool = cast(int) first_bool + bool.size);
>}
>
>If you substitute int in place of bit, this works. But not as it is.
>
>This is A Bad Thing, and violates several rules that I hold dear:
>
>1) Keep It Simple, Stupid
>
>  In current D, bit is not just a normal type for which the basic
>  operations can implemented like for any other type. It is the
>  nightmare of D language implementors. It doesn't leave many language
>  features unaffected.  The implementation of pointers and references
>  (as in inout and out parameters) has to be rewritten. Slices cannot be
>  implemented that easily either, and I suspect they never will.
>
>  A slight exaggeration is in place: the boolean type is to D what
>  export is to C++.
>
>2) Occam's Razor (which happens to be the underlying principle of Rule (1))
>
>  To understand bool, you have to understand all of its special cases
>  where it doesn't behave as a normal variable behaves. This means that
>  you cannot explain nor understand bool fully without understanding
>  pointers, parameter passing modes, arrays, bitarrays, integer
>  representation, assembly language, etc. And I didn't even mention all
>  of the thousands of different uses that 'bit' might have in templates,
>  of which we don't even *know* yet. And which *will* be broken once we
>  get there.
>
>  This is a blatant violation of Occam's Razor, one real-life
>  application of which is in learning:
>
>  One should not increase, beyond what is necessary, the number of
>  entities required to understand other entities.
>
>3) The Rule of Least Surprise
>
>  The number #1 rule in user interface design, one of the cornerstones
>  of the Unix philosophy, this rule would be of utmost importance
>  especially for the aspiring novice who first encounters the D
>  language. He creates an integer, and lo, an integer is created. He
>  passes it as inout reference, and rejoices of his success. Then,
>  he proceeds to to create a boolean variable, which is fine also.
>  Confidently and determinedly he tries to pass the variable as inout
>  reference. The result: he is utterly disappointed, abandons the
>  language, and turns to another, more logical languages, such as C++ or
>  Scheme.
>
>  [I could go on about the same thing between ints/structs and classes
>  but everyone knows Java already so this would probably be in vain]
>
>The only argument of having bit.size practically 0.125 is that you can use the array syntax to create arrays of bits. Too bad that it just conflicts with the very foundations of the language. *everything else* is byte-addressable, and this basic type is not, and just because a silly bit array.
>
>Admit it, the idea of having a bit-sized boolean type was a bad idea. It might've been a clever-sounding trick when it was conceived but hey, in reality it doesn't provide that much value.
>
>So let's move on and define a *real* boolean type, for example one of the same size as integer, or maybe a byte. If I were to implement it, it would probably be implemented as a 32-bit integer.  false would be 0 and true anything else. Checking for truth would be easy since processors tend to have these "jump if (not) zero" kind of instructions.  And testing for truth value (besides assignment) is the first and foremost use for bool.  Occasionally you need to convert it to int, and why not have an implicit conversion from false => 0 and true => 1. As easy as that. But nothing so silly as adding too booleans together or anything like that.
>
>Heh, if you wanted a smaller bool (to consume less memory), maybe implement bool8 or even bool16 for that purpose. Wouldn't hurt anyone.
>
>Besides, having bitarrays implemented as a language-level primitive is an insult to the D language itself. Is the language really so weak that you can't implement a bitset in the standard?
>
>Surely you can!
>
>The only reason _not_ to implement things in standard library is speed of compilation, which I don't think is a problem with the current D implementation, and optimization opportunities, which I believe can very well be done after the fact if the need arises.
>
>So there.
>
>-Antti
>
>-- 
>I will not be using Plan 9 in the creation of weapons of mass destruction to be used by nations other than the US.


June 05, 2004
Antti Sykäri wrote:

>The only reason _not_ to implement things in standard library is speed
>of compilation, which I don't think is a problem with the current D
>implementation, and optimization opportunities, which I believe can very
>well be done after the fact if the need arises.
>
>So there.
>
>-Antti
>  
>
For bit arrays its not just a question of speed of compilation, its a question of readability.  To make a bit array as efficient as D has the chance to be, you need all sorts of ugly bitwise operations. Obviously it could be implemented into a struct but then you still lose some efficiency and readability.

-- 
-Anderson: http://badmama.com.au/~anderson/
June 05, 2004
In article <slrncc26jr.n9h.jsykari@pulu.hut.fi>, Antti =?iso-8859-1?Q?Syk=E4ri?= says...
>
>Boolean types are basic types and should be reasoned about in the same way as any other type. This includes doing things like:

Much as I would love to agree with you(and I would - I really would, because I want a working bool type as much as anyone), your points are not actually points in favor of making bool=int, they are points in favor of FIXING THE BUGS IN "bit". (Obviously I agree with you on both counts though).

If we are going to have a type, bit, which behaves like a primative type, then it must be properly implemented. It must be possible to take the address of a bit. Pointer arithmetic must work. Slicing, both by copy and by reference, must work, even on non-byte boundaries.

There is a way that this can be done easily - but I suspect that a lot of people won't like it. The D compiler needs to take these three steps (and they are not trivial).

(1) The property bit.sizeof() must return a float or a double, not an int, with
value 0.125.

(2) Taking the address of a bit must return a new type, a "bit pointer". The simplest way to implement this is as double. Doubles can store a superset of the values that uints can store, and in addition they are capable of handling those 0.125 fractional parts. Example, bit 0 at byte-address 1193046 would have bit-address 1193046.0; bit 1 at the same byte-address would have bit-address 1193046.0125, and so on.

(3) Given that currently, slices consist of a struct containing a pointer and a length, so bit-slices must consist of a struct containing a bit-pointer as described above, and a length.

Walter may be able to think of other ways of achieving this, as he's a smart guy. But the only reasonable alternative to unambiguously succeeding (when taking the address of a bit), is throwing an exception. Returning a byte-address can only ever lead to undefined behaviour. Same goes for bitslicing on not-necessarily-byte boundaries.

Arcane Jill



June 05, 2004
In article <slrncc26jr.n9h.jsykari@pulu.hut.fi>, Antti =?iso-8859-1?Q?Syk=E4ri?= says...
>
>I've just finished reading a hundred-message thread about the boolean type that brought me to the following conclusion:
>
>Boolean types are basic types and should be reasoned about in the same way as any other type. This includes doing things like:
>
>void catastrophe1(inout bool y)
>{
>    if (y == false)
>        y = true;
>}
>
>void catastrophe2(bool* y)
>{
>    if (*y == false)
>        *y = true;
>}
>
>void main()
>{
>    bool[16] x;
>    catastrophe1(x[5]);
>    catastrophe2(&x[5]);
>
>    bool* first_bool = &x[0];
>    bool* second_bool = &x[1];
>    assert(second_bool == first_bool + 1);
>    assert(cast(int) second_bool = cast(int) first_bool + bool.size);
>}
>
>If you substitute int in place of bit, this works. But not as it is.

These are the exact problems vector<bool> has in the C++ standard library, and something I think should be corrected in both D and in C++.  If a method can't be found to provide a hidden proxy value for such things then I'd be willing to lose the automatic space savings and have bool always be one byte or larger. There are certainly times when I do need the space efficiency single bit storage provides, but not always, and not always at the expense of subtly broken code. I'd be quite willing to settle for a special container that does bit packing and leave bool[] as a normal byte array.


Sean


June 05, 2004
Agreed!

Bit on modern processors is not an addressable object. So it should not be a regular language object.

"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:c9s72o$1108$1@digitaldaemon.com...
> In article <slrncc26jr.n9h.jsykari@pulu.hut.fi>, Antti
=?iso-8859-1?Q?Syk=E4ri?=
> says...
> >
> >Boolean types are basic types and should be reasoned about in the same way as any other type. This includes doing things like:
>
> Much as I would love to agree with you(and I would - I really would,
because I
> want a working bool type as much as anyone), your points are not actually
points
> in favor of making bool=int, they are points in favor of FIXING THE BUGS
IN
> "bit". (Obviously I agree with you on both counts though).
>
> If we are going to have a type, bit, which behaves like a primative type,
then
> it must be properly implemented. It must be possible to take the address
of a
> bit. Pointer arithmetic must work. Slicing, both by copy and by reference,
must
> work, even on non-byte boundaries.
>
> There is a way that this can be done easily - but I suspect that a lot of
people
> won't like it. The D compiler needs to take these three steps (and they
are not
> trivial).
>
> (1) The property bit.sizeof() must return a float or a double, not an int,
with
> value 0.125.
>
> (2) Taking the address of a bit must return a new type, a "bit pointer".
The
> simplest way to implement this is as double. Doubles can store a superset
of the
> values that uints can store, and in addition they are capable of handling
those
> 0.125 fractional parts. Example, bit 0 at byte-address 1193046 would have bit-address 1193046.0; bit 1 at the same byte-address would have
bit-address
> 1193046.0125, and so on.
>
> (3) Given that currently, slices consist of a struct containing a pointer
and a
> length, so bit-slices must consist of a struct containing a bit-pointer as described above, and a length.
>
> Walter may be able to think of other ways of achieving this, as he's a
smart
> guy. But the only reasonable alternative to unambiguously succeeding (when taking the address of a bit), is throwing an exception. Returning a
byte-address
> can only ever lead to undefined behaviour. Same goes for bitslicing on not-necessarily-byte boundaries.
>
> Arcane Jill
>
>
>


June 05, 2004
In article <c9rsm1$f7f$1@digitaldaemon.com>, Kevin Bealer says...
>
>
>1. Your example fails to compile, and fails with a reasonable message, so there is no language bug there.
>
>2. The bit/bit array objects are a *feature*.  All the behaviours that that you and the other anti-bit folks want in a boolean ARE ALREADY AVAILABLE in other types.  You can use typedef if you are afraid of automatic conversion.
>
>3. You argue that it is hard to understand.  Well tough.

But what about template code?  Say I write a template function that manipulates arrays.  Why should bool[] be a special case that the function can't operate on? As I said in another message, this is the exact same issue as the vector<bool> specialization in C++.  And because of the contention surrounding vector<bool> I don't expect this to be settled amicably either.

>Bit arrays aren't needed everywhere.  Like C, C++, and the professional paint sprayer, they are a power tool.  If you want a simple tool with a different interface, don't use them.  But getting this functionality to run fast IS very important for a lot of applications, so it should be in the language, not a library.

It shouldn't matter whether a feature is in the language or in its standard library, so long as the reason for the choice makes sense.  Adding a feature to the language allows for better error handling and integration, but this is not always necessary nor desirable.  You say that bit arrays aren't needed everywhere, but by integrating them into the language you require that they be used everywhere whether you want them or not.  What does the person who just wants a plain old vector of boolean values do?

>Between enums, the dozens of integer types, and structures, the functionality you want is available.  You just have to accept that for "int" semantics, you want the int type.

So why should bool be different?  It's a primitive type that can be assigned to and compared.  It can be stored in arrays, etc.  But taking the address of a bool when it's in an array is illegal?

I should back up and say that I am playing devils' advocate to a degree here. This problem wouldn't affect me either way because I know the language well enough to avoid it.  But because of the vector<bool> issue I know that it confuse other people.  And while I'm typically inclined to say RTFM, I'm not sure that such a special case should be built into the language rather than provided as a library feature.


Sean


June 05, 2004
In article <c9s72o$1108$1@digitaldaemon.com>, Arcane Jill says...
>
>In article <slrncc26jr.n9h.jsykari@pulu.hut.fi>, Antti =?iso-8859-1?Q?Syk=E4ri?= says...
>>
>>Boolean types are basic types and should be reasoned about in the same way as any other type. This includes doing things like:
>
>Much as I would love to agree with you(and I would - I really would, because I want a working bool type as much as anyone), your points are not actually points in favor of making bool=int, they are points in favor of FIXING THE BUGS IN "bit". (Obviously I agree with you on both counts though).

Exactly :)

>There is a way that this can be done easily - but I suspect that a lot of people won't like it. The D compiler needs to take these three steps (and they are not trivial).
>
>(1) The property bit.sizeof() must return a float or a double, not an int, with
>value 0.125.
>
>(2) Taking the address of a bit must return a new type, a "bit pointer". The simplest way to implement this is as double. Doubles can store a superset of the values that uints can store, and in addition they are capable of handling those 0.125 fractional parts. Example, bit 0 at byte-address 1193046 would have bit-address 1193046.0; bit 1 at the same byte-address would have bit-address 1193046.0125, and so on.
>
>(3) Given that currently, slices consist of a struct containing a pointer and a length, so bit-slices must consist of a struct containing a bit-pointer as described above, and a length.

Very clever, but the thought of it makes me cringe.  If this is what's required then I'd prefer to just leave everything as-is.

>Walter may be able to think of other ways of achieving this, as he's a smart guy. But the only reasonable alternative to unambiguously succeeding (when taking the address of a bit), is throwing an exception. Returning a byte-address can only ever lead to undefined behaviour. Same goes for bitslicing on not-necessarily-byte boundaries.

I'd prefer to issue a compiler error in this case.  Exceptions would be a last resort.

Sean


« First   ‹ Prev
1 2 3