Reduce by two with named function

94 views Asked by At

I'm using GNU APL. Also, I'm not really sure what the correct name for this is, but the basic idea is that I have a list of things and I want to do something with each pair. It's complex, so I've made a function for it. I notice that this works:

      2+/1 2 3 4 5
┌→──────┐
│3 5 7 9│
└───────┘

I can even use an anonymous lambda to do the same thing:

      2{⍺+⍵}/1 2 3 4 5
┌→──────┐
│3 5 7 9│
└───────┘

However, it doesn't seem to work if I give that function a name:

      ∇R←X FOO Y
         R←X+Y
      ∇

      2FOO/1 2 3 4 5
SYNTAX ERROR
μ-Z__pA_LO_REDUCE_X4_B[3]  μ-T←⊂(⊃μ-B3[μ-H;μ-a-μ-M;μ-L])μ-LO⊃μ-T
                           ^    ^

Spacing differently doesn't seem to have any particular effect. Also, I'm not really able to see the relationship between the error message I got and what I typed in, so any insight into what is going on there would be very helpful to me. Thanks!

2

There are 2 answers

1
Fred Weigel On BEST ANSWER

It works with the current GNU APL (1.7, svn 1013).

      ∇r←x foo y
[1] r←x + y
[2] ∇
      2 foo / 1 2 3 4
3 5 7
3
Jürgen Sauermann On

as to the insight:

If you call a primitive operator (like /) with a defined function argument (like FOO) then GNU APL does not evaluate the built-in primitive operator but a built-in macro.

The μ- prefix that you see (and which was never meant to be seen in the first place) distinguishes names in built-in macros from user-defined names. If you remove the y- prefix then the error message that you see becomes a little more readable:

Z__pA_LO_REDUCE_X4_B[3] T←⊂(⊃B3[H;a-M;L])LO⊃T

So you got a syntax error in line 3 of (APL macro) Z__pA_LO_REDUCE_X4_B. The source file Macro.def in the GNU APL sources then tell you the full story:

/// reduce N-wise: Z←A LO/[X] B with positive A
//
mac_def(   Z__pA_LO_REDUCE_X4_B,
" Z←A1 (LO Z__pA_LO_REDUCE_X4_B) [X4] B;rho_B3;B3;rho_Z;rho_Z3;T;H;M;L;a;N;I;I_max\n"
" (X4 rho_Z rho_Z3 rho_B3)←X4 ◊ B3←rho_B3⍴B ◊ I_max←⎕IO+⍴I←,⍳⍴Z←(rho_Z3)⍴0 ◊ N←⎕IO\n"
"LOOPN: (H a L)←⊃I[N] ◊ M←A1+1 ◊ T←B3[H;a-A1;L]\n"
"LOOPM: T← ⊂(⊃B3[H;a-M;L]) LO ⊃T ◊ →(0≥M←M+1)⍴LOOPM\n"
"       Z[H;a;L]←T               ◊ →(I_max>N←N+1)⍴LOOPN\n"
" Z←rho_Z⍴Z\n")

In short: mac_def() is a C++ macro that establishes a defined APL system function which uses a "namespace" μ- to avoid name-clashes with user defined names.