This page is no longer maintained — Please continue to the home page at www.scala-lang.org

open class in scala and polymorphism

10 replies
Olivier Barais
Joined: 2009-03-30,
User offline. Last seen 42 years 45 weeks ago.
Hello,

I try to implement a visitor pattern using open-class principle like in ruby or like using the AspectJ introduction. I want to weave a set of "flatshort" methods into a hierarchy of Java classes (I can not modify their sourcce code).

My hierarchy contains an EPackage class which has a set of EClassifier that can be EClass or EDataType.

I use the implicit def mechanism to manage the openclass definition (see code below).

However, when I call value.getEClassifiers.toArray.foreach(e=>e.asInstanceOf[EClassifier].flatshort) (in the flatshort method in the EPackage context so value is an EPackage), the flatshort method of RichEClassifier is always invoked although the objects are EClass or EDataType. I expected that the invocation of the flatshort method of RichEClass or EDatatype. In fact, I lost the dynamic binding because, the Rich element object which is created is always a RichEClassifier.

Is there a way to manage easily this problem ?

It works if I replace   implicit def e(xs:EClassifier  ) = new RichEClassifier(xs)
with :
implicit def e(xs:EClassifier  )  = {
                                 var result : RichEClassifier =null;
                                 if (xs.isInstanceOf[EClass]){
                                          result = new RichEClass(xs.asInstanceOf[EClass])
                                 }else if(xs.isInstanceOf[EClassifier]){
                                          result =new RichEClassifier(xs.asInstanceOf[EClassifier])                                  
                                 }else if(xs.isInstanceOf[EDataType]){
                                          result =new RichEDataType(xs.asInstanceOf[EDataType])                                  
                                 }
                                 result
  }

But is is a bit horrible. Is there any other solution.

Here is the example of code which does not work as expected.

class RichEPackage  (value: org.eclipse.emf.ecore.EPackage)  {
  implicit def e(xs:EClassifier  ) = new RichEClassifier(xs)
  implicit def e( xs: EClass)   = new RichEClass(xs)
   implicit def e(xs: EDataType) = new RichEDataType(xs)
  implicit def e(xs: EPackage) = new RichEPackage(xs)

  def flatshort() : Void = {
        println(value.getName   )
        value.getESubpackages.toArray.foreach(e=>e.asInstanceOf[EPackage].flatshort)
        value.getEClassifiers.toArray.foreach(e=>e.asInstanceOf[EClassifier].flatshort)    
        return null;
     }
}

class RichEClassifier(value: EClassifier)  {
  def flatshort() : Void = {
        println("classifier = "  + this.getClass() + value.getClass() +  " " +value.getName)
        return null;
     }
}

class RichEDataType(value: EDataType)  extends RichEClassifier(value: EDataType){
  override def flatshort() : Void = {
        println("datatype = "  + this.getClass() + value.getClass() +  " " +value.getName)
        return null;
     }
}

class RichEClass(value: EClass) extends RichEClassifier(value: EClassifier) {
  override def flatshort() : Void = {
          println("EClass = "  + this.getClass() + value.getClass() +  " " +value.getName)
          super.flatshort
          return null;
         
     }
}

Best regards,

Olivier


Vladimir Kirichenko
Joined: 2009-02-19,
User offline. Last seen 42 years 45 weeks ago.
Re: open class in scala and polymorphism

implicit def eclr(xs:EClassifier ) = new RichEClassifier(xs)
implicit def ecls( xs: EClass) = new RichEClass(xs)
implicit def etype(xs: EDataType) = new RichEDataType(xs)
implicit def epack(xs: EPackage) = new RichEPackage(xs)

?

Olivier Barais
Joined: 2009-03-30,
User offline. Last seen 42 years 45 weeks ago.
Re: open class in scala and polymorphism

Vladimir Kirichenko a écrit :
> implicit def eclr(xs:EClassifier ) = new RichEClassifier(xs)
> implicit def ecls( xs: EClass) = new RichEClass(xs)
> implicit def etype(xs: EDataType) = new RichEDataType(xs)
> implicit def epack(xs: EPackage) = new RichEPackage(xs)
>
> ?
>
In fact, it does not work.

Here is the output for the corresponding call
// println("classifier = " + this.getClass()+ " " + value.getClass()
+ " " +value.getName)
classifier = class p1.RichEClassifier class
org.eclipse.emf.ecore.impl.EClassImpl EAttribute
classifier = class p1.RichEClassifier class
org.eclipse.emf.ecore.impl.EClassImpl EAnnotation
classifier = class p1.RichEClassifier class
org.eclipse.emf.ecore.impl.EClassImpl EClass

...

the object type is class but the rich object type is RichEClassifier.

So when scala finds a class it replaces it by a RichEClassifier.

implicit def eclr(xs:EClassifier ) = new RichEClassifier(xs) match.

I put the project here.
https://transfert.inria.fr/fichiers/1b32c8a40c63db18793f2d4cef9d554f/Tes...

Olivier

James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: open class in scala and polymorphism
implicit conversions are chosen statically at compile time based on static types. So they work quite differently from Ruby style dynamic metaprogramming.  There is a clean way to get around it without all your instanceof checking

implicit def e(eclr:EClassifier  )  = ecl match {
  case ecls : Eclass => new RichEClass(ecls)
  case edt : EDataType => new RichEDataType(edt)
  case _ => new RichEClassifier(ecl)
}
 

This works best if the EClassifier hierarchy is sealed.

On Mon, Mar 30, 2009 at 5:19 AM, Olivier Barais <olivier.barais@gmail.com> wrote:
Hello,

I try to implement a visitor pattern using open-class principle like in ruby or like using the AspectJ introduction. I want to weave a set of "flatshort" methods into a hierarchy of Java classes (I can not modify their sourcce code).




DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: open class in scala and polymorphism

2009/3/30 Olivier Barais :
> Hello,
> It works if I replace   implicit def e(xs:EClassifier  ) = new
> RichEClassifier(xs)
> with :
> implicit def e(xs:EClassifier  )  = {
>                                  var result : RichEClassifier =null;
>                                  if (xs.isInstanceOf[EClass]){
>                                           result = new
> RichEClass(xs.asInstanceOf[EClass])
>                                  }else if(xs.isInstanceOf[EClassifier]){
>                                           result =new
> RichEClassifier(xs.asInstanceOf[EClassifier])
>                                  }else if(xs.isInstanceOf[EDataType]){
>                                           result =new
> RichEDataType(xs.asInstanceOf[EDataType])
>                                  }
>                                  result
>   }
>
> But is is a bit horrible.

As a side note, independently of your question, this is a terrible way
to write this code.

def e(xs : EClassifier) = e match { // this probably shouldn't be
EClassifier as you'll stop midway through?
case (ys : EClass) => new RichEClass(ys);
case (ys : EClassifier) => new RichEClassifier(ys);
case (ys : EDataType) => new RichEDataType(ys);
}

Olivier Barais 2
Joined: 2009-03-30,
User offline. Last seen 2 years 31 weeks ago.
Re: open class in scala and polymorphism
Thanks for these infos.

Do you have some articles that explain why there is no open class support in scala

Olivier



2009/3/30 James Iry <jamesiry@gmail.com>
implicit conversions are chosen statically at compile time based on static types. So they work quite differently from Ruby style dynamic metaprogramming.  There is a clean way to get around it without all your instanceof checking

implicit def e(eclr:EClassifier  )  = ecl match {
  case ecls : Eclass => new RichEClass(ecls)
  case edt : EDataType => new RichEDataType(edt)
  case _ => new RichEClassifier(ecl)
}
 

This works best if the EClassifier hierarchy is sealed.

On Mon, Mar 30, 2009 at 5:19 AM, Olivier Barais <olivier.barais@gmail.com> wrote:
Hello,

I try to implement a visitor pattern using open-class principle like in ruby or like using the AspectJ introduction. I want to weave a set of "flatshort" methods into a hierarchy of Java classes (I can not modify their sourcce code).





David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: open class in scala and polymorphism


On Mon, Mar 30, 2009 at 8:47 AM, Olivier Barais <barais@irisa.fr> wrote:
Thanks for these infos.

Do you have some articles that explain why there is no open class support in scala

Scala sits on top of the Java Virtual Machine and as version 6 of the JVM, there is no open class support.  So, from a purely technical perspective, there is a significant performance hit to emulate open classes.

At the philosophical level, Scala's focus on immutability is at odds with open classes.  Java focuses on mutable data and gives second class support to immutability.  Ruby focuses on mutable data *and* mutable programs with open classes.  Having programmed in Java, Ruby and Scala, I find that immutable data and immutable code leads to the most stable, bug-free, predictable code.

It might be worthwhile to see what you can do with Scala and pattern matching as well as structural typing and see if you can code stuff up without Aspects or open classes.
 


Olivier



2009/3/30 James Iry <jamesiry@gmail.com>
implicit conversions are chosen statically at compile time based on static types. So they work quite differently from Ruby style dynamic metaprogramming.  There is a clean way to get around it without all your instanceof checking

implicit def e(eclr:EClassifier  )  = ecl match {
  case ecls : Eclass => new RichEClass(ecls)
  case edt : EDataType => new RichEDataType(edt)
  case _ => new RichEClassifier(ecl)
}
 

This works best if the EClassifier hierarchy is sealed.

On Mon, Mar 30, 2009 at 5:19 AM, Olivier Barais <olivier.barais@gmail.com> wrote:
Hello,

I try to implement a visitor pattern using open-class principle like in ruby or like using the AspectJ introduction. I want to weave a set of "flatshort" methods into a hierarchy of Java classes (I can not modify their sourcce code).








--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Olivier Barais
Joined: 2009-03-30,
User offline. Last seen 42 years 45 weeks ago.
Re: open class in scala and polymorphism
Ok, thanks a lot, it is clear.

I will keep playing with scala and try to see what I can  do with Scala and pattern matching

Olivier

David Pollak a écrit :
cdbebedf0903300857g76dd4238w72d984fc2aad6010 [at] mail [dot] gmail [dot] com" type="cite">

On Mon, Mar 30, 2009 at 8:47 AM, Olivier Barais <barais [at] irisa [dot] fr" rel="nofollow">barais@irisa.fr> wrote:
Thanks for these infos.

Do you have some articles that explain why there is no open class support in scala

Scala sits on top of the Java Virtual Machine and as version 6 of the JVM, there is no open class support.  So, from a purely technical perspective, there is a significant performance hit to emulate open classes.

At the philosophical level, Scala's focus on immutability is at odds with open classes.  Java focuses on mutable data and gives second class support to immutability.  Ruby focuses on mutable data *and* mutable programs with open classes.  Having programmed in Java, Ruby and Scala, I find that immutable data and immutable code leads to the most stable, bug-free, predictable code.

It might be worthwhile to see what you can do with Scala and pattern matching as well as structural typing and see if you can code stuff up without Aspects or open classes.
 


Olivier



2009/3/30 James Iry <jamesiry [at] gmail [dot] com" target="_blank" rel="nofollow">jamesiry@gmail.com>
implicit conversions are chosen statically at compile time based on static types. So they work quite differently from Ruby style dynamic metaprogramming.  There is a clean way to get around it without all your instanceof checking

implicit def e(eclr:EClassifier  )  = ecl match {
  case ecls : Eclass => new RichEClass(ecls)
  case edt : EDataType => new RichEDataType(edt)
  case _ => new RichEClassifier(ecl)
}
 

This works best if the EClassifier hierarchy is sealed.

On Mon, Mar 30, 2009 at 5:19 AM, Olivier Barais <olivier [dot] barais [at] gmail [dot] com" target="_blank" rel="nofollow">olivier.barais@gmail.com> wrote:
Hello,

I try to implement a visitor pattern using open-class principle like in ruby or like using the AspectJ introduction. I want to weave a set of "flatshort" methods into a hierarchy of Java classes (I can not modify their sourcce code).








Vladimir Kirichenko
Joined: 2009-02-19,
User offline. Last seen 42 years 45 weeks ago.
Re: open class in scala and polymorphism

David Pollak wrote:
> At the philosophical level, Scala's focus on immutability is at odds
> with open classes. Java focuses on mutable data and gives second class
> support to immutability. Ruby focuses on mutable data *and* mutable
> programs with open classes. Having programmed in Java, Ruby and Scala,
> I find that immutable data and immutable code leads to the most stable,
> bug-free, predictable code.

Actually a lot of implicit conversions is actually used for the same
purpose as open classes. I mean those ones with RichXX-peers. So it's
really sad that JVM have no such ability to implement open classes in scala.

Robert Fischer
Joined: 2009-01-31,
User offline. Last seen 42 years 45 weeks ago.
Re: open class in scala and polymorphism

David Pollak wrote:
>
> On Mon, Mar 30, 2009 at 8:47 AM, Olivier Barais > wrote:
>
> Thanks for these infos.
>
> Do you have some articles that explain why there is no open class
> support in scala
>
>
> Scala sits on top of the Java Virtual Machine and as version 6 of the
> JVM, there is no open class support. So, from a purely technical
> perspective, there is a significant performance hit to emulate open classes.
>
>

I disbelieve.

What would be the performance hit of allowing open classes? As long as the open classes still had
to be defined at compile time, there'd be no run-time penalty at all -- in fact, the runtime
wouldn't know the class had been opened.

~~ Robert Fischer.
Grails Training http://GroovyMag.com/training
Smokejumper Consulting http://SmokejumperIT.com
Enfranchised Mind Blog http://EnfranchisedMind.com/blog

Check out my book, "Grails Persistence with GORM and GSQL"!
http://www.smokejumperit.com/redirect.html

James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: open class in scala and polymorphism
You're talking about two different things.  Ruby style dynamic meta-programming on the one hand vs a static uber-mixin capability.  I.e.

// in one file
class Foo {
  def bar = ...
}

// in another file
class Foo {
  def baz = ...
}

// synthesized by compiler, linker, or whatever
class Foo {
  def bar = ...
  def baz = ...


The barrier to this is practical (it plays hell with separate compilation) and conceptual (it plays hell with certain notions of encapsulation).  But it's certainly not impossible and wouldn't have any performance impact.

On Mon, Mar 30, 2009 at 10:01 AM, Robert Fischer <robert.fischer@smokejumperit.com> wrote:

I disbelieve.

What would be the performance hit of allowing open classes?  As long as the open classes still had to be defined at compile time, there'd be no run-time penalty at all -- in fact, the runtime wouldn't know the class had been opened.

~~ Robert Fischer.
Grails Training        http://GroovyMag.com/training
Smokejumper Consulting http://SmokejumperIT.com
Enfranchised Mind Blog http://EnfranchisedMind.com/blog

Check out my book, "Grails Persistence with GORM and GSQL"!
http://www.smokejumperit.com/redirect.html

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland