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

a small conundrum

4 replies
Meredith Gregory
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Dear Scalarazzi,
Consider a couple of case classes tied together inside a parametric trait
trait T1[X,Y,Z] {
   case class CC1( x : X, y : Y ) }
Best wishes,
--greg

--
L.G. Meredith
Managing Partner
Biosimilarity LLC
7329 39th Ave SWSeattle, WA 98136

+1 206.650.3740

http://biosimilarity.blogspot.com
Meredith Gregory
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: a small conundrum
Sorry -- emacs bindings don't work well with the gmail client -- this got sent before completion...
Dear Scalarazzi,

Consider a couple of case classes tied together inside a parametric trait trait T1[X,Y,Z] {   trait Expr[X,Y,Z]   case class CC1( x : X, y : Y ) extends Expr[X,Y,Z]   case class CC2( y : Y, z : Z ) extends Expr[X,Y,Z]}
Further suppose a class parametric
class Messenger[Msg]( ) {   def send( msg : Msg ) : Unit   def recv( ) : Msg   ...}
Now, is there a way to specialize Messenger to be parametric in Expr?
One obvious solution is
trait T1Scope[X,Y,Z] {   type LocalT1 <: T1[X,Y,Z]    def getLocalT1 : LocalT1   val localT1 : LocalT1 = getLocalT1
   class T1Messenger( ) extends Messenger[localT1.Expr[X,Y,Z]]( )}
But, now consider the following elaboration
trait T2Scope[X,Y,Z] extends T1Scope[X,Y,Z] {    class T2Messenger( storage : SomePersistentStore ) extends T1Messenger( ) with Serializable {       def flyInTheOintment( kkey : String ) : Unit = {             reset {                shift {                   ( k : Unit => Unit @suspendable ) => {                        storage.store( kkey, serializer.serialize( k ) )                    }                }            }       }   }}
All this can be made to work. But, upon deserialization, this will fail because T1Messenger does not inherit from Serializable and does not actually have a 0-arg constructor. This is because the Scala compiler will munge it's constructor to pass in the surrounding scope.
If we further suppose that T1Messenger cannot (for contextual reasons) inherit from Serializable, then we have but one option, to attempt to pass the scope just like the Scala compiler does. There's just one little problem, we can no longer refer to localT.Expr in the specialization of Messenger. 
If we assume that T1 is legacy code, i.e. handed to us and it is not an option to explode that scope, is there a way to define the specialization of Messenger other than effectively enclosing it in a T1Scope-like device?
Best wishes,
--greg
On Mon, Jan 9, 2012 at 1:19 AM, Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com> wrote:
Dear Scalarazzi,
Consider a couple of case classes tied together inside a parametric trait
trait T1[X,Y,Z] {
   case class CC1( x : X, y : Y ) }
Best wishes,
--greg

--
L.G. Meredith
Managing Partner
Biosimilarity LLC
7329 39th Ave SW Seattle, WA 98136

+1 206.650.3740

http://biosimilarity.blogspot.com



--
L.G. Meredith
Managing Partner
Biosimilarity LLC
7329 39th Ave SWSeattle, WA 98136

+1 206.650.3740

http://biosimilarity.blogspot.com
Meredith Gregory
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: a small conundrum
Dear Scalarazzi,
To verify that the 0-arg ctor has been eliminated, here is the code to add to the previous code
object T1StringScope extends T1Scope[String,String,String] {   override type LocalT1 = T1[String,String,String]  object LocalizedT1 extends T1[String,String,String]  def getLocalT1 = LocalizedT1}
def classChain( c : java.lang.Class[_] ) : List[java.lang.Class[_]] = {   if ( c != classOf[java.lang.Object] ) {    c :: classChain( c.getSuperclass ) }  else {    Nil  }}
def showClassChainCtors( c : java.lang.Class[_] ) : Unit = {   println( ">>>>>>>>>>>>>>>>>>>>>>>" )  println( c + " has constructors: " )  for( m <- c.getConstructors ) { println( m ) }   println()}
which produces
scala> showClassChainCtors( classOf[T1StringScope.T1Messenger] )>>>>>>>>>>>>>>>>>>>>>>> class $line28.$read$$iw$$iw$T1Scope$T1Messenger has constructors: public $line28.$read$$iw$$iw$T1Scope$T1Messenger($line28.$read$$iw$$iw$T1Scope)

Best wishes,
--greg

On Mon, Jan 9, 2012 at 1:49 AM, Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com> wrote:
Sorry -- emacs bindings don't work well with the gmail client -- this got sent before completion...
Dear Scalarazzi,

Consider a couple of case classes tied together inside a parametric trait trait T1[X,Y,Z] {   trait Expr[X,Y,Z]   case class CC1( x : X, y : Y ) extends Expr[X,Y,Z]   case class CC2( y : Y, z : Z ) extends Expr[X,Y,Z] }
Further suppose a class parametric
class Messenger[Msg]( ) {   def send( msg : Msg ) : Unit   def recv( ) : Msg   ...}
Now, is there a way to specialize Messenger to be parametric in Expr?
One obvious solution is
trait T1Scope[X,Y,Z] {   type LocalT1 <: T1[X,Y,Z]    def getLocalT1 : LocalT1   val localT1 : LocalT1 = getLocalT1
   class T1Messenger( ) extends Messenger[localT1.Expr[X,Y,Z]]( )}
But, now consider the following elaboration
trait T2Scope[X,Y,Z] extends T1Scope[X,Y,Z] {    class T2Messenger( storage : SomePersistentStore ) extends T1Messenger( ) with Serializable {       def flyInTheOintment( kkey : String ) : Unit = {             reset {                shift {                   ( k : Unit => Unit @suspendable ) => {                        storage.store( kkey, serializer.serialize( k ) )                    }                }            }       }   }}
All this can be made to work. But, upon deserialization, this will fail because T1Messenger does not inherit from Serializable and does not actually have a 0-arg constructor. This is because the Scala compiler will munge it's constructor to pass in the surrounding scope.
If we further suppose that T1Messenger cannot (for contextual reasons) inherit from Serializable, then we have but one option, to attempt to pass the scope just like the Scala compiler does. There's just one little problem, we can no longer refer to localT.Expr in the specialization of Messenger. 
If we assume that T1 is legacy code, i.e. handed to us and it is not an option to explode that scope, is there a way to define the specialization of Messenger other than effectively enclosing it in a T1Scope-like device?
Best wishes,
--greg
On Mon, Jan 9, 2012 at 1:19 AM, Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com> wrote:
Dear Scalarazzi,
Consider a couple of case classes tied together inside a parametric trait
trait T1[X,Y,Z] {
   case class CC1( x : X, y : Y ) }
Best wishes,
--greg

--
L.G. Meredith
Managing Partner
Biosimilarity LLC
7329 39th Ave SW Seattle, WA 98136

+1 206.650.3740

http://biosimilarity.blogspot.com



--
L.G. Meredith
Managing Partner
Biosimilarity LLC
7329 39th Ave SWSeattle, WA 98136

+1 206.650.3740

http://biosimilarity.blogspot.com



--
L.G. Meredith
Managing Partner
Biosimilarity LLC
7329 39th Ave SWSeattle, WA 98136

+1 206.650.3740

http://biosimilarity.blogspot.com
milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: Re: a small conundrum

On Mon, Jan 9, 2012 at 9:49 AM, Meredith Gregory
wrote:
> All this can be made to work. But, upon deserialization, this will fail
> because T1Messenger does not inherit from Serializable and does not actually
> have a 0-arg constructor. This is because the Scala compiler will munge it's
> constructor to pass in the surrounding scope.
>
> If we further suppose that T1Messenger cannot (for contextual reasons)
> inherit from Serializable, then we have but one option, to attempt to pass
> the scope just like the Scala compiler does. There's just one little
> problem, we can no longer refer to localT.Expr in the specialization of
> Messenger.
>
> If we assume that T1 is legacy code, i.e. handed to us and it is not an
> option to explode that scope, is there a way to define the specialization of
> Messenger other than effectively enclosing it in a T1Scope-like device?

I can't quite tell if it meets all your constraints, but how about,

trait T1Scope[X,Y,Z] {
type LocalT1 <: T1[X,Y,Z]
def getLocalT1 : LocalT1
val localT1 : LocalT1 = getLocalT1

//class T1Messenger( ) extends Messenger[localT1.Expr[X,Y,Z]]( )
type T1Messenger = Messenger[localT1.Expr[X,Y,Z]]
}

Cheers,

Miles

Meredith Gregory
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: a small conundrum
Dear Miles,
There is a lot of merit to your proposal! Of course, one would have to modify the definition of T2Messenger to inherit from Messenger and/or move the flytInTheOintment method to a different scope.
Best wishes,
--greg

On Mon, Jan 9, 2012 at 2:43 AM, Miles Sabin <miles [at] milessabin [dot] com> wrote:
On Mon, Jan 9, 2012 at 9:49 AM, Meredith Gregory
<lgreg [dot] meredith [at] gmail [dot] com> wrote:
> All this can be made to work. But, upon deserialization, this will fail
> because T1Messenger does not inherit from Serializable and does not actually
> have a 0-arg constructor. This is because the Scala compiler will munge it's
> constructor to pass in the surrounding scope.
>
> If we further suppose that T1Messenger cannot (for contextual reasons)
> inherit from Serializable, then we have but one option, to attempt to pass
> the scope just like the Scala compiler does. There's just one little
> problem, we can no longer refer to localT.Expr in the specialization of
> Messenger.
>
> If we assume that T1 is legacy code, i.e. handed to us and it is not an
> option to explode that scope, is there a way to define the specialization of
> Messenger other than effectively enclosing it in a T1Scope-like device?

I can't quite tell if it meets all your constraints, but how about,

 trait T1Scope[X,Y,Z] {
    type LocalT1 <: T1[X,Y,Z]
    def getLocalT1 : LocalT1
    val localT1 : LocalT1 = getLocalT1

    //class T1Messenger( ) extends Messenger[localT1.Expr[X,Y,Z]]( )
    type T1Messenger = Messenger[localT1.Expr[X,Y,Z]]
 }

Cheers,


Miles

--
Miles Sabin
tel: +44 7813 944 528
gtalk: miles [at] milessabin [dot] com
skype: milessabin
g+: http://www.milessabin.com
http://twitter.com/milessabin
http://www.chuusai.com/



--
L.G. Meredith
Managing Partner
Biosimilarity LLC
7329 39th Ave SWSeattle, WA 98136

+1 206.650.3740

http://biosimilarity.blogspot.com

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