(In)consequence of hyperized comparison

Is it a bug? Hmm .. it may be a feature. But an undocumented one, and I think it would be wise to remedy at least the latter.

How this issue originated
I’ve been working on a DEEP KEEP block, and this is what I encountered:

I was puzzled, as one of the OR-block’s arguments reports true. if the order of the arguments is changed, the result is different:


IMAO that’s at least pretty strange: the result of an OR-block being dependent on the order of its arguments (other than in obvious cases, such as: 1. evaluating an argument causes side-effects influencing the evaluation of the other argument, or 2. evaluating one of the arguments, regardless of the other’s value, causes unbounded recursion).

User analysis
I did some analysis and discovered the root cause: LIBRARY OF recursion script pic 5

This comparison doesn’t report true or false but ( false ), that is a list with false as its one item. Then the OR-block reports: ( false ) OR true := ( true ). But when the order of the arguments is reversed, it reports: true OR [unevaluated] := true.

To even complicate things, when ( true ) is used as 1st argument in a command-IF block, it is considered true, just like any other list, AFAIK. So in this case, untypically:

… reports differently from:

… reports the same as:

So what?
I expect @bh wiil confirm it’s kinda weird, and he will talk to @jens, who will rebuff it’s all working according to specification. :smirk:

I don’t have a technical solution up my sleeve either (except abolishing the hyperization of comparisons). My suggestion is to document this “feature” for users: reference manual, on-line block help, etc.

This happens due to hyper-blocks. If you disable hyper-blocks via Shift-clicking the gear icon on the top, the same input gives true, not (true).
Also, (false) is considered true.

It's probably caused by a short-circuited evaluation that does not trigger hyper operation for the scalar argument
untitled script pic - 2024-01-08T014347.667
untitled script pic - 2024-01-08T014350.864
untitled script pic - 2024-01-08T014620.846

This is indeed intended, although I'm confused about keep items not accepting a list. Yes, I know there are 2 different things it could look for, if any item is true, or if all the items are true.

One workaround is to test if the solution is a list, and then check if it's true. I would create a custom block to handle this.

(The any block is just the or block but drop the conditions variable onto the black arrows)

I think kinda-weird results are occasionally to be expected from hyperization, especially in these lists-of-Booleans cases (because a list is True because we inherit JS's lousy type system so as not to slow things down with our own type checks, but if it's a list of Booleans then it might be taken as a single value or as a vector depending on the context).

In particular, it's not surprising if reporter IF behaves differently from command IF, because the former is hyperizable but the latter isn't.

I agree that we need much more and better documentation about hyperblocks. They should have their own chapter. There's a problem about organizing the manual, though, that I haven't figured out. (If you read what we have with an eye to this problem, you'll see how awkwardly I've tried to solve it.) Does the hyperblocks chapter come early or late?

If it comes early, then we can't give examples, or at least not enough examples, especially of screwy edge cases, without forward references to things the user hasn't read yet (e.g., lists). This requires a zillion footnotes to resolve the forward references, and the whole thing reads as if a lawyer wrote it.

If it comes late, then the explanation is much easier and more sensible, but it means that prior to that chapter, we have to lie about how all the blocks work, i.e., pretend they only work on scalars. We can avoid lawsuits (or forum bug reports) with a general warning at the beginning saying "WARNING: Everything up to Chapter 12 [or wherever it ends up] in this manual is a lie. Trust us anyway. Read the manual twice." But it still feels a little weird.

We could theoretically do dimensional analysis of all the inputs to OR before we actually compute their values, and then reshape scalars to the maximal dimension before evaluation. But that would slow things down immensely and kinda defeat the point of short circuiting.

There are some heuristics applied to the dimension of arguments, so this result is kind of intuitive.

But the auto-truncation makes this rather unexpected

untitled script pic (47)
untitled script pic (48)

Maybe a single-element list should be treated as atomic in hyper context.

Why not present a short introduction of hyperblocks early in the manual, explain that some of what’s in the next chapters may be different for hyperblocks, and refer forward - only once! - to a late chapter or appendix where hyperblocks, and their consequences, are discussed in-depth?

Yeah, I'll probably end up doing something like that, but I'm not happy about it, because saying "different for hyperblocks" would be okay if there were six of them, but in fact almost every reporter is now hyper, and so the hyper behavior is the normal thing. I almost wish that blocks with more than one input would only accept inputs of exactly the same shape unless the program turned on some flag first.

Perhaps I should have formulated the proposed disclaimer more precisely: "... some of what’s in the next chapters may be different for hyperblocks when applied on a list".

That might work. I'll try it.

Brian, do you consider this as "works as designed" (v.9.2) ?

untitled script pic - 2024-01-11T211711.160
untitled script pic - 2024-01-08T014347.667

Or should it be a bug report?

hmm... those results are both what I would expect from a short-circuited Boolean operator. But I might be wrong. Can you explain which results you would expect?

I'm not sure but it seems to be very confusing now