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

write once only field

28 replies
Ishaaq Chandy
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Hi all,
Just wanted to know what patterns people use to emulate a value that allows you to write only once to it. What I'd love to have is a modifier to the val keyword (much like the "lazy" modifier) that gets the compiler to check for multiple writes to the val and give a compile error - of course, I can envisage that this is probably not as simple as I make it out to be here.

Cheers,
Ishaaq
Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: write once only field

Can you give a use case?

2009/5/13 Ishaaq Chandy :
> Hi all,
> Just wanted to know what patterns people use to emulate a value that allows
> you to write only once to it. What I'd love to have is a modifier to the val
> keyword (much like the "lazy" modifier) that gets the compiler to check for
> multiple writes to the val and give a compile error - of course, I can
> envisage that this is probably not as simple as I make it out to be here.
>
> Cheers,
> Ishaaq
>

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: write once only field

On Wednesday May 13 2009, Ricky Clarkson wrote:
> 2009/5/13 Ishaaq Chandy :
> > Hi all,
> > Just wanted to know what patterns people use to emulate a value
> > that allows you to write only once to it. What I'd love to have is
> > a modifier to the val keyword (much like the "lazy" modifier) that
> > gets the compiler to check for multiple writes to the val and give
> > a compile error - of course, I can envisage that this is probably
> > not as simple as I make it out to be here.
> >
> > Cheers,
> > Ishaaq
>
> Can you give a use case?

I've been fond of the Immutable After Initialization (IAI) pattern,
which this language featrue could be seen as supporting. It allows
instance properties to be established incrementally without having to
have them all available for the constructor invocation.

I've used IAI extensively in Java, but it's quite tedious to implement.
In Scala I'm anticipating writing Builders (Chapter 2, Item 2
of "Effective Java" 2nd ed.) for cases where I would have used IAI in
the past.

If IAI was easier to use, I'd stick with it, but in Scala it would mean
using vars, and that seems to be a very bad idea.

Randall Schulz

Larry Yogman
Joined: 2009-05-11,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field

I'm struggling to come up with a single assignment use case that isn't
handled already. I've used all of the below to gradually turn my single
assignment var fields into val fields.

* if-expressions and match expressions
* lazy val
* constructor parameters, were a parameter can be exposed as a val

Randall Schulz wrote:
>
> On Wednesday May 13 2009, Ricky Clarkson wrote:
>> 2009/5/13 Ishaaq Chandy :
>> > Hi all,
>> > Just wanted to know what patterns people use to emulate a value
>> > that allows you to write only once to it. What I'd love to have is
>> > a modifier to the val keyword (much like the "lazy" modifier) that
>> > gets the compiler to check for multiple writes to the val and give
>> > a compile error - of course, I can envisage that this is probably
>> > not as simple as I make it out to be here.
>> >
>> > Cheers,
>> > Ishaaq
>>
>> Can you give a use case?
>
> I've been fond of the Immutable After Initialization (IAI) pattern,
> which this language featrue could be seen as supporting. It allows
> instance properties to be established incrementally without having to
> have them all available for the constructor invocation.
>
> I've used IAI extensively in Java, but it's quite tedious to implement.
> In Scala I'm anticipating writing Builders (Chapter 2, Item 2
> of "Effective Java" 2nd ed.) for cases where I would have used IAI in
> the past.
>
> If IAI was easier to use, I'd stick with it, but in Scala it would mean
> using vars, and that seems to be a very bad idea.
>
>
> Randall Schulz
>
>

Dave Griffith
Joined: 2009-01-14,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field

Setter-based dependency injection, although this would probably have to
manifest as a run-time error rather than a compile-time one.

(And yes, I already know about the cake pattern.)

--Dave Griffith

Ricky Clarkson wrote:
>
> Can you give a use case?
>
> 2009/5/13 Ishaaq Chandy :
>> Hi all,
>> Just wanted to know what patterns people use to emulate a value that
>> allows
>> you to write only once to it. What I'd love to have is a modifier to the
>> val
>> keyword (much like the "lazy" modifier) that gets the compiler to check
>> for
>> multiple writes to the val and give a compile error - of course, I can
>> envisage that this is probably not as simple as I make it out to be here.
>>
>> Cheers,
>> Ishaaq
>>
>
>

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: write once only field

trait Immutable { val x: Int; val y: Int }

object Builder { def apply(__x__: Int) = new { def apply(__y__: Int) =
new Immutable { val x = __x__; val y = __y__ } } }

__ used to emphasise how annoying it is to not be able to write val x = x.

2009/5/13 Randall R Schulz :
> On Wednesday May 13 2009, Ricky Clarkson wrote:
>> 2009/5/13 Ishaaq Chandy :
>> > Hi all,
>> > Just wanted to know what patterns people use to emulate a value
>> > that allows you to write only once to it. What I'd love to have is
>> > a modifier to the val keyword (much like the "lazy" modifier) that
>> > gets the compiler to check for multiple writes to the val and give
>> > a compile error - of course, I can envisage that this is probably
>> > not as simple as I make it out to be here.
>> >
>> > Cheers,
>> > Ishaaq
>>
>> Can you give a use case?
>
> I've been fond of the Immutable After Initialization (IAI) pattern,
> which this language featrue could be seen as supporting. It allows
> instance properties to be established incrementally without having to
> have them all available for the constructor invocation.
>
> I've used IAI extensively in Java, but it's quite tedious to implement.
> In Scala I'm anticipating writing Builders (Chapter 2, Item 2
> of "Effective Java" 2nd ed.) for cases where I would have used IAI in
> the past.
>
> If IAI was easier to use, I'd stick with it, but in Scala it would mean
> using vars, and that seems to be a very bad idea.
>
>
> Randall Schulz
>

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: write once only field

On Wednesday May 13 2009, Ricky Clarkson wrote:
> 2009/5/13 Randall R Schulz :
> > On Wednesday May 13 2009, Ricky Clarkson wrote:
> >> ...
> >>
> >> Can you give a use case?
> >
> > I've been fond of the Immutable After Initialization (IAI) pattern,
> > which this language feature could be seen as supporting. ...
> >
> > I've used IAI extensively in Java, but it's quite tedious to
> > implement. In Scala I'm anticipating writing Builders (Chapter 2,
> > Item 2 of "Effective Java" 2nd ed.) for cases where I would have
> > used IAI in the past.
> > ...
> >
> >
> > Randall Schulz
>
> trait Immutable { val x: Int; val y: Int }
>
> object Builder { def apply(__x__: Int) = new { def apply(__y__: Int)
> = new Immutable { val x = __x__; val y = __y__ } } }
>
> __ used to emphasise how annoying it is to not be able to write val x
> = x.

I'm not seeing how that addresses the problem. Don't I still need all
the instance properties up front?

How would I incrementally establish the values of properties with that
pattern?

Randall Schulz

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: write once only field

case class Immutable(val x: Int, val y: Int)

class Mutable(var x: Int, var y: Int) { def setInStone = Immutable(x, y) }

Howzat?

2009/5/13 Randall R Schulz :
> On Wednesday May 13 2009, Ricky Clarkson wrote:
>> 2009/5/13 Randall R Schulz :
>> > On Wednesday May 13 2009, Ricky Clarkson wrote:
>> >> ...
>> >>
>> >> Can you give a use case?
>> >
>> > I've been fond of the Immutable After Initialization (IAI) pattern,
>> > which this language feature could be seen as supporting. ...
>> >
>> > I've used IAI extensively in Java, but it's quite tedious to
>> > implement. In Scala I'm anticipating writing Builders (Chapter 2,
>> > Item 2 of "Effective Java" 2nd ed.) for cases where I would have
>> > used IAI in the past.
>> > ...
>> >
>> >
>> > Randall Schulz
>>
>> trait Immutable { val x: Int; val y: Int }
>>
>> object Builder { def apply(__x__: Int) = new { def apply(__y__: Int)
>> = new Immutable { val x = __x__; val y = __y__ } } }
>>
>> __ used to emphasise how annoying it is to not be able to write val x
>> = x.
>
> I'm not seeing how that addresses the problem. Don't I still need all
> the instance properties up front?
>
> How would I incrementally establish the values of properties with that
> pattern?
>
>
> Randall Schulz
>
>

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: write once only field

On Wednesday May 13 2009, Ricky Clarkson wrote:
> 2009/5/13 Randall R Schulz :
> > On Wednesday May 13 2009, Ricky Clarkson wrote:
> >> 2009/5/13 Randall R Schulz :
> >> > On Wednesday May 13 2009, Ricky Clarkson wrote:
> >> >> ...
> >> >>
> >> >> Can you give a use case?
> >> >
> >> > I've been fond of the Immutable After Initialization (IAI)
> >> > pattern, which this language feature could be seen as
> >> > supporting. ...
> >> >
> >> > I've used IAI extensively in Java, but it's quite tedious to
> >> > implement. In Scala I'm anticipating writing Builders (Chapter
> >> > 2, Item 2 of "Effective Java" 2nd ed.) for cases where I would
> >> > have used IAI in the past.
> >> > ...
> >> >
> >> >
> >> > Randall Schulz
> >>
> >> trait Immutable { val x: Int; val y: Int }
> >>
> >> object Builder { def apply(__x__: Int) = new { def apply(__y__:
> >> Int) = new Immutable { val x = __x__; val y = __y__ } } }
> >>
> >> __ used to emphasise how annoying it is to not be able to write
> >> val x = x.
> >
> > I'm not seeing how that addresses the problem. Don't I still need
> > all the instance properties up front?
> >
> > How would I incrementally establish the values of properties with
> > that pattern?
> >
> >
> > Randall Schulz
>
> case class Immutable(val x: Int, val y: Int)
>
> class Mutable(var x: Int, var y: Int) { def setInStone = Immutable(x,
> y) }
>
> Howzat?

I think at least one of us is confused...

Do you understand what I mean by Immutable After Initialization? I can
new an instance (with a default constructor) and then establish its
property values one by one, but cannot establish any given property's
value more than once (for a given instance).

Do your suggestions do that?

Randall Schulz

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: write once only field

Nope, as it's inherently not as good as the last approach I showed.
But I wrote a blog post some time ago about what you want plus some:
http://rickyclarkson.blogspot.com/2008/09/implementing-builder-pattern-i...

2009/5/13 Randall R Schulz :
> On Wednesday May 13 2009, Ricky Clarkson wrote:
>> 2009/5/13 Randall R Schulz :
>> > On Wednesday May 13 2009, Ricky Clarkson wrote:
>> >> 2009/5/13 Randall R Schulz :
>> >> > On Wednesday May 13 2009, Ricky Clarkson wrote:
>> >> >> ...
>> >> >>
>> >> >> Can you give a use case?
>> >> >
>> >> > I've been fond of the Immutable After Initialization (IAI)
>> >> > pattern, which this language feature could be seen as
>> >> > supporting. ...
>> >> >
>> >> > I've used IAI extensively in Java, but it's quite tedious to
>> >> > implement. In Scala I'm anticipating writing Builders (Chapter
>> >> > 2, Item 2 of "Effective Java" 2nd ed.) for cases where I would
>> >> > have used IAI in the past.
>> >> > ...
>> >> >
>> >> >
>> >> > Randall Schulz
>> >>
>> >> trait Immutable { val x: Int; val y: Int }
>> >>
>> >> object Builder { def apply(__x__: Int) = new { def apply(__y__:
>> >> Int) = new Immutable { val x = __x__; val y = __y__ } } }
>> >>
>> >> __ used to emphasise how annoying it is to not be able to write
>> >> val x = x.
>> >
>> > I'm not seeing how that addresses the problem. Don't I still need
>> > all the instance properties up front?
>> >
>> > How would I incrementally establish the values of properties with
>> > that pattern?
>> >
>> >
>> > Randall Schulz
>>
>> case class Immutable(val x: Int, val y: Int)
>>
>> class Mutable(var x: Int, var y: Int) { def setInStone = Immutable(x,
>> y) }
>>
>> Howzat?
>
> I think at least one of us is confused...
>
> Do you understand what I mean by Immutable After Initialization? I can
> new an instance (with a default constructor) and then establish its
> property values one by one, but cannot establish any given property's
> value more than once (for a given instance).
>
> Do your suggestions do that?
>
>
> Randall Schulz
>
>

Christian Szegedy
Joined: 2009-02-08,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field
What about this? Have not tested just improvized:

class WriteOnce[A] {
    private var v:Option[A] = None

    def get:A = v match {
       case Some(x) => x
       case None => error("Accessing uninitialized WriteOnce value")
    }

    def set(x:A) {
        v match {
           case Some(x) => error("Trying to rewrite WriteOnce value")
           case None => v = x
        }
    }
  
   override def toString:String = v.toString
}

implicit def SetOnce2Val[A](s:SetOnce[A]) = x.get

object Test {
    val name = new WriteOnce[String]
}

Test.name.get // should fail
Test.name.set("Bob") // should work
Test.name.set("Rob") // should fail
var x:String = Test.name // should work






On 5/13/09, Randall R Schulz <rschulz@sonic.net> wrote:

I think at least one of us is confused...

Do you understand what I mean by Immutable After Initialization? I can
new an instance (with a default constructor) and then establish its
property values one by one, but cannot establish any given property's
value more than once (for a given instance).

Do your suggestions do that?



Randall Schulz


Landei
Joined: 2008-12-18,
User offline. Last seen 45 weeks 4 days ago.
Re: write once only field

Ishaaq Chandy wrote:
>
> Hi all,
> Just wanted to know what patterns people use to emulate a value that
> allows
> you to write only once to it. What I'd love to have is a modifier to the
> val
> keyword (much like the "lazy" modifier) that gets the compiler to check
> for
> multiple writes to the val and give a compile error - of course, I can
> envisage that this is probably not as simple as I make it out to be here.
>
> Cheers,
> Ishaaq
>
>

Hi,

the best I could come up with was this:

class SetOnce[T] {
var t:Option[T] = None
def get = t.getOrElse(error("not initialized"))
def set(initT:T) { if (t == None) t = Some(initT) else
error("already initialized") }
}

class Immutable {
val xso = new SetOnce[Int]
def x = xso.get; def x_= = xso.set _
val yso = new SetOnce[String]
def y = yso.get; def y_= = yso.set _
}

val v = new Immutable
v.x = 42
println(v.x)
//println(v.y) --> error "not initilized"
v.y = "answer"
println(v.y)
//v.y = "no answer" --> error "already initilized"

OK, it's not really nice, but at least short and easy to use...

Cheers,
Daniel

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: write once only field

On Wednesday May 13 2009, Christian Szegedy wrote:
> What about this? Have not tested just improvized:
>
> class WriteOnce[A] {
> private var v:Option[A] = None
>
> def get:A = v match {
> case Some(x) => x
> case None => error("Accessing uninitialized WriteOnce value")
> }
>
> def set(x:A) {
> v match {
> case Some(x) => error("Trying to rewrite WriteOnce value")
> case None => v = x
> }
> }
>
> override def toString:String = v.toString
> }
>
> implicit def SetOnce2Val[A](s:SetOnce[A]) = x.get
>
> object Test {
> val name = new WriteOnce[String]
> }
>
> Test.name.get // should fail
> Test.name.set("Bob") // should work
> Test.name.set("Rob") // should fail
> var x:String = Test.name // should work

Both this and Daniel's / Landei's solution introduce two extra layers of
object encapsulation / indirection. In key use cases for me, these are
high-volume classes, and this space overhead is not acceptable.

I will, as I mentioned before, go with the Builder pattern in my Scala
code and look for ways to cut the code replication / boilerplate code
required to realize builders.

Randall Schulz

Christian Szegedy
Joined: 2009-02-08,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field
The following code does not require any additional layers,
but the boilerplate is significant, but does not exceed
the typical effort in java to define accessors. Additionally it can
be used intuitively.

trait OnceSetters {
  def setOnce[A](get: =>Any,setUnsafe:A=>Unit)(a:A) {
    if(get.isInstanceOf[Unit]) setUnsafe(a) else error("Trying to reinitialize value")
  }  
}

class X extends OnceSetters {
  private var _name:Any = ()
  def name_= = setOnce[String](_name,_name_=)(_)
  def name  = _name.asInstanceOf[String]
}




On 5/13/09, Randall R Schulz <rschulz@sonic.net> wrote:
On Wednesday May 13 2009, Christian Szegedy wrote:
> What about this? Have not tested just improvized:
>
> class WriteOnce[A] {
>     private var v:Option[A] = None
>
>     def get:A = v match {
>        case Some(x) => x
>        case None => error("Accessing uninitialized WriteOnce value")
>     }
>
>     def set(x:A) {
>         v match {
>            case Some(x) => error("Trying to rewrite WriteOnce value")
>            case None => v = x
>         }
>     }
>
>    override def toString:String = v.toString
> }
>
> implicit def SetOnce2Val[A](s:SetOnce[A]) = x.get
>
> object Test {
>     val name = new WriteOnce[String]
> }
>
> Test.name.get // should fail
> Test.name.set("Bob") // should work
> Test.name.set("Rob") // should fail
> var x:String = Test.name // should work


Both this and Daniel's / Landei's solution introduce two extra layers of
object encapsulation / indirection. In key use cases for me, these are
high-volume classes, and this space overhead is not acceptable.

I will, as I mentioned before, go with the Builder pattern in my Scala
code and look for ways to cut the code replication / boilerplate code
required to realize builders.



Randall Schulz

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: write once only field

On Wednesday May 13 2009, Christian Szegedy wrote:
> On 5/13/09, Randall R Schulz wrote:
> > On Wednesday May 13 2009, Christian Szegedy wrote:
> > > What about this? Have not tested just improvized:
> > >
> > > ...
> >
> > Both this and Daniel's / Landei's solution introduce two extra
> > layers of object encapsulation / indirection. In key use cases for
> > me, these are high-volume classes, and this space overhead is not
> > acceptable.
> >
> > I will, as I mentioned before, go with the Builder pattern in my
> > Scala code and look for ways to cut the code replication /
> > boilerplate code required to realize builders.
> >
> >
> >
> > Randall Schulz
>
> The following code does not require any additional layers,
> but the boilerplate is significant, but does not exceed
> the typical effort in java to define accessors. Additionally it can
> be used intuitively.
>
> trait OnceSetters {
> def setOnce[A](get: =>Any,setUnsafe:A=>Unit)(a:A) {
> if(get.isInstanceOf[Unit]) setUnsafe(a) else error("Trying to
> reinitialize value")
> }
> }
>
> class X extends OnceSetters {
> private var _name:Any = ()
> def name_= = setOnce[String](_name,_name_=)(_)
> def name = _name.asInstanceOf[String]
> }

I does introduce one extra layer, represented by X itself in this
example. Every use of one of these to declare a "once-settable" String
property within another class has an extra instance (an X) on top of
the String payload.

In my opinion, all these gyrations constitute support for the original
request for a write-once / delayed initialization feature.

Lacking write-once vals, I'll stick with the Builder pattern.

Randall Schulz

Christian Szegedy
Joined: 2009-02-08,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field
Here is a solution with even less boilerplate code, but now, you
would need setName(...),name() to write/read the variable.

trait OnceSetters {
  def setOnce[A](get: =>Any,setUnsafe:A=>Unit)(a:A) {
    if(get.isInstanceOf[Unit]) {
       setUnsafe(a)
    }else  error("Trying to reinitialize value")
  }
 
  def accessOnce[A](get: =>Any,setUnsafe:A=>Unit) = (
     ( x => setOnce[A](get,setUnsafe)(x)),
     ( () => get.asInstanceOf[A]))
}


object Test extends OnceSetters {
  private var _name:Any = ()
  val (setName,name) = accessOnce[String](_name,_name_=)
}



On 5/13/09, Randall R Schulz <rschulz@sonic.net> wrote:

In my opinion, all these gyrations constitute support for the original
request for a write-once / delayed initialization feature.

Lacking write-once vals, I'll stick with the Builder pattern.



Randall Schulz

Ishaaq Chandy
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field
I guess there a number of ways to skin this cat - I was just interested in how others approached this problem - you've given me food for thought - thanks. However, all of your solutions (as do my own simplistic ones) suffer from the same problem - they rely on late runtime checking. Ideally what I'd like is to be able to get the compiler to complain on consecutive writes after the first one, much like it complains when I attempt to change the value of a val. I don't know how this can be done or if it is even possible - just wishing for something I have no idea how to implement :)

Ishaaq

2009/5/14 Christian Szegedy <christian.szegedy@gmail.com>
Here is a solution with even less boilerplate code, but now, you
would need setName(...),name() to write/read the variable.

trait OnceSetters {
  def setOnce[A](get: =>Any,setUnsafe:A=>Unit)(a:A) {
    if(get.isInstanceOf[Unit]) {
       setUnsafe(a)
    }else  error("Trying to reinitialize value")
  }
 
  def accessOnce[A](get: =>Any,setUnsafe:A=>Unit) = (
     ( x => setOnce[A](get,setUnsafe)(x)),
     ( () => get.asInstanceOf[A]))
}


object Test extends OnceSetters {
  private var _name:Any = ()
  val (setName,name) = accessOnce[String](_name,_name_=)
}



On 5/13/09, Randall R Schulz <rschulz@sonic.net> wrote:

In my opinion, all these gyrations constitute support for the original
request for a write-once / delayed initialization feature.

Lacking write-once vals, I'll stick with the Builder pattern.



Randall Schulz


Christian Szegedy
Joined: 2009-02-08,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field
You definitely get the effect if you use trait mixins for initialization.
For example if you want a,b and c to be initialized exactly once, then you
can write

trait InitializeThese{
   val a
   val b
   val c
}

class Test(...) extends InitializeThese {
   /* some code that will have to initialize every one
      of the above varibles exactly once by having a
      val statement. */
}

You get static type error if you initialize something
twice and also an error if you forget to initialize any of them.

I still like to see any practical situation when this does not fit.

The only situation not checked *statically* is whether you use
your variable before initializing it. For example:

trait A {
   val a:String
   val b:Int
}

class B extends A {
   println(a)
   val b = 2
   val a = "a"+b
}

object Y extends B {
  def main(x:Array[String]) {
     println(b)
  }  
}

Running it outputs:

null
2

On 5/13/09, Ishaaq Chandy <ishaaq@gmail.com> wrote:
I guess there a number of ways to skin this cat - I was just interested in how others approached this problem - you've given me food for thought - thanks. However, all of your solutions (as do my own simplistic ones) suffer from the same problem - they rely on late runtime checking. Ideally what I'd like is to be able to get the compiler to complain on consecutive writes after the first one, much like it complains when I attempt to change the value of a val. I don't know how this can be done or if it is even possible - just wishing for something I have no idea how to implement :)

Ishaaq

2009/5/14 Christian Szegedy <christian.szegedy@gmail.com>
Here is a solution with even less boilerplate code, but now, you
would need setName(...),name() to write/read the variable.

trait OnceSetters {
  def setOnce[A](get: =>Any,setUnsafe:A=>Unit)(a:A) {
    if(get.isInstanceOf[Unit]) {
       setUnsafe(a)
    }else  error("Trying to reinitialize value")
  }
 
  def accessOnce[A](get: =>Any,setUnsafe:A=>Unit) = (
     ( x => setOnce[A](get,setUnsafe)(x)),
     ( () => get.asInstanceOf[A]))
}


object Test extends OnceSetters {
  private var _name:Any = ()
  val (setName,name) = accessOnce[String](_name,_name_=)
}



On 5/13/09, Randall R Schulz <rschulz@sonic.net> wrote:

In my opinion, all these gyrations constitute support for the original
request for a write-once / delayed initialization feature.

Lacking write-once vals, I'll stick with the Builder pattern.



Randall Schulz



Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: write once only field

On Wednesday May 13 2009, Christian Szegedy wrote:
> You definitely get the effect if you use trait mixins for
> initialization. For example if you want a,b and c to be initialized
> exactly once, then you can write
>
> trait InitializeThese{
> val a
> val b
> val c
> }
>
> class Test(...) extends InitializeThese {
> /* some code that will have to initialize every one
> of the above varibles exactly once by having a
> val statement. */
> }
>
> You get static type error if you initialize something
> twice and also an error if you forget to initialize any of them.

Is it not the case that all the vals have to have values established in
the constructor? That still does not equate to or even approximate
Immutable After Initialization.

> I still like to see any practical situation when this does not fit.

It does not handle any situation in which you wish to relieve the client
of the class from having to present all the property values to the
constructor.

> The only situation not checked *statically* is whether you use
> your variable before initializing it. For example:
>
> ...

Randall Schulz

Petr Gladkikh
Joined: 2009-01-20,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field

On Thu, May 14, 2009 at 10:16 AM, Randall R Schulz wrote:
> On Wednesday May 13 2009, Christian Szegedy wrote:
>> You definitely get the effect if you use trait mixins for
>> initialization. For example if you want a,b and c to be initialized
>> exactly once, then you can write
>>
>> trait InitializeThese{
>>    val a
>>    val b
>>    val c
>> }
>>
>> class Test(...) extends InitializeThese {
>>    /* some code that will have to initialize every one
>>       of the above varibles exactly once by having a
>>       val statement. */
>> }
>>
>> You get static type error if you initialize something
>> twice and also an error if you forget to initialize any of them.
>
> Is it not the case that all the vals have to have values established in
> the constructor? That still does not equate to or even approximate
> Immutable After Initialization.
>
>
>> I still like to see any practical situation when this does not fit.
>
> It does not handle any situation in which you wish to relieve the client
> of the class from having to present all the property values to the
> constructor.
>
>
>> The only situation not checked *statically* is whether you use
>> your variable before initializing it. For example:
>>
>> ...
>
> Randall Schulz
>

I think that core problem here is that static checking required for
dynamic behaviour. And these are essentially mutually exlusive
requirements. As far as I understnd all this.

Maybe someone would come up with a monad for class being initialzed so
initialization invariants are checked :)

Just saying ...

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: write once only field

On Wed, May 13, 2009 at 3:44 PM, Ricky Clarkson
wrote:
> Can you give a use case?
>
> 2009/5/13 Ishaaq Chandy :
>> Hi all,
>> Just wanted to know what patterns people use to emulate a value that allows
>> you to write only once to it. What I'd love to have is a modifier to the val
>> keyword (much like the "lazy" modifier) that gets the compiler to check for
>> multiple writes to the val and give a compile error - of course, I can
>> envisage that this is probably not as simple as I make it out to be here.
>>
>> Cheers,
>> Ishaaq
>>
>
A very interesting use case is dataflow concurrency, which is built on
the concept of write-once variables. Interestingly, Scala's lazy val
mechanism already provides all the machinery for write checking. It
could be easily adapted to enforce write once variables. The question
is more whether we want to introduce language support for it, and, if
yes, what the syntax should be.

Cheers

Ishaaq Chandy
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field
+1 - if it is relatively simple to do so then yes please!

There have been so many times I've needed to initialize a value long after its containing object has been instantiated but wanted to guarantee that it could only be written to once. All the solutions to this problem have involved dynamic runtime checking, static compile-time checking would be very tasty indeed.

As for syntax I have no idea - do other languages have something similar?

Ishaaq

2009/5/14 martin odersky <martin.odersky@epfl.ch>

A very interesting use case is dataflow concurrency, which is built on
the concept of write-once variables. Interestingly, Scala's lazy val
mechanism already provides all the machinery for write checking. It
could be easily adapted to enforce write once variables. The question
is more whether we want to introduce language support for it, and, if
yes, what the syntax should be.

Cheers

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: write once only field

On Thu, May 14, 2009 at 12:35 PM, Ishaaq Chandy wrote:
> +1 - if it is relatively simple to do so then yes please!
>
> There have been so many times I've needed to initialize a value long after
> its containing object has been instantiated but wanted to guarantee that it
> could only be written to once. All the solutions to this problem have
> involved dynamic runtime checking, static compile-time checking would be
> very tasty indeed.
>
Actually, the proposed scheme would also rely on dynamic run-time
checking. But such checking would be fairly lightweight and efficient.

Cheers

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: write once only field

Can you imagine how such static checking could work? Can you give a
case you'd like the Scala compiler to reject?

2009/5/14 Ishaaq Chandy :
> +1 - if it is relatively simple to do so then yes please!
>
> There have been so many times I've needed to initialize a value long after
> its containing object has been instantiated but wanted to guarantee that it
> could only be written to once. All the solutions to this problem have
> involved dynamic runtime checking, static compile-time checking would be
> very tasty indeed.
>
> As for syntax I have no idea - do other languages have something similar?
>
> Ishaaq
>
> 2009/5/14 martin odersky
>>
>> A very interesting use case is dataflow concurrency, which is built on
>> the concept of write-once variables. Interestingly, Scala's lazy val
>> mechanism already provides all the machinery for write checking. It
>> could be easily adapted to enforce write once variables. The question
>> is more whether we want to introduce language support for it, and, if
>> yes, what the syntax should be.
>>
>> Cheers
>>
>>  -- Martin
>
>

nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: write once only field
On Thu, May 14, 2009 at 5:39 AM, martin odersky <martin.odersky@epfl.ch> wrote:
On Thu, May 14, 2009 at 12:35 PM, Ishaaq Chandy <ishaaq@gmail.com> wrote:
> +1 - if it is relatively simple to do so then yes please!
>
> There have been so many times I've needed to initialize a value long after
> its containing object has been instantiated but wanted to guarantee that it
> could only be written to once. All the solutions to this problem have
> involved dynamic runtime checking, static compile-time checking would be
> very tasty indeed.
>
Actually, the proposed scheme would also rely on dynamic run-time
checking. But such checking would be fairly lightweight and efficient.

Would a new subclass of Option be appropriate?
Ishaaq Chandy
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field
Nope, as I said before, I have no idea how this would work - I just wished it were possible - while admitting the possibility that it might well be impossible - and the more I think about it now, the more I realise it probably is impossible for the compiler to catch this in all but the most trivial of cases.

Ishaaq

2009/5/14 Ricky Clarkson <ricky.clarkson@gmail.com>
Can you imagine how such static checking could work?  Can you give a
case you'd like the Scala compiler to reject?

2009/5/14 Ishaaq Chandy <ishaaq@gmail.com>:
> +1 - if it is relatively simple to do so then yes please!
>
> There have been so many times I've needed to initialize a value long after
> its containing object has been instantiated but wanted to guarantee that it
> could only be written to once. All the solutions to this problem have
> involved dynamic runtime checking, static compile-time checking would be
> very tasty indeed.
>
> As for syntax I have no idea - do other languages have something similar?
>
> Ishaaq
>
> 2009/5/14 martin odersky <martin.odersky@epfl.ch>
>>
>> A very interesting use case is dataflow concurrency, which is built on
>> the concept of write-once variables. Interestingly, Scala's lazy val
>> mechanism already provides all the machinery for write checking. It
>> could be easily adapted to enforce write once variables. The question
>> is more whether we want to introduce language support for it, and, if
>> yes, what the syntax should be.
>>
>> Cheers
>>
>>  -- Martin
>
>

Christian Szegedy
Joined: 2009-02-08,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field

The current way of using traits with uninitialized vals and using a block to
initialize them catches all the simple cases:

trait T {
val a: Int
val b:Double
///...
}

object {
val test = new T {
// Complicated code, but initializes all open vals eventually.
}
}

It is easy to see that it is a computationally undecidable problem to
check whether each variable is initialized exactly once up to
a certain point in the code.

It is possible to design conservative typing if the type checker
assumes that every piece of the code is really reachable
(type inference uses that assumption today, anyways),
but it would boil down to a complicated static analysis task, esp.
in the presence of higher order functions.

I think it is way beyond the scope of type inference of the
current Scala compiler and also probably it would be still too
conservative for the really interesting applications.

On 5/14/09, Ishaaq Chandy wrote:
> Nope, as I said before, I have no idea how this would work - I just wished
> it were possible - while admitting the possibility that it might well be
> impossible - and the more I think about it now, the more I realise it
> probably is impossible for the compiler to catch this in all but the most
> trivial of cases.
>
> Ishaaq
>
> 2009/5/14 Ricky Clarkson
>
>> Can you imagine how such static checking could work? Can you give a
>> case you'd like the Scala compiler to reject?
>>
>> 2009/5/14 Ishaaq Chandy :
>> > +1 - if it is relatively simple to do so then yes please!
>> >
>> > There have been so many times I've needed to initialize a value long
>> after
>> > its containing object has been instantiated but wanted to guarantee that
>> it
>> > could only be written to once. All the solutions to this problem have
>> > involved dynamic runtime checking, static compile-time checking would be
>> > very tasty indeed.
>> >
>> > As for syntax I have no idea - do other languages have something
>> > similar?
>> >
>> > Ishaaq
>> >
>> > 2009/5/14 martin odersky
>> >>
>> >> A very interesting use case is dataflow concurrency, which is built on
>> >> the concept of write-once variables. Interestingly, Scala's lazy val
>> >> mechanism already provides all the machinery for write checking. It
>> >> could be easily adapted to enforce write once variables. The question
>> >> is more whether we want to introduce language support for it, and, if
>> >> yes, what the syntax should be.
>> >>
>> >> Cheers
>> >>
>> >> -- Martin
>> >
>> >
>>
>

Kris Nuttycombe
Joined: 2009-01-16,
User offline. Last seen 42 years 45 weeks ago.
Re: write once only field

I'm a bit late to the discussion, but how about an immutable
doubly-linked list, or indeed any immutable structure with
bidirectional associations? Would such a thing be made possible with
the suggested feature?

Kris

On Wed, May 13, 2009 at 7:44 AM, Ricky Clarkson
wrote:
> Can you give a use case?
>
> 2009/5/13 Ishaaq Chandy :
>> Hi all,
>> Just wanted to know what patterns people use to emulate a value that allows
>> you to write only once to it. What I'd love to have is a modifier to the val
>> keyword (much like the "lazy" modifier) that gets the compiler to check for
>> multiple writes to the val and give a compile error - of course, I can
>> envisage that this is probably not as simple as I make it out to be here.
>>
>> Cheers,
>> Ishaaq
>>
>

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: write once only field

No. Option is an algebraic datatype. Adding another subclass breaks
pattern matching on it.

2009/5/14 Nils Kilden-Pedersen :
> On Thu, May 14, 2009 at 5:39 AM, martin odersky
> wrote:
>>
>> On Thu, May 14, 2009 at 12:35 PM, Ishaaq Chandy wrote:
>> > +1 - if it is relatively simple to do so then yes please!
>> >
>> > There have been so many times I've needed to initialize a value long
>> > after
>> > its containing object has been instantiated but wanted to guarantee that
>> > it
>> > could only be written to once. All the solutions to this problem have
>> > involved dynamic runtime checking, static compile-time checking would be
>> > very tasty indeed.
>> >
>> Actually, the proposed scheme would also rely on dynamic run-time
>> checking. But such checking would be fairly lightweight and efficient.
>
> Would a new subclass of Option be appropriate?
>

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