- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Two questions on Unique References
Wed, 2011-04-13, 20:28
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.
Thu, 2011-04-14, 01:57
#2
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
>
>
Thu, 2011-04-14, 03:57
#3
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
>>
>>
>
>
>
Thu, 2011-04-14, 15:27
#4
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:
--
Daniel C. Sobral
I travel to the future all the time.
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.
Thu, 2011-04-14, 22:37
#5
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:
Erik Petersonm: (281) 804-9023ep@ardec.com
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
Thu, 2011-04-14, 23:57
#6
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.
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