patterns for representing enumerations/constants

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

patterns for representing enumerations/constants

Peter Uhnak
Hi,

as this probably doesn't have one solution I am interested in your approach, if you have any.

The problem is that often you want to create instances (or just return constants) in some particular domain, e.g.

Color red.
Color blue.

Unfortunately this doesn't scale, because putting unary methods on the class-side is a good way to break your image.

1) capitalize

doesn't follow method naming conventions

Color Red.
ParticipantType Organization (uncapitalized returns ClassOrganization)
VisibilityKind Package (package returns package)

2) have it on instance-side

need for an extra singleton and more typing

Color default red.
ParticipantType default organization.
VisibilityKind default package.

maybe #enum could work better?

Color enum red.
VisibilityKind enum package.

3) use ALLCAPS

looks like C/Java… ugly af
also same issue as 1)

Color RED.
ParticipantType ORGANIZATION.
VisibilityKind PACKAGE.

4) use some prefix/suffix?

may not be enough, can be confusing when implementing a domain with given specifications

Color redColor.
ParticipantType organizationType.
VisibilityKind packageKind

5) something better?

All the above work (obviously) but all are broken to some extent… so it's picking the best of the worst. -_-

Any ideas appreciated,

Peter
Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

Peter Uhnak
Plus this may typically interact with some serialization/materialization which would use the base format ('red', 'organization', 'kind'), so if there's any change to the name another mapping format would be required.

On Wed, Mar 23, 2016 at 5:41 PM, Peter Uhnák <[hidden email]> wrote:
Hi,

as this probably doesn't have one solution I am interested in your approach, if you have any.

The problem is that often you want to create instances (or just return constants) in some particular domain, e.g.

Color red.
Color blue.

Unfortunately this doesn't scale, because putting unary methods on the class-side is a good way to break your image.

1) capitalize

doesn't follow method naming conventions

Color Red.
ParticipantType Organization (uncapitalized returns ClassOrganization)
VisibilityKind Package (package returns package)

2) have it on instance-side

need for an extra singleton and more typing

Color default red.
ParticipantType default organization.
VisibilityKind default package.

maybe #enum could work better?

Color enum red.
VisibilityKind enum package.

3) use ALLCAPS

looks like C/Java… ugly af
also same issue as 1)

Color RED.
ParticipantType ORGANIZATION.
VisibilityKind PACKAGE.

4) use some prefix/suffix?

may not be enough, can be confusing when implementing a domain with given specifications

Color redColor.
ParticipantType organizationType.
VisibilityKind packageKind

5) something better?

All the above work (obviously) but all are broken to some extent… so it's picking the best of the worst. -_-

Any ideas appreciated,

Peter

Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

Damien Pollet-2


On 23 March 2016 at 17:49, Peter Uhnák <[hidden email]> wrote:
Color red.
Color blue.

Unfortunately this doesn't scale, because putting unary methods on the class-side is a good way to break your image.

Why / how ? 

Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

Peter Uhnak
Why / how ? 

As explained in the first example.

Try adding #organization or #package methods to the class-side.
Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

jfabry
In reply to this post by Peter Uhnak
I would do something like:

Color named: #red.
Color named: #blue.

et cetera.

the implementation of named: is a dictionary lookup.

Color class>>named: aSymbol
^self colors at: aSymbol

And the colors dictionary is a class instance variable that is lazily initialized by its accessor.

Pros are that there is no endless lists of methods at class side, and by using the accessor with lazy init there is no risk for the class instance variable to be nil because of class initialization weirdness. (Not that there is a bug with it, but I am not happy with my  understanding of when this happens.)

On Mar 23, 2016, at 13:41, Peter Uhnák <[hidden email]> wrote:

Hi,

as this probably doesn't have one solution I am interested in your approach, if you have any.

The problem is that often you want to create instances (or just return constants) in some particular domain, e.g.

Color red.
Color blue.

Unfortunately this doesn't scale, because putting unary methods on the class-side is a good way to break your image.



---> Save our in-boxes! http://emailcharter.org <---

Johan Fabry   -   http://pleiad.cl/~jfabry
PLEIAD and RyCh labs  -  Computer Science Department (DCC)  -  University of Chile

Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

Esteban A. Maringolo
In reply to this post by Peter Uhnak
2016-03-23 14:40 GMT-03:00 Peter Uhnák <[hidden email]>:
>> Why / how ?
>
>
> As explained in the first example.
>
> Try adding #organization or #package methods to the class-side.

The "only 5 reserved keywords" is just a half-truth. :)

Some selectors are used by the the tooling, and with names to broad
that make collision with your own methods a very common issue.

The most common is the #name selector, which is on its way out fortunately.


Esteban A. Maringolo

Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

stepharo
In reply to this post by jfabry
+1


Le 23/3/16 18:53, Johan Fabry a écrit :
I would do something like:

Color named: #red.
Color named: #blue.

et cetera.

the implementation of named: is a dictionary lookup.

Color class>>named: aSymbol
^self colors at: aSymbol

And the colors dictionary is a class instance variable that is lazily initialized by its accessor.

Pros are that there is no endless lists of methods at class side, and by using the accessor with lazy init there is no risk for the class instance variable to be nil because of class initialization weirdness. (Not that there is a bug with it, but I am not happy with my  understanding of when this happens.)

On Mar 23, 2016, at 13:41, Peter Uhnák <[hidden email]> wrote:

Hi,

as this probably doesn't have one solution I am interested in your approach, if you have any.

The problem is that often you want to create instances (or just return constants) in some particular domain, e.g.

Color red.
Color blue.

Unfortunately this doesn't scale, because putting unary methods on the class-side is a good way to break your image.



---> Save our in-boxes! http://emailcharter.org <---

Johan Fabry   -   http://pleiad.cl/~jfabry
PLEIAD and RyCh labs  -  Computer Science Department (DCC)  -  University of Chile


Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

Peter Uhnak
I would do something like:

Color named: #red.
Color named: #blue.

That idea crossed my mind (it would be good for serialization from some external data), but how would you as user/programmer know what to put in there?
The idea of enums is that you have a predetermined set of predetermined values, so this

Pros are that there is no endless lists of methods at class side

is actually a con, because the user doesn't know them.

Everyone knows red and blue, but nobody remembers to the letter domain-specific props (in fact half of the class-side colors you wouldn't guess you could use named).

BormParticipantRole class selectors "#(#Approves #Undefined #Performs #Initiates #IsResponsible #Acquires #Cooperates #IsInformed #Consults)"
BormParticipantType class selectors "#(#Organization #System #Person)"

But maybe Color was wrong example because the set can be very large (although the set of options is also limited if you consider some standards).
Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

Esteban A. Maringolo
2016-03-23 16:31 GMT-03:00 Peter Uhnák <[hidden email]>:

>> I would do something like:
>>
>> Color named: #red.
>> Color named: #blue.
>
>
> That idea crossed my mind (it would be good for serialization from some
> external data), but how would you as user/programmer know what to put in
> there?
> The idea of enums is that you have a predetermined set of predetermined
> values, so this
>
>> Pros are that there is no endless lists of methods at class side
>
>
> is actually a con, because the user doesn't know them.
>
> Everyone knows red and blue, but nobody remembers to the letter
> domain-specific props (in fact half of the class-side colors you wouldn't
> guess you could use named).
>
> BormParticipantRole class selectors "#(#Approves #Undefined #Performs
> #Initiates #IsResponsible #Acquires #Cooperates #IsInformed #Consults)"
> BormParticipantType class selectors "#(#Organization #System #Person)"
>
> But maybe Color was wrong example because the set can be very large
> (although the set of options is also limited if you consider some
> standards).


You can have something at the class side that return the colors name,
using this example, by returning the keys of such dictionary.

Something like

YourClass class>>#colors

   ^Colors ifNil: [Colors := Dictionary new at: #red put: ...; at:
#blue put: ..; yourself]

Then you can have

YourClass class>>#colorsConstants
  ^self colors keys asSortedCollection

Regards

Esteban A. Maringolo

Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

Michal Balda
In reply to this post by Peter Uhnak
If there are not so many options and if they do not programatically
change, I would suggest creating a dedicated subclass for all of them:

– BormParticipantOrganizationType
– BormParticipantSystemType
– BormParticipantPersonType

All subclasses of BormParticipantType.

And then use something like:
1) BormParticipantOrganizationType new
2) BormParticipantOrganizationType instance
3) …or your preferred way of making singletons

The advantages?
– It shows well in the autocompletion.
– The values can have different behavior.
– And probably some more.

The disadvantages?
– Serialization into a simple String (and subsequent deserialization)
does not come for free, though it is easy to create methods for that.
– Longer class names.
– With a lot of different enums, the class count will grow significantly.


Michal



On 23.3.2016 20:31, Peter Uhnák wrote:
> BormParticipantRole class selectors "#(#Approves #Undefined #Performs
> #Initiates #IsResponsible #Acquires #Cooperates #IsInformed #Consults)"
> BormParticipantType class selectors "#(#Organization #System #Person)"
>
> But maybe Color was wrong example because the set can be very large
> (although the set of options is also limited if you consider some
> standards).


Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

Damien Pollet-2
In reply to this post by Peter Uhnak
On 23 March 2016 at 18:40, Peter Uhnák <[hidden email]> wrote:
Why / how ? 

As explained in the first example.

Try adding #organization or #package methods to the class-side.

I'd rather have selector namespaces to remove homonymy conflicts…
Reply | Threaded
Open this post in threaded view
|

Re: patterns for representing enumerations/constants

jfabry
In reply to this post by Esteban A. Maringolo

Exactly the solution that I thought of :-)

> On Mar 23, 2016, at 16:51, Esteban A. Maringolo <[hidden email]> wrote:
>
> 2016-03-23 16:31 GMT-03:00 Peter Uhnák <[hidden email]>:
>>> I would do something like:
>>>
>>> Color named: #red.
>>> Color named: #blue.
>>
>>
>> That idea crossed my mind (it would be good for serialization from some
>> external data), but how would you as user/programmer know what to put in
>> there?
>> The idea of enums is that you have a predetermined set of predetermined
>> values, so this
>>
>>> Pros are that there is no endless lists of methods at class side
>>
>>
>> is actually a con, because the user doesn't know them.
>>
>> Everyone knows red and blue, but nobody remembers to the letter
>> domain-specific props (in fact half of the class-side colors you wouldn't
>> guess you could use named).
>>
>> BormParticipantRole class selectors "#(#Approves #Undefined #Performs
>> #Initiates #IsResponsible #Acquires #Cooperates #IsInformed #Consults)"
>> BormParticipantType class selectors "#(#Organization #System #Person)"
>>
>> But maybe Color was wrong example because the set can be very large
>> (although the set of options is also limited if you consider some
>> standards).
>
>
> You can have something at the class side that return the colors name,
> using this example, by returning the keys of such dictionary.
>
> Something like
>
> YourClass class>>#colors
>
>   ^Colors ifNil: [Colors := Dictionary new at: #red put: ...; at:
> #blue put: ..; yourself]
>
> Then you can have
>
> YourClass class>>#colorsConstants
>  ^self colors keys asSortedCollection
>
> Regards
>
> Esteban A. Maringolo
>
>



---> Save our in-boxes! http://emailcharter.org <---

Johan Fabry   -   http://pleiad.cl/~jfabry
PLEIAD and RyCh labs  -  Computer Science Department (DCC)  -  University of Chile