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

Special mixing of traits and/or classes (a strange subject, yes :)

13 replies
Victor NOEL
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.

Hello,

I am trying to do something a little twisted and I am wondering if
it is even possible :)

Let me expose the idea.
Suppose we have theses classes :

trait A {
def changeA(a: String)
def readA: String
}

trait B {
def changeB(a: String)
def readB: String
}

class AImpl extends A {
var state = ""
def changeA(a: String) {
state = a
}
def readA: String = state
}

class BImpl extends B {
var state = ""
def changeB(a: String) {
state = a
}
def readB: String = state
}

class One {
self: A with B =>
}

class Two {
self: B =>
}

class Three {
self: B =>
}

As you may guess, I would like to mix AImpl and BImpl (yes, they are
classes for now, but they can be changed to whatever anybody want)
with One, Two and Three wrt the explicitly typed self references
of each one of them.

BUT, I want something else at the same time :
* One, Two and Three must only be able to access what is
declared in A and B !
* One and Two must share the same BImpl instantiation, but Three must
not share the same BImpl instantiation than One and Two !

Suppose one, two and three are 3 values that contains such
instantiations of One, Two and Three, I would like :
one.changeA("1")
one.changeB("2")
two.changeB("3")
three.changeB("4")

println(one.readA) // prints 1
println(one.readB) // prints 3
println(two.readB) // prints 3
println(three.readB) // prints 4

I tried different things, using this for example :
trait A1 extends AImpl // used by One
trait B1 extends BImpl // used by One and Two
trait B2 extends BImpl // used by Three

val one = new One with A1 with B1
val two = new Two with B1
val three = new Three with B2

But I get errors like this one :
illegal inheritance; superclass One is not a subclass
of the superclass AImpl of the mixin trait A1

And I can't just make One extends AImpl, it removes all of the
idea of modularity :)

Thanks you for any help :)

Victor

ewilligers
Joined: 2008-08-20,
User offline. Last seen 3 years 17 weeks ago.
Re: Special mixing of traits and/or classes (a strange subject,

Victor NOEL wrote:
> Hello,
>
> I am trying to do something a little twisted and I am wondering if
> it is even possible :)
>
> Let me expose the idea.
> Suppose we have theses classes :
>
> trait A {
> def changeA(a: String)
> def readA: String
> }
>
> trait B {
> def changeB(a: String)
> def readB: String
> }
>
> class AImpl extends A {
> var state = ""
> def changeA(a: String) {
> state = a
> }
> def readA: String = state
> }
>
> class BImpl extends B {
> var state = ""
> def changeB(a: String) {
> state = a
> }
> def readB: String = state
> }
>
> class One {
> self: A with B =>
> }
>
> class Two {
> self: B =>
> }
>
> class Three {
> self: B =>
> }
>
> As you may guess, I would like to mix AImpl and BImpl (yes, they are
> classes for now, but they can be changed to whatever anybody want)
> with One, Two and Three wrt the explicitly typed self references
> of each one of them.
>
> BUT, I want something else at the same time :
> * One, Two and Three must only be able to access what is
> declared in A and B !
> * One and Two must share the same BImpl instantiation, but Three must
> not share the same BImpl instantiation than One and Two !
>
> Suppose one, two and three are 3 values that contains such
> instantiations of One, Two and Three, I would like :
> one.changeA("1")
> one.changeB("2")
> two.changeB("3")
> three.changeB("4")
>
> println(one.readA) // prints 1
> println(one.readB) // prints 3
> println(two.readB) // prints 3
> println(three.readB) // prints 4
>
> I tried different things, using this for example :
> trait A1 extends AImpl // used by One
> trait B1 extends BImpl // used by One and Two
> trait B2 extends BImpl // used by Three
>
> val one = new One with A1 with B1
> val two = new Two with B1
> val three = new Three with B2
>
> But I get errors like this one :
> illegal inheritance; superclass One is not a subclass
> of the superclass AImpl of the mixin trait A1
>
> And I can't just make One extends AImpl, it removes all of the
> idea of modularity :)
>
> Thanks you for any help :)
>
> Victor

For distinct instances of One and Two to share the same BImpl
instantiation, we need to use delegation instead of inheritance.

A, B, AImpl and BImpl need not change. (Optionally, AImpl and BImpl can
be made final. Also, in recent versions of Scala, "self: A with B =>"
can be changed to "this: A with B =>".)

trait AForwarder extends A {
val delegateA: A
def changeA(a: String) { delegateA.changeA(a) }
def readA: String = delegateA.readA
}

trait BForwarder extends B {
val delegateB: B
def changeB(a: String) { delegateB.changeB(a) }
def readB: String = delegateB.readB
}

// One and Two must share the same BImpl instantiation, but Three must
// not share the same BImpl instantiation than One and Two !
val oneA = new AImpl
val oneTwoB = new BImpl
val threeB = new BImpl

val one = new One with AForwarder with BForwarder {
val delegateA = oneA
val delegateB = oneTwoB
}

val two = new Two with BForwarder {
val delegateB = oneTwoB
}

val three = new Three with BForwarder {
val delegateB = threeB
}

Victor NOEL
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Special mixing of traits and/or classes (a strange sub

On Wed, Jan 07, 2009 at 08:44:30AM +1100, Eric Willigers wrote:
> Victor NOEL wrote:
>> Hello,
>>
>> I am trying to do something a little twisted and I am wondering if
>> it is even possible :)
>>
>> Let me expose the idea.
>> Suppose we have theses classes :
>>

>> As you may guess, I would like to mix AImpl and BImpl (yes, they are
>> classes for now, but they can be changed to whatever anybody want)
>> with One, Two and Three wrt the explicitly typed self references
>> of each one of them.
>>
>> BUT, I want something else at the same time : * One, Two and Three
>> must only be able to access what is
>> declared in A and B !
>> * One and Two must share the same BImpl instantiation, but Three must
>> not share the same BImpl instantiation than One and Two !
>>

>
> For distinct instances of One and Two to share the same BImpl
> instantiation, we need to use delegation instead of inheritance.

Ok, I was guessing I will need something like that, but hoping
that there was a more general solution that do not need to create
specific trait each time we add a inheriting class or a mixed in
class.

Also, I was going to add to this model the possibility to specify
which method of which mixed in class is available to which
inheriting class, so I guess this is the only way to do it :)
(create a delegate trait for each access policy)

>
> A, B, AImpl and BImpl need not change. (Optionally, AImpl and BImpl can
> be made final. Also, in recent versions of Scala, "self: A with B =>"
> can be changed to "this: A with B =>".)

Isn't this the same ? With the difference that self become an
alias for this ?

Anyway, thanks a lot for your clear answer :)

Victor

Victor NOEL
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Special mixing of traits and/or classes (a strange sub

On Wed, Jan 07, 2009 at 08:44:30AM +1100, Eric Willigers wrote:
> Victor NOEL wrote:
>> As you may guess, I would like to mix AImpl and BImpl (yes, they are
>> classes for now, but they can be changed to whatever anybody want)
>> with One, Two and Three wrt the explicitly typed self references
>> of each one of them.
>>
>> BUT, I want something else at the same time : * One, Two and Three
>> must only be able to access what is
>> declared in A and B !
>> * One and Two must share the same BImpl instantiation, but Three must
>> not share the same BImpl instantiation than One and Two !
>>
>
> For distinct instances of One and Two to share the same BImpl
> instantiation, we need to use delegation instead of inheritance.
>
> A, B, AImpl and BImpl need not change. (Optionally, AImpl and BImpl can
> be made final. Also, in recent versions of Scala, "self: A with B =>"
> can be changed to "this: A with B =>".)

Now another question :)

What if B is declared like that (I removed Three) :
trait B {
this: A => // add a requirement for A by B
def changeB(a: String)
def readB: String
}

The solution I found is :
class BImpl extends B {
this: A => // need this because compiler complains
... etc ...
}

val oneA = new AImpl
val onetwoB = new BImpl with AForwarder {
val delegateA = oneA
}

val one = new One with AForwarder with BForwarder {
val delegateA = oneA
val delegateB = onetwoB
}

val two = new Two with BForwarder with AForwarder {
val delegateA = oneA
val delegateB = onetwoB
}

And now it has become a big mess with a lot of boilerplate :)

Is there something simpler than that ?

Thanks again for any help :)

Victor

ewilligers
Joined: 2008-08-20,
User offline. Last seen 3 years 17 weeks ago.
Re: Special mixing of traits and/or classes (a strange subject

>> Also, in recent versions of Scala, "self: A with B =>"
>> can be changed to "this: A with B =>".)
>
> Isn't this the same ? With the difference that self become an
> alias for this ?

Yes, just a style suggestion as the alias isn't used.

> Now another question :)
> And now it has become a big mess with a lot of boilerplate :)
> Is there something simpler than that ?

Perhaps make BForwarder an AForwarder. Then

val one = new One with BForwarder {
val delegateB = onetwoB
}

val two = new Two with BForwarder {
val delegateB = onetwoB
}

See attached.

There may be much simpler solutions. Hard to tell without your actual
code and high level objectives.

Ken Egervari
Joined: 2009-07-19,
User offline. Last seen 42 years 45 weeks ago.
Can I make subtypes of every other type, like Nothing, or is thi
Hi!
I'm still getting head around creating types that are subtypes of everything, even though they are not known ;) Is this some form of special case at work, or is there really a way to extend on this and start making user defined types that extend everything? The concept is kind of mind-blowing to me because I've never seen such a thing. 
The concept "Nothing" makes a lot of sense, and it's remarkably elegant as I see it used in various places in the libraries. I couldn't even begin to think of how I would make my own uses of such a concept, but that's probably because I am not accustomed to thinking that way. 
Any thoughts on this?

Ken
ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Re: Can I make subtypes of every other type, like Nothing, or

If you were able to do so, you would create circular inheritance
between your type and Nothing! :)

2009/10/23 Ken Egervari :
> Hi!
> I'm still getting head around creating types that are subtypes of
> everything, even though they are not known ;) Is this some form of special
> case at work, or is there really a way to extend on this and start making
> user defined types that extend everything? The concept is kind of
> mind-blowing to me because I've never seen such a thing.
> The concept "Nothing" makes a lot of sense, and it's remarkably elegant as I
> see it used in various places in the libraries. I couldn't even begin to
> think of how I would make my own uses of such a concept, but that's probably
> because I am not accustomed to thinking that way.
> Any thoughts on this?
>
> Ken
>

Johannes Rudolph
Joined: 2008-12-17,
User offline. Last seen 29 weeks 19 hours ago.
Re: Can I make subtypes of every other type, like Nothing, or

On Fri, Oct 23, 2009 at 2:48 PM, Ken Egervari wrote:
> Hi!
> I'm still getting head around creating types that are subtypes of
> everything, even though they are not known ;) Is this some form of special
> case at work, or is there really a way to extend on this and start making
> user defined types that extend everything? The concept is kind of
> mind-blowing to me because I've never seen such a thing.
> The concept "Nothing" makes a lot of sense, and it's remarkably elegant as I
> see it used in various places in the libraries. I couldn't even begin to
> think of how I would make my own uses of such a concept, but that's probably
> because I am not accustomed to thinking that way.
> Any thoughts on this?

I'm no expert in these matters but I think on the one hand it is an
artifact of the type system and type inference. So for type inference
it is the 'lowest' type to choose if a type has no other lower bounds.

On the other hand, since Nothing has no values, it can be used to
denote a function which doesn't return normally. I once read, that the
Scala compiler would flag an error if a call to a function returning
Nothing would be followed by other instructions (in fact dead code
that should never be reachable) but that's not what is happening [1],
at least in the versions I tested. Even 'throw' can be handled like a
function returning Nothing.

And as Jim said, creating other types like Nothing, contradicts its
definition. Though, in this regard I don't understand how Null and
Nothing relate...

See http://en.wikipedia.org/wiki/Bottom_type for a more general explanation.

Colin Bullock
Joined: 2009-01-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Can I make subtypes of every other type, like Nothing, or
Razvan Cojocaru 2
Joined: 2009-11-20,
User offline. Last seen 42 years 45 weeks ago.
hardcore DSL question :)

I'm playing with a workflow DSL...I'm trying to closely follow a "normal"
language syntax BUT to build an activity graph structure instead of actually
running the statements. This activity definition will be executed as a
process for each "instance"... later.

i was able to do this:

val spec1 =

wif (1==1) {
println("it's ")
println("true ")
println("...")
} welse wif (1==2) {
println("you wish it's ")
println("true ")
println("...")
} welse
wf {println ("it's")} +
wf {println ("false")} +
wf {println ("!!!")}

with something like this:

def wif (cond : => Boolean) (f: => Unit) = WfIf (()=>cond, WfScala(()=>f))

-------------

question is...how do i do this?

expr wmatch {
wcase MyClass (x) => println(x)
}

Basically, I'm assuming I will have to make it look like this:

wmatch (expr) {
wcase (MyClass(x)) { println(x) } ::
...//other cases
Nil
}

Before you ask why bother with this instead of strait scala match/case, each
case branch (activity) needs to be a separate node in a graph...think
BPELish

It's been haunting me for 2 days now...

Mucho thanks.

-----
Razvan Cojocaru,
Work: http://www.sigma-systems.com
Playground: http://wiki.homecloud.ca
Latest cool toy: http://scripster.codewitter.com
Follow me: http://feeds.razie.com/RazvanTech RSS Feed ,
http://twitter.com/razie Twitter , http://github.com/razie GitHub .

Razvan Cojocaru 2
Joined: 2009-11-20,
User offline. Last seen 42 years 45 weeks ago.
Re: hardcore DSL question :)

I see that I like multi-part posts...sorry.

I can do this:

wcase (expr) {
case 1 => println("it's ")
case 2 => println("true ")
case 3 => println("...")
}

but can't do the version similar to the welse (above), which builds a
sequence of 3 activities.

This construct is of special interest to me, since I always liked Ada's
guarded entry points...trying to mimick them here...

Razvan Cojocaru wrote:
>
> I'm playing with a workflow DSL...I'm trying to closely follow a "normal"
> language syntax BUT to build an activity graph structure instead of
> actually running the statements. This activity definition will be executed
> as a process for each "instance"... later.
>
> i was able to do this:
>
> val spec1 =
>
> wif (1==1) {
> println("it's ")
> println("true ")
> println("...")
> } welse wif (1==2) {
> println("you wish it's ")
> println("true ")
> println("...")
> } welse
> wf {println ("it's")} +
> wf {println ("false")} +
> wf {println ("!!!")}
>
> with something like this:
>
> def wif (cond : => Boolean) (f: => Unit) = WfIf (()=>cond,
> WfScala(()=>f))
>
> -------------
>
> question is...how do i do this?
>
> expr wmatch {
> wcase MyClass (x) => println(x)
> }
>
> Basically, I'm assuming I will have to make it look like this:
>
> wmatch (expr) {
> wcase (MyClass(x)) { println(x) } ::
> ...//other cases
> Nil
> }
>
> Before you ask why bother with this instead of strait scala match/case,
> each case branch (activity) needs to be a separate node in a graph...think
> BPELish
>
> It's been haunting me for 2 days now...
>
> Mucho thanks.
>
>

-----
Razvan Cojocaru,
Work: http://www.sigma-systems.com
Playground: http://wiki.homecloud.ca
Latest cool toy: http://scripster.codewitter.com
Follow me: http://feeds.razie.com/RazvanTech RSS Feed ,
http://twitter.com/razie Twitter , http://github.com/razie GitHub .

Arthur Peters 2
Joined: 2009-01-10,
User offline. Last seen 42 years 45 weeks ago.
Re: hardcore DSL question :)

Isn't there a bit-rotted and incomplete compiler plugin that allows you to make some expressions to be given to the program at runtime as ASTs (or something similar) instead of compiling them into real code?

That seems like something that might be useful for you.  Though I bet it would need a lot of work.

-Arthur (sent from phone)

On Mar 31, 2010 4:32 PM, "Razvan Cojocaru" <razie [at] razie [dot] com> wrote:


I see that I like multi-part posts...sorry.

I can do this:

wcase (expr) {
 case 1 =>   println("it's ")
 case 2 =>   println("true ")
 case 3 =>   println("...")
}

but can't do the version similar to the welse (above), which builds a
sequence of 3 activities.

This construct is of special interest to me, since I always liked Ada's
guarded entry points...trying to mimick them here...




Razvan Cojocaru wrote:
>
> I'm playing with a workflow DSL...I'm trying to closely follow a "nor...

View this message in context: http://old.nabble.com/hardcore-DSL-question-%3A%29-tp28101278p28101339.html

Sent from the Scala - User mailing list archive at Nabble.com.

Johannes Rudolph 2
Joined: 2010-02-12,
User offline. Last seen 42 years 45 weeks ago.
Re: hardcore DSL question :)

On Thu, Apr 1, 2010 at 1:56 AM, Arthur Peters wrote:
> Isn't there a bit-rotted and incomplete compiler plugin that allows you to
> make some expressions to be given to the program at runtime as ASTs (or
> something similar) instead of compiling them into real code?

Yes, there is, but it is limited in the type of ASTs supported and
there is no runtime compilation like in .NET, so you would have to do
that yourself.

>
> That seems like something that might be useful for you.  Though I bet it
> would need a lot of work.
>
> -Arthur (sent from phone)
>
> On Mar 31, 2010 4:32 PM, "Razvan Cojocaru" wrote:
>
>
> I see that I like multi-part posts...sorry.
>
> I can do this:
>
> wcase (expr) {
>  case 1 =>   println("it's ")
>  case 2 =>   println("true ")
>  case 3 =>   println("...")
> }
>
> but can't do the version similar to the welse (above), which builds a
> sequence of 3 activities.
>
> This construct is of special interest to me, since I always liked Ada's
> guarded entry points...trying to mimick them here...
>
>
>
> Razvan Cojocaru wrote:
>>
>> I'm playing with a workflow DSL...I'm trying to closely follow a "nor...
>
> View this message in context:
> http://old.nabble.com/hardcore-DSL-question-%3A%29-tp28101278p28101339.html
>
> Sent from the Scala - User mailing list archive at Nabble.com.
>

Johannes Rudolph 2
Joined: 2010-02-12,
User offline. Last seen 42 years 45 weeks ago.
Re: hardcore DSL question :)

I think you should look at specs, since they use a similar technique
for specifying examples.

On Wed, Mar 31, 2010 at 10:31 PM, Razvan Cojocaru wrote:
>
> I see that I like multi-part posts...sorry.
>
> I can do this:
>
> wcase (expr) {
>  case 1 =>   println("it's ")
>  case 2 =>   println("true ")
>  case 3 =>   println("...")
> }
>
> but can't do the version similar to the welse (above), which builds a
> sequence of 3 activities.
>
> This construct is of special interest to me, since I always liked Ada's
> guarded entry points...trying to mimick them here...
>
>
>
> Razvan Cojocaru wrote:
>>
>> I'm playing with a workflow DSL...I'm trying to closely follow a "normal"
>> language syntax BUT to build an activity graph structure instead of
>> actually running the statements. This activity definition will be executed
>> as a process for each "instance"... later.
>>
>> i was able to do this:
>>
>>   val spec1 =
>>
>>   wif (1==1) {
>>      println("it's ")
>>      println("true ")
>>      println("...")
>>   } welse wif (1==2) {
>>      println("you wish it's ")
>>      println("true ")
>>      println("...")
>>   } welse
>>      wf {println ("it's")} +
>>      wf {println ("false")} +
>>      wf {println ("!!!")}
>>
>> with something like this:
>>
>>   def wif (cond : => Boolean) (f: => Unit) = WfIf (()=>cond,
>> WfScala(()=>f))
>>
>> -------------
>>
>> question is...how do i do this?
>>
>> expr wmatch  {
>>  wcase MyClass (x) => println(x)
>> }
>>
>> Basically, I'm assuming I will have to make it look like this:
>>
>> wmatch (expr) {
>>    wcase (MyClass(x)) { println(x) } ::
>>    ...//other cases
>>    Nil
>> }
>>
>> Before you ask why bother with this instead of strait scala match/case,
>> each case branch (activity) needs to be a separate node in a graph...think
>> BPELish
>>
>> It's been haunting me for 2 days now...
>>
>> Mucho thanks.
>>
>>
>
>
> -----
> Razvan Cojocaru,
> Work: http://www.sigma-systems.com
> Playground: http://wiki.homecloud.ca
> Latest cool toy: http://scripster.codewitter.com
> Follow me:  http://feeds.razie.com/RazvanTech RSS Feed ,
> http://twitter.com/razie Twitter ,  http://github.com/razie GitHub .
>
> --
> View this message in context: http://old.nabble.com/hardcore-DSL-question-%3A%29-tp28101278p28101339.html
> Sent from the Scala - User mailing list archive at Nabble.com.
>
>

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