Hi Tobia,

the quick answer is this. Suppose we have:

A / ¨ B.

The the parser does this:

read B (no pattern match)
read ¨ (no pattern match)
read /

At this point we could:
(i) take / to mean (function) compress, bind / to ¨ and finally try A (/¨) B, or
(ii) take / to mean (operator) reduce and try (A/)¯B.

Both interpretations (i) and (ii) are in accordance with the ISO standard and also with the IBM APL2 binding rules.
In the special case above (i) will always give a valence error but in general (e.g. user defined operator instead of ¨)
we cannot know. And instead of A there could be an arbitrarily complex left hand side which was the reason why I tried
to resolve the nature of / at ⎕FX time.

/// Jürgen



On 12/29/2014 12:59 PM, Tobia Conforto wrote:
Thanks.

I understand that there is a tradeoff involving run-time lookahead. It's still not entirely clear to me why simple cases would parse correctly, even with a user-defined symbol as the left argument (A/B) while applying an operator would break the parser (A/¨B). I'll have to study the parser to understand the issue.

In the meantime, I propose adding an explanation to the docs (see attached patch) since it's an implementation choice that differs from some other well-known APL interpreters.

Tobia


On Sun, Dec 28, 2014 at 7:43 PM, Juergen Sauermann <juergen.sauerm...@t-online.de> wrote:
Hi Tobia,

I have fixed the special case

    {(2|⍵) / ⍵} ⍳3

 that you reported, SVN 519.

There remains a handful of border cases related to / ⌿ \ and ⍀ caused by the ambiguity of these symbols
because, for example, function / parses differently than operator /.

In order to avoid lengthy and complicated run-time lookaheads of the left argument of / and friends,
GNU APL tries to resolve this ambiguity at ⎕FX time. This works well except if the left argument is a
user-defined symbol, say U. In that case the rule in GNU APL is that (U) is assumed to be a value
while U alone is assumed to be a function. Then U/ takes / as an operator (and U/ a derived function),
while (U)/ takes / as a function and (U) i.e. U its left argument.

Neither the ISO standard nor the APL2 manual provide enough information to cleanly resolve these border cases.
I have tried the "/ is always operator" approach earlier but it was breaking quite a few GNU APL testcases
so I decided not to follow it.

/// Jürgen



On 12/28/2014 05:12 PM, Tobia Conforto wrote:
Hello

Sorry for opening a new post above, I did not realize this was already being discussed here.

I'm far from being an APL expert, but I humbly believe the current behavior to be a bug. Consider this _expression_, where A and B are arrays (or scalars):

      A F / B

If F is a function, then / should perform N-wise reduction (ISO 13751 §9.2.3, shown being used without parentheses.) But if F is an array, then A F is a nested array and / should perform the replicate function (§10.2.5, again shown being used without parentheses.)

I'm not sure if the ambiguity inherent in the symbol / (and others) is mentioned anywhere in the standard. But I'm quite sure other APL implementations solve the issue by always treating / and other such symbols as operators.

When such an operator receives an array as the left operand it will perform replication; otherwise it will perform reduction.

This is also the only way an APL programmer may define a symbol like that, because a given name may only be defined to be either a function or an operator, not both.

Tobia


On Thu, Nov 27, 2014 at 10:56 AM, Jay Foad <jay.f...@gmail.com> wrote:
Hi Jürgen,

Thanks for doing the analysis.

> 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.

I don't understand this bit. Monadic operators don't bind like this in APL2.

 Surely the way to get APL2 behaviour is:
- never downgrade / to a function
- introduce an A M pattern to allow operators to have arrays as left operands

Jay.





Reply via email to