Tried it and it returns false for this Windows VM. Phil On Wed, Jan 25, 2017 at 2:14 PM, Clément Bera <[hidden email]> wrote:
|
In reply to this post by Clément Béra
2017-01-25 13:59 GMT+01:00 Clément Bera <[hidden email]>:
I think we need move it to MirrorPrimitives which was introduced in Pharo 6. |
In reply to this post by Clément Béra
Clément,
thank you very much for the explanation. What was the rationale behind doing nothing as default? I can see there is two interpretations of read-only. One being just don't modify the object the other being throwing an exception when an attempt to modify is made. I think that having an exception thrown would make it easier to write code using it. I don't want to monkey patch Object but still make this general applicable. Modification tracking is exactly the reason why I look into it. I have two other approaches doing modification tracking. But both are inferior to an approach using read-only objects. Norbert
|
In reply to this post by Denis Kudriashov
@Phil, then the VM does not support it. I believe the latest VM from files.pharo.org should support it, but not the stable one.
@Denis Sure move it to MirrorPrimitive and update the WriteBarrier tests. On Wed, Jan 25, 2017 at 3:09 PM, Denis Kudriashov <[hidden email]> wrote:
|
In reply to this post by NorbertHartl
Norbert,
On Wed, Jan 25, 2017 at 3:36 PM, Norbert Hartl <[hidden email]> wrote:
Well, when I introduced the code I thought someone would build a ModificationTracker framework... I think there should be a modification tracker framework that throws an exception only if no program is registered to handle the modification failure. No exception should be thrown in the generic case.
Overall, you need to: - change the code of all numbered primitives mutating objects (such as at:put:) so that when they fail because of a read-only object they call the modification tracker framework. - add the call to the modification tracker framework from the #attemptToAssign:withIndex: call-back. - build a Modification tracker framework where external programs can easily register themselves to catch modification on specific objects or all instances of a specific class. Programs tracking modifications should be able to temporarily make the object writable, perform the modification and make it read-only again. You can check the VisualWork implementation (check for example the fall-back code of #at:put: and what it calls) and the comment I wrote in #attemptToAssign:withIndex: to get inspired. If you do something like that, please, *please*, please contribute it back to the base Pharo image. Thank you for experimenting with read-only objects. Don't hesitate to contact me if you have issues or questions.
|
In reply to this post by philippeback
nevertheless it should be there in latests vms.
which version are you using? Esteban
|
In reply to this post by Clément Béra
I am using a quite recent VM that Esteban provides on the JFrog bintray (debug version with symbols). So this is a bit surprising. Phil On Wed, Jan 25, 2017 at 3:41 PM, Clément Bera <[hidden email]> wrote:
|
In reply to this post by Clément Béra
2017-01-25 15:52 GMT+01:00 Clément Bera <[hidden email]>:
I think it is for future. But now behaviour is just inconsistent because making object readonly breaks any app using it silently. Also I see that instVarAt:put: will raise error instead of skipping it. So two ways to modify object lead to different behavior. It's not good. My conclusion: it must be error by default. Something like this:
It is not fix completely inconsistence with #instVarAt:put: but at least they both will fail. By the way I was supprized that failed #instVarAt:put: shows "bad receiver" in primitive er variable (<primitive: 174 error: ec>). Is "bad receiver" is always about mutability? And if not then how we will distinguish different cases? |
Another question Clement. I found that current method doing something strange:
Could you comment why new process needed here? I just check simple version with error and it works:
Also if I will modify #contents: as "^contents:=newValue" then following code is working well:
So I not understand the problem described in method comment. 2017-01-25 16:21 GMT+01:00 Denis Kudriashov <[hidden email]>:
|
On Wed, Jan 25, 2017 at 4:42 PM, Denis Kudriashov <[hidden email]> wrote:
Hi Denis, I will look into this case tomorrow, it looks like a bug. Thanks for reporting. For the Process hack, it's because the call-back was designed to return no value. It may look like it works when returning a value but you will have uncommon crashes.
|
In reply to this post by EstebanLM
pharo-win-i386-201701151442-c50dec0.zip On Wed, Jan 25, 2017 at 3:57 PM, Esteban Lorenzano <[hidden email]> wrote:
|
In reply to this post by EstebanLM
On 01/25/2017 03:59 AM, Esteban Lorenzano wrote:
> but this is not real immutability, is like a write barrier, that’s why > those method names were not chosen. Thank you for choosing names based on "write barrier," not the incorrect "read-only" or "immutable" (which are just things that can be done with a write barrier, but not the only useful things). Regards, -Martin |
In reply to this post by philippeback
yeah, something fishy is happening there. I will take a look.
|
In reply to this post by Clément Béra
2017-01-25 18:23 GMT+01:00 Clément Bera <[hidden email]>: For the Process hack, it's because the call-back was designed to return no value. Now I am confused. Why anybody needs to return value from this method? And why there is "CAN'T REACH" comment at the end of method? Do you mean that method should never return? It may look like it works when returning a value but you will have uncommon crashes. That's fun :) |
2017-01-25 22:24 GMT+01:00 Denis Kudriashov <[hidden email]>: For the Process hack, it's because the call-back was designed to return no value. And is it safe to just signal error? |
The "CAN'T REACH" comment is there because execution never reach that part of the code. If you write code there, it will never be executed. The process code performs a return without pushing any value on stack. Signalling an error is safe if the error is never resumed. But you'll need the returnNoValue for performance intensive modification tracking. On Wed, Jan 25, 2017 at 10:26 PM, Denis Kudriashov <[hidden email]> wrote:
|
Because you return from the sender, right? Ok, while you are popping of the stack there is no way to return, right? I cannot see what it has to be that way but I can see that my approach cannot work this way. In my case the error is resumed because not resuming would defeat the purpose of having transparent modification tracking. I'll use announcements for it because it is a better fit for that anyway. Norbert
|
In reply to this post by Clément Béra
2017-01-26 8:11 GMT+01:00 Clément Bera <[hidden email]>:
Sorry Clement, maybe I am stupid but it is not clear for me. If I put halt after "CAN'T REACH" I got debugger which means that it "can reach". Maybe by "CAN'T REACH" you mean that any return value will not be used? But it is not true: if I return something it will be result of original assignment expression. But as you said it could crash VM.
Also I not get your "returnNoValue" sentence. |
In reply to this post by NorbertHartl
On Thu, Jan 26, 2017 at 9:54 AM, Norbert Hartl <[hidden email]> wrote:
Yes because the process code returns to the sender. In Smalltalk a send returns necessarily a value to be pushed on the stack of the context performing the send. In the write barrier call-back, the context is not performing a send, but an instance variable store. Unlike sends, instance variable stores are not expected to push a value on stack. If the call-back returns a value, it's pushed on stack while nothing is expected, and if further code use values on stack it will use the returned value instead of the correct one, furthermore, stack depth computation is messed up, overflowing the context stack somewhere in the runtime memory leading to data corruption.
You can signal an error, but then keep the process code. For example: Object>>#attemptToAssign: value withIndex: index | process | NoModification signal. process := Processor activeProcess. [ process suspendedContext: process suspendedContext sender ] forkAt: Processor activePriority + 1. Processor yield. this method just works fine. However, Object>>#attemptToAssign: value withIndex: index NoModification signal. this method does not work because it returns a value.
|
In reply to this post by Denis Kudriashov
Sorry Clement, maybe I am stupid but it is not clear for me. If I put halt after "CAN'T REACH" I got debugger which means that it "can reach". Maybe by "CAN'T REACH" you mean that any return value will not be used? But it is not true: if I return something it will be result of original assignment expression. But as you said it could crash VM. Ok I tried and I can see that. This is why I have bugs. Well "CAN'T REACH" was supposed to mean it cannot be reached, I don't understand how it could be reached. On Thu, Jan 26, 2017 at 10:18 AM, Denis Kudriashov <[hidden email]> wrote:
|
Free forum by Nabble | Edit this page |