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

Two questions on Unique References

6 replies
Dmitry Grigoriev
Joined: 2009-07-12,
User offline. Last seen 42 years 45 weeks ago.

Hello all!

Here I found that unique types plugin are to be included into 2.9
"official" part of the language:
http://stackoverflow.com/questions/5065861/programming-languages-based-o...

Q1: is that true?

Considering example in the section 1.3 here: http://lamp.epfl.ch/~phaller/readme_uniqueness.html

Q2: what must I do if I want not "same method with same arg (BTW, on
same instance?) can be called only once", but "any method on same
instance can be called only once"? That is, I want to encode state
machine into type system. For example, after I call "val file2 =
file1.open(...)", I cannot call any other method on the same file1,
but I continue to work on file2. After I call "fileN.close()" which
returns Unit, I cannot call anything else neither on fileN nor on any
previous file instance.

I can only imagine some singleton backend like this:

class FileImpl {
def open(...): FileImpl
def close(): Unit
}
object FileImpl {
// Every call to any File method passes through here,
// so any File instance can receive method call only once.
def get(f: File @Unique): FileImpl
}
class File {
def open(...) = FileImpl.get(f).open(...)
def close() = FileImpl.get(f).close()
}

Thanks.

Erik Peterson
Joined: 2010-08-02,
User offline. Last seen 42 years 45 weeks ago.
Stacked traits and their methods

I have several traits that can be stacked in any order. When I call toString on an object with several traits mixed in, I'd like toString executed for each trait that extends a marker trait.

1) How could the following be designed so that toString is called for the traits mixed in? Tried to have each trait's toString prepend a call its parent trait toString, but that failed.

scala> trait A {
| val a: String
| override def toString = a
| }
defined trait A

scala> trait B {
| val b: String
| override def toString = b
| }
defined trait B

scala> val a = new A {val a="A"}
a: java.lang.Object with A = A

scala> println(a)
A

scala> val b = new B {val b="B"}
b: java.lang.Object with B = B

scala> println(b)
B

scala> val ab = new A with B {val a="A"; val b="B"}
ab: java.lang.Object with A with B = B

scala> println(ab)
B

scala> val ba = new B with A {val a="A"; val b="B"}
ba: java.lang.Object with B with A = A

scala> println(ba)
A

2) Why do I not get the same output from these two statements then both ab and ba have A mixed in?

scala> println(if(ab.isInstanceOf[A]) ab.asInstanceOf[A])
B

scala> println(if(ba.isInstanceOf[A]) ba.asInstanceOf[A])
A

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Stacked traits and their methods

1)

scala> trait A {
| val a: String
| abstract override def toString = a + super.toString
| }
defined trait A

scala> trait B {
| val b: String
| abstract override def toString = b + super.toString
| }
defined trait B

scala> val ab = new A with B { val a = "A"; val b = "B" }
ab: java.lang.Object with A with B = BA$anon$1@384e9bea

scala> println(ab)
BA$line3.$read$$iw$$iw$$anon$1@384e9bea

scala> val ba = new B with A { val a = "A"; val b = "B" }
ba: java.lang.Object with B with A = AB$anon$1@24748417

scala> println(ba)
AB$line5.$read$$iw$$iw$$anon$1@24748417

The $line...etc is from the default toString.

2) Because what the compiler thinks a type is have no relevance to
method overrides. If it did, then inheritance would be pretty silly.
Any place where you had def f(x: A), it wouldn't matter what class you
actually passed to f, x would always act like an A.

On Wed, Apr 13, 2011 at 19:59, coach3pete wrote:
> I have several traits that can be stacked in any order. When I call toString on an object with several traits mixed in, I'd like toString executed for each trait that extends a marker trait.
>
> 1) How could the following be designed so that toString is called for the traits mixed in? Tried to have each trait's toString prepend a call its parent trait toString, but that failed.
>
> scala> trait A {
>     | val a: String
>     | override def toString = a
>     | }
> defined trait A
>
> scala> trait B {
>     | val b: String
>     | override def toString = b
>     | }
> defined trait B
>
> scala> val a = new A {val a="A"}
> a: java.lang.Object with A = A
>
> scala> println(a)
> A
>
> scala> val b = new B {val b="B"}
> b: java.lang.Object with B = B
>
> scala> println(b)
> B
>
> scala> val ab = new A with B {val a="A"; val b="B"}
> ab: java.lang.Object with A with B = B
>
> scala> println(ab)
> B
>
> scala> val ba = new B with A {val a="A"; val b="B"}
> ba: java.lang.Object with B with A = A
>
> scala> println(ba)
> A
>
> 2) Why do I not get the same output from these two statements then both ab and ba have A mixed in?
>
> scala> println(if(ab.isInstanceOf[A]) ab.asInstanceOf[A])
> B
>
> scala> println(if(ba.isInstanceOf[A]) ba.asInstanceOf[A])
> A
>
>

Erik Peterson
Joined: 2010-08-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Stacked traits and their methods

Thanks Daniel. Adding a Base trait and a little more work to get desired behavior. Perhaps there is a better way?

trait Base {
override def toString = ""
}
trait A extends Base {
val a: String
abstract override def toString = (if(super.toString.size > 0) (super.toString+ "\n\t") else "") + a
}
trait B extends Base {
val b: String
abstract override def toString = (if(super.toString.size > 0) (super.toString + "\n\t") else "") + b
}
val a = new A {val a="A"}
println(a)
val b = new B {val b="B"}
println(b)
val ab = new Base with A with B {val a="A"; val b="B"}
println(ab)
val ba = new Base with B with A {val a="A"; val b="B"}
println(ba)

On Apr 13, 2011, at 6:52 PM, Daniel Sobral wrote:

> 1)
>
> scala> trait A {
> | val a: String
> | abstract override def toString = a + super.toString
> | }
> defined trait A
>
> scala> trait B {
> | val b: String
> | abstract override def toString = b + super.toString
> | }
> defined trait B
>
> scala> val ab = new A with B { val a = "A"; val b = "B" }
> ab: java.lang.Object with A with B = BA$anon$1@384e9bea
>
> scala> println(ab)
> BA$line3.$read$$iw$$iw$$anon$1@384e9bea
>
> scala> val ba = new B with A { val a = "A"; val b = "B" }
> ba: java.lang.Object with B with A = AB$anon$1@24748417
>
> scala> println(ba)
> AB$line5.$read$$iw$$iw$$anon$1@24748417
>
> The $line...etc is from the default toString.
>
> 2) Because what the compiler thinks a type is have no relevance to
> method overrides. If it did, then inheritance would be pretty silly.
> Any place where you had def f(x: A), it wouldn't matter what class you
> actually passed to f, x would always act like an A.
>
>
> On Wed, Apr 13, 2011 at 19:59, coach3pete wrote:
>> I have several traits that can be stacked in any order. When I call toString on an object with several traits mixed in, I'd like toString executed for each trait that extends a marker trait.
>>
>> 1) How could the following be designed so that toString is called for the traits mixed in? Tried to have each trait's toString prepend a call its parent trait toString, but that failed.
>>
>> scala> trait A {
>> | val a: String
>> | override def toString = a
>> | }
>> defined trait A
>>
>> scala> trait B {
>> | val b: String
>> | override def toString = b
>> | }
>> defined trait B
>>
>> scala> val a = new A {val a="A"}
>> a: java.lang.Object with A = A
>>
>> scala> println(a)
>> A
>>
>> scala> val b = new B {val b="B"}
>> b: java.lang.Object with B = B
>>
>> scala> println(b)
>> B
>>
>> scala> val ab = new A with B {val a="A"; val b="B"}
>> ab: java.lang.Object with A with B = B
>>
>> scala> println(ab)
>> B
>>
>> scala> val ba = new B with A {val a="A"; val b="B"}
>> ba: java.lang.Object with B with A = A
>>
>> scala> println(ba)
>> A
>>
>> 2) Why do I not get the same output from these two statements then both ab and ba have A mixed in?
>>
>> scala> println(if(ab.isInstanceOf[A]) ab.asInstanceOf[A])
>> B
>>
>> scala> println(if(ba.isInstanceOf[A]) ba.asInstanceOf[A])
>> A
>>
>>
>
>
>

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Stacked traits and their methods
If there's a better way depends on what you actually want.

On Wed, Apr 13, 2011 at 23:47, coach3pete <coach3pete@gmail.com> wrote:
Thanks Daniel. Adding a Base trait and a little more work to get desired behavior. Perhaps there is a better way?

trait Base {
override def toString = ""
}
trait A extends Base {
val a: String
abstract override def toString = (if(super.toString.size > 0) (super.toString+ "\n\t")  else "") + a
}
trait B extends Base {
val b: String
abstract override def toString = (if(super.toString.size > 0) (super.toString + "\n\t")  else "") + b
}
val a = new A {val a="A"}
println(a)
val b = new B {val b="B"}
println(b)
val ab = new Base with A with B {val a="A"; val b="B"}
println(ab)
val ba = new Base with B with A {val a="A"; val b="B"}
println(ba)



On Apr 13, 2011, at 6:52 PM, Daniel Sobral wrote:

> 1)
>
> scala> trait A {
>     |   val a: String
>     |   abstract override def toString = a + super.toString
>     | }
> defined trait A
>
> scala> trait B {
>     |   val b: String
>     |   abstract override def toString = b + super.toString
>     | }
> defined trait B
>
> scala> val ab = new A with B { val a = "A"; val b = "B" }
> ab: java.lang.Object with A with B = BA$anon$1@384e9bea
>
> scala> println(ab)
> BA$line3.$read$$iw$$iw$$anon$1@384e9bea
>
> scala> val ba = new B with A { val a = "A"; val b = "B" }
> ba: java.lang.Object with B with A = AB$anon$1@24748417
>
> scala> println(ba)
> AB$line5.$read$$iw$$iw$$anon$1@24748417
>
> The $line...etc is from the default toString.
>
> 2) Because what the compiler thinks a type is have no relevance to
> method overrides. If it did, then inheritance would be pretty silly.
> Any place where you had def f(x: A), it wouldn't matter what class you
> actually passed to f, x would always act like an A.
>
>
> On Wed, Apr 13, 2011 at 19:59, coach3pete <coach3pete@gmail.com> wrote:
>> I have several traits that can be stacked in any order. When I call toString on an object with several traits mixed in, I'd like toString executed for each trait that extends a marker trait.
>>
>> 1) How could the following be designed so that toString is called for the traits mixed in? Tried to have each trait's toString prepend a call its parent trait toString, but that failed.
>>
>> scala> trait A {
>>     | val a: String
>>     | override def toString = a
>>     | }
>> defined trait A
>>
>> scala> trait B {
>>     | val b: String
>>     | override def toString = b
>>     | }
>> defined trait B
>>
>> scala> val a = new A {val a="A"}
>> a: java.lang.Object with A = A
>>
>> scala> println(a)
>> A
>>
>> scala> val b = new B {val b="B"}
>> b: java.lang.Object with B = B
>>
>> scala> println(b)
>> B
>>
>> scala> val ab = new A with B {val a="A"; val b="B"}
>> ab: java.lang.Object with A with B = B
>>
>> scala> println(ab)
>> B
>>
>> scala> val ba = new B with A {val a="A"; val b="B"}
>> ba: java.lang.Object with B with A = A
>>
>> scala> println(ba)
>> A
>>
>> 2) Why do I not get the same output from these two statements then both ab and ba have A mixed in?
>>
>> scala> println(if(ab.isInstanceOf[A]) ab.asInstanceOf[A])
>> B
>>
>> scala> println(if(ba.isInstanceOf[A]) ba.asInstanceOf[A])
>> A
>>
>>
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.

Erik Peterson
m: (281) 804-9023
ep@ardec.com






--
Daniel C. Sobral

I travel to the future all the time.
Erik Peterson
Joined: 2010-08-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Stacked traits and their methods
Well, I'm trying to aggregate function output (toString in this case) of stacked traits and my solution, though workable, smells by testing for an empty string "" in the Base marker trait. I thought using a marker trait like this might work:
scala> trait Basedefined trait Base
scala> trait A extends Base {     | val a: String     | abstract override def toString = (if(super.isInstanceOf[Base]) "" else (super.toString+ "\n\t") ) + a     | }<console>:39: error: super not allowed here: use this.isInstanceOf instead       abstract override def toString = (if(super.isInstanceOf[Base]) "" else (super.toString+ "\n\t") ) + a                                                  ^...but why is super not allowed here?




trait Basetrait A extends Base {val a: Stringabstract override def toString = (if(super.isInstanceOf[Base]) "" else (super.toString+ "\n\t") ) + a}




scala> trait Base {     | override def toString = ""     | }defined trait Base
scala> trait A extends Base {     | val a: String     | abstract override def toString = (if(!super.isInstanceOf[Base]) (super.toString+ "\n\t")  else "") + a     | }<console>:19: error: super not allowed here: use this.isInstanceOf instead       abstract override def toString = (if(!super.isInstanceOf[Base]) (super.toString+ "\n\t")  else "") + a


On Apr 14, 2011, at 8:25 AM, Daniel Sobral wrote:
If there's a better way depends on what you actually want.

On Wed, Apr 13, 2011 at 23:47, coach3pete <coach3pete@gmail.com> wrote:
Thanks Daniel. Adding a Base trait and a little more work to get desired behavior. Perhaps there is a better way?

trait Base {
override def toString = ""
}
trait A extends Base {
val a: String
abstract override def toString = (if(super.toString.size > 0) (super.toString+ "\n\t")  else "") + a
}
trait B extends Base {
val b: String
abstract override def toString = (if(super.toString.size > 0) (super.toString + "\n\t")  else "") + b
}
val a = new A {val a="A"}
println(a)
val b = new B {val b="B"}
println(b)
val ab = new Base with A with B {val a="A"; val b="B"}
println(ab)
val ba = new Base with B with A {val a="A"; val b="B"}
println(ba)



On Apr 13, 2011, at 6:52 PM, Daniel Sobral wrote:

> 1)
>
> scala> trait A {
>     |   val a: String
>     |   abstract override def toString = a + super.toString
>     | }
> defined trait A
>
> scala> trait B {
>     |   val b: String
>     |   abstract override def toString = b + super.toString
>     | }
> defined trait B
>
> scala> val ab = new A with B { val a = "A"; val b = "B" }
> ab: java.lang.Object with A with B = BA$anon$1@384e9bea
>
> scala> println(ab)
> BA$line3.$read$$iw$$iw$$anon$1@384e9bea
>
> scala> val ba = new B with A { val a = "A"; val b = "B" }
> ba: java.lang.Object with B with A = AB$anon$1@24748417
>
> scala> println(ba)
> AB$line5.$read$$iw$$iw$$anon$1@24748417
>
> The $line...etc is from the default toString.
>
> 2) Because what the compiler thinks a type is have no relevance to
> method overrides. If it did, then inheritance would be pretty silly.
> Any place where you had def f(x: A), it wouldn't matter what class you
> actually passed to f, x would always act like an A.
>
>
> On Wed, Apr 13, 2011 at 19:59, coach3pete <coach3pete@gmail.com> wrote:
>> I have several traits that can be stacked in any order. When I call toString on an object with several traits mixed in, I'd like toString executed for each trait that extends a marker trait.
>>
>> 1) How could the following be designed so that toString is called for the traits mixed in? Tried to have each trait's toString prepend a call its parent trait toString, but that failed.
>>
>> scala> trait A {
>>     | val a: String
>>     | override def toString = a
>>     | }
>> defined trait A
>>
>> scala> trait B {
>>     | val b: String
>>     | override def toString = b
>>     | }
>> defined trait B
>>
>> scala> val a = new A {val a="A"}
>> a: java.lang.Object with A = A
>>
>> scala> println(a)
>> A
>>
>> scala> val b = new B {val b="B"}
>> b: java.lang.Object with B = B
>>
>> scala> println(b)
>> B
>>
>> scala> val ab = new A with B {val a="A"; val b="B"}
>> ab: java.lang.Object with A with B = B
>>
>> scala> println(ab)
>> B
>>
>> scala> val ba = new B with A {val a="A"; val b="B"}
>> ba: java.lang.Object with B with A = A
>>
>> scala> println(ba)
>> A
>>
>> 2) Why do I not get the same output from these two statements then both ab and ba have A mixed in?
>>
>> scala> println(if(ab.isInstanceOf[A]) ab.asInstanceOf[A])
>> B
>>
>> scala> println(if(ba.isInstanceOf[A]) ba.asInstanceOf[A])
>> A
>>
>>
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.

Erik Peterson
m: (281) 804-9023
ep@ardec.com






--
Daniel C. Sobral

I travel to the future all the time.

Erik Petersonm: (281) 804-9023ep@ardec.com


extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Stacked traits and their methods

On 4/14/11 2:33 PM, coach3pete wrote:
> :39: error: super not allowed here: use this.isInstanceOf instead
> abstract override def toString = (if(super.isInstanceOf[Base]) "" else
> (super.toString+ "\n\t") ) + a
> ^
> ...but why is super not allowed here?

The reason there's a message is that it had a habit of crashing the
compiler, because super needs a lot of special handling and there are
some places more likely to take programmers by surprise than other
places. But what is the situation where you think you'd get an an
answer from super.isInstanceOf[Foo] than you wouldn't get from
this.isInstanceOf[Foo] ? There's a pretty tiny zone of potential
difference there, and if I grant for the sake of argument a legitimate
need to see into that zone, it won't work right anyway.

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