- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
enums like Java
Sun, 2009-05-03, 14:27
From the Java tutorial we have rich enums like this
public enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7),
SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7),
NEPTUNE (1.024e+26, 2.4746e7);
private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
private double mass() { return mass; }
private double radius() { return radius; }
….
}
As far as I can see this can’t be done with the scala enumeration where the Value takes a few predefined constructors including
Value(Int, String) – which at least allows you to assign your own ids.
Is there a direct equivalent in Scala? I can see various ways around it but just wondered whether I’m missing something about the Enumeration type.
Tim
Sun, 2009-05-03, 15:17
#2
Re: enums like Java
I'm not sure how you consider this more convenient:
case object MERCURY extends Planet(3.303e+23, 2.4397e6)case object VENUS extends Planet(4.869e+24, 6.0518e6)case object EARTH extends Planet(5.976e+24, 6.37814e6) case object MARS extends Planet(6.421e+23, 3.3972e6)case object JUPITER extends Planet(1.9e+27, 7.1492e7)case object SATURN extends Planet(5.688e+26, 6.0268e7)case object URANUS extends Planet(8.686e+25, 2.5559e7) case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)case object PLUTO extends Planet(1.27e+22, 1.137e6)
Than the Java version:
public enum Planet { MERCURY (3.303e+23, 2.4397e6), VENUS (4.869e+24, 6.0518e6), EARTH (5.976e+24, 6.37814e6), MARS (6.421e+23, 3.3972e6), JUPITER (1.9e+27, 7.1492e7), SATURN (5.688e+26, 6.0268e7), URANUS (8.686e+25, 2.5559e7), NEPTUNE (1.024e+26, 2.4746e7), PLUTO (1.27e+22, 1.137e6);
In the Java version, the only overhead in defining a constant is writing its name and its constructor arguments (and it can't get much briefer than that!). In your case you also have "case object" and "extends Planet" for every constant.
And, of course, in the Java version you can write for (Planet planet : Planet.values()) ...
2009/5/3 Landei <Daniel.Gronau@gmx.de>
case object MERCURY extends Planet(3.303e+23, 2.4397e6)case object VENUS extends Planet(4.869e+24, 6.0518e6)case object EARTH extends Planet(5.976e+24, 6.37814e6) case object MARS extends Planet(6.421e+23, 3.3972e6)case object JUPITER extends Planet(1.9e+27, 7.1492e7)case object SATURN extends Planet(5.688e+26, 6.0268e7)case object URANUS extends Planet(8.686e+25, 2.5559e7) case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)case object PLUTO extends Planet(1.27e+22, 1.137e6)
Than the Java version:
public enum Planet { MERCURY (3.303e+23, 2.4397e6), VENUS (4.869e+24, 6.0518e6), EARTH (5.976e+24, 6.37814e6), MARS (6.421e+23, 3.3972e6), JUPITER (1.9e+27, 7.1492e7), SATURN (5.688e+26, 6.0268e7), URANUS (8.686e+25, 2.5559e7), NEPTUNE (1.024e+26, 2.4746e7), PLUTO (1.27e+22, 1.137e6);
In the Java version, the only overhead in defining a constant is writing its name and its constructor arguments (and it can't get much briefer than that!). In your case you also have "case object" and "extends Planet" for every constant.
And, of course, in the Java version you can write for (Planet planet : Planet.values()) ...
2009/5/3 Landei <Daniel.Gronau@gmx.de>
tim pigden wrote:
>
> From the Java tutorial we have rich enums like this
>
>
>
> public enum Planet {
>
> MERCURY (3.303e+23, 2.4397e6),
>
> VENUS (4.869e+24, 6.0518e6),
>
> EARTH (5.976e+24, 6.37814e6),
>
> MARS (6.421e+23, 3.3972e6),
>
> JUPITER (1.9e+27, 7.1492e7),
>
> SATURN (5.688e+26, 6.0268e7),
>
> URANUS (8.686e+25, 2.5559e7),
>
> NEPTUNE (1.024e+26, 2.4746e7);
>
>
>
> private final double mass; // in kilograms
>
> private final double radius; // in meters
>
> Planet(double mass, double radius) {
>
> this.mass = mass;
>
> this.radius = radius;
>
> }
>
> private double mass() { return mass; }
>
> private double radius() { return radius; }
>
> ....
>
> }
>
>
>
> As far as I can see this can't be done with the scala enumeration where
> the Value takes a few predefined constructors including
>
> Value(Int, String) - which at least allows you to assign your own ids.
>
>
>
> Is there a direct equivalent in Scala? I can see various ways around it
> but just wondered whether I'm missing something about the Enumeration
> type.
>
> Tim
>
Hi Tim,
I find myself using enumerations in Scala much less than in Java, especially
because objects or case objects are often more convenient.
E.g. look at this version:
http://jackcoughonsoftware.blogspot.com/2008/06/scala-and-enums.html
Cheers,
Daniel
--
View this message in context: http://www.nabble.com/enums-like-Java-tp23355754p23356003.html
Sent from the Scala - User mailing list archive at Nabble.com.
Sun, 2009-05-03, 15:57
#3
Re: enums like Java
Dimitris Andreou wrote:
>
> I'm not sure how you consider this more convenient:
> case object MERCURY extends Planet(3.303e+23, 2.4397e6)
> case object VENUS extends Planet(4.869e+24, 6.0518e6)
> case object EARTH extends Planet(5.976e+24, 6.37814e6)
> case object MARS extends Planet(6.421e+23, 3.3972e6)
> case object JUPITER extends Planet(1.9e+27, 7.1492e7)
> case object SATURN extends Planet(5.688e+26, 6.0268e7)
> case object URANUS extends Planet(8.686e+25, 2.5559e7)
> case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
> case object PLUTO extends Planet(1.27e+22, 1.137e6)
>
> Than the Java version:
>
> public enum Planet {
> MERCURY (3.303e+23, 2.4397e6),
> VENUS (4.869e+24, 6.0518e6),
> EARTH (5.976e+24, 6.37814e6),
> MARS (6.421e+23, 3.3972e6),
> JUPITER (1.9e+27, 7.1492e7),
> SATURN (5.688e+26, 6.0268e7),
> URANUS (8.686e+25, 2.5559e7),
> NEPTUNE (1.024e+26, 2.4746e7),
> PLUTO (1.27e+22, 1.137e6);
>
> In the Java version, the only overhead in defining a constant is writing
> its
> name and its constructor arguments (and it can't get much briefer than
> that!). In your case you also have "case object" and "extends Planet" for
> every constant.
>
> And, of course, in the Java version you can write
> for (Planet planet : Planet.values()) ...
>
> 2009/5/3 Landei
>
>>
>>
>>
>> tim pigden wrote:
>> >
>> > From the Java tutorial we have rich enums like this
>> >
>> >
>> >
>> > public enum Planet {
>> >
>> > MERCURY (3.303e+23, 2.4397e6),
>> >
>> > VENUS (4.869e+24, 6.0518e6),
>> >
>> > EARTH (5.976e+24, 6.37814e6),
>> >
>> > MARS (6.421e+23, 3.3972e6),
>> >
>> > JUPITER (1.9e+27, 7.1492e7),
>> >
>> > SATURN (5.688e+26, 6.0268e7),
>> >
>> > URANUS (8.686e+25, 2.5559e7),
>> >
>> > NEPTUNE (1.024e+26, 2.4746e7);
>> >
>> >
>> >
>> > private final double mass; // in kilograms
>> >
>> > private final double radius; // in meters
>> >
>> > Planet(double mass, double radius) {
>> >
>> > this.mass = mass;
>> >
>> > this.radius = radius;
>> >
>> > }
>> >
>> > private double mass() { return mass; }
>> >
>> > private double radius() { return radius; }
>> >
>> > ....
>> >
>> > }
>> >
>> >
>> >
>> > As far as I can see this can't be done with the scala enumeration where
>> > the Value takes a few predefined constructors including
>> >
>> > Value(Int, String) - which at least allows you to assign your own ids.
>> >
>> >
>> >
>> > Is there a direct equivalent in Scala? I can see various ways around it
>> > but just wondered whether I'm missing something about the Enumeration
>> > type.
>> >
>> > Tim
>> >
>>
>> Hi Tim,
>>
>> I find myself using enumerations in Scala much less than in Java,
>> especially
>> because objects or case objects are often more convenient.
>>
>> E.g. look at this version:
>> http://jackcoughonsoftware.blogspot.com/2008/06/scala-and-enums.html
>>
>> Cheers,
>> Daniel
>>
>>
>>
>>
>> --
>> View this message in context:
>> http://www.nabble.com/enums-like-Java-tp23355754p23356003.html
>> Sent from the Scala - User mailing list archive at Nabble.com.
>>
>>
>
>
I meant that objects or case objects can be more convenient than *Scala*
enumerations. True, Java's compiler support makes enum short, but the price
is another language exception with speacial rules etc., and Scala decided to
avoid to throw heavy magic at this quite special and limited part of the
language, so we have to live with a slighly more verbose solution.
BTW: "Convenient" doesn't mean always "short". One "pro" of the object
approach is that they are real classes (and object) and hence they are
easier to change than enumerations (e.g. going from enums to a real
hierarchy by introducing stars, moons...)
Cheers
Daniel
Mon, 2009-05-04, 00:17
#4
Re: enums like Java
And, of course, in the Java version you can write for (Planet planet : Planet.values()) ...
Hi,
What's the scala way to build java-like enumerations then?
I gave it a try by combining iterable and case objects and I ended up with the "baroque" code below... Any suggestion on how to make it look better?
Thanks,
Sebastien
package pkg
abstract class Enumeration[T] extends Iterable[T] {
private[this] val _elems = new scala.collection.mutable.HashSet[T]
protected def add(elem:T) = _elems += elem
def elements = _elems.elements
}
abstract class Galaxy extends Enumeration[Planet]
abstract case class Planet(galaxy:Galaxy, mass: Double, radius: Double)
case object MilkyWay extends Galaxy {
sealed abstract case class Planet(override val mass: Double, override val radius: Double) extends pkg.Planet(this, mass, radius)
case object MERCURY extends Planet(3.303e+23, 2.4397e6)
add(MERCURY)
case object VENUS extends Planet(4.869e+24, 6.0518e6)
add(VENUS)
case object EARTH extends Planet(5.976e+24, 6.37814e6)
add(EARTH)
case object MARS extends Planet(6.421e+23, 3.3972e6)
add(MARS)
case object JUPITER extends Planet(1.9e+27, 7.1492e7)
add(JUPITER)
case object SATURN extends Planet(5.688e+26, 6.0268e7)
add(SATURN)
case object URANUS extends Planet(8.686e+25, 2.5559e7)
add(URANUS)
case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
add(NEPTUNE)
case object PLUTO extends Planet(1.27e+22, 1.137e6)
add(PLUTO)
}
object MilkyTest {
def main(args : Array[String]) : Unit = {
for (planet <- MilkyWay) {
println("Hello " + planet)
}
val planet:Planet = MilkyWay.MERCURY
planet match {
case p@Planet(g, m, v) => println(g + "." + p +"," + m + "," + v)
}
val milkyplanet:MilkyWay.Planet = MilkyWay.VENUS
milkyplanet match { // ok, match is not exhaustive...
case p@MilkyWay.VENUS => println("Found " + p)
}
}
}
// Output:
//Hello NEPTUNE
//Hello MARS
//Hello PLUTO
//Hello EARTH
//Hello MERCURY
//Hello VENUS
//Hello JUPITER
//Hello SATURN
//Hello URANUS
//MilkyWay.MERCURY,3.303E23,2439700.0
//Found VENUS
Mon, 2009-05-04, 00:47
#5
Re: enums like Java
Oh and I forgot. Let's consider there are only these nine planets in our galaxy for the sake of the example, please :-)
2009/5/4 Sébastien Bocq <sebastien.bocq@gmail.com>
2009/5/4 Sébastien Bocq <sebastien.bocq@gmail.com>
And, of course, in the Java version you can write for (Planet planet : Planet.values()) ...
Hi,
What's the scala way to build java-like enumerations then?
I gave it a try by combining iterable and case objects and I ended up with the "baroque" code below... Any suggestion on how to make it look better?
Thanks,
Sebastien
package pkg
abstract class Enumeration[T] extends Iterable[T] {
private[this] val _elems = new scala.collection.mutable.HashSet[T]
protected def add(elem:T) = _elems += elem
def elements = _elems.elements
}
abstract class Galaxy extends Enumeration[Planet]
abstract case class Planet(galaxy:Galaxy, mass: Double, radius: Double)
case object MilkyWay extends Galaxy {
sealed abstract case class Planet(override val mass: Double, override val radius: Double) extends pkg.Planet(this, mass, radius)
case object MERCURY extends Planet(3.303e+23, 2.4397e6)
add(MERCURY)
case object VENUS extends Planet(4.869e+24, 6.0518e6)
add(VENUS)
case object EARTH extends Planet(5.976e+24, 6.37814e6)
add(EARTH)
case object MARS extends Planet(6.421e+23, 3.3972e6)
add(MARS)
case object JUPITER extends Planet(1.9e+27, 7.1492e7)
add(JUPITER)
case object SATURN extends Planet(5.688e+26, 6.0268e7)
add(SATURN)
case object URANUS extends Planet(8.686e+25, 2.5559e7)
add(URANUS)
case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
add(NEPTUNE)
case object PLUTO extends Planet(1.27e+22, 1.137e6)
add(PLUTO)
}
object MilkyTest {
def main(args : Array[String]) : Unit = {
for (planet <- MilkyWay) {
println("Hello " + planet)
}
val planet:Planet = MilkyWay.MERCURY
planet match {
case p@Planet(g, m, v) => println(g + "." + p +"," + m + "," + v)
}
val milkyplanet:MilkyWay.Planet = MilkyWay.VENUS
milkyplanet match { // ok, match is not exhaustive...
case p@MilkyWay.VENUS => println("Found " + p)
}
}
}
// Output:
//Hello NEPTUNE
//Hello MARS
//Hello PLUTO
//Hello EARTH
//Hello MERCURY
//Hello VENUS
//Hello JUPITER
//Hello SATURN
//Hello URANUS
//MilkyWay.MERCURY,3.303E23,2439700.0
//Found VENUS
Mon, 2009-05-04, 01:17
#6
Re: enums like Java
You're doing it wrong. There are actually no planets, they are really just points projected to the galaxy, so your example sucks.
Oh, sorry, wrong thread :)
2009/5/4 Sébastien Bocq <sebastien.bocq@gmail.com>
Oh, sorry, wrong thread :)
2009/5/4 Sébastien Bocq <sebastien.bocq@gmail.com>
Oh and I forgot. Let's consider there are only these nine planets in our galaxy for the sake of the example, please :-)
2009/5/4 Sébastien Bocq <sebastien.bocq@gmail.com>And, of course, in the Java version you can write for (Planet planet : Planet.values()) ...
Hi,
What's the scala way to build java-like enumerations then?
I gave it a try by combining iterable and case objects and I ended up with the "baroque" code below... Any suggestion on how to make it look better?
Thanks,
Sebastien
package pkg
abstract class Enumeration[T] extends Iterable[T] {
private[this] val _elems = new scala.collection.mutable.HashSet[T]
protected def add(elem:T) = _elems += elem
def elements = _elems.elements
}
abstract class Galaxy extends Enumeration[Planet]
abstract case class Planet(galaxy:Galaxy, mass: Double, radius: Double)
case object MilkyWay extends Galaxy {
sealed abstract case class Planet(override val mass: Double, override val radius: Double) extends pkg.Planet(this, mass, radius)
case object MERCURY extends Planet(3.303e+23, 2.4397e6)
add(MERCURY)
case object VENUS extends Planet(4.869e+24, 6.0518e6)
add(VENUS)
case object EARTH extends Planet(5.976e+24, 6.37814e6)
add(EARTH)
case object MARS extends Planet(6.421e+23, 3.3972e6)
add(MARS)
case object JUPITER extends Planet(1.9e+27, 7.1492e7)
add(JUPITER)
case object SATURN extends Planet(5.688e+26, 6.0268e7)
add(SATURN)
case object URANUS extends Planet(8.686e+25, 2.5559e7)
add(URANUS)
case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
add(NEPTUNE)
case object PLUTO extends Planet(1.27e+22, 1.137e6)
add(PLUTO)
}
object MilkyTest {
def main(args : Array[String]) : Unit = {
for (planet <- MilkyWay) {
println("Hello " + planet)
}
val planet:Planet = MilkyWay.MERCURY
planet match {
case p@Planet(g, m, v) => println(g + "." + p +"," + m + "," + v)
}
val milkyplanet:MilkyWay.Planet = MilkyWay.VENUS
milkyplanet match { // ok, match is not exhaustive...
case p@MilkyWay.VENUS => println("Found " + p)
}
}
}
// Output:
//Hello NEPTUNE
//Hello MARS
//Hello PLUTO
//Hello EARTH
//Hello MERCURY
//Hello VENUS
//Hello JUPITER
//Hello SATURN
//Hello URANUS
//MilkyWay.MERCURY,3.303E23,2439700.0
//Found VENUS
Mon, 2009-05-04, 02:07
#7
Re: enums like Java
I don't like Scala Enumerations, I started writing all enums in Java,
while the rest of my code is Scala.
Erkki
Tim Pigden wrote:
>
> From the Java tutorial we have rich enums like this
>
> public enum Planet {
>
> MERCURY (3.303e+23, 2.4397e6),
>
> VENUS (4.869e+24, 6.0518e6),
>
> EARTH (5.976e+24, 6.37814e6),
>
> MARS (6.421e+23, 3.3972e6),
>
> JUPITER (1.9e+27, 7.1492e7),
>
> SATURN (5.688e+26, 6.0268e7),
>
> URANUS (8.686e+25, 2.5559e7),
>
> NEPTUNE (1.024e+26, 2.4746e7);
>
> private final double mass; // in kilograms
>
> private final double radius; // in meters
>
> Planet(double mass, double radius) {
>
> this.mass = mass;
>
> this.radius = radius;
>
> }
>
> private double mass() { return mass; }
>
> private double radius() { return radius; }
>
> ….
>
> }
>
> As far as I can see this can’t be done with the scala enumeration
> where the Value takes a few predefined constructors including
>
> Value(Int, String) – which at least allows you to assign your own ids.
>
> Is there a direct equivalent in Scala? I can see various ways around
> it but just wondered whether I’m missing something about the
> Enumeration type.
>
> Tim
>
Mon, 2009-05-04, 08:07
#8
Re: enums like Java
Sébastien,
On Mon, 2009-05-04 at 01:44 +0200, Sébastien Bocq wrote:
> Oh and I forgot. Let's consider there are only these nine planets in
> our galaxy for the sake of the example, please :-)
>
Actually your example is not correct: there are only eight planets.
Pluto is not a planet, it got demoted to being a "dwarf planet" or
"minor planet" in 2006.
See for example: http://news.bbc.co.uk/1/hi/in_depth/5282440.stm
Mon, 2009-05-04, 09:47
#9
RE: enums like Java
> From: Russel Winder [mailto:russel.winder@concertant.com]
> On Mon, 2009-05-04 at 01:44 +0200, Sébastien Bocq wrote:
> > Oh and I forgot. Let's consider there are only these nine planets in
> > our galaxy for the sake of the example, please :-)
> >
> Actually your example is not correct: there are only eight planets.
> Pluto is not a planet, it got demoted to being a "dwarf planet" or
> "minor planet" in 2006.
So the question arises: How is pre-2006 Scala code using enums
affected by that decision?
(Oh, it's monday again ...)
Mon, 2009-05-04, 10:17
#10
Re: enums like Java
I knew I won't get away with it... I fixed the names and removed Pluto (see below).
Now to come back to our main topic, what would be nice is to be able to force initialization of inner objects by passing them to a method during initialization.
I mean if this is allowed:
add(new pkg.Planet(this, (3.303e+23, 2.4397e6)) {})
Why not allow this as well?
add(case object MERCURY extends Planet(3.303e+23, 2.4397e6))
Sebastien
abstract class Enumeration[T] extends Iterable[T] {
private[this] val _elems = new scala.collection.mutable.HashSet[T]
protected def add(elem:T) = _elems += elem
def elements = _elems.elements
}
abstract class StarSystem extends Enumeration[Planet]
abstract case class Planet(startSystem:StarSystem, mass: Double, radius: Double)
case object SolarSystem extends StarSystem {
sealed abstract case class Planet(override val mass: Double, override val radius: Double) extends pkg.Planet(this, mass, radius)
case object MERCURY extends Planet(3.303e+23, 2.4397e6)
add(MERCURY)
case object VENUS extends Planet(4.869e+24, 6.0518e6)
add(VENUS)
case object EARTH extends Planet(5.976e+24, 6.37814e6)
add(EARTH)
case object MARS extends Planet(6.421e+23, 3.3972e6)
add(MARS)
case object JUPITER extends Planet(1.9e+27, 7.1492e7)
add(JUPITER)
case object SATURN extends Planet(5.688e+26, 6.0268e7)
add(SATURN)
case object URANUS extends Planet(8.686e+25, 2.5559e7)
add(URANUS)
case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
add(NEPTUNE)
}
object SolarTest {
def main(args : Array[String]) : Unit = {
for (planet <- SolarSystem) {
println("Hello " + planet)
}
val planet:Planet = SolarSystem.MERCURY
planet match {
case p@Planet(g, m, v) => println(g + "." + p +"," + m + "," + v)
}
val splanet:SolarSystem.Planet = SolarSystem.VENUS
splanet match { // ok, match is not exhaustive...
case p@SolarSystem.VENUS => println("Found " + p)
}
}
}
2009/5/4 Russel Winder <russel.winder@concertant.com>
Now to come back to our main topic, what would be nice is to be able to force initialization of inner objects by passing them to a method during initialization.
I mean if this is allowed:
add(new pkg.Planet(this, (3.303e+23, 2.4397e6)) {})
Why not allow this as well?
add(case object MERCURY extends Planet(3.303e+23, 2.4397e6))
Sebastien
abstract class Enumeration[T] extends Iterable[T] {
private[this] val _elems = new scala.collection.mutable.HashSet[T]
protected def add(elem:T) = _elems += elem
def elements = _elems.elements
}
abstract class StarSystem extends Enumeration[Planet]
abstract case class Planet(startSystem:StarSystem, mass: Double, radius: Double)
case object SolarSystem extends StarSystem {
sealed abstract case class Planet(override val mass: Double, override val radius: Double) extends pkg.Planet(this, mass, radius)
case object MERCURY extends Planet(3.303e+23, 2.4397e6)
add(MERCURY)
case object VENUS extends Planet(4.869e+24, 6.0518e6)
add(VENUS)
case object EARTH extends Planet(5.976e+24, 6.37814e6)
add(EARTH)
case object MARS extends Planet(6.421e+23, 3.3972e6)
add(MARS)
case object JUPITER extends Planet(1.9e+27, 7.1492e7)
add(JUPITER)
case object SATURN extends Planet(5.688e+26, 6.0268e7)
add(SATURN)
case object URANUS extends Planet(8.686e+25, 2.5559e7)
add(URANUS)
case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
add(NEPTUNE)
}
object SolarTest {
def main(args : Array[String]) : Unit = {
for (planet <- SolarSystem) {
println("Hello " + planet)
}
val planet:Planet = SolarSystem.MERCURY
planet match {
case p@Planet(g, m, v) => println(g + "." + p +"," + m + "," + v)
}
val splanet:SolarSystem.Planet = SolarSystem.VENUS
splanet match { // ok, match is not exhaustive...
case p@SolarSystem.VENUS => println("Found " + p)
}
}
}
2009/5/4 Russel Winder <russel.winder@concertant.com>
Sébastien,
On Mon, 2009-05-04 at 01:44 +0200, Sébastien Bocq wrote:
> Oh and I forgot. Let's consider there are only these nine planets in
> our galaxy for the sake of the example, please :-)
>
Actually your example is not correct: there are only eight planets.
Pluto is not a planet, it got demoted to being a "dwarf planet" or
"minor planet" in 2006.
See for example: http://news.bbc.co.uk/1/hi/in_depth/5282440.stm
--
Russel.
============================================================
Dr Russel Winder Partner
Concertant LLP t: +44 20 7585 2200, +44 20 7193 9203
41 Buckmaster Road, f: +44 8700 516 084 voip: 3Arussel [dot] winder [at] ekiga [dot] net" target="_blank" rel="nofollow">sip:russel.winder@ekiga.net
London SW11 1EN, UK. m: +44 7770 465 077 xmpp: russel@russel.org.uk
Mon, 2009-05-04, 10:27
#11
RE: enums like Java
> From: Landei [mailto:Daniel.Gronau@gmx.de]
>
> Dimitris Andreou wrote:
> >
> > I'm not sure how you consider this more convenient:
> > case object MERCURY extends Planet(3.303e+23, 2.4397e6)
> > case object VENUS extends Planet(4.869e+24, 6.0518e6)
[...]
> >
> > Than the Java version:
> >
> > public enum Planet {
> > MERCURY (3.303e+23, 2.4397e6),
> > VENUS (4.869e+24, 6.0518e6),
[...]
> >
[...]
> >
> > And, of course, in the Java version you can write
> > for (Planet planet : Planet.values()) ...
> >
[...]
> I meant that objects or case objects can be more convenient
> than *Scala*
> enumerations. True, Java's compiler support makes enum short,
> but the price
> is another language exception with speacial rules etc., and
> Scala decided to
> avoid to throw heavy magic at this quite special and limited
> part of the
> language, so we have to live with a slighly more verbose solution.
In what aspect do you think it is 'quite special and limited' ?
> BTW: "Convenient" doesn't mean always "short". One "pro" of the object
> approach is that they are real classes (and object) and hence they are
> easier to change than enumerations (e.g. going from enums to a real
> hierarchy by introducing stars, moons...)
Well, if you are doing that, I would assume that you are
working in a scenario where the enum approach was questionable
right in the first place.
BTW: I consider enum being ONE type with a limited discrete value set.
The object approach breaks that notion in my eyes, or did I
miss something?
Mon, 2009-05-04, 14:47
#12
RE: enums like Java
Detering Dirk-2 wrote:
>
>> From: Landei [mailto:Daniel.Gronau@gmx.de]
>>
>> Dimitris Andreou wrote:
>> >
>> > I'm not sure how you consider this more convenient:
>> > case object MERCURY extends Planet(3.303e+23, 2.4397e6)
>> > case object VENUS extends Planet(4.869e+24, 6.0518e6)
> [...]
>> >
>> > Than the Java version:
>> >
>> > public enum Planet {
>> > MERCURY (3.303e+23, 2.4397e6),
>> > VENUS (4.869e+24, 6.0518e6),
> [...]
>> >
> [...]
>> >
>> > And, of course, in the Java version you can write
>> > for (Planet planet : Planet.values()) ...
>> >
>
> [...]
>> I meant that objects or case objects can be more convenient
>> than *Scala*
>> enumerations. True, Java's compiler support makes enum short,
>> but the price
>> is another language exception with speacial rules etc., and
>> Scala decided to
>> avoid to throw heavy magic at this quite special and limited
>> part of the
>> language, so we have to live with a slighly more verbose solution.
>
> In what aspect do you think it is 'quite special and limited' ?
>
>> BTW: "Convenient" doesn't mean always "short". One "pro" of the object
>> approach is that they are real classes (and object) and hence they are
>> easier to change than enumerations (e.g. going from enums to a real
>> hierarchy by introducing stars, moons...)
>
> Well, if you are doing that, I would assume that you are
> working in a scenario where the enum approach was questionable
> right in the first place.
>
> BTW: I consider enum being ONE type with a limited discrete value set.
> The object approach breaks that notion in my eyes, or did I
> miss something?
>
I don't have much enums in my day-to-day Java code, and even less in Scala.
I try to imagine a scenario where you would need plenty of enums, but I
can't find one. That's what I consider "limited". Yes, it's nice to have
special enum support in the language, but the question is if we want to pay
the price for an additional feature cluttering the language and introduce
new pitfalls. Scala decided against this, and I think this is a good
decision, as you can simulate a very similar behavior with little effort in
the language itself (and you probably agree that the Scala solution looks
better than the class based pre-enum Java solution as propagated by Sun).
Regarding your last remark: If you want to ensure that you never get
additional objects, you can derive them from a sealed abstract class -
problem solved.
However if you really can't live with enums, you have still the possibility
to write a compiler plugin..
Regards,
Daniel
Mon, 2009-05-04, 15:07
#13
Re: enums like Java
Scala support is kind of satisfying, although I wish we didn't have the following slight redundancy:
object WeekOfDay extends Enumeration { type WeekDay = Value val Mon = Value("Mon") val Tue = Value("Tue") ...}
(Because it's very cumbersome to have constants without proper toString implementations)
But it's workable and the redundancy very much localized.
2009/5/4 Landei <Daniel.Gronau@gmx.de>
object WeekOfDay extends Enumeration { type WeekDay = Value val Mon = Value("Mon") val Tue = Value("Tue") ...}
(Because it's very cumbersome to have constants without proper toString implementations)
But it's workable and the redundancy very much localized.
2009/5/4 Landei <Daniel.Gronau@gmx.de>
Detering Dirk-2 wrote:
>
>> From: Landei [mailto:Daniel.Gronau@gmx.de]
>>
>> Dimitris Andreou wrote:
>> >
>> > I'm not sure how you consider this more convenient:
>> > case object MERCURY extends Planet(3.303e+23, 2.4397e6)
>> > case object VENUS extends Planet(4.869e+24, 6.0518e6)
> [...]
>> >
>> > Than the Java version:
>> >
>> > public enum Planet {
>> > MERCURY (3.303e+23, 2.4397e6),
>> > VENUS (4.869e+24, 6.0518e6),
> [...]
>> >
> [...]
>> >
>> > And, of course, in the Java version you can write
>> > for (Planet planet : Planet.values()) ...
>> >
>
> [...]
>> I meant that objects or case objects can be more convenient
>> than *Scala*
>> enumerations. True, Java's compiler support makes enum short,
>> but the price
>> is another language exception with speacial rules etc., and
>> Scala decided to
>> avoid to throw heavy magic at this quite special and limited
>> part of the
>> language, so we have to live with a slighly more verbose solution.
>
> In what aspect do you think it is 'quite special and limited' ?
>
>> BTW: "Convenient" doesn't mean always "short". One "pro" of the object
>> approach is that they are real classes (and object) and hence they are
>> easier to change than enumerations (e.g. going from enums to a real
>> hierarchy by introducing stars, moons...)
>
> Well, if you are doing that, I would assume that you are
> working in a scenario where the enum approach was questionable
> right in the first place.
>
> BTW: I consider enum being ONE type with a limited discrete value set.
> The object approach breaks that notion in my eyes, or did I
> miss something?
>
I don't have much enums in my day-to-day Java code, and even less in Scala.
I try to imagine a scenario where you would need plenty of enums, but I
can't find one. That's what I consider "limited". Yes, it's nice to have
special enum support in the language, but the question is if we want to pay
the price for an additional feature cluttering the language and introduce
new pitfalls. Scala decided against this, and I think this is a good
decision, as you can simulate a very similar behavior with little effort in
the language itself (and you probably agree that the Scala solution looks
better than the class based pre-enum Java solution as propagated by Sun).
Regarding your last remark: If you want to ensure that you never get
additional objects, you can derive them from a sealed abstract class -
problem solved.
However if you really can't live with enums, you have still the possibility
to write a compiler plugin..
Regards,
Daniel
--
View this message in context: http://www.nabble.com/enums-like-Java-tp23355754p23367847.html
Sent from the Scala - User mailing list archive at Nabble.com.
Mon, 2009-05-04, 15:17
#14
Re: enums like Java
On Monday May 4 2009, Landei wrote:
> ...
>
> I don't have much enums in my day-to-day Java code, and even less in
> Scala. I try to imagine a scenario where you would need plenty of
> enums, but I can't find one. That's what I consider "limited". Yes,
> it's nice to have special enum support in the language, but the
> question is if we want to pay the price for an additional feature
> cluttering the language and introduce new pitfalls. Scala decided
> against this, and I think this is a good decision, as you can
> simulate a very similar behavior with little effort in the language
> itself (and you probably agree that the Scala solution looks better
> than the class based pre-enum Java solution as propagated by Sun).
I've used enums extensively in Java code. I tend to have many simple
ones (just enumerations of values) and a few complex ones. Complex
enums include things like internal per-value state (not mutable,
though), multiple constructors, ability to decouple external names from
internal value names multiple external per-value forms (strings) such
as terse, abbreviated and full, etc.
It seems to me that a meta-programming / macro facility for Scala would
be an appropriate locus for creating a rich enumeration capability for
Scala.
> ...
>
> However if you really can't live with enums, you have still the
> possibility to write a compiler plugin..
The problem with that (by comparison to a language-supported
implementation using macros) is that is not truly supported and ties
the code to the compiler plug-in.
> Regards,
> Daniel
Randall Schulz
Mon, 2009-05-04, 15:37
#15
RE: enums like Java
> I try to imagine a scenario where you would need plenty of
> enums, but I can't find one.
Hmmm. Enterprise software, health insurance sector:
We have a lot. Due to a pre-enum history and an MDA approach
they are the classical style and due to design decisions taken
early not easily changeable now, but would be Java enums if
we would write it once anew I suppose.
Again, everywhere where you have types with a closed set of
distinct values: Gender, Insurance State, Civil Status,
Disease Categorisation, Form of Salutation, Employment Status,
whatever makes sense or is obliged by the terms of law and
constitutes a limited value set (I'm no insurance clerk).
Also technical types like BatchRunState, ValidationState
or whatever.
> (and you probably agree that the Scala solution looks better
> than the class based pre-enum Java solution as propagated by Sun).
Well ... *hehe*. Yes.
But does that count?
Following this argument we would continue implementing in C
and not discuss about object-functional approaches, as C looks
better than assembler anyway.
> Regarding your last remark: If you want to ensure that you never get
> additional objects, you can derive them from a sealed abstract class -
> problem solved.
Technically yes. It only feels a bit weird to have a bunch of classes
(types),
each with exactly one instance which represents exactly one value
of a set, instead of having one class (type) with a bunch of instances
where each one represents a value and said class is conceptually the
set.
(If we would ever implement it that way we should never tell our
OOA people ... ;-) )
But that may be a matter of taste or habit.
> However if you really can't live with enums, you have still
> the possibility to write a compiler plugin.
Yep.
KR
Det
Mon, 2009-05-04, 15:57
#16
Re: enums like Java
On Mon, May 4, 2009 at 9:36 AM, Detering Dirk <Dirk.Detering@bitmarck.de> wrote:
This is also the case in Java *when* your enum has abstract methods, either defined on the enum itself or by having the enum implement an interface.
Technically yes. It only feels a bit weird to have a bunch of classes
(types), each with exactly one instance which represents exactly one value
of a set
This is also the case in Java *when* your enum has abstract methods, either defined on the enum itself or by having the enum implement an interface.
Tue, 2009-05-05, 17:37
#17
Re: enums like Java
Maybe it would be possible to have an Enumeration class that instead of using val x = Value, would use a syntax of (case) object x extends Value. Value's constructor could add the instance to the list, and also since it's a class it could know its own name, not requiring you to specify it.
On Mon, May 4, 2009 at 10:55 AM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
On Mon, May 4, 2009 at 10:55 AM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
On Mon, May 4, 2009 at 9:36 AM, Detering Dirk <Dirk.Detering@bitmarck.de> wrote:Technically yes. It only feels a bit weird to have a bunch of classes
(types), each with exactly one instance which represents exactly one value
of a set
This is also the case in Java *when* your enum has abstract methods, either defined on the enum itself or by having the enum implement an interface.
Tue, 2009-05-05, 22:37
#18
Re: enums like Java
I thought also about this but since objects are lazy initialized you have to force their initialization manually which looks as bad as adding them manually in the list like in the example I provided. It is not the first time I encounter this problem. I would really like to have something like an 'eager' keyword to declare non lazy objects.
2009/5/5 Naftoli Gugenheim <naftoligug@gmail.com>
2009/5/5 Naftoli Gugenheim <naftoligug@gmail.com>
Maybe it would be possible to have an Enumeration class that instead of using val x = Value, would use a syntax of (case) object x extends Value. Value's constructor could add the instance to the list, and also since it's a class it could know its own name, not requiring you to specify it.
On Mon, May 4, 2009 at 10:55 AM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:On Mon, May 4, 2009 at 9:36 AM, Detering Dirk <Dirk.Detering@bitmarck.de> wrote:Technically yes. It only feels a bit weird to have a bunch of classes
(types), each with exactly one instance which represents exactly one value
of a set
This is also the case in Java *when* your enum has abstract methods, either defined on the enum itself or by having the enum implement an interface.
Tue, 2009-05-05, 22:57
#19
Re: enums like Java
But at least you don't have to call an add method - just refer to everything at once:
abstract class Enumeration[T] extends Iterable[T] {
private[this] val _elems = new scala.collection.mutable.HashSet[T]
protected def add(elem:T) = _elems += elem
def elements = _elems.elements
}
abstract class StarSystem extends Enumeration[Planet]
case object SolarSystem extends StarSystem { sealed abstract case class Planet(override val mass: Double, override val radius: Double) extends pkg.Planet(this, mass, radius) { add(this); }
case object MERCURY extends Planet(3.303e+23, 2.4397e6)
case object VENUS extends Planet(4.869e+24, 6.0518e6)
case object EARTH extends Planet(5.976e+24, 6.37814e6)
case object MARS extends Planet(6.421e+23, 3.3972e6)
case object JUPITER extends Planet(1.9e+27, 7.1492e7)
case object SATURN extends Planet(5.688e+26, 6.0268e7)
case object URANUS extends Planet(8.686e+25, 2.5559e7)
case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
MERCURY; VENUS; EARTH; MARS; JUPITER; SATURN; URANUS; NEPTUNE// or if you like: (MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE)
}
On Tue, May 5, 2009 at 5:30 PM, Sébastien Bocq <sebastien.bocq@gmail.com> wrote:
abstract class Enumeration[T] extends Iterable[T] {
private[this] val _elems = new scala.collection.mutable.HashSet[T]
protected def add(elem:T) = _elems += elem
def elements = _elems.elements
}
abstract class StarSystem extends Enumeration[Planet]
case object SolarSystem extends StarSystem { sealed abstract case class Planet(override val mass: Double, override val radius: Double) extends pkg.Planet(this, mass, radius) { add(this); }
case object MERCURY extends Planet(3.303e+23, 2.4397e6)
case object VENUS extends Planet(4.869e+24, 6.0518e6)
case object EARTH extends Planet(5.976e+24, 6.37814e6)
case object MARS extends Planet(6.421e+23, 3.3972e6)
case object JUPITER extends Planet(1.9e+27, 7.1492e7)
case object SATURN extends Planet(5.688e+26, 6.0268e7)
case object URANUS extends Planet(8.686e+25, 2.5559e7)
case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
MERCURY; VENUS; EARTH; MARS; JUPITER; SATURN; URANUS; NEPTUNE// or if you like: (MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE)
}
On Tue, May 5, 2009 at 5:30 PM, Sébastien Bocq <sebastien.bocq@gmail.com> wrote:
I thought also about this but since objects are lazy initialized you have to force their initialization manually which looks as bad as adding them manually in the list like in the example I provided. It is not the first time I encounter this problem. I would really like to have something like an 'eager' keyword to declare non lazy objects.
2009/5/5 Naftoli Gugenheim <naftoligug@gmail.com>Maybe it would be possible to have an Enumeration class that instead of using val x = Value, would use a syntax of (case) object x extends Value. Value's constructor could add the instance to the list, and also since it's a class it could know its own name, not requiring you to specify it.
On Mon, May 4, 2009 at 10:55 AM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:On Mon, May 4, 2009 at 9:36 AM, Detering Dirk <Dirk.Detering@bitmarck.de> wrote:Technically yes. It only feels a bit weird to have a bunch of classes
(types), each with exactly one instance which represents exactly one value
of a set
This is also the case in Java *when* your enum has abstract methods, either defined on the enum itself or by having the enum implement an interface.
Tue, 2009-05-05, 23:17
#20
Re: enums like Java
It is a bit shorter you increase the chance somebody forgets an object from the list. I find it a pity that there is no better alternative in Scala, especially now that Pluto is not a planet anymore.
2009/5/5 Naftoli Gugenheim <naftoligug@gmail.com>
2009/5/5 Naftoli Gugenheim <naftoligug@gmail.com>
But at least you don't have to call an add method - just refer to everything at once:
abstract class Enumeration[T] extends Iterable[T] {
private[this] val _elems = new scala.collection.mutable.HashSet[T]
protected def add(elem:T) = _elems += elem
def elements = _elems.elements
}
abstract class StarSystem extends Enumeration[Planet]
case object SolarSystem extends StarSystem { sealed abstract case class Planet(override val mass: Double, override val radius: Double) extends pkg.Planet(this, mass, radius) { add(this); }
case object MERCURY extends Planet(3.303e+23, 2.4397e6)
case object VENUS extends Planet(4.869e+24, 6.0518e6)
case object EARTH extends Planet(5.976e+24, 6.37814e6)
case object MARS extends Planet(6.421e+23, 3.3972e6)
case object JUPITER extends Planet(1.9e+27, 7.1492e7)
case object SATURN extends Planet(5.688e+26, 6.0268e7)
case object URANUS extends Planet(8.686e+25, 2.5559e7)
case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
MERCURY; VENUS; EARTH; MARS; JUPITER; SATURN; URANUS; NEPTUNE// or if you like: (MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE)
}
On Tue, May 5, 2009 at 5:30 PM, Sébastien Bocq <sebastien.bocq@gmail.com> wrote:I thought also about this but since objects are lazy initialized you have to force their initialization manually which looks as bad as adding them manually in the list like in the example I provided. It is not the first time I encounter this problem. I would really like to have something like an 'eager' keyword to declare non lazy objects.
2009/5/5 Naftoli Gugenheim <naftoligug@gmail.com>Maybe it would be possible to have an Enumeration class that instead of using val x = Value, would use a syntax of (case) object x extends Value. Value's constructor could add the instance to the list, and also since it's a class it could know its own name, not requiring you to specify it.
On Mon, May 4, 2009 at 10:55 AM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:On Mon, May 4, 2009 at 9:36 AM, Detering Dirk <Dirk.Detering@bitmarck.de> wrote:Technically yes. It only feels a bit weird to have a bunch of classes
(types), each with exactly one instance which represents exactly one value
of a set
This is also the case in Java *when* your enum has abstract methods, either defined on the enum itself or by having the enum implement an interface.
Wed, 2009-05-06, 07:47
#21
RE: enums like Java
> It is a bit shorter you increase the chance somebody forgets
> an object from the list. I find it a pity that there is no
> better alternative in Scala,
Yep. It somehow feels like we are discussing too much the
way of implementation (case objects, sealed parent class keeps list)
of what should have an easy syntax and be otherwise
the compiler's concern.
In comparision to Java this seems somehow not Scala-ish to me,
as for so many topics it is the other way round: Scala provides
better (abstract) syntax where Java needs implementation aware coding
(see 'object' instead of singleton implementation for instance, or
Traits instead of Interface plus implementation class plus delegation)
KR
Det
Wed, 2009-05-06, 09:37
#22
Re: enums like Java
Naftoli Gugenheim wrote:
>
> But at least you don't have to call an add method - just refer to
> everything
> at once:
> abstract class Enumeration[T] extends Iterable[T] {
>
> private[this] val _elems = new scala.collection.mutable.HashSet[T]
>
> protected def add(elem:T) = _elems += elem
>
> def elements = _elems.elements
> }
>
> abstract class StarSystem extends Enumeration[Planet]
>
> case object SolarSystem extends StarSystem { sealed abstract case class
> Planet(override val mass: Double, override val radius: Double) extends
> pkg.Planet(this, mass, radius) { add(this); }
> case object MERCURY extends Planet(3.303e+23, 2.4397e6)
> case object VENUS extends Planet(4.869e+24, 6.0518e6)
> case object EARTH extends Planet(5.976e+24, 6.37814e6)
> case object MARS extends Planet(6.421e+23, 3.3972e6)
> case object JUPITER extends Planet(1.9e+27, 7.1492e7)
> case object SATURN extends Planet(5.688e+26, 6.0268e7)
> case object URANUS extends Planet(8.686e+25, 2.5559e7)
> case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
>
> MERCURY; VENUS; EARTH; MARS; JUPITER; SATURN; URANUS; NEPTUNE
> // or if you like: (MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS,
> NEPTUNE)
> }
>
>
> On Tue, May 5, 2009 at 5:30 PM, Sébastien Bocq
> wrote:
>
>> I thought also about this but since objects are lazy initialized you have
>> to force their initialization manually which looks as bad as adding them
>> manually in the list like in the example I provided. It is not the first
>> time I encounter this problem. I would really like to have something like
>> an
>> 'eager' keyword to declare non lazy objects.
>>
>> 2009/5/5 Naftoli Gugenheim
>>
>> Maybe it would be possible to have an Enumeration class that instead of
>>> using val x = Value, would use a syntax of (case) object x extends
>>> Value.
>>> Value's constructor could add the instance to the list, and also since
>>> it's
>>> a class it could know its own name, not requiring you to specify it.
>>>
>>>
>>> On Mon, May 4, 2009 at 10:55 AM, Nils Kilden-Pedersen
>>> wrote:
>>>
>>>> On Mon, May 4, 2009 at 9:36 AM, Detering Dirk
>>>> >>> > wrote:
>>>>
>>>>> Technically yes. It only feels a bit weird to have a bunch of classes
>>>>> (types), each with exactly one instance which represents exactly one
>>>>> value
>>>>> of a set
>>>>
>>>>
>>>> This is also the case in Java *when* your enum has abstract methods,
>>>> either defined on the enum itself or by having the enum implement an
>>>> interface.
>>>>
>>>>
>>>>
>>>
>>
>
>
Out of curiosity: What's wrong with:
case object SolarSystem extends StarSystem {
sealed case class Planet(override val mass: Double, override val radius:
Double) extends pkg.Planet(this, mass, radius) { add(this); }
val MERCURY = Planet(3.303e+23, 2.4397e6)
val VENUS = Planet(4.869e+24, 6.0518e6)
val EARTH = Planet(5.976e+24, 6.37814e6)
val MARS = Planet(6.421e+23, 3.3972e6)
val JUPITER = Planet(1.9e+27, 7.1492e7)
val SATURN = Planet(5.688e+26, 6.0268e7)
val URANUS = Planet(8.686e+25, 2.5559e7)
val NEPTUNE = Planet(1.024e+26, 2.4746e7)
}
The vals should be eagerly initialized, right?
Cheers,
Daniel
Wed, 2009-05-06, 13:17
#23
Re: enums like Java
On Sun, May 3, 2009 at 8:05 PM, Erkki Lindpere <erkki@lap.ee> wrote:
Sad to say that of all the solutions, I probably like this one the best.
I don't like Scala Enumerations, I started writing all enums in Java, while the rest of my code is Scala.
Sad to say that of all the solutions, I probably like this one the best.
Wed, 2009-05-06, 19:27
#24
Re: enums like Java
> Yep. It somehow feels like we are discussing too much the
> way of implementation (case objects, sealed parent class keeps list)
> of what should have an easy syntax and be otherwise
> the compiler's concern.
>
> In comparision to Java this seems somehow not Scala-ish to me,
> as for so many topics it is the other way round: Scala provides
> better (abstract) syntax where Java needs implementation aware coding
> (see 'object' instead of singleton implementation for instance, or
> Traits instead of Interface plus implementation class plus delegation)
yes! :-(
Wed, 2009-05-06, 23:57
#25
Re: enums like Java
Hi Daniel,
You have almost the same issues than in Java when you use constants instead of enums. You can't print them easily and you will break client code if you decide to change the coordinates of a planet in your library. Additionally in Scala, you won't get a compiler warning anymore if a pattern match is not exhaustive.
Cheers,
Sebastien
2009/5/6 Landei <Daniel.Gronau@gmx.de>
You have almost the same issues than in Java when you use constants instead of enums. You can't print them easily and you will break client code if you decide to change the coordinates of a planet in your library. Additionally in Scala, you won't get a compiler warning anymore if a pattern match is not exhaustive.
Cheers,
Sebastien
2009/5/6 Landei <Daniel.Gronau@gmx.de>
Naftoli Gugenheim wrote:
>
> But at least you don't have to call an add method - just refer to
> everything
> at once:
> abstract class Enumeration[T] extends Iterable[T] {
>
> private[this] val _elems = new scala.collection.mutable.HashSet[T]
>
> protected def add(elem:T) = _elems += elem
>
> def elements = _elems.elements
> }
>
> abstract class StarSystem extends Enumeration[Planet]
>
> case object SolarSystem extends StarSystem { sealed abstract case class
> Planet(override val mass: Double, override val radius: Double) extends
> pkg.Planet(this, mass, radius) { add(this); }
> case object MERCURY extends Planet(3.303e+23, 2.4397e6)
> case object VENUS extends Planet(4.869e+24, 6.0518e6)
> case object EARTH extends Planet(5.976e+24, 6.37814e6)
> case object MARS extends Planet(6.421e+23, 3.3972e6)
> case object JUPITER extends Planet(1.9e+27, 7.1492e7)
> case object SATURN extends Planet(5.688e+26, 6.0268e7)
> case object URANUS extends Planet(8.686e+25, 2.5559e7)
> case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
>
> MERCURY; VENUS; EARTH; MARS; JUPITER; SATURN; URANUS; NEPTUNE
> // or if you like: (MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS,
> NEPTUNE)
> }
>
>
> On Tue, May 5, 2009 at 5:30 PM, Sébastien Bocq
> <sebastien.bocq@gmail.com>wrote:
>
>> I thought also about this but since objects are lazy initialized you have
>> to force their initialization manually which looks as bad as adding them
>> manually in the list like in the example I provided. It is not the first
>> time I encounter this problem. I would really like to have something like
>> an
>> 'eager' keyword to declare non lazy objects.
>>
>> 2009/5/5 Naftoli Gugenheim <naftoligug@gmail.com>
>>
>> Maybe it would be possible to have an Enumeration class that instead of
>>> using val x = Value, would use a syntax of (case) object x extends
>>> Value.
>>> Value's constructor could add the instance to the list, and also since
>>> it's
>>> a class it could know its own name, not requiring you to specify it.
>>>
>>>
>>> On Mon, May 4, 2009 at 10:55 AM, Nils Kilden-Pedersen
>>> <nilskp@gmail.com>wrote:
>>>
>>>> On Mon, May 4, 2009 at 9:36 AM, Detering Dirk
>>>> <Dirk.Detering@bitmarck.de
>>>> > wrote:
>>>>
>>>>> Technically yes. It only feels a bit weird to have a bunch of classes
>>>>> (types), each with exactly one instance which represents exactly one
>>>>> value
>>>>> of a set
>>>>
>>>>
>>>> This is also the case in Java *when* your enum has abstract methods,
>>>> either defined on the enum itself or by having the enum implement an
>>>> interface.
>>>>
>>>>
>>>>
>>>
>>
>
>
Out of curiosity: What's wrong with:
case object SolarSystem extends StarSystem {
sealed case class Planet(override val mass: Double, override val radius:
Double) extends pkg.Planet(this, mass, radius) { add(this); }
val MERCURY = Planet(3.303e+23, 2.4397e6)
val VENUS = Planet(4.869e+24, 6.0518e6)
val EARTH = Planet(5.976e+24, 6.37814e6)
val MARS = Planet(6.421e+23, 3.3972e6)
val JUPITER = Planet(1.9e+27, 7.1492e7)
val SATURN = Planet(5.688e+26, 6.0268e7)
val URANUS = Planet(8.686e+25, 2.5559e7)
val NEPTUNE = Planet(1.024e+26, 2.4746e7)
}
The vals should be eagerly initialized, right?
Cheers,
Daniel
--
View this message in context: http://www.nabble.com/enums-like-Java-tp23355754p23402259.html
Sent from the Scala - User mailing list archive at Nabble.com.
Tue, 2009-06-23, 02:17
#26
Re: enums like Java
This thread isn't so new, but I have something to add.
Basically, the suggestion was made to implement better enums, by having an enum superclass with an abstract member class that behaves similarly to Enumeration's Value method, but in a class instead of a method. Then you define your abstract base case class deriving from the Value equivalent, and case objects that derive from it. The "Value" base class' constructor would add the instance to the outer Enumeration equivalent, with the added benefit that the name can be automatically be inferred from the class of the object instance. In addition, the members of the enum are classes that can have custom behaviors.
The problem was raised, though, that since objects are lazy, the outer Enum class will not know about any enum member until it was individually referenced. It seems that there is a solution to this problem, though --- one that is used by Lift's Mapper. Basically the outer (super)class can figure out its members using some reflection tricks. Anyone who is interested could look over there for details.
So I think this could make for a very clean, elegant, and powerful scala enum implementation. It would look something like:
object Planets extends Enum {
abstract case class Planet(mass: Double, radius: Double) { def volume = ... def density = ... }
case object MERCURY extends Planet(3.303e+23, 2.4397e6)
case object VENUS extends Planet(4.869e+24, 6.0518e6)
case object EARTH extends Planet(5.976e+24, 6.37814e6)
case object MARS extends Planet(6.421e+23, 3.3972e6)
case object JUPITER extends Planet(1.9e+27, 7.1492e7)
case object SATURN extends Planet(5.688e+26, 6.0268e7)
case object URANUS extends Planet(8.686e+25, 2.5559e7)
case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
}Is there even a benefit of the concrete subclasses being case objects? Since they derive from a case class and don't introduce new parameters (they're singletons) maybe we could just do:
object Planets extends Enum {
abstract case class Planet(mass: Double, radius: Double) { def volume = ... def density = ... }
object MERCURY extends Planet(3.303e+23, 2.4397e6)
object VENUS extends Planet(4.869e+24, 6.0518e6)
object EARTH extends Planet(5.976e+24, 6.37814e6)
object MARS extends Planet(6.421e+23, 3.3972e6)
object JUPITER extends Planet(1.9e+27, 7.1492e7)
object SATURN extends Planet(5.688e+26, 6.0268e7)
object URANUS extends Planet(8.686e+25, 2.5559e7)
object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
}Which is not very long...
2009/5/5 Naftoli Gugenheim <naftoligug@gmail.com>
2009/5/5 Naftoli Gugenheim <naftoligug@gmail.com>
But at least you don't have to call an add method - just refer to everything at once:
abstract class Enumeration[T] extends Iterable[T] {
private[this] val _elems = new scala.collection.mutable.HashSet[T]
protected def add(elem:T) = _elems += elem
def elements = _elems.elements
}
abstract class StarSystem extends Enumeration[Planet]
case object SolarSystem extends StarSystem { sealed abstract case class Planet(override val mass: Double, override val radius: Double) extends pkg.Planet(this, mass, radius) { add(this); }
case object MERCURY extends Planet(3.303e+23, 2.4397e6)
case object VENUS extends Planet(4.869e+24, 6.0518e6)
case object EARTH extends Planet(5.976e+24, 6.37814e6)
case object MARS extends Planet(6.421e+23, 3.3972e6)
case object JUPITER extends Planet(1.9e+27, 7.1492e7)
case object SATURN extends Planet(5.688e+26, 6.0268e7)
case object URANUS extends Planet(8.686e+25, 2.5559e7)
case object NEPTUNE extends Planet(1.024e+26, 2.4746e7)
MERCURY; VENUS; EARTH; MARS; JUPITER; SATURN; URANUS; NEPTUNE// or if you like: (MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE)
}
On Tue, May 5, 2009 at 5:30 PM, Sébastien Bocq <sebastien.bocq@gmail.com> wrote:I thought also about this but since objects are lazy initialized you have to force their initialization manually which looks as bad as adding them manually in the list like in the example I provided. It is not the first time I encounter this problem. I would really like to have something like an 'eager' keyword to declare non lazy objects.
2009/5/5 Naftoli Gugenheim <naftoligug@gmail.com>Maybe it would be possible to have an Enumeration class that instead of using val x = Value, would use a syntax of (case) object x extends Value. Value's constructor could add the instance to the list, and also since it's a class it could know its own name, not requiring you to specify it.
On Mon, May 4, 2009 at 10:55 AM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:On Mon, May 4, 2009 at 9:36 AM, Detering Dirk <Dirk.Detering@bitmarck.de> wrote:Technically yes. It only feels a bit weird to have a bunch of classes
(types), each with exactly one instance which represents exactly one value
of a set
This is also the case in Java *when* your enum has abstract methods, either defined on the enum itself or by having the enum implement an interface.
tim pigden wrote:
>
> From the Java tutorial we have rich enums like this
>
>
>
> public enum Planet {
>
> MERCURY (3.303e+23, 2.4397e6),
>
> VENUS (4.869e+24, 6.0518e6),
>
> EARTH (5.976e+24, 6.37814e6),
>
> MARS (6.421e+23, 3.3972e6),
>
> JUPITER (1.9e+27, 7.1492e7),
>
> SATURN (5.688e+26, 6.0268e7),
>
> URANUS (8.686e+25, 2.5559e7),
>
> NEPTUNE (1.024e+26, 2.4746e7);
>
>
>
> private final double mass; // in kilograms
>
> private final double radius; // in meters
>
> Planet(double mass, double radius) {
>
> this.mass = mass;
>
> this.radius = radius;
>
> }
>
> private double mass() { return mass; }
>
> private double radius() { return radius; }
>
> ....
>
> }
>
>
>
> As far as I can see this can't be done with the scala enumeration where
> the Value takes a few predefined constructors including
>
> Value(Int, String) - which at least allows you to assign your own ids.
>
>
>
> Is there a direct equivalent in Scala? I can see various ways around it
> but just wondered whether I'm missing something about the Enumeration
> type.
>
> Tim
>
Hi Tim,
I find myself using enumerations in Scala much less than in Java, especially
because objects or case objects are often more convenient.
E.g. look at this version:
http://jackcoughonsoftware.blogspot.com/2008/06/scala-and-enums.html
Cheers,
Daniel