pharo-users@lists.pharo.org

Any question about pharo is welcome

View all threads

Comparison of blocks

SM
Steffen Märcker
Thu, Apr 13, 2023 6:55 AM

Hi!

In VisualWorks, blocks can be compared with each other. In Pharo the
comparison just checks for Identity. Is this on purpose? For reference,
that's how BlockClosure>>= is implemented in VW:

= aBlockClosure
^aBlockClosure class = self class and:
[method = aBlockClosure method and:
[outerContext = aBlockClosure outerContext and:
[copiedValues = aBlockClosure copiedValues]]]

Kind regards,
Steffen

Hi! In VisualWorks, blocks can be compared with each other. In Pharo the comparison just checks for Identity. Is this on purpose? For reference, that's how BlockClosure>>= is implemented in VW: = aBlockClosure ^aBlockClosure class = self class and: [method = aBlockClosure method and: [outerContext = aBlockClosure outerContext and: [copiedValues = aBlockClosure copiedValues]]] Kind regards, Steffen
RO
Richard O'Keefe
Thu, Apr 13, 2023 10:17 AM

There is no agreement between Smalltalk systems about how to
compare block contexts for equality.  In Smalltalk-80 (and I
have two versions of Smalltalk-80 to compare), block equality
is identity.  The same in VisualAge Smalltalk 8.6.3.  The
same in GNU Smalltalk.  The same in Smalltalk/X-JV.
Squeak has a similar definition to  VW.
My reading of the ANSI standard is that it is carefully vague about this.

Equality of functions has been troublesome for decades.
Haskell: bans it.
Standard ML: bans it.
Some other ML-family languages: it's a run-time error.
Lisp family: varies.  Interlisp says nothing.  Scheme gives lower and upper
bounds.

Imagine a Smalltalk that recognises [<literal>] blocks and
allocates one static closure per <literal>.  Then
[true] == [true] hence [true] = [true] even when the two
<block constructor>s were in different methods.  The Squeak
and VW definitions would regard them as unequal.  (This is
on my TODO list, principally for [] [true] [false] and [0].)
For the special case of [], you don't have to imagine it.
If I'm reading VAST correctly, it treats "empty blocks"
specially.

If you rely on the definition of #= for block contexts/closures
you are almost certainly doing something dangerous.  You are
certainly doing something that is not portable.

On Thu, 13 Apr 2023 at 18:55, Steffen Märcker merkste@web.de wrote:

Hi!

In VisualWorks, blocks can be compared with each other. In Pharo the
comparison just checks for Identity. Is this on purpose? For reference,
that's how BlockClosure>>= is implemented in VW:

= aBlockClosure
^aBlockClosure class = self class and:
[method = aBlockClosure method and:
[outerContext = aBlockClosure outerContext and:
[copiedValues = aBlockClosure copiedValues]]]

Kind regards,
Steffen

There is no agreement between Smalltalk systems about how to compare block contexts for equality. In Smalltalk-80 (and I have two versions of Smalltalk-80 to compare), block equality is identity. The same in VisualAge Smalltalk 8.6.3. The same in GNU Smalltalk. The same in Smalltalk/X-JV. Squeak has a similar definition to VW. My reading of the ANSI standard is that it is carefully vague about this. Equality of functions has been troublesome for decades. Haskell: bans it. Standard ML: bans it. Some other ML-family languages: it's a run-time error. Lisp family: varies. Interlisp says nothing. Scheme gives lower and upper bounds. Imagine a Smalltalk that recognises [<literal>] blocks and allocates one static closure per <literal>. Then [true] == [true] hence [true] = [true] even when the two <block constructor>s were in different methods. The Squeak and VW definitions would regard them as unequal. (This is on my TODO list, principally for [] [true] [false] and [0].) For the special case of [], you don't *have* to imagine it. If I'm reading VAST correctly, it treats "empty blocks" specially. If you *rely* on the definition of #= for block contexts/closures you are almost certainly doing something dangerous. You are certainly doing something that is not portable. On Thu, 13 Apr 2023 at 18:55, Steffen Märcker <merkste@web.de> wrote: > Hi! > > In VisualWorks, blocks can be compared with each other. In Pharo the > comparison just checks for Identity. Is this on purpose? For reference, > that's how BlockClosure>>= is implemented in VW: > > > = aBlockClosure > ^aBlockClosure class = self class and: > [method = aBlockClosure method and: > [outerContext = aBlockClosure outerContext and: > [copiedValues = aBlockClosure copiedValues]]] > > Kind regards, > Steffen >
SM
Steffen Märcker
Thu, Apr 13, 2023 1:14 PM

Hi Richard!

You're completely right. Function equivalence is a beast and in the context of a computer program undecidable for nontrivial cases. And that's a valid reason to ban this entirely. Personally, I can also see some value in recognizing equality in trivial cases, e.g.,

  1. constant blocks: [ <same code> ] = [ <same code> ]
  2. pure functions: [:a1 ... | <same code> ] = [:a1 ... | <same code> ]
  3. enclosed constants: same as 1) and 2) but with references to variables that do not change after block creation.

If I am not mistaken VW 1) and 2) are considered clean blocks and 3) a copying block. For both equality is recognized if the bytecode is identical even if they are created in different contexts. Why do think VW regards them not equal? Do you mean another case or did I miss something? I did a short positive test in my VW 8.3 image.

Of course, one can have different opinions on the matter depending on the applications. I just wonder whether it was a conscious decision not to implement this in Pharo or just one of the thing that could be but haven't been done yet. And no, I do not rely on this functionality. I am just curious. ;-)

Kind regards,
Steffen

Richard O'Keefe schrieb am Donnerstag, 13. April 2023 12:17:05 (+02:00):

There is no agreement between Smalltalk systems about how to
compare block contexts for equality.  In Smalltalk-80 (and I
have two versions of Smalltalk-80 to compare), block equality
is identity.  The same in VisualAge Smalltalk 8.6.3.  The
same in GNU Smalltalk.  The same in Smalltalk/X-JV.
Squeak has a similar definition to  VW.
My reading of the ANSI standard is that it is carefully vague about this.

Equality of functions has been troublesome for decades.
Haskell: bans it.
Standard ML: bans it.
Some other ML-family languages: it's a run-time error.
Lisp family: varies.  Interlisp says nothing.  Scheme gives lower and upper bounds.

Imagine a Smalltalk that recognises [<literal>] blocks and
allocates one static closure per <literal>.  Then
[true] == [true] hence [true] = [true] even when the two
<block constructor>s were in different methods.  The Squeak
and VW definitions would regard them as unequal.  (This is
on my TODO list, principally for [] [true] [false] and [0].)
For the special case of [], you don't have to imagine it.
If I'm reading VAST correctly, it treats "empty blocks"
specially.

If you rely on the definition of #= for block contexts/closures
you are almost certainly doing something dangerous.  You are
certainly doing something that is not portable.

On Thu, 13 Apr 2023 at 18:55, Steffen Märcker merkste@web.de wrote:

Hi!

In VisualWorks, blocks can be compared with each other. In Pharo the
comparison just checks for Identity. Is this on purpose? For reference,
that's how BlockClosure>>= is implemented in VW:

= aBlockClosure
^aBlockClosure class = self class and:
[method = aBlockClosure method and:
[outerContext = aBlockClosure outerContext and:
[copiedValues = aBlockClosure copiedValues]]]

Kind regards,
Steffen

--
Gesendet mit Vivaldi Mail. Laden Sie Vivaldi kostenlos von vivaldi.com herunter.

Hi Richard! You're completely right. Function equivalence is a beast and in the context of a computer program undecidable for nontrivial cases. And that's a valid reason to ban this entirely. Personally, I can also see some value in recognizing equality in trivial cases, e.g., 1) constant blocks: [ <same code> ] = [ <same code> ] 2) pure functions: [:a1 ... | <same code> ] = [:a1 ... | <same code> ] 3) enclosed constants: same as 1) and 2) but with references to variables that do not change after block creation. If I am not mistaken VW 1) and 2) are considered clean blocks and 3) a copying block. For both equality is recognized if the bytecode is identical even if they are created in different contexts. Why do think VW regards them not equal? Do you mean another case or did I miss something? I did a short positive test in my VW 8.3 image. Of course, one can have different opinions on the matter depending on the applications. I just wonder whether it was a conscious decision not to implement this in Pharo or just one of the thing that could be but haven't been done yet. And no, I do not rely on this functionality. I am just curious. ;-) Kind regards, Steffen Richard O'Keefe schrieb am Donnerstag, 13. April 2023 12:17:05 (+02:00): There is no agreement between Smalltalk systems about how to compare block contexts for equality. In Smalltalk-80 (and I have two versions of Smalltalk-80 to compare), block equality is identity. The same in VisualAge Smalltalk 8.6.3. The same in GNU Smalltalk. The same in Smalltalk/X-JV. Squeak has a similar definition to VW. My reading of the ANSI standard is that it is carefully vague about this. Equality of functions has been troublesome for decades. Haskell: bans it. Standard ML: bans it. Some other ML-family languages: it's a run-time error. Lisp family: varies. Interlisp says nothing. Scheme gives lower and upper bounds. Imagine a Smalltalk that recognises [<literal>] blocks and allocates one static closure per <literal>. Then [true] == [true] hence [true] = [true] even when the two <block constructor>s were in different methods. The Squeak and VW definitions would regard them as unequal. (This is on my TODO list, principally for [] [true] [false] and [0].) For the special case of [], you don't *have* to imagine it. If I'm reading VAST correctly, it treats "empty blocks" specially. If you *rely* on the definition of #= for block contexts/closures you are almost certainly doing something dangerous. You are certainly doing something that is not portable. On Thu, 13 Apr 2023 at 18:55, Steffen Märcker <merkste@web.de> wrote: Hi! In VisualWorks, blocks can be compared with each other. In Pharo the comparison just checks for Identity. Is this on purpose? For reference, that's how BlockClosure>>= is implemented in VW: = aBlockClosure ^aBlockClosure class = self class and: [method = aBlockClosure method and: [outerContext = aBlockClosure outerContext and: [copiedValues = aBlockClosure copiedValues]]] Kind regards, Steffen -- Gesendet mit Vivaldi Mail. Laden Sie Vivaldi kostenlos von vivaldi.com herunter.
SM
Steffen Märcker
Thu, Apr 13, 2023 2:09 PM

I forgot:

Is there currently a good way to test whether a block is a copying block (in the VW meaning) in Pharo (11)? This means a block that:

  • Copies only variables not changing after block creation
  • Does not need the outer context for evaluation
    So far did not find an obvious way. It seems that a block always has a reference to its outer context. Variables in copiedValues are not modified after block creation if I understand the class comment correctly, but variables in tempVector can, right?

Best,
Steffen

Steffen Märcker schrieb am Donnerstag, 13. April 2023 15:14:16 (+02:00):

Hi Richard!

You're completely right. Function equivalence is a beast and in the context of a computer program undecidable for nontrivial cases. And that's a valid reason to ban this entirely. Personally, I can also see some value in recognizing equality in trivial cases, e.g.,

  1. constant blocks: [ <same code> ] = [ <same code> ]
  2. pure functions: [:a1 ... | <same code> ] = [:a1 ... | <same code> ]
  3. enclosed constants: same as 1) and 2) but with references to variables that do not change after block creation.

If I am not mistaken VW 1) and 2) are considered clean blocks and 3) a copying block. For both equality is recognized if the bytecode is identical even if they are created in different contexts. Why do think VW regards them not equal? Do you mean another case or did I miss something? I did a short positive test in my VW 8.3 image.

Of course, one can have different opinions on the matter depending on the applications. I just wonder whether it was a conscious decision not to implement this in Pharo or just one of the thing that could be but haven't been done yet. And no, I do not rely on this functionality. I am just curious. ;-)

Kind regards,
Steffen

Richard O'Keefe schrieb am Donnerstag, 13. April 2023 12:17:05 (+02:00):

There is no agreement between Smalltalk systems about how to
compare block contexts for equality.  In Smalltalk-80 (and I
have two versions of Smalltalk-80 to compare), block equality
is identity.  The same in VisualAge Smalltalk 8.6.3.  The
same in GNU Smalltalk.  The same in Smalltalk/X-JV.
Squeak has a similar definition to  VW.
My reading of the ANSI standard is that it is carefully vague about this.

Equality of functions has been troublesome for decades.
Haskell: bans it.
Standard ML: bans it.
Some other ML-family languages: it's a run-time error.
Lisp family: varies.  Interlisp says nothing.  Scheme gives lower and upper bounds.

Imagine a Smalltalk that recognises [<literal>] blocks and
allocates one static closure per <literal>.  Then
[true] == [true] hence [true] = [true] even when the two
<block constructor>s were in different methods.  The Squeak
and VW definitions would regard them as unequal.  (This is
on my TODO list, principally for [] [true] [false] and [0].)
For the special case of [], you don't have to imagine it.
If I'm reading VAST correctly, it treats "empty blocks"
specially.

If you rely on the definition of #= for block contexts/closures
you are almost certainly doing something dangerous.  You are
certainly doing something that is not portable.

On Thu, 13 Apr 2023 at 18:55, Steffen Märcker merkste@web.de wrote:

Hi!

In VisualWorks, blocks can be compared with each other. In Pharo the
comparison just checks for Identity. Is this on purpose? For reference,
that's how BlockClosure>>= is implemented in VW:

= aBlockClosure
^aBlockClosure class = self class and:
[method = aBlockClosure method and:
[outerContext = aBlockClosure outerContext and:
[copiedValues = aBlockClosure copiedValues]]]

Kind regards,
Steffen

--
Gesendet mit Vivaldi Mail. Laden Sie Vivaldi kostenlos von vivaldi.com herunter.

I forgot: Is there currently a good way to test whether a block is a copying block (in the VW meaning) in Pharo (11)? This means a block that: - Copies only variables not changing after block creation - Does not need the outer context for evaluation So far did not find an obvious way. It seems that a block always has a reference to its outer context. Variables in copiedValues are not modified after block creation if I understand the class comment correctly, but variables in tempVector can, right? Best, Steffen Steffen Märcker schrieb am Donnerstag, 13. April 2023 15:14:16 (+02:00): Hi Richard! You're completely right. Function equivalence is a beast and in the context of a computer program undecidable for nontrivial cases. And that's a valid reason to ban this entirely. Personally, I can also see some value in recognizing equality in trivial cases, e.g., 1) constant blocks: [ <same code> ] = [ <same code> ] 2) pure functions: [:a1 ... | <same code> ] = [:a1 ... | <same code> ] 3) enclosed constants: same as 1) and 2) but with references to variables that do not change after block creation. If I am not mistaken VW 1) and 2) are considered clean blocks and 3) a copying block. For both equality is recognized if the bytecode is identical even if they are created in different contexts. Why do think VW regards them not equal? Do you mean another case or did I miss something? I did a short positive test in my VW 8.3 image. Of course, one can have different opinions on the matter depending on the applications. I just wonder whether it was a conscious decision not to implement this in Pharo or just one of the thing that could be but haven't been done yet. And no, I do not rely on this functionality. I am just curious. ;-) Kind regards, Steffen Richard O'Keefe schrieb am Donnerstag, 13. April 2023 12:17:05 (+02:00): There is no agreement between Smalltalk systems about how to compare block contexts for equality. In Smalltalk-80 (and I have two versions of Smalltalk-80 to compare), block equality is identity. The same in VisualAge Smalltalk 8.6.3. The same in GNU Smalltalk. The same in Smalltalk/X-JV. Squeak has a similar definition to VW. My reading of the ANSI standard is that it is carefully vague about this. Equality of functions has been troublesome for decades. Haskell: bans it. Standard ML: bans it. Some other ML-family languages: it's a run-time error. Lisp family: varies. Interlisp says nothing. Scheme gives lower and upper bounds. Imagine a Smalltalk that recognises [<literal>] blocks and allocates one static closure per <literal>. Then [true] == [true] hence [true] = [true] even when the two <block constructor>s were in different methods. The Squeak and VW definitions would regard them as unequal. (This is on my TODO list, principally for [] [true] [false] and [0].) For the special case of [], you don't *have* to imagine it. If I'm reading VAST correctly, it treats "empty blocks" specially. If you *rely* on the definition of #= for block contexts/closures you are almost certainly doing something dangerous. You are certainly doing something that is not portable. On Thu, 13 Apr 2023 at 18:55, Steffen Märcker <merkste@web.de> wrote: Hi! In VisualWorks, blocks can be compared with each other. In Pharo the comparison just checks for Identity. Is this on purpose? For reference, that's how BlockClosure>>= is implemented in VW: = aBlockClosure ^aBlockClosure class = self class and: [method = aBlockClosure method and: [outerContext = aBlockClosure outerContext and: [copiedValues = aBlockClosure copiedValues]]] Kind regards, Steffen -- Gesendet mit Vivaldi Mail. Laden Sie Vivaldi kostenlos von vivaldi.com herunter.