Hi when I execute the following first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil. first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp output 2 on the transcript. Stef
This is because of compilation optimization. 2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr>
Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
thanks! It makes a lot of sense. I will play with another example because I want to really understand the outerContext of closure vs the home context. Stef On Jul 23, 2013, at 6:58 AM, Clément Bera <bera.clement@gmail.com> wrote:
This is because of compilation optimization.
2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr> Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse <stephane.ducasse@inria.fr
wrote:
thanks! It makes a lot of sense. I will play with another example because I want to really understand the outerContext of closure vs the home context.
The outerContext is a link in the static chain. Each block is created inside some context. This is the block's outerContext. If the block is not nested then the outerCOntext will also be the home context But if the block is nested inside another block activation, then the outerContext refers to that block activation, and the block activation's block's outerContext is the home context. So there are as many outerContext steps as there are nesting levels. | homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. b2 value]. b1 value Ignore the "bN appears to be undefined at this point" and evaluate the above. No assert fails. Draw a picture.
Stef
On Jul 23, 2013, at 6:58 AM, Clément Bera <bera.clement@gmail.com> wrote:
This is because of compilation optimization.
2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr>
Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
-- best, Eliot
Thanks. Ok This is clear now - the outerContext is like my scheme environment. This is what I was thinking but the examples I was trying (stupidly) where just passing the block as argument to different methods and they were not changing the outerContext :) Clement will write some class comments and method comments and I'm finishing the block chapter. I will use this example because I realise that I forgot block nesting. Stef On Jul 25, 2013, at 2:44 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote: thanks! It makes a lot of sense. I will play with another example because I want to really understand the outerContext of closure vs the home context.
The outerContext is a link in the static chain. Each block is created inside some context. This is the block's outerContext. If the block is not nested then the outerCOntext will also be the home context But if the block is nested inside another block activation, then the outerContext refers to that block activation, and the block activation's block's outerContext is the home context. So there are as many outerContext steps as there are nesting levels.
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. b2 value]. b1 value
Ignore the "bN appears to be undefined at this point" and evaluate the above. No assert fails.
Draw a picture.
Stef
On Jul 23, 2013, at 6:58 AM, Clément Bera <bera.clement@gmail.com> wrote:
This is because of compilation optimization.
2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr> Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
-- best, Eliot
I wrote some class comments, but somehow it cannot be merged in Pharo in a normal way. Warning: 'You should not change blockclosure' or something like that I will check with Marcus later. 2013/7/25 Stéphane Ducasse <stephane.ducasse@inria.fr>
Thanks. Ok This is clear now - the outerContext is like my scheme environment. This is what I was thinking but the examples I was trying (stupidly) where just passing the block as argument to different methods and they were not changing the outerContext :)
Clement will write some class comments and method comments and I'm finishing the block chapter. I will use this example because I realise that I forgot block nesting. Stef
On Jul 25, 2013, at 2:44 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse < stephane.ducasse@inria.fr> wrote:
thanks! It makes a lot of sense. I will play with another example because I want to really understand the outerContext of closure vs the home context.
The outerContext is a link in the static chain. Each block is created inside some context. This is the block's outerContext. If the block is not nested then the outerCOntext will also be the home context But if the block is nested inside another block activation, then the outerContext refers to that block activation, and the block activation's block's outerContext is the home context. So there are as many outerContext steps as there are nesting levels.
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. b2 value]. b1 value
Ignore the "bN appears to be undefined at this point" and evaluate the above. No assert fails.
Draw a picture.
Stef
On Jul 23, 2013, at 6:58 AM, Clément Bera <bera.clement@gmail.com> wrote:
This is because of compilation optimization.
2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr>
Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
-- best, Eliot
For the people following I added a test to show the homeContext of a block | homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. self assert: b1 home = homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. self assert: b2 home = homeContext. b2 value]. b1 value
On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote: thanks! It makes a lot of sense. I will play with another example because I want to really understand the outerContext of closure vs the home context.
The outerContext is a link in the static chain. Each block is created inside some context. This is the block's outerContext. If the block is not nested then the outerCOntext will also be the home context But if the block is nested inside another block activation, then the outerContext refers to that block activation, and the block activation's block's outerContext is the home context. So there are as many outerContext steps as there are nesting levels.
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. b2 value]. b1 value
Ignore the "bN appears to be undefined at this point" and evaluate the above. No assert fails.
Draw a picture.
Stef
On Jul 23, 2013, at 6:58 AM, Clément Bera <bera.clement@gmail.com> wrote:
This is because of compilation optimization.
2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr> Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
-- best, Eliot
Perhaps you should add some value message so that the assertions are actually run, shouldn't you ? 2013/7/25 Stéphane Ducasse <stephane.ducasse@inria.fr>
For the people following I added a test to show the homeContext of a block
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. self assert: b1 home = homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. self assert: b2 home = homeContext. b2 value]. b1 value
On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse < stephane.ducasse@inria.fr> wrote:
thanks! It makes a lot of sense. I will play with another example because I want to really understand the outerContext of closure vs the home context.
The outerContext is a link in the static chain. Each block is created inside some context. This is the block's outerContext. If the block is not nested then the outerCOntext will also be the home context But if the block is nested inside another block activation, then the outerContext refers to that block activation, and the block activation's block's outerContext is the home context. So there are as many outerContext steps as there are nesting levels.
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. b2 value]. b1 value
Ignore the "bN appears to be undefined at this point" and evaluate the above. No assert fails.
Draw a picture.
Stef
On Jul 23, 2013, at 6:58 AM, Clément Bera <bera.clement@gmail.com> wrote:
This is because of compilation optimization.
2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr>
Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
-- best, Eliot
On 25 juil. 2013, at 13:12, Clément Bera wrote:
Perhaps you should add some value message so that the assertions are actually run, shouldn't you ?
I always felt that e-mails lack an unsend command :D
2013/7/25 Stéphane Ducasse <stephane.ducasse@inria.fr> For the people following I added a test to show the homeContext of a block
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. self assert: b1 home = homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. self assert: b2 home = homeContext. b2 value]. b1 value
On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote: thanks! It makes a lot of sense. I will play with another example because I want to really understand the outerContext of closure vs the home context.
The outerContext is a link in the static chain. Each block is created inside some context. This is the block's outerContext. If the block is not nested then the outerCOntext will also be the home context But if the block is nested inside another block activation, then the outerContext refers to that block activation, and the block activation's block's outerContext is the home context. So there are as many outerContext steps as there are nesting levels.
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. b2 value]. b1 value
Ignore the "bN appears to be undefined at this point" and evaluate the above. No assert fails.
Draw a picture.
Stef
On Jul 23, 2013, at 6:58 AM, Clément Bera <bera.clement@gmail.com> wrote:
This is because of compilation optimization.
2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr> Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
-- best, Eliot
On Thu, Jul 25, 2013 at 1:17 PM, Camille Teruel <camille.teruel@gmail.com>wrote:
On 25 juil. 2013, at 13:12, Clément Bera wrote:
Perhaps you should add some value message so that the assertions are actually run, shouldn't you ?
I always felt that e-mails lack an unsend command :D
Or gmail quotes should work properly :P
2013/7/25 Stéphane Ducasse <stephane.ducasse@inria.fr>
For the people following I added a test to show the homeContext of a block
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. self assert: b1 home = homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. self assert: b2 home = homeContext. b2 value]. b1 value
On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse < stephane.ducasse@inria.fr> wrote:
thanks! It makes a lot of sense. I will play with another example because I want to really understand the outerContext of closure vs the home context.
The outerContext is a link in the static chain. Each block is created inside some context. This is the block's outerContext. If the block is not nested then the outerCOntext will also be the home context But if the block is nested inside another block activation, then the outerContext refers to that block activation, and the block activation's block's outerContext is the home context. So there are as many outerContext steps as there are nesting levels.
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. b2 value]. b1 value
Ignore the "bN appears to be undefined at this point" and evaluate the above. No assert fails.
Draw a picture.
Stef
On Jul 23, 2013, at 6:58 AM, Clément Bera <bera.clement@gmail.com> wrote:
This is because of compilation optimization.
2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr>
Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
-- best, Eliot
:) On Jul 25, 2013, at 1:20 PM, Guillermo Polito <guillermopolito@gmail.com> wrote:
On Thu, Jul 25, 2013 at 1:17 PM, Camille Teruel <camille.teruel@gmail.com> wrote:
On 25 juil. 2013, at 13:12, Clément Bera wrote:
Perhaps you should add some value message so that the assertions are actually run, shouldn't you ?
I always felt that e-mails lack an unsend command :D
Or gmail quotes should work properly :P
2013/7/25 Stéphane Ducasse <stephane.ducasse@inria.fr> For the people following I added a test to show the homeContext of a block
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. self assert: b1 home = homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. self assert: b2 home = homeContext. b2 value]. b1 value
On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote: thanks! It makes a lot of sense. I will play with another example because I want to really understand the outerContext of closure vs the home context.
The outerContext is a link in the static chain. Each block is created inside some context. This is the block's outerContext. If the block is not nested then the outerCOntext will also be the home context But if the block is nested inside another block activation, then the outerContext refers to that block activation, and the block activation's block's outerContext is the home context. So there are as many outerContext steps as there are nesting levels.
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. b2 value]. b1 value
Ignore the "bN appears to be undefined at this point" and evaluate the above. No assert fails.
Draw a picture.
Stef
On Jul 23, 2013, at 6:58 AM, Clément Bera <bera.clement@gmail.com> wrote:
This is because of compilation optimization.
2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr> Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
-- best, Eliot
Ah yeah it is due to gmail quote that hid it. sorry. 2013/7/25 Stéphane Ducasse <stephane.ducasse@inria.fr>
:)
On Jul 25, 2013, at 1:20 PM, Guillermo Polito <guillermopolito@gmail.com> wrote:
On Thu, Jul 25, 2013 at 1:17 PM, Camille Teruel <camille.teruel@gmail.com>wrote:
On 25 juil. 2013, at 13:12, Clément Bera wrote:
Perhaps you should add some value message so that the assertions are actually run, shouldn't you ?
I always felt that e-mails lack an unsend command :D
Or gmail quotes should work properly :P
2013/7/25 Stéphane Ducasse <stephane.ducasse@inria.fr>
For the people following I added a test to show the homeContext of a block
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. self assert: b1 home = homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. self assert: b2 home = homeContext. b2 value]. b1 value
On Tue, Jul 23, 2013 at 2:02 AM, Stéphane Ducasse < stephane.ducasse@inria.fr> wrote:
thanks! It makes a lot of sense. I will play with another example because I want to really understand the outerContext of closure vs the home context.
The outerContext is a link in the static chain. Each block is created inside some context. This is the block's outerContext. If the block is not nested then the outerCOntext will also be the home context But if the block is nested inside another block activation, then the outerContext refers to that block activation, and the block activation's block's outerContext is the home context. So there are as many outerContext steps as there are nesting levels.
| homeContext b1 | homeContext := thisContext. b1 := [| b2 | self assert: thisContext closure == b1. self assert: b1 outerContext == homeContext. b2 := [self assert: thisContext closure == b2. self assert: b2 outerContext closure outerContext == homeContext]. b2 value]. b1 value
Ignore the "bN appears to be undefined at this point" and evaluate the above. No assert fails.
Draw a picture.
Stef
On Jul 23, 2013, at 6:58 AM, Clément Bera <bera.clement@gmail.com> wrote:
This is because of compilation optimization.
2013/7/22 Stéphane Ducasse <stephane.ducasse@inria.fr>
Hi
when I execute the following
first "Bexp new first" | temp | temp := 2. [ temp. thisContext inspect.] value. ^ temp
tmp in the inspector is nil and does not hold 2 and I was wondering why. I thought that thisContext was returning the blockContext In the outercontext of thisContext blockClosure, tmp is also nil.
This is because here 'temp.' is evaluated for effect (the value is not stored anywhere) and it has no side effect (reading a variable cannot lead to a modification of state of another object). So the compiler removes it. As it is removed, it is the same as if it was not in the block. So the block cannot access temp. Now write 'temp:= #foo' or 'temp foo' you will get it.
first "Bexp new first" | temp | temp := 2. [ temp. temp traceCr. thisContext inspect.] value. ^ temp
output 2 on the transcript.
In this case 'temp.' is still removed, but the value of temp still need to be copied in the block for ' temp traceCr.'.'temp traceCr' is also evaluated for effect, but has the side effect to output the transcript, so the compiler cannot remove it.
Basically the is very few things that the compiler removes, and one of them is variable read for effect, because you are sure it cannot lead to any issue.
Stef
-- best, Eliot
participants (5)
-
Camille Teruel -
Clément Bera -
Eliot Miranda -
Guillermo Polito -
Stéphane Ducasse