Eiffel enumerations 
Author Message
 Eiffel enumerations

The lack of an enumerated type facility in Eiffel can be a serious
problem with "similar" types. The use of names of INTEGER values to specify
different, essentially hardcoded, values is only slightly better then
using the actual integer values themselves in some cases.

For example, if two methods take predefined INTEGER values as parameters
to invoke different behaviour things can get confusing. Say parameter X takes
OPTION_A or OPTION_B, while parameter Y can be OPTION_1 or OPTION_2.
Eiffel allows improperly mixing of these parameters (passing OPTION_1 for X
and OPTION_B to Y) which can lead to confusing code & behaviour.

A simple way to avoid this is to add an enumerated type facility so that
X & Y can be declared of different types, in which case the above error
would be caught at compile time.

The use of enumerated types, and the inherent safety, appears more inline
with the "safe programming" aspects of Eiffel and as such I think is worth
adding to the language. Any comments?



Mon, 08 Dec 1997 03:00:00 GMT  
 Eiffel enumerations
: The lack of an enumerated type facility in Eiffel can be a serious
: problem with "similar" types. The use of names of INTEGER values to specify
: different, essentially hardcoded, values is only slightly better then
: using the actual integer values themselves in some cases.

: For example, if two methods take predefined INTEGER values as parameters
: to invoke different behaviour things can get confusing. Say parameter X takes
: OPTION_A or OPTION_B, while parameter Y can be OPTION_1 or OPTION_2.
: Eiffel allows improperly mixing of these parameters (passing OPTION_1 for X
: and OPTION_B to Y) which can lead to confusing code & behaviour.

: A simple way to avoid this is to add an enumerated type facility so that
: X & Y can be declared of different types, in which case the above error
: would be caught at compile time.

Uh you mean something like:

class LETTERED_OPTIONS is
    feature
         datum:INTEGER
        -- add routines to return '.a' and '.b'
end;

class NUMBERED_OPTIONS is
        feature
           datum:INTEGER
      -- add routines to return '.one' and '.two' or whatever.
end

perhaps?



Mon, 08 Dec 1997 03:00:00 GMT  
 Eiffel enumerations
What about a class with an integer as representation and a feature
that returns that value. The creation procedure will set that value.

Just emagin the above is an abstract enumeration type. For a concrete
type use inheritance and restrict the range for the integer. When
passing the enumeration to features, the usual type checking will be
enforced.

Just an idea...



Mon, 08 Dec 1997 03:00:00 GMT  
 Eiffel enumerations

Quote:

>The lack of an enumerated type facility in Eiffel can be a serious
>problem with "similar" types. The use of names of INTEGER values to specify
>different, essentially hardcoded, values is only slightly better then
>using the actual integer values themselves in some cases.

>For example, if two methods take predefined INTEGER values as parameters
>to invoke different behaviour things can get confusing. Say parameter X takes
>OPTION_A or OPTION_B, while parameter Y can be OPTION_1 or OPTION_2.
>Eiffel allows improperly mixing of these parameters (passing OPTION_1 for X
>and OPTION_B to Y) which can lead to confusing code & behaviour.

>A simple way to avoid this is to add an enumerated type facility so that
>X & Y can be declared of different types, in which case the above error
>would be caught at compile time.

>The use of enumerated types, and the inherent safety, appears more inline
>with the "safe programming" aspects of Eiffel and as such I think is worth
>adding to the language. Any comments?

If you think about what you want to do with the option inside the
called routine, you may come up with something like this:

Using options represented as integers as you suggest, you might have
something like:

class X

        do_something (option: INTEGER) is
        do
           inspect option
           when option_a then routine_a
           when option_b then routine_b
           ...

To get type safety and some other benefits, I would use
a mechanism more like this:

deferred class OPTION_LETTER
-- an option to X.do_something

feature {X}
-- I tend to do that for documentation as much as anything else.
     do_it (x: X) is deferred end
end

class OPTION_A
inherit OPTION_LETTER
feature
     do_it (x:X) is
     x.routine_a
     end
end

-- similarly class OPTION_B etc

and now the 'inspect' statement disappears, because we are using
polymorphism instead:

class X
        do_something (option: OPTION_LETTER) is
        do
           option.do_it(Current)
           -- note the passing of 'Current' to the option to allow it
           -- to invoke feature(s) of this instance of X

Clients of X would also inherit from USE_X which supplies the
'constants' option_a etc:

class USE_X

feature
        option_a: OPTION_A is
        once !!Result
        end
-- etc, replacing the previous 'option_a: INTEGER is unique' you might
-- have had before.

Notice that the client of X still says 'do_something(option_a)'
exactly as he did before: only the supplier side has changed.

In practice of course 'do_something', 'option_a', 'do_it' etc would
be given meaningful names.  You will usually find that the
OPTION_LETTER class need several  routines rather than one.

If you have not seen that sort of construction before, you may need
to ponder on it awhile.  Once you see the idea however it becomes
second nature to use polymorphism in this way.

What have we got for this extra verbosity other than type safety?

A very clear record of exaclty what option_a, option_b etc
represent: e.g. to work out the difference between option_a and
option_b I simply compare the texts of the two corresponding
classes: no need to work through a labrynth of complicated
conditionals.  Similarly if I want an option_c that is very like
option_a, I make OPTION_C inherit from OPTION_A and use
redefinition.  If written with some thought, the option classes
become self-documenting,

I have been an Eiffel user for many years, and have never used
'unique', never mind felt the urge to invent enumerated types: I
hope you can now see why.

Trevor Nash



Fri, 12 Dec 1997 03:00:00 GMT  
 Eiffel enumerations
: In practice of course 'do_something', 'option_a', 'do_it' etc would
: be given meaningful names.  You will usually find that the
: OPTION_LETTER class need several  routines rather than one.
:        
: If you have not seen that sort of construction before, you may need
: to ponder on it awhile.  Once you see the idea however it becomes
: second nature to use polymorphism in this way.
:  
: What have we got for this extra verbosity other than type safety?

: A very clear record of exaclty what option_a, option_b etc
: represent: e.g. to work out the difference between option_a and
: option_b I simply compare the texts of the two corresponding
: classes: no need to work through a labrynth of complicated
: conditionals.  Similarly if I want an option_c that is very like
: option_a, I make OPTION_C inherit from OPTION_A and use
: redefinition.  If written with some thought, the option classes
: become self-documenting,

: I have been an Eiffel user for many years, and have never used
: 'unique', never mind felt the urge to invent enumerated types: I
: hope you can now see why.

This is literally a textbook example of the "Strategy" pattern
from Gamma et al.  Quoting:

Strategy:  Define a family of algorithms, encapsulate each one, and
make them interchangable.  Strategy lets the algorithm vary independently
from clients that use it.

Now you see, you stopped thinking about "I want to give symbolic names
to 5 different integers" and you started thinking about "what do
these things represent".

I presume the empirical experience demonstrates that if you have a need
for symbolic enumeration, you may generally have a need for something
greater still and you ought to go for it right away.

: Trevor Nash

Those design patterns give names and clear explanation to the sorts of "Good
proven object oriented solutions" that the wisest have been inventing, and
reinventing over the years.

cheers
matt

Oh by the way, if you're obstinate
you could always get symbolic constants with something
like: (in Sather syntax):

class MY_PARTICULAR_SET_OF_ENUMERATIONS is
        include INT;
        create(arg:INT) -- put creation routine

        first:SAME return 1 end;
        second:SAME return 2 end;
        shave_and_a_hair_cut:SAME return 2 end;
        two_bits:SAME return 50 end;

end;



Fri, 12 Dec 1997 03:00:00 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Enumerations in Eiffel

2. Follow up on enumerations

3. Reading ActiveX Control Enumerations

4. Fanaticism [was Re: Enumerations and Arrays Unnecessary!???]

5. Size of enumerations/subranges in Modula-2

6. Size of enumerations/subranges in Modula-2

7. Enumerations

8. enumerations

9. Enumerations - slow down a minute!

10. Pattern for enumerations? (Attn: Roger Browne)

11. Enumerations in Oberon (was: Re: Enumerated types)

12. enumerations

 

 
Powered by phpBB® Forum Software