PUBKAR - parentheses not always first 
Author Message
 PUBKAR - parentheses not always first

A little puzzle:

self blowUp: Transcript cr reallyGood: (Transcript show: 'parens')

Should the #cr or the #show: happen first?  The answer is that the #cr is
first.  Putting parenthesis around the #show: (necessary in this case)
doesn't cause it to be evaluated first, as people quoting 'PUBKAR'
precedence order might think.  The answer seems obvious to me, but I find
it hard to explain my reasoning.  I'd say something like "At the highest
level, it's a keyword message, and its arguments are evaluated left to
right, as if you go through PUBKAR backwards and decide first what to do
last...".  Perhaps someone could quote the spec.

How about this:

| i |
i := 2.
3 between: i and: (i := 4)

Should the answer be true or false?

VAST 5.5.2 and VSE 3.1.1 answer true.  VW5i4 answers false, whether this
is done in a workspace or in a method, UNLESS you step through it with a
de{*filter*} where the answer will be true.  Interesting.
--
Wayne Johnston



Tue, 18 Jan 2005 21:44:50 GMT  
 PUBKAR - parentheses not always first

Quote:

> Perhaps someone could quote the spec.

According to ANSI, section 3.4.5.3 "Messages":

------------
All message arguments are also references to objects, represented
in the same way as the receiver. The receiver and the arguments
are evaluated before the message is sent. They are evaluated in
a left-to-right order.
------------

    -- chris



Tue, 18 Jan 2005 22:37:55 GMT  
 PUBKAR - parentheses not always first

Quote:


> > A little puzzle:

> > self blowUp: Transcript cr reallyGood: (Transcript show: 'parens')

> > Should the #cr or the #show: happen first?  The answer is that the #cr is
> > first.  Putting parenthesis around the #show: (necessary in this case)
> > doesn't cause it to be evaluated first, as people quoting 'PUBKAR'
> > precedence order might think.  The answer seems obvious to me, but I find
> > it hard to explain my reasoning.  I'd say something like "At the highest
> > level, it's a keyword message, and its arguments are evaluated left to
> > right, as if you go through PUBKAR backwards and decide first what to do
> > last...".  Perhaps someone could quote the spec.

> In Section 2.4.5.3 (of the Draft I have) of the ANSI Standard:

> "A <messages> clause can be made up of multiple message sends.
>  The order of evaluation of the message sends are defined by the
>  following precedence rules:.  Sequences of <unary message>
>  clauses are evaluated left to right. The result of each message
>  becomes the receiver to the <unary message> to its immediate
>  right.  Sequences of <binary message> clauses are also evaluated
>  strictly left to right. The <binary argument> of a <binary
>  message> is evaluated before performing the binary message send.
>  The result of each binary message becomes the receiver for the
>  <binary message> to its immediate right. The <keyword argument>
>  clauses of a <keyword message> are evaluated left to right.
>  The final message send of a <messages> clause is its <keyword
>  message>."

Umm,  This does not say anything about parens.

- Show quoted text -

Quote:

> > How about this:

> > | i |
> > i := 2.
> > 3 between: i and: (i := 4)

> > Should the answer be true or false?

> > VAST 5.5.2 and VSE 3.1.1 answer true.  VW5i4 answers false, whether this
> > is done in a workspace or in a method, UNLESS you step through it with a
> > de{*filter*} where the answer will be true.  Interesting.

> Argh!  This is a code generator bug in the VW engine.
> It goes back to at least 3.0.  Thank you!
> --
> _______________,,,^..^,,,____________________________
> Eliot Miranda              Smalltalk - Scene not herd



Wed, 19 Jan 2005 03:12:16 GMT  
 PUBKAR - parentheses not always first
[...]

Quote:

> | i |
> i := 2.
> 3 between: i and: (i := 4)

> Should the answer be true or false?

Funny! The following variation returns "true":

| i |
i := 2.
^ 3 between: (i := i) and: (i := 4)



Wed, 19 Jan 2005 03:29:59 GMT  
 PUBKAR - parentheses not always first
The old rule you learned in math classes
and repeated in all your programming language classes
is *wrong*: compilers built according to the usual techniques don't do this.
Within any subexpression,
evaluation proceeds left to right across equivalent precedence levels.
When different precedence levels are encountered,
evaluation will be deferred as long as the rightward precedence is higher.
When the rightward precedence is no longer higher,
evaluation will proceed backwards until the rightward precedence is higher.
Parentheses delimit a new subexpression,
which defers all pending evaluation until the subexpression is complete,
but compilers do not seek out parenthesized expressions first:
they evaluate them as they are encountered from left to right.

In stateless mathematics, the "evaluate parens first" rule works.
In programming languages, especially stateful languages like Smalltalk,
using the "math class" rule can lead to erroneous expectations.
If you send multiple state-changing messages to the same object,
or if you do embedded assignments,
you might be in for trouble if you use the "math class" rule.
However, trouble usually only arrives in complex expressions.
Few people write expressions as complex as
3 between: i and: (i := 4).
I am one such person,
and if VW answers false to this expression when i is initially 2,
that's a bug that needs to be fixed.

Steve
--
Steven T Abell
Software Designer
http://www.*-*-*.com/

In software, nothing is more concrete than a good abstraction.

Quote:

> A little puzzle:

> self blowUp: Transcript cr reallyGood: (Transcript show: 'parens')

> Should the #cr or the #show: happen first?  The answer is that the #cr is
> first.  Putting parenthesis around the #show: (necessary in this case)
> doesn't cause it to be evaluated first, as people quoting 'PUBKAR'
> precedence order might think.  The answer seems obvious to me, but I find
> it hard to explain my reasoning.  I'd say something like "At the highest
> level, it's a keyword message, and its arguments are evaluated left to
> right, as if you go through PUBKAR backwards and decide first what to do
> last...".  Perhaps someone could quote the spec.

> How about this:

> | i |
> i := 2.
> 3 between: i and: (i := 4)

> Should the answer be true or false?

> VAST 5.5.2 and VSE 3.1.1 answer true.  VW5i4 answers false, whether this
> is done in a workspace or in a method, UNLESS you step through it with a
> de{*filter*} where the answer will be true.  Interesting.
> --
> Wayne Johnston



Wed, 19 Jan 2005 04:59:50 GMT  
 PUBKAR - parentheses not always first
[snip to the good bits]

Quote:
> | i |
> i := 2.
> 3 between: i and: (i := 4)

> Should the answer be true or false?

> VAST 5.5.2 and VSE 3.1.1 answer true.  VW5i4 answers false, whether this
> is done in a workspace or in a method, UNLESS you step through it with a
> de{*filter*} where the answer will be true.  Interesting.

Here are the bytecodes for that Doit (wrap it in square brackets,
inspect it, and click "byte codes"):

normal CompiledBlock numArgs=0 numTemps=1 frameSize=12
literals: (#between:and: )
1 <4B> push 2
2 <4C> store local 0; pop
3 <D8 03> push 3
5 <10> push local 0
6 <D8 04> push 4
8 <4C> store local 0; pop
9 <10> push local 0
10 <CC 40> no-check send between:and:
12 <65> return

My guess is the 5i.4's VM has a native code generation problem with
bytes 8 and 9.  By the way, you don't actually have to debug the
method; inserting "self halt" at the beginning and pressing proceed
causes the same problem.  Probably because proceed has to complete the
current frame by simulation.

Could someone knowledgeable at Cincom please dump the generated native
code to this newsgroup?  Although this particular case isn't common,
the bug may be more general, such as (1) missed conditions in the data
dependency graph, or (2) an invalid peephole optimization.  Any
takers?

Upon further testing, the following code does *not* exhibit the same
problem:

| i |
i := 2.
i < (i := 4)

Here's what I think is happening.  Intermediate virtual registers are
allocated to hold the arguments to the call:

...
vr1 := vrLocalI.
...assign 4 to local i...
vr2 := vrLocalI.   ;because of the way "store;pop, push" works
call #< with (vr1, vr2)
...

Next, registers with moves between them are collapsed out, but due
care is not taken with (vr1,vrLocalI).  This move should not be
collapsed because the source of the move is modified before the target
of the move is used.  See "Modern Compiler Implementation in Java" by
Andrew Appel, chapter 10, the section titled "Interference Graphs" (p.
231-233 in first edition).



Wed, 19 Jan 2005 06:32:45 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. less parentheses --> fewer parentheses

2. less parentheses --> fewer parentheses

3. Dangling Closing Parentheses vs. Stacked Closing Parentheses

4. Parentheses not balanced error on this regsub - why?

5. Not always updating

6. Formula Not Always Formulating

7. event:columnresize not always generated

8. Index causes GPF error, but not always

9. Help IDLE.OBJ does not always work!!!!!!

10. Values not always updating on front panel

11. Why does it work sometimes but not always?

12. logo-l not always posting to comp.lang.logo

 

 
Powered by phpBB® Forum Software