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?
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 ≠ - ┌┴┐
⊢ /