View mode: basic / threaded / horizontal-split · Log in · Help
August 10, 2004
Re: Enums can be annoyingly verbose...
On Tue, 10 Aug 2004 11:56:06 +0000 (UTC), Arcane Jill 
<Arcane_member@pathlink.com> wrote:
> In article <opschrxff75a2sq9@digitalmars.com>, Regan Heath says...
>
>>   //proposed method
>>   fooBar(THE|QUICK|BROWN|FOX|JUMPS|OVER|THE|LAZY|DOG);
>
> Would that work? I mean, I can see that:
>
> #    fooBar(THE);
>
> would work, since (assuming your proposed scheme) the compiler would be 
> able to
> infer the type of the fooBar parameter. But as for
>
> #    fooBar(THE|QUICK|BROWN|FOX|JUMPS|OVER|THE|LAZY|DOG);
>
> I have to ask - what is the compile-time type of the expression:
>
> #    THE|QUICK|BROWN|FOX|JUMPS|OVER|THE|LAZY|DOG
>
> My guess is that the compile-time type of even the expression:
>
> #
> FooBarBaz.THE|FooBarBaz.QUICK|FooBarBaz.BROWN|FooBarBaz.FOX|FooBarBaz.JUMP|FooBarBaz.OVER|FooBarBaz.THE|FooBarBaz.LAZY|FooBarBaz.DOG
>
> is not actually FooBarBaz, but is in fact int. Does the | operator 
> preserve the
> type of an enum? I'm not sure that it does.

Good question.. I think Walter is the only one who can really answer it, 
however, my tests show that you cannot pass an 'int' to a function 
expecting a 'FooBarBaz', but you can pass something like 
'FooBarBaz.ONE|FooBarBaz.TWO'. In fact you can also cast and pass another 
enum type if you want.

enum FooBarBaz {
  ONE   = 0x1,
  TWO   = 0x2,
  THREE = 0x4,
  FOUR  = 0x8
}

enum BarBazFoo {
  ONE   = 0x8,
  TWO   = 0x4,
  THREE = 0x2,
  FOUR  = 0x1
}

void fooBar(FooBarBaz a) {
	printf("%x\n",a);
}

void main()
{
  int i = FooBarBaz.ONE|FooBarBaz.TWO;
  fooBar(i);  //function fooBar (FooBarBaz a) does not match argument 
types (int)
              //cannot implicitly convert expression i of type int to 
FooBarBaz
  fooBar(FooBarBaz.ONE|FooBarBaz.TWO);
  fooBar(cast(FooBarBaz)BarBazFoo.ONE|BarBazFoo.TWO);
}

> Arcane Jill
> (basically in support but with one or two niggling doubts).

Glad to see someone is thinking about how genreally 'nice' this would be 
without accusing me of being lazy.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
August 11, 2004
OT Laziness (was Re: Enums...)
In article <opscjhxy015a2sq9@digitalmars.com>, Regan Heath says...

>Glad to see someone is thinking about how genreally 'nice' this would be 
>without accusing me of being lazy.

I take pride in being lazy. When I was studying math at school, I was taught
that math is all about being lazy, and that the very best mathematicians are the
laziest of all. If you cou prove a theorem ONCE for (say) "rings", then you've
proven it for reals, integers, whatever. There are parallels with OOP here -
component re-use is all about being lazy. I also write libraries because I'm
lazy (why write the same piece of code more than once?). I use Phobos routines
because I'm lazy (why write a piece of code at all if someone else has done it
for me?). I even write in D because I'm lazy (why invent my own brand new
computer language when I can just use Walter's?). I dunno, but I guess those mad
workaholic types just enjoy re-inventing the wheel all the time, or maybe they
just get a buzz out of pressing keys on their keyboard?

Jill
(Lazy and proud of it)
August 11, 2004
Re: OT Laziness (was Re: Enums...)
In article <cfcgjg$4v6$1@digitaldaemon.com>, Arcane Jill says...
>
>In article <opscjhxy015a2sq9@digitalmars.com>, Regan Heath says...
>
>>Glad to see someone is thinking about how genreally 'nice' this would be 
>>without accusing me of being lazy.
>
>I take pride in being lazy.

and of course
"efficience is the smart lazy"
(better wording welcome)

Ant
August 11, 2004
Re: OT Laziness (was Re: Enums...)
Give the hardest job to the laziest person and they will find the quickest way of doing it.


On Wed, 11 Aug 2004 12:30:56 +0000 (UTC)
Ant <Ant_member@pathlink.com> wrote:

> In article <cfcgjg$4v6$1@digitaldaemon.com>, Arcane Jill says...
> >
> >In article <opscjhxy015a2sq9@digitalmars.com>, Regan Heath says...
> >
> >>Glad to see someone is thinking about how genreally 'nice' this would be 
> >>without accusing me of being lazy.
> >
> >I take pride in being lazy.
> 
> and of course
> "efficience is the smart lazy"
> (better wording welcome)
> 
> Ant
> 
>
August 11, 2004
Re: Enums can be annoyingly verbose...
"Jarrett Billingsley" <kb3ctd2@yahoo.com> escribió en el mensaje
news:cf99h1$160a$1@digitaldaemon.com
| or you can do it like this.
|
| enum : ushort
| {
|    THE=0x01;
|    ...
| }
|
| only problem is that you lose the enum name, which is nice to have if you
| have conflicting names (but that shouldn't happen very often).

But then he loses his FooBarBaz type.

-----------------------
Carlos Santander Bernal
August 11, 2004
Re: Enums can be annoyingly verbose...
Regan Heath wrote:
> I have mentioned this before, but I kinda want some more opinions on the 
> matter/idea.
> 
> Currently we have to specify an enum by it's full name, this can be 
> quite long and you can end up writing/copying/pasting the enum name a 
> few times.
> 
> Surely it's possible in most cases for the compiler to determine the 
> Enum name and thus it's not really required.
> 
> Example:
> 
> enum FooBarBaz : ushort
> {
>   THE   = 0x0001,
>   QUICK = 0x0002,
>   BROWN = 0x0004,
>   FOX   = 0x0008,
>   JUMPS = 0x0010,
>   OVER  = 0x0020,
>   THE   = 0x0040,
>   LAZY  = 0x0080,
>   DOG   = 0x0100
> }
> 
> void fooBar(FooBarBaz a) {}
> 
> void main()
> {
>   //current method
>   
> fooBar(FooBarBaz.THE|FooBarBaz.QUICK|FooBarBaz.BROWN|FooBarBaz.FOX|FooBarBaz.JUMP|FooBarBaz.OVER|FooBarBaz.THE|FooBarBaz.LAZY|FooBarBaz.DOG); 
> 
> 
>   //proposed method
>   fooBar(THE|QUICK|BROWN|FOX|JUMP|OVER|THE|LAZY|DOG);
> 
>   //alternate method
>   fooBar(with(FooBarBaz){THE|QUICK|BROWN|FOX|JUMP|OVER|THE|LAZY|DOG});
> }

I don't think it's a good idea to get DMD guessing which namespaces to 
search when it can't find a symbol, nor does it feel like a particularly 
good idea to use the with() construct as an expression.

What would be simpler, and about as useful, though, would be if with() 
were also usable as an attribute specifier, like public/private/etc.

    class Foo {
        // Java-style
        with(FooBarBaz) const FooBarBaz flags = THE | QUICK | BROWN | FOX;

        // C++-style
    with (FooBarBaz):
        const FooBarBaz flags = ...;
    }

Incidently, it's becoming apparent that we have three different keywords 
for almost the same thing: with(), import, and alias. :)

 -- andy
August 11, 2004
Re: Enums can be annoyingly verbose...
In article <opscjg92ma5a2sq9@digitalmars.com>, Regan Heath says...
>
>On Tue, 10 Aug 2004 00:28:55 -0500, Deja Augustine <deja@scratch-ware.net> 
>wrote:
>>
>> I can see no justification for coding implicit enum resolution into the 
>> compiler when there are several much less ambiguous options available.
>
>Firstly my initial suggestion is not ambiguous, your example, which was 
>not what I was suggesting was ambiguous. To explain, my idea:
>
>enum FooBarBaz {
>   ONE,TWO
>}
>
>fooBar(ONE);
>
>is not any more/less ambiguous than
>
>fooBar(FooBarBaz.ONE);
>
>because if you're wondering what ONE is, and what it means to FooBar you 
>have to lookup both the 'fooBar' function and the 'FooBarBaz' enum. In the 
>case of my example, the former gives you the name of the latter.

But if the 'FooBarBaz' is omitted then the user does not know which enum to
check.  This is especially true if fooBar takes an int value and the enum is
being implicitly cast.  IMO D corrects what can be a very subtle source of bugs
in C/C++ by requiring named enums to be qualified appropriately.  I would very
much not like this to change, especially if the reason is just to save a few
keystrokes.

>Sure it's not a super important feature/idea, but it's a nice touch, one 
>that so far you have given no real reasons against it, all you have said 
>is:
>  - that I am lazy
>  - that walter has more important thing to do
>  - that it is ambiguous.

The only point I agree with is the one regarding ambiguity.  Consider this code:

# module a;
#
# enum ScreenColor {
#   RED = 1,
#   GREEN = 2,
#   BLUE = 3 }
#
# module b;
#
# enum PaintColor {
#   RED = 53,
#   GREEN = 85,
#   BLUE = 16 }
#
# module c;
#
# void PaintScreen( int color ) { ... } 
#
# void main() { PaintScreen( RED ); }

The above is unambiguous because there is only one defined value for RED.
However, assume that during the course of maintenance a programmer discovers
that he needs something from module b, so he imports that and for some reason
removes the line importing module a.  Everything compiles just fine because RED
is still defined, but the PaintScreen call is now operating on a completely
different value.  In more complex cases such bugs can be extremely difficult to
diagnose, especially if the affected code is something that has been left
unchanged for years.


Sean
August 11, 2004
Re: Enums can be annoyingly verbose...
On Wed, 11 Aug 2004 21:23:57 +0000 (UTC), Sean Kelly <sean@f4.ca> wrote:
> In article <opscjg92ma5a2sq9@digitalmars.com>, Regan Heath says...
>>
>> On Tue, 10 Aug 2004 00:28:55 -0500, Deja Augustine 
>> <deja@scratch-ware.net>
>> wrote:
>>>
>>> I can see no justification for coding implicit enum resolution into the
>>> compiler when there are several much less ambiguous options available.
>>
>> Firstly my initial suggestion is not ambiguous, your example, which was
>> not what I was suggesting was ambiguous. To explain, my idea:
>>
>> enum FooBarBaz {
>>   ONE,TWO
>> }
>>
>> fooBar(ONE);
>>
>> is not any more/less ambiguous than
>>
>> fooBar(FooBarBaz.ONE);
>>
>> because if you're wondering what ONE is, and what it means to FooBar you
>> have to lookup both the 'fooBar' function and the 'FooBarBaz' enum. In 
>> the
>> case of my example, the former gives you the name of the latter.
>
> But if the 'FooBarBaz' is omitted then the user does not know which enum 
> to
> check.

Yes they do.. think about how you'd go about it, first you'd look up the 
function, because what point is knowing the value of the enum if you don't 
know what's being done with it. The function includes the name of the 
enum... well... until I read your statement below I assumed it would :)

> This is especially true if fooBar takes an int value and the enum is
> being implicitly cast.

Ahh.. I didn't think of this. :)

So.. 'enum' is implicitly convertable to 'int' but 'int' is not implicitly 
convertable to 'enum', is that completely sensible do you think?

I guess I assumed as 'int' wasn't implicitly convertable to 'enum' that 
the reverse would hold true also.


I have just discovered something slightly weird...

enum Test : ubyte {
  ONE = 0x1,
  TWO = 0x2
}

void foo(Test a)
{
}

void main()
{
  foo(Test.ONE);
  foo(Test.ONE|Test.TWO);  //function foo (Test a) does not match argument 
types (int)
                           //cannot implicitly convert expression 
cast(int)(1)
                           // | cast(int)(2) of type int to Test
}

Bug? or not?

> IMO D corrects what can be a very subtle source of bugs
> in C/C++ by requiring named enums to be qualified appropriately.  I 
> would very
> much not like this to change, especially if the reason is just to save a 
> few
> keystrokes.

The reason above is the first good one I've heard against my proposal. It 
probably kills it stone dead too.

>> Sure it's not a super important feature/idea, but it's a nice touch, one
>> that so far you have given no real reasons against it, all you have said
>> is:
>>  - that I am lazy
>>  - that walter has more important thing to do
>>  - that it is ambiguous.
>
> The only point I agree with is the one regarding ambiguity.  Consider 
> this code:
>
> # module a;
> #
> # enum ScreenColor {
> #   RED = 1,
> #   GREEN = 2,
> #   BLUE = 3 }
> #
> # module b;
> #
> # enum PaintColor {
> #   RED = 53,
> #   GREEN = 85,
> #   BLUE = 16 }
> #
> # module c;
> #
> # void PaintScreen( int color ) { ... }
> #
> # void main() { PaintScreen( RED ); }
>
> The above is unambiguous because there is only one defined value for RED.

I assume you're missing an 'import b'; above?

> However, assume that during the course of maintenance a programmer 
> discovers
> that he needs something from module b, so he imports that and for some 
> reason
> removes the line importing module a.  Everything compiles just fine 
> because RED
> is still defined, but the PaintScreen call is now operating on a 
> completely
> different value.  In more complex cases such bugs can be extremely 
> difficult to
> diagnose, especially if the affected code is something that has been left
> unchanged for years.

Yeah.. my assumption about the implicit conversion was the killer.

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
August 12, 2004
Re: Enums can be annoyingly verbose...
In article <opscld1nzg5a2sq9@digitalmars.com>, Regan Heath says...

>> This is especially true if fooBar takes an int value and the enum is
>> being implicitly cast.
>
>Ahh.. I didn't think of this. :)

Yes you did. Or at least, your original idea, as I now understand it, completely
covers this possibility. It works like this - assume your enum-type-detection
system is up and running, then:

#    enum Qwerty { ONE=1, TWO=2 };
#    void f(int x) { /*whatever*/ }
#    f(ONE);

This is simply a compile error, because f takes an int, and therefore "with
Qwerty" is not assumed when parsing f(ONE); Accordingly, ONE is simply an
unknown identifier. To get it to compile, you'd have either to change line 3 to
f(Qwerty.ONE); or else change line 2 to void f(Qwerty x);





>I have just discovered something slightly weird...
>
>enum Test : ubyte {
>   ONE = 0x1,
>   TWO = 0x2
>}
>
>void foo(Test a)
>{
>}
>
>void main()
>{
>   foo(Test.ONE);
>   foo(Test.ONE|Test.TWO);  //function foo (Test a) does not match argument 
>types (int)
>                            //cannot implicitly convert expression 
>cast(int)(1)
>                            // | cast(int)(2) of type int to Test
>}
>
>Bug? or not?

I think this is what I tried to mention in my last responce. The type of
Test.ONE is Test, but the operator | takes ints, and returns an int, so both
Test.ONE and Test.TWO are converted to int for the benefit of operator |, and
the result is syntactically an int. Since ints cannot be implicitly cast to
named enums, you have a compile error. You make it compile by doing:

#   foo(cast(Test)(Test.ONE|Test.TWO)); 

I have to say, though, I'm not greatly in favor of using enums as bit masks. I
realize that (other) people do it all the time, but it seems to me that using an
enum variable to hold a numerical value for which there is no corresponding enum
name is violating (my conception of) what an enum is for. But that's just me,
and I know other people do things differently.


>> IMO D corrects what can be a very subtle source of bugs
>> in C/C++ by requiring named enums to be qualified appropriately.  I 
>> would very
>> much not like this to change, especially if the reason is just to save a 
>> few
>> keystrokes.
>
>The reason above is the first good one I've heard against my proposal. It 
>probably kills it stone dead too.

I've argued that it doesn't, however, /this/ might do:

#    enum A { ONE=1, TWO=2 };
#    enum B { ONE=2, TWO=1 };
#    void f(A x);
#    void f(B x);
#    f(ONE);

The evaluation of the expression f(ONE) requires an implicit "with", which the
compiler can only get from the declaration of f() - but this requires knowing in
advance which overload of f() is going to be used. Unfortunately, overload
resolution requires knowing the types of the arguments, and so requires the
arguments to be parsed /first/. We have ourselves some circularity! The only way
out of this would be to allow "implicit withs" only on non-overloaded functions.
(Or at least, functions which are not overloaded to the point of ambiguity, but
we may be asking too much of the compiler at this point).

Arcane Jill
August 13, 2004
Re: Enums can be annoyingly verbose...
Regan Heath schrieb:

>> Arcane Jill
>> (basically in support but with one or two niggling doubts).
> 
> Glad to see someone is thinking about how genreally 'nice' this would be 
> without accusing me of being lazy.

I would like to silently thumb up the remark and ideas as well.

-eye
1 2 3 4 5
Top | Discussion index | About this forum | D home