This ambiguity does not arise in APL2. The A (O P) B parsing is invalid
because an operator (O) can't be the operand of another operator (P).

Jay.

On Sat, 28 Nov 2020, 12:59 Dr. Jürgen Sauermann, <mail@jürgen-sauermann.de>
wrote:

> Hi Hans-Peter,
>
> this kind of surprises has puzzled me since the early days of APL.
> They already existed in APL1 but never occurred in practice since
> the number of constructs affected, for instance +//'ABC'  was small
> and did not make much sense at that time.
>
> The proliferation of operators in APL2 then not only increased the
> number of affected constructs but also included constructs that could
> make sense. Your examples are instances of these constructs.
>
> In C/C++ the order in which functions/operators are evaluated is
> unambiguously defined by two attributes of each operator: its precedence
> and its associativity. The precedence defines in which order different
> groups
> of operators (like × or ÷ versus + or -) are computed while the
> associativity
> defines the order (like left-to-right or right-to-left) in which operators
> with
> the same precedence are computed.
>
> In APL, however, the situation is rather different. The ISO standard
> indirectly
> specifies the well-known right-to-left evaluation of APL expressions, but
> does
> not specify an order when it comes to APL functions versus APL operators.
> Hybrids like /, ⌿, \, and ⍀ make matters even worse. IBM APL2 is more
> specific
> about that by essentially defining that:
>
> (1)  /, ⌿, \, and ⍀ are (monadic) operators (even though their (single)
> left argument could
>     be a value), and
>
> (2) arguments of operators bind stronger than arguments of functions.
>
> (3) the left operand of an operator can be a value or  a function,
>
> Although these rules determine the order of evaluation in most cases they
> do not,
> at least as I understand the matter, catch all cases. The missing piece is
> how two
> handle the pattern A O P B where A and B are values and O and P are monadic
> operators (of which O allows a value as left argument). This pattern has
> two
> valid evaluations:
>
> (A O) P B and A (O P) B
>
> The first evaluation binds A to O, the derived function (A O) is then
> bound to P,
> giving another derived function ((A O) P) which is then evaluated with
> argument B.
>
> The second evaluation binds O to P, and the derived function (O P) is then
> evaluated with arguments A and B.
>
> As already mentioned this this can only occur if an operator allows a
> value as left
> argument, which is fortunately only the case for a few pathological
> operators,
> (in particular /, ⌿, \, and ⍀).
>
> I have tried to explain this in earlier versions of the GNU info manual,
> but have removed
> it recently due to a somewhat incorrect and misleading wording in the
> manual.
>
> With the above explanation in mind, I believe that GNU APL behaves
> correctly even
> though a different behaviour (with unfortunately different resuilts) would
> be equally correct.
>
> You can, BTW,  watch the GNU parser at work by enabling logging facility
> 32 (note
> that the program counter PC of the virtual APL machine counts from right
> to left).
>
>
>
> *      ]LOG 32       1 2 3 / ¨ 'ABC'*
>
> *changed to Prefix[si=2]) ============================================*
> *    [si=2 PC=0] Read token[0] (←0←) VALUE1«≡⊏3⊐ABC» TC_VALUE*
> *fifo[si=2 len=1 PC=1] is now : TC_VALUE  at Prefix.cc:564*
> *    [si=2 PC=1] Read token[1] (←0←) ¨ TC_OPER1*
> *fifo[si=2 len=2 PC=2] is now : TC_OPER1 TC_VALUE  at Prefix.cc:564*
> *    [si=2 PC=2] Read token[2] (←0←) / TC_OPER1*
> *fifo[si=2 len=3 PC=3] is now : TC_OPER1 TC_OPER1 TC_VALUE  at
> Prefix.cc:564*
> *   phrase #297: M M matches, prio 42, calling reduce_M_M__()*
> *   reduce_M_M__() returned: RA_CONTINUE*
> *fifo[si=2 len=2 PC=3] is now : TC_FUN12 TC_VALUE  at Prefix.cc:564*
> *    [si=2 PC=3] Read token[2] (←0←) VALUE3«≡⊏3⊐1 2 3» TC_VALUE*
> *fifo[si=2 len=3 PC=4] is now : TC_VALUE TC_FUN12 TC_VALUE  at
> Prefix.cc:564*
> *   phrase #234: A F B matches, prio 33, calling reduce_A_F_B_()*
> *   reduce_A_F_B_() returned: RA_CONTINUE*
> *fifo[si=2 len=1 PC=4] is now : TC_VALUE  at Prefix.cc:564*
> *    [si=2 PC=4] Read token[1] (←0←) ENDL TC_END*
> *fifo[si=2 len=2 PC=5] is now : TC_END TC_VALUE  at Prefix.cc:564*
> *   phrase #46: END B matches, prio 2, calling reduce_END_B__()*
> * A BB CCC *
> *   reduce_END_B__() returned: RA_PUSH_NEXT*
> *    [si=2 PC=5] Read token[0] (←0←) RETURN_STATS TC_RETURN*
> *fifo[si=2 len=1 PC=6] is now : TC_RETURN  at Prefix.cc:564*
> *   phrase #13: RETC matches, prio 1, calling reduce_RETC___()*
> *- end of ◊ context*
> *   reduce_RETC___() returned: RA_RETURN*
> *Prefix::reduce_statements(si=2) returned VOID in StateIndicator::run()*
> *      1 2 3 / ¨ 'ABC'*
>
> Finally, if you need GNU APL to behave differently, then you can
> enforce a different order by means of { and }, similar to ( and ) for
> values.
>
> The default behaviour of GNU APL is this:
>
> *       1 2 3 /¨ 'ABC'*
> *   ⍝  / bound to ¨ ** A BB CCC *
>
> which corresponds to pattern A (O P) B above. If you prefer (A O) P B
> instead,
> then you can do this:
>
> *      {1 2 3/⍵} ¨ 'ABC'   ⍝ 1 2 3 bound to /*
>
>
> * AAAAAA BBBBBB CCCCCC *which corresponds to pattern (A O) P B above.
> This is almost as easy as
> using parentheses for values.
>
> Best Regards,
> Jürgen
>
>
>
> On 11/26/20 1:28 PM, Hans-Peter Sorge wrote:
>
> Hi,
>
> I thought so, APL is fun:-)
>
> The following 4 expressions are just a repeat:
> ⍝1 - a vector replicates a scalar. The result is a simple vector
>      1 2 3/'A'
> AAAAAA
>
> ⍝2 - scalar by scalar - simple vector as result
>       1 2 3/'ABC'
> ABBCCC
>
> ⍝3 - as in ⍝1 but  for each scalar  a vector replicates a scalar. The
> result is a nested vector of simple vectors
>       (⊂1 2 3)/¨'ABC'
>  AAAAAA BBBBBB CCCCCC
>
> ⍝4 - is consistent with ⍝2  the each-operator introduces one level of depth
>       1 2 3/¨'ABC'
>  A BB CCC
>
> The next result would be "surprising" to me as it is somewhere between 2
> and 3 and logic asside, "feels" inconsistent:
> ⍝4
> ⍝      1 2 3/¨'ABC'
> ⍝ AAAAAA BBBBBB CCCCCC
>
>
> Going a little further. The simple vector 'ABC' is being turned into a
> nested vector.
> ⍝5,6
>       1 2 3/,¨'ABC'
>  A B B C C C
>       1 2 3/∊¨'ABC'
>  A B B C C C
>
> ⍝9 - scalar applied to simple vector
>       2/'ABC'
> AABBCC
>       2/¨'ABC'
>  AA BB CC
>
> ⍝ 10  -  as expected having a nested vector:
>        2/,¨'ABC'
>  A A B B C C
>
> Here comes my irritation. Or some missing knowledge ....
> ⍝ 11 - if this is true ( from ⍝3 )
>      (⊂1 2 3)/¨'ABC'
>  AAAAAA BBBBBB CCCCCC
>
> ⍝ 12 - then this schould be different
>       (⊂1 2 3)/¨,¨'ABC'
>  AAAAAA BBBBBB CCCCCC
> ⍝ expected
>   A AA AAA  B BB BBB  C CC CCC
>
>
> ⍝ 13 - instead of domain error ..
>       (⊂1 2 3)/'ABC'
> DOMAIN ERROR
>       (⊂1 2 3)/'ABC'
>       ^       ^
> ⍝ the result could be
> AAAAAABBBBBBCCCCCC
>
> ⍝ 14 - like in case of a simple vector, the nested vector results are
> accordingly:
>       1 2 3/'AA' 'BB' 'CC'
>  AA BB BB CC CC CC
>
> ⍝like ⍝4
>        1 2 3/¨'AA' 'BB' 'CC'
>  AA BBBB CCCCCC
>
> ⍝ 15 - and , analogous to 12
>       (⊂1 2 3)/¨'AA' 'BB' 'CC'
> LENGTH ERROR
>       (⊂1 2 3)/¨'AA' 'BB' 'CC'
>       ^        ^
> ⍝ could then be
>   AA  AA AA  AA AA AA   BB  BB BB  BB BB BB   CC  CC CC  CC CC CC
>
> Just my thoughts..
>
> Best Regards
> Hans-Peter
>
>
> Am 24.11.20 um 17:17 schrieb Dr. Jürgen Sauermann:
>
> Hi Adam,
>
> thanks, see below.
>
> Best Regards,
> Jürgen
>
>
> On 11/23/20 11:07 PM, Adám Brudzewsky wrote:
>
> For the sake of compatibility with IBM APL2
>
>
> Speaking of which, what is GNU APL's official policy?
>
> GNU APL's general policy regarding standards and the like is to consider,
> (in that order):
>
> 1. the IBM APL2 language reference manual,
> 2. the IBM APL2 implementation (PC demo version, can't aford the
> commercial version),
> 3. the ISO standard,
> 4. other APL implementations and suggestions from bug-apl@gnu.org.
>
> Sometimes, however, this can have undesirable consequences and then
> some sort of common sense is applied to change the order.
>
> I noticed that the info manual (
> https://www.gnu.org/software/apl/apl.html#APL-symbols-that-can-be-functions-or-operators)
> is factually wrong about APL2, claiming that:
>
>> the ambiguity related to / ⌿ \ and ⍀ is not resolved by these rules.
>>
> I see. That statement is probably a left-over from the early days of GNU
> APL. When I started
> with GNU APL, all I had was some vague recollection of APL1 from the 1970s
> (my first APL
> computer was an IBM 5110 desktop, a precursor of the IBM PC). At that time
> functions were
> functions and values were values. At some later time, triggered by the
> ⍤-operator (which was
> not implemented in IBM APL2 but defined in ISO), I changed to the APL2 way
> of handling /
> and \.
>
> I have updated the documentation, *SVN 1363*.
>
> The APL2 language reference does in fact make it perfectly clear how / and
> friends are treated, namely as operators. Always. Note:
>
>> [image: image.png]
>>
> And then:
>
>> [image: image.png]
>>
> Note that this makes APL2 ISO non-compliant. Indeed, here, GNU APL follows
> Dyalog and NARS2000:
>       1 2 3/¨'ABC'
>  A BB CCC
> While APL2 and APLX give:
>       1 2 3/¨'ABC'
>  AAAAAA BBBBBB CCCCCC
> This is because 1 2 3/ is a derived monadic function and ¨ maps the
> entire function to each letter.
>
> I believe older GNU APL versions would have given the APL2/APL X results,
> while newer versions
> give the other result. This is one of the examples where the general GNU
> APL policy is not being
> followed. If an incompatibility with APL2 exists long enough with no
> complaints from the users,
> then I believe backward compatibility with GNU APL is more important than
> compatibility with IBM
> APL2.
>
> On Mon, Nov 23, 2020 at 9:21 PM Dr. Jürgen Sauermann <
> mail@jürgen-sauermann.de> wrote:
>
>> Hi Kacper, Adam,
>>
>> thanks. For the sake of compatibility with IBM APL2 I have changed *⎕UCS*
>> so that
>> it accepts float and complex numbers that are near to integers.  My
>> initial thinking was
>> that e.g.* ⎕UCS* of a complex number is most likely a programming
>> mistake so
>> that a DOMAIN ERROR would be more helpful than being a burden. But APL2
>> compatibility is an even stronger argument in this case.
>>
>> I have also adjusted the integer domain which is now -$80 ... $7FFFFFFF
>> so that no conflicts with signed bytes from *⎕FIO *should arise.
>>
>> *SVN 1362*.
>>
>> Best Regards,
>> Jürgen
>>
>>
>>
>> On 11/22/20 11:11 PM, Kacper Gutowski wrote:
>>
>> On Sun, Nov 22, 2020 at 03:19:19PM +0100, Dr. Jürgen Sauermann wrote:
>>
>> Floating point and complex numbers are not allowed as to avoid
>> interference with ⎕CT (i.e. how should rounding be performed?).
>>
>>
>> I share your sentiment regarding the upper bound of the ⎕UCS domain, but
>> throwing a domain error on ⎕UCS1E2 looks like a bug to me too.  1E2 is
>> clearly an integer regardless of the implementation details, and I would be
>> surprised if APL2 didn't accept it.  I would expect rounding to be the same
>> as in all the other places that require near-integers, like array indices.
>>
>> The negative ones are also a bit weird.  I wasn't aware of their
>> existence, and they seem to work in surprising ways when passed to various
>> variants of ⎕CR.
>>
>> -k
>>
>>
>>
>
>
>

Reply via email to