Thread overview
Const transitivity is bad sometimes
Jan 12, 2008
naryl
Jan 14, 2008
Jason House
Jan 16, 2008
naryl
Jan 16, 2008
Robert Fraser
Jan 16, 2008
naryl
January 12, 2008
For example, I have this piece of (useless) code:

http://paste.dprogramming.com/dpmmwnah

If there were more subscribers the same message would be sent to every one of them. And there may be several messages, carrying the same notifier as their data. While compiling this I got the following errors (DMD 2.009):

main.d(28): function main.SystemShutdownNotifier.addSubscriber (Subscriber) does not match parameter types (Subscriber)
main.d(28): Error: (cmd.notifier).addSubscriber can only be called on a mutable object, not const(SystemShutdownNotifier)

I know. Notifier has become const because const is transitive, but in this example I don't need transitivity. I can't even think of a workaround for that. Maybe someone can help?
January 14, 2008
naryl wrote:

> For example, I have this piece of (useless) code:
> 
> http://paste.dprogramming.com/dpmmwnah
> 
> If there were more subscribers the same message would be sent to every one of them. And there may be several messages, carrying the same notifier as their data. While compiling this I got the following errors (DMD 2.009):
> 
> main.d(28): function main.SystemShutdownNotifier.addSubscriber
> (Subscriber) does not match parameter types (Subscriber)
> main.d(28): Error: (cmd.notifier).addSubscriber can only be called on a
> mutable object, not const(SystemShutdownNotifier)
> 
> I know. Notifier has become const because const is transitive, but in this example I don't need transitivity. I can't even think of a workaround for that. Maybe someone can help?

I think this is the classic sort of problem people have complained about with const transitivity.  I don't know what people have suggested as the workaround for this.  Personally, I've been thinking it'd be nice to mark objects with something that says "I'll write to this, but will never read from it".
January 16, 2008
On Mon, 14 Jan 2008 17:01:27 +0300, Jason House <jason.james.house@gmail.com> wrote:

> naryl wrote:
>
>> For example, I have this piece of (useless) code:
>>
>> http://paste.dprogramming.com/dpmmwnah
>>
>> If there were more subscribers the same message would be sent to every one
>> of them. And there may be several messages, carrying the same notifier as
>> their data. While compiling this I got the following errors (DMD 2.009):
>>
>> main.d(28): function main.SystemShutdownNotifier.addSubscriber
>> (Subscriber) does not match parameter types (Subscriber)
>> main.d(28): Error: (cmd.notifier).addSubscriber can only be called on a
>> mutable object, not const(SystemShutdownNotifier)
>>
>> I know. Notifier has become const because const is transitive, but in this
>> example I don't need transitivity. I can't even think of a workaround for
>> that. Maybe someone can help?
>
> I think this is the classic sort of problem people have complained about
> with const transitivity.  I don't know what people have suggested as the
> workaround for this.  Personally, I've been thinking it'd be nice to mark
> objects with something that says "I'll write to this, but will never read
> from it".

I've found several similar cases. It happens when short-lived invariant object has reference to long-lived mutable object, but not the object itself. When one object creates, contains and finalizes another it is logical to make contained object invariant if container is invariant. But when (as in example) invariant Message is used only to deliver notifier to several subscribers, transitive const doesn't fit. Of course I can cast it away, but on http://www.digitalmars.com/d/const3.html it states that "modification after casting away const" [is] "undefined behavior".
January 16, 2008
naryl wrote:
> I've found several similar cases. It happens when short-lived invariant object has reference to long-lived mutable object, but not the object itself. When one object creates, contains and finalizes another it is logical to make contained object invariant if container is invariant. But when (as in example) invariant Message is used only to deliver notifier to several subscribers, transitive const doesn't fit. Of course I can cast it away, but on http://www.digitalmars.com/d/const3.html it states that "modification after casting away const" [is] "undefined behavior".

I think in this case it should be okay as long as at least one mutable reference to the object exists, since the referenced object can't be treated as invariant.
January 16, 2008
"naryl" wrote
> For example, I have this piece of (useless) code:
>
> http://paste.dprogramming.com/dpmmwnah
>
> If there were more subscribers the same message would be sent to every one of them. And there may be several messages, carrying the same notifier as their data. While compiling this I got the following errors (DMD 2.009):
>
> main.d(28): function main.SystemShutdownNotifier.addSubscriber
> (Subscriber) does not match parameter types (Subscriber)
> main.d(28): Error: (cmd.notifier).addSubscriber can only be called on a
> mutable object, not const(SystemShutdownNotifier)
>
> I know. Notifier has become const because const is transitive, but in this example I don't need transitivity. I can't even think of a workaround for that. Maybe someone can help?

This is an example of something that should be re-designed.  It looks more like the subscriber should contain the notifier, not the message.  However, I don't see where this stuff is used, so I'm not sure how you designed the rest of it.

Another option is to build in the invariance in the class itself.  So instead of making the whole message invariant, just make the portions that aren't going to change invariant (your example really doesn't have any other members, but I'm assuming normal messages have other data that you want to be invariant?), and then you are free to modify the notifier.

-Steve


January 16, 2008
On Wed, 16 Jan 2008 21:45:43 +0300, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> "naryl" wrote
>> For example, I have this piece of (useless) code:
>>
>> http://paste.dprogramming.com/dpmmwnah
>>
>> If there were more subscribers the same message would be sent to every one
>> of them. And there may be several messages, carrying the same notifier as
>> their data. While compiling this I got the following errors (DMD 2.009):
>>
>> main.d(28): function main.SystemShutdownNotifier.addSubscriber
>> (Subscriber) does not match parameter types (Subscriber)
>> main.d(28): Error: (cmd.notifier).addSubscriber can only be called on a
>> mutable object, not const(SystemShutdownNotifier)
>>
>> I know. Notifier has become const because const is transitive, but in this
>> example I don't need transitivity. I can't even think of a workaround for
>> that. Maybe someone can help?
>
> This is an example of something that should be re-designed.  It looks more
> like the subscriber should contain the notifier, not the message.  However,
> I don't see where this stuff is used, so I'm not sure how you designed the
> rest of it.
>
> Another option is to build in the invariance in the class itself.  So
> instead of making the whole message invariant, just make the portions that
> aren't going to change invariant (your example really doesn't have any other
> members, but I'm assuming normal messages have other data that you want to
> be invariant?), and then you are free to modify the notifier.
>
> -Steve
>
>

Thanks! I forgot that message is intended to be invariant-only. Then I can build it in the class and leave notifier mutable.