InvariantString asString

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

InvariantString asString

SeanTAllen
if

|invariant|

invariant := 'Joe'.

creates an invariant string in Gemstone.

how come after executing as this, variant is a invariant?

|variant|

variant := 'Joe' asString.

when asString does

String withAll: self

and

|variant|

variant := String withAll: 'Joe'

does create a mutable string.
Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

James Foster
Sean,

The general approach is that objects are mutable unless there is some reason for them to immutable. Many Smalltalks (including GemStone/S) have an optimization in which literal references in method source code are used directly but are immutable so that if you call the method multiple times you are guaranteed to get the same literal each time. Consider the implications if string literals were not immutable:

        | b x y z |
        b := ['bbb'].
        x := b value. "bbb"
        y := b value. "bbb"
        x == y. "true" "identical object references to the thing inside the block (or method)"
        x at: 2 put: $A. "bAb"
        x == y. "true"
        z := b value. "bAb" "<<== this is unexpected--call the block/method and the string is different!?"

Compare to:

        | x y z |
        x := 'bbb'.
        y := String withAll: x. "bbb"
        x ~~ y. "true"
        x = y. "true"
        y at: 2 put: $A. "bAb"
        z := String withAll: x. "bbb"
        y = z. "false"

James

On Feb 28, 2010, at 4:00 PM, Sean Allen wrote:

> if
>
> |invariant|
>
> invariant := 'Joe'.
>
> creates an invariant string in Gemstone.
>
> how come after executing as this, variant is a invariant?
>
> |variant|
>
> variant := 'Joe' asString.
>
> when asString does
>
> String withAll: self
>
> and
>
> |variant|
>
> variant := String withAll: 'Joe'
>
> does create a mutable string.

Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

SeanTAllen
That makes sense to me but what I dont understand is why

String withAll: 'xxx' in mutable but
'xxx' asString isnt

when InvariantString>asString is

^ String withAll: self



On Mon, Mar 1, 2010 at 12:47 PM, James Foster <[hidden email]> wrote:

> Sean,
>
> The general approach is that objects are mutable unless there is some reason for them to immutable. Many Smalltalks (including GemStone/S) have an optimization in which literal references in method source code are used directly but are immutable so that if you call the method multiple times you are guaranteed to get the same literal each time. Consider the implications if string literals were not immutable:
>
>        | b x y z |
>        b := ['bbb'].
>        x := b value.           "bbb"
>        y := b value.           "bbb"
>        x == y.                 "true"  "identical object references to the thing inside the block (or method)"
>        x at: 2 put: $A.        "bAb"
>        x == y.                 "true"
>        z := b value.           "bAb"   "<<== this is unexpected--call the block/method and the string is different!?"
>
> Compare to:
>
>        | x y z |
>        x := 'bbb'.
>        y := String withAll: x. "bbb"
>        x ~~ y.                         "true"
>        x = y.                          "true"
>        y at: 2 put: $A.                "bAb"
>        z := String withAll: x. "bbb"
>        y = z.                          "false"
>
> James
>
> On Feb 28, 2010, at 4:00 PM, Sean Allen wrote:
>
>> if
>>
>> |invariant|
>>
>> invariant := 'Joe'.
>>
>> creates an invariant string in Gemstone.
>>
>> how come after executing as this, variant is a invariant?
>>
>> |variant|
>>
>> variant := 'Joe' asString.
>>
>> when asString does
>>
>> String withAll: self
>>
>> and
>>
>> |variant|
>>
>> variant := String withAll: 'Joe'
>>
>> does create a mutable string.
>
>
Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

James Foster
Are you assuming 'xxx' is an instance of InvariantString? What do you get from the following?

        'xxx' class.

The trick is that mutability is an attribute of any object (see Object>>#'immidiateInvariant'), and String>>#'asString' simply returns self.

James

On Mar 1, 2010, at 9:51 AM, Sean Allen wrote:

> That makes sense to me but what I dont understand is why
>
> String withAll: 'xxx' in mutable but
> 'xxx' asString isnt
>
> when InvariantString>asString is
>
> ^ String withAll: self
>
>
>
> On Mon, Mar 1, 2010 at 12:47 PM, James Foster <[hidden email]> wrote:
>> Sean,
>>
>> The general approach is that objects are mutable unless there is some reason for them to immutable. Many Smalltalks (including GemStone/S) have an optimization in which literal references in method source code are used directly but are immutable so that if you call the method multiple times you are guaranteed to get the same literal each time. Consider the implications if string literals were not immutable:
>>
>>        | b x y z |
>>        b := ['bbb'].
>>        x := b value.           "bbb"
>>        y := b value.           "bbb"
>>        x == y.                 "true"  "identical object references to the thing inside the block (or method)"
>>        x at: 2 put: $A.        "bAb"
>>        x == y.                 "true"
>>        z := b value.           "bAb"   "<<== this is unexpected--call the block/method and the string is different!?"
>>
>> Compare to:
>>
>>        | x y z |
>>        x := 'bbb'.
>>        y := String withAll: x. "bbb"
>>        x ~~ y.                         "true"
>>        x = y.                          "true"
>>        y at: 2 put: $A.                "bAb"
>>        z := String withAll: x. "bbb"
>>        y = z.                          "false"
>>
>> James
>>
>> On Feb 28, 2010, at 4:00 PM, Sean Allen wrote:
>>
>>> if
>>>
>>> |invariant|
>>>
>>> invariant := 'Joe'.
>>>
>>> creates an invariant string in Gemstone.
>>>
>>> how come after executing as this, variant is a invariant?
>>>
>>> |variant|
>>>
>>> variant := 'Joe' asString.
>>>
>>> when asString does
>>>
>>> String withAll: self
>>>
>>> and
>>>
>>> |variant|
>>>
>>> variant := String withAll: 'Joe'
>>>
>>> does create a mutable string.
>>
>>

Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

SeanTAllen
I was assuming that because

| a |
a := 'xxx'.
a add: $s

results in an invariant error.
as does:

| a |
a := 'xxx' asString.
a add: $s

so if 'xxx' class is 'String'
when does it become an InvariantString?

This is still 'String'

| a |

a := 'xxx'.
a class

but if I do

| a |

a := 'xxx'.
a class. => 'String'
a add: $s. => 'invariant error'



On Mon, Mar 1, 2010 at 12:58 PM, James Foster <[hidden email]> wrote:

> Are you assuming 'xxx' is an instance of InvariantString? What do you get from the following?
>
>        'xxx' class.
>
> The trick is that mutability is an attribute of any object (see Object>>#'immidiateInvariant'), and String>>#'asString' simply returns self.
>
> James
>
> On Mar 1, 2010, at 9:51 AM, Sean Allen wrote:
>
>> That makes sense to me but what I dont understand is why
>>
>> String withAll: 'xxx' in mutable but
>> 'xxx' asString isnt
>>
>> when InvariantString>asString is
>>
>> ^ String withAll: self
>>
>>
>>
>> On Mon, Mar 1, 2010 at 12:47 PM, James Foster <[hidden email]> wrote:
>>> Sean,
>>>
>>> The general approach is that objects are mutable unless there is some reason for them to immutable. Many Smalltalks (including GemStone/S) have an optimization in which literal references in method source code are used directly but are immutable so that if you call the method multiple times you are guaranteed to get the same literal each time. Consider the implications if string literals were not immutable:
>>>
>>>        | b x y z |
>>>        b := ['bbb'].
>>>        x := b value.           "bbb"
>>>        y := b value.           "bbb"
>>>        x == y.                 "true"  "identical object references to the thing inside the block (or method)"
>>>        x at: 2 put: $A.        "bAb"
>>>        x == y.                 "true"
>>>        z := b value.           "bAb"   "<<== this is unexpected--call the block/method and the string is different!?"
>>>
>>> Compare to:
>>>
>>>        | x y z |
>>>        x := 'bbb'.
>>>        y := String withAll: x. "bbb"
>>>        x ~~ y.                         "true"
>>>        x = y.                          "true"
>>>        y at: 2 put: $A.                "bAb"
>>>        z := String withAll: x. "bbb"
>>>        y = z.                          "false"
>>>
>>> James
>>>
>>> On Feb 28, 2010, at 4:00 PM, Sean Allen wrote:
>>>
>>>> if
>>>>
>>>> |invariant|
>>>>
>>>> invariant := 'Joe'.
>>>>
>>>> creates an invariant string in Gemstone.
>>>>
>>>> how come after executing as this, variant is a invariant?
>>>>
>>>> |variant|
>>>>
>>>> variant := 'Joe' asString.
>>>>
>>>> when asString does
>>>>
>>>> String withAll: self
>>>>
>>>> and
>>>>
>>>> |variant|
>>>>
>>>> variant := String withAll: 'Joe'
>>>>
>>>> does create a mutable string.
>>>
>>>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

James Foster
"Invariant error" would probably be better phrased as "Immutable error."

On Mar 1, 2010, at 10:04 AM, Sean Allen wrote:

> I was assuming that because
>
> | a |
> a := 'xxx'.
> a add: $s
>
> results in an invariant error.
> as does:
>
> | a |
> a := 'xxx' asString.
> a add: $s
>
> so if 'xxx' class is 'String'
> when does it become an InvariantString?
>
> This is still 'String'
>
> | a |
>
> a := 'xxx'.
> a class
>
> but if I do
>
> | a |
>
> a := 'xxx'.
> a class. => 'String'
> a add: $s. => 'invariant error'
>
>
>
> On Mon, Mar 1, 2010 at 12:58 PM, James Foster <[hidden email]> wrote:
>> Are you assuming 'xxx' is an instance of InvariantString? What do you get from the following?
>>
>>        'xxx' class.
>>
>> The trick is that mutability is an attribute of any object (see Object>>#'immidiateInvariant'), and String>>#'asString' simply returns self.
>>
>> James
>>
>> On Mar 1, 2010, at 9:51 AM, Sean Allen wrote:
>>
>>> That makes sense to me but what I dont understand is why
>>>
>>> String withAll: 'xxx' in mutable but
>>> 'xxx' asString isnt
>>>
>>> when InvariantString>asString is
>>>
>>> ^ String withAll: self
>>>
>>>
>>>
>>> On Mon, Mar 1, 2010 at 12:47 PM, James Foster <[hidden email]> wrote:
>>>> Sean,
>>>>
>>>> The general approach is that objects are mutable unless there is some reason for them to immutable. Many Smalltalks (including GemStone/S) have an optimization in which literal references in method source code are used directly but are immutable so that if you call the method multiple times you are guaranteed to get the same literal each time. Consider the implications if string literals were not immutable:
>>>>
>>>>        | b x y z |
>>>>        b := ['bbb'].
>>>>        x := b value.           "bbb"
>>>>        y := b value.           "bbb"
>>>>        x == y.                 "true"  "identical object references to the thing inside the block (or method)"
>>>>        x at: 2 put: $A.        "bAb"
>>>>        x == y.                 "true"
>>>>        z := b value.           "bAb"   "<<== this is unexpected--call the block/method and the string is different!?"
>>>>
>>>> Compare to:
>>>>
>>>>        | x y z |
>>>>        x := 'bbb'.
>>>>        y := String withAll: x. "bbb"
>>>>        x ~~ y.                         "true"
>>>>        x = y.                          "true"
>>>>        y at: 2 put: $A.                "bAb"
>>>>        z := String withAll: x. "bbb"
>>>>        y = z.                          "false"
>>>>
>>>> James
>>>>
>>>> On Feb 28, 2010, at 4:00 PM, Sean Allen wrote:
>>>>
>>>>> if
>>>>>
>>>>> |invariant|
>>>>>
>>>>> invariant := 'Joe'.
>>>>>
>>>>> creates an invariant string in Gemstone.
>>>>>
>>>>> how come after executing as this, variant is a invariant?
>>>>>
>>>>> |variant|
>>>>>
>>>>> variant := 'Joe' asString.
>>>>>
>>>>> when asString does
>>>>>
>>>>> String withAll: self
>>>>>
>>>>> and
>>>>>
>>>>> |variant|
>>>>>
>>>>> variant := String withAll: 'Joe'
>>>>>
>>>>> does create a mutable string.
>>>>
>>>>
>>
>>

Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

James Foster
In reply to this post by SeanTAllen
Any immutable object gives an ("invariant") error if you try to modify it. The class of the object hasn't changed just because it became immutable:

        | assoc |
        assoc := Association newWithKey: 1 value: 'one'.
        assoc immediateInvariant.
        assoc value: '1'.

On Mar 1, 2010, at 10:04 AM, Sean Allen wrote:

> I was assuming that because
>
> | a |
> a := 'xxx'.
> a add: $s
>
> results in an invariant error.
> as does:
>
> | a |
> a := 'xxx' asString.
> a add: $s
>
> so if 'xxx' class is 'String'
> when does it become an InvariantString?
>
> This is still 'String'
>
> | a |
>
> a := 'xxx'.
> a class
>
> but if I do
>
> | a |
>
> a := 'xxx'.
> a class. => 'String'
> a add: $s. => 'invariant error'
>
>
>
> On Mon, Mar 1, 2010 at 12:58 PM, James Foster <[hidden email]> wrote:
>> Are you assuming 'xxx' is an instance of InvariantString? What do you get from the following?
>>
>>        'xxx' class.
>>
>> The trick is that mutability is an attribute of any object (see Object>>#'immidiateInvariant'), and String>>#'asString' simply returns self.
>>
>> James
>>
>> On Mar 1, 2010, at 9:51 AM, Sean Allen wrote:
>>
>>> That makes sense to me but what I dont understand is why
>>>
>>> String withAll: 'xxx' in mutable but
>>> 'xxx' asString isnt
>>>
>>> when InvariantString>asString is
>>>
>>> ^ String withAll: self
>>>
>>>
>>>
>>> On Mon, Mar 1, 2010 at 12:47 PM, James Foster <[hidden email]> wrote:
>>>> Sean,
>>>>
>>>> The general approach is that objects are mutable unless there is some reason for them to immutable. Many Smalltalks (including GemStone/S) have an optimization in which literal references in method source code are used directly but are immutable so that if you call the method multiple times you are guaranteed to get the same literal each time. Consider the implications if string literals were not immutable:
>>>>
>>>>        | b x y z |
>>>>        b := ['bbb'].
>>>>        x := b value.           "bbb"
>>>>        y := b value.           "bbb"
>>>>        x == y.                 "true"  "identical object references to the thing inside the block (or method)"
>>>>        x at: 2 put: $A.        "bAb"
>>>>        x == y.                 "true"
>>>>        z := b value.           "bAb"   "<<== this is unexpected--call the block/method and the string is different!?"
>>>>
>>>> Compare to:
>>>>
>>>>        | x y z |
>>>>        x := 'bbb'.
>>>>        y := String withAll: x. "bbb"
>>>>        x ~~ y.                         "true"
>>>>        x = y.                          "true"
>>>>        y at: 2 put: $A.                "bAb"
>>>>        z := String withAll: x. "bbb"
>>>>        y = z.                          "false"
>>>>
>>>> James
>>>>
>>>> On Feb 28, 2010, at 4:00 PM, Sean Allen wrote:
>>>>
>>>>> if
>>>>>
>>>>> |invariant|
>>>>>
>>>>> invariant := 'Joe'.
>>>>>
>>>>> creates an invariant string in Gemstone.
>>>>>
>>>>> how come after executing as this, variant is a invariant?
>>>>>
>>>>> |variant|
>>>>>
>>>>> variant := 'Joe' asString.
>>>>>
>>>>> when asString does
>>>>>
>>>>> String withAll: self
>>>>>
>>>>> and
>>>>>
>>>>> |variant|
>>>>>
>>>>> variant := String withAll: 'Joe'
>>>>>
>>>>> does create a mutable string.
>>>>
>>>>
>>
>>

Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

SeanTAllen
So you cant take an immutable string and use asString to get a mutable
version. That just feels odd.
Is there a message that can be sent to immutable object to make them mutable?


On Mon, Mar 1, 2010 at 1:08 PM, James Foster <[hidden email]> wrote:

> Any immutable object gives an ("invariant") error if you try to modify it. The class of the object hasn't changed just because it became immutable:
>
>        | assoc |
>        assoc := Association newWithKey: 1 value: 'one'.
>        assoc immediateInvariant.
>        assoc value: '1'.
>
> On Mar 1, 2010, at 10:04 AM, Sean Allen wrote:
>
>> I was assuming that because
>>
>> | a |
>> a := 'xxx'.
>> a add: $s
>>
>> results in an invariant error.
>> as does:
>>
>> | a |
>> a := 'xxx' asString.
>> a add: $s
>>
>> so if 'xxx' class is 'String'
>> when does it become an InvariantString?
>>
>> This is still 'String'
>>
>> | a |
>>
>> a := 'xxx'.
>> a class
>>
>> but if I do
>>
>> | a |
>>
>> a := 'xxx'.
>> a class. => 'String'
>> a add: $s. => 'invariant error'
>>
>>
>>
>> On Mon, Mar 1, 2010 at 12:58 PM, James Foster <[hidden email]> wrote:
>>> Are you assuming 'xxx' is an instance of InvariantString? What do you get from the following?
>>>
>>>        'xxx' class.
>>>
>>> The trick is that mutability is an attribute of any object (see Object>>#'immidiateInvariant'), and String>>#'asString' simply returns self.
>>>
>>> James
>>>
>>> On Mar 1, 2010, at 9:51 AM, Sean Allen wrote:
>>>
>>>> That makes sense to me but what I dont understand is why
>>>>
>>>> String withAll: 'xxx' in mutable but
>>>> 'xxx' asString isnt
>>>>
>>>> when InvariantString>asString is
>>>>
>>>> ^ String withAll: self
>>>>
>>>>
>>>>
>>>> On Mon, Mar 1, 2010 at 12:47 PM, James Foster <[hidden email]> wrote:
>>>>> Sean,
>>>>>
>>>>> The general approach is that objects are mutable unless there is some reason for them to immutable. Many Smalltalks (including GemStone/S) have an optimization in which literal references in method source code are used directly but are immutable so that if you call the method multiple times you are guaranteed to get the same literal each time. Consider the implications if string literals were not immutable:
>>>>>
>>>>>        | b x y z |
>>>>>        b := ['bbb'].
>>>>>        x := b value.           "bbb"
>>>>>        y := b value.           "bbb"
>>>>>        x == y.                 "true"  "identical object references to the thing inside the block (or method)"
>>>>>        x at: 2 put: $A.        "bAb"
>>>>>        x == y.                 "true"
>>>>>        z := b value.           "bAb"   "<<== this is unexpected--call the block/method and the string is different!?"
>>>>>
>>>>> Compare to:
>>>>>
>>>>>        | x y z |
>>>>>        x := 'bbb'.
>>>>>        y := String withAll: x. "bbb"
>>>>>        x ~~ y.                         "true"
>>>>>        x = y.                          "true"
>>>>>        y at: 2 put: $A.                "bAb"
>>>>>        z := String withAll: x. "bbb"
>>>>>        y = z.                          "false"
>>>>>
>>>>> James
>>>>>
>>>>> On Feb 28, 2010, at 4:00 PM, Sean Allen wrote:
>>>>>
>>>>>> if
>>>>>>
>>>>>> |invariant|
>>>>>>
>>>>>> invariant := 'Joe'.
>>>>>>
>>>>>> creates an invariant string in Gemstone.
>>>>>>
>>>>>> how come after executing as this, variant is a invariant?
>>>>>>
>>>>>> |variant|
>>>>>>
>>>>>> variant := 'Joe' asString.
>>>>>>
>>>>>> when asString does
>>>>>>
>>>>>> String withAll: self
>>>>>>
>>>>>> and
>>>>>>
>>>>>> |variant|
>>>>>>
>>>>>> variant := String withAll: 'Joe'
>>>>>>
>>>>>> does create a mutable string.
>>>>>
>>>>>
>>>
>>>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

James Foster
On Mar 1, 2010, at 10:16 AM, Sean Allen wrote:

> Is there a message that can be sent to immutable object to make them mutable?

See the comment in Object>>#'immediateInvariant'

"There is no protocol to reverse the effect of this method.  If the
 receiver is a temporary object , there is no way to undo the effect
 of this method.  If the receiver was committed before the start
 of the current transaction, the effect of this method can be undone
 by aborting the transaction."

See also Class>>#'__makeVariant'.

Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

SeanTAllen
Thanks James,

This has been a great learning experience. Glad I asked the original question.
One more for you, if

'xxx' class => String

What is the purpose of the InvariantString class?


On Mon, Mar 1, 2010 at 1:20 PM, James Foster <[hidden email]> wrote:

> On Mar 1, 2010, at 10:16 AM, Sean Allen wrote:
>
>> Is there a message that can be sent to immutable object to make them mutable?
>
> See the comment in Object>>#'immediateInvariant'
>
> "There is no protocol to reverse the effect of this method.  If the
>  receiver is a temporary object , there is no way to undo the effect
>  of this method.  If the receiver was committed before the start
>  of the current transaction, the effect of this method can be undone
>  by aborting the transaction."
>
> See also Class>>#'__makeVariant'.
>
>
Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

James Foster
On Mar 1, 2010, at 10:23 AM, Sean Allen wrote:

> What is the purpose of the InvariantString class?

Given that it is the superclass for ObsoleteSymbol, my guess is that it is something historic.

Reply | Threaded
Open this post in threaded view
|

Re: InvariantString asString

SeanTAllen
On Mon, Mar 1, 2010 at 2:29 PM, James Foster <[hidden email]> wrote:
> On Mar 1, 2010, at 10:23 AM, Sean Allen wrote:
>
>> What is the purpose of the InvariantString class?
>
> Given that it is the superclass for ObsoleteSymbol, my guess is that it is something historic.
>

Thanks James.