[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-apl] Bug in the parser?

From: Elias Mårtenson
Subject: Re: [Bug-apl] Bug in the parser?
Date: Wed, 26 Nov 2014 23:38:22 +0800

Hello Jürgen and thanks for the explanation.

Based on what you just explained, I would have assumed the following to work?

      m (/⍨) 2 = +/[1] 0 = m ∘.| m←⍳N

But this variation works?

      m (/⍨) (2 = +/[1] 0 = m ∘.| m←⍳N)
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97


On 26 November 2014 at 21:45, Juergen Sauermann <address@hidden> wrote:
Hi again,

I have analyzed this a bit further. Below are my conclusions.

1. Problem description

Elias' initial question can be reduced to this: Given APL values A and B, say

      A←1 2 3 4 5 and
      B←1 1 0 1 0

how shall the  following expressions be evaluated:

      A /⍨ B
      A (/⍨) B
      (A) /⍨ B

The matter is a bit complicated by the ambiguity of the / token:

For historical reasons the token / is ambiguous and could mean the dyadic function compress or
the monadic operator reduce. GNU APL resolves this ambiguity at ⎕FX time when possible. For example,
in 1 2 3 / B the operator / is  "downgraded" from 
"operator reduce" to "function compress" because 1 2 3 is a value
and therefore only function compress makes sense. However in A / B it is not known at ⎕FX time whether A is a function
or a value. In that case a symbol is assumed to be a function (and hence / an operator) while something in parentheses like
(A) is assumed to be a value. That is the reason why A / B gives a syntax error while (A) /⍨ B does not. IBM APL2 also
downgrades / from operator reduce to function compress, but at a later time.

The behavior of IBM APL2 in that special case is somewhat sub-optimal because insisting in / being an operator even
if it is obviously not leads to the following inconsistency:


      1 (+¨) 1
      1 (/¨) 1


      1 (+¨) 1
      1 (/¨)1

2. Alternatives

I have tested what happens if we would introduce a M M pattern into GNU APL in order to
get IBM APL2's behavior. In the above examples (I used ¨ instead of Elias' original ⍨ because ¨ is
present in IBM APL2 while ⍨ is not). (+¨) is reduced by a pattern F M (function monadic-operator) to a
derived function. In contrast 
(/¨) is not reduced because there is no M M pattern (except in the cases where
/ was downgraded). The M M is shifted  rather than reduced and the first F in a sequence F M M ... causes
the whole chain to be unrolled from left to right, This is the difference that Jay has observed between IBM APL2
and the others.

Adding a M M rule forces the parser to reduce M M immediately rather than shifting it. After doing that, a few regression
testcases did fail. Looking at the test results my impression was that the current behavior of GNU APL is the preferred one.

3. Conclusion

My conclusion so far is that we should leave things as they are.

Putting things in parentheses is, in my opinion, not such a bad thing and it makes programs more explicit and more portable.

When choosing between:

      A (/⍨) B and
      (A) /⍨ B

I would recommend the former because that expresses better what is desired and the latter may change at some point in time.

/// Jürgen

On 11/25/2014 04:01 PM, Juergen Sauermann wrote:
Hi Jay,

yes, what I meant is that / is called like a dyadic function as in 1 1 1 / 1 2 3.

But handling it always like an operator could be a better solution.
Currently in GNU APL operators are distinguished from functions which works well
except for / and friends which are parsed as function in some contexts and parsed as operator in others.

I will look into changing this to making operators accept a non-function left argument.

/// Jürgen

On 11/25/2014 03:33 PM, Jay Foad wrote:
On 25 November 2014 at 14:06, Jay Foad <address@hidden> wrote:
On 25 November 2014 at 13:38, Juergen Sauermann
<address@hidden> wrote:
I have read the IBM binding rules a number of times but they seem not to
help. The problem of these rules is
that they give different results in the cases where / is an operator and
where / is a function.
In IBM APL2 / is always an operator.
For example:

      1 2/¨3 4 ⍝ GNU APL, NARS2000 and Dyalog: parse as 1 2(/¨)3 4
 3  4 4

     1 2/¨3 4 ⍝ APL2: parse as (1 2/)¨3 4
 3 3 3  4 4 4


reply via email to

[Prev in Thread] Current Thread [Next in Thread]