functionapldyalog

# Two APL functions give different results, but their boxing is identical

I am trying to create an APL function which returns differences (non-identical items with identical index) between two vectors. I have come up with the following and it works fine, subtracting two vectors and discarding zeroes from the result:

``````func ← {((⍺-⍵)≠0)/(⍺-⍵)}
``````

However, I was not satisfied with repeating the `(⍺-⍵)` part, so I optimized it a little:

``````func ← {(⍺ (0≠-) ⍵) / (⍺-⍵)}
``````

That also works (`(1 2 3 4) func (4 2 0 4)` returns `-3 3`, as expected), so I went ahead:

``````func ← {⍺ ((0≠-)/-) ⍵}
``````

And that, in fact, does not work for vectors longer than one element. It just returns `1` whenever there is a difference, without showing how big it is (`(1 2 3 4) func (4 2 0 4)` now returns `1`). Why?

I checked the problematic function both in https://tryapl.org editor and in a local environment - neither works.
I checked the composition rules again - I tried to use the one saying that `⍺ (f g h) ⍵` and `(⍺ f ⍵) g (⍺ h ⍵)` are equivalent, where in my case:

• `f` is the `(0≠-)` train,
• `g` is the compression function `/`,
• `h` is the subtraction funcion `-`.

Perhaps the most peculiar thing for me - I checked the boxing of two functions. It's identical!

``````⍝ the working function
⍝ func ← {(⍺ (0≠-) ⍵) / (⍺-⍵)}

]boxing on
((0≠-))/(-)
┌───────────┬─┐
│┌───────┬─┐│-│
││┌─┬─┬─┐│/││ │
│││0│≠│-││ ││ │
││└─┴─┴─┘│ ││ │
│└───────┴─┘│ │
└───────────┴─┘
``````
``````⍝ the "broken" function
⍝ func ← {⍺ ((0≠-)/-) ⍵}

]boxing on
((0≠-)/-)
┌───────────┬─┐
│┌───────┬─┐│-│
││┌─┬─┬─┐│/││ │
│││0│≠│-││ ││ │
││└─┴─┴─┘│ ││ │
│└───────┴─┘│ │
└───────────┴─┘
``````

It's also identical in tree mode and parentheses mode.

What happened? Am I not allowed to nest trains? Did I get my composition parameters wrong? Did I make a typo while checking the boxings?

Solution

• I think your problem is that `/` wants to be an operator in a train. You have to coerce it into its function form:

``````  1 2 3 4 ((0≠-)⊢⍤/-) 4 2 0 4
┌→───┐
│¯3 3│
└~───┘
``````

The `⊢⍤/` might be weird-looking, but it's the "slash-as-function" pattern to commit to memory when using trains.

Note the difference:

``````  (0≠-)/-
┌┴┐
/ -
┌─┘
┌─┼─┐
0 ≠ -

(0≠-)⊢⍤/-
┌────┼─┐
┌─┼─┐  ⍤ -
0 ≠ - ┌┴┐
⊢ /
``````