I think this is the right direction. The primitive datatypes should have certain values defined to be falsy and the rest to be truthy. If I understand, APL seems to try to make every combination of operations make sense (not quite, but that's the feeling I get), so this is a good thing to preserve in KAP. Thus, in addition to primitive types, you need a way to judge the truthyness of n-dimensional arrays; the obvious way to do that is to either call an array false iff all its members are false or true off all its members are true. I would pick the first, since it matches primitive data types better, which usually make vast majority of their values truthy and have only one or two false values.
@philipwhite @kensanata@octodon.social @loke
From my personal experience with similar constructs and desiring natural implicit behavior I found that it can get rather confusing, that is in some expressions you expect the conjunction, and in others the disjunction.
Simplest example (pseudo code cause I don't know APL):
[1,2] = [1,3] - false with conjunction, true otherwise
[1,2] =/= [1,3] - true with disjunction, false otherwise
Not sure if an inequality check is a thing in KAP, but in general it can affect more complex logic expressions as well.
In other words for checking equality conjunction is natural, for inequality - disjunction.
One could also argue that there is so much more wrong here, and so many other intuitions break when doing this kind of implicit reduction that this small adjustment doesn't really matter, but that's just my 2 cents in trying to figure it out and make some use of it.
Yes, I understood the element-wise action, that's what I assume in my examples for both equality and inequality. The problem that in one case conjunctive reduction and in other case disjunctive reduction is natural comes from exactly that behaviour.
To illustrate in a more general algebraic sense: when reduced in same way (in contexts where that happens implicitly, like the if statement) expressions "A=/=B" and "A=B" can both result in false (or true in case of disjunction), reading "A is neither equal nor not-equal to B" (or "both equal and not-equal). Usually this screams "stop right there criminal scum!", but I killed the guard and explored this further, in my case having the operators return different types (called conjunctive_vector for = and disjunctive_vector for =/=) that would reduce in different ways.
There are still other issues (probably a lot of), for example "not(a=b)" can bypass the operator, assuming element-wise logical not, and result in similar pathological behaviour. Here perhaps the logical not should also flip the resulting type from conjunctive to disjunctive and vice versa, but in my case I just went with simpler approach of two distinct operators, one reducing and one element-wise (! and ~, in my case), mostly using the reducing one in logical expressions, unless feeling creative.
Note that all-zero case also differs because of this: the conjunction needs to be performed with an initial false value, and the disjunction - with a true value (similar to what you would do when implement these reductions with a basic for loop, or recursion).
@philipwhite @kensanata@octodon.social
@loke
To summarize all the ranting here, you need to keep track of the https://en.wikipedia.org/wiki/De_Morgan's_laws
@philipwhite @kensanata@octodon.social