An else before if block

I'm a wizard in the same sense as the Wizard of Oz.

I've managed to mangle the code in the Node-RED switch node (its equivalent of if / else if / else) - this was the other place I mentioned in the OP

I'm not sure my change will be accepted but at least I've proved it's possible to do :slight_smile:

FYI The reason for wanting to do this is to avoid crossing wires. Crossing the wires doesn't actually cause an issue at all but they don't look nice and make it harder to follow program flow :slight_smile:

For almost all of the book, people were pretty dang sure Mr. Oz was, in fact, a wizard. Then people learned stuff and realized they could pull it off too :~)

Though unfamiliar with the discussion on another forum @cymplecy refers to,
I'd like to elaborate why in my view untitled script pic (51) is superior to untitled script pic (52), by far
(and therefore deserves to be included into the "Iteration, composition" or "Multi-branched conditional" library! - BTW IMO the latter ought to be included in the former).

Pros of IF ALL ELSE FAILS over CASES IF THEN ELSE

  • Most importantly, a default action fundamentally differs from the (ELSE) IF THEN-clauses. Therefore it makes sense to feature it by putting it first, as is done in IF ALL ELSE FAILS.
  • Secondly, the code of IF ALL ELSE FAILS is naturally (i.e. without any shortcuts) a tad shorter, which is generally a good thing (Occams Razor and all that).
  • Thirdly, IF ALL ELSE FAILS needs only one companion: untitled script pic (53), and nothing untitled script pic (54).
  • Last but not least, the user is far less likely to forget about defining a default action.

Kudos
:+1: @cymplecy!

All else
IF ALL ELSE FAILS is quite a witty designation; however for clarity one might consider renaming the blocks: untitled script pic (58), and untitled script pic (59) (or untitled script pic (60)), respectively.

Incidentally, from studying this topic I've learned that any predicate can be included in a case block, even if it doesn't accomplish any action: simply to exclude that case from further evaluation. Wasn't aware of that.

I think (in Snap!) the block looks wrong (e.g there nothing in the 1st slot) if no default action is wanted/required.

I just wanted to show that putting the else clause at the beginning could be a lifestyle choice and that having it at the end wasn't set in stone :slight_smile:

But in Snap! (and 99% of other languages) I think the traditional way of (optionally) putting it at the end is better.

If you look at some of comments on the Node-RED forum, I think my suggestion is causing cognitive issues for some of them :slight_smile:

@cymplecy: You're too modest! Who cares about 99%?

Still, if you keep worrying about other programmers who might judge "nothing" in the first slot to "look wrong", why not try the following version?

Programming tools SANDBOX script pic (16)

To my mind- you've just demonstrated putting the else at the end :slight_smile:

But in other news from the other place, someone pointed out that JavaScript itself is happy to have the "if all else fails" at the beginning :slight_smile:

image

An empty C-slot does look wrong in Snap! - anyone would think that there was something missing and would be reporting it as a bug :slight_smile:

I did that on purpose - just to show that the Four Pro's of your IF ALL ELSE FAILS proposal vs. the Snap! library's current CASES implementation are independent of where the default action is situated within the block.

Perhaps a (primitive or library-canonized) Programming tools SANDBOX script pic (18) block will ease the pain (Programming tools SANDBOX script pic (19), and even more so Programming tools SANDBOX script pic (20), will do as well, but a separate COMMENT block would be better, also for stimulating Snap! users to document their code, which is a Good Practice, whatever Hon. Oz may think about influencing user practices :slight_smile: ).

influencing users' programming practices

("We are not in the business of preventing users from doing anything!") - OK, I'm aware that this may be a strawman fallacy, since preventing bad practice and stimulating good practice are not exactly the same thing.

So, what do you say ... change this topic into a Feature Request? (or was that only for Snap! primitives? if so, where can library suggestions be "officially" made? o, well, @bh probably reads everything posted on the forum anyway - hi, there! :slight_smile: )

I think for any chance of getting a block like this into the libary, we'd have to show that it was worth it

And, at the moment, its just a different syntax on the existing constructs.

I don't think it brings any extra value

Unlike in Node-RED where it helps things look nicer and therefore serves a useful purpose :slight_smile:

I am leaning toward No. I think it's great that you can make your own version! But to me the existing version is much more understandable, because the cases are in the order in which they're tested. That's particularly important in the situation in which the various tests aren't mutually exclusive, and the one that comes first wins. I understand that the "else" case is different because it has to happen last, but that might not be obvious to a user if the else clause isn't syntactically at the end. And if the library has two variants, users will think there has to be a reason; compare the case of
untitled script pic
versus
untitled script pic (1)

this means do...while loop

Did we witness your transformation just now from Wizard of Oz to Dr. No? :slight_smile:

I agree, by now - better keep the ELSE at the end (like demonstrated in post #17). I’d still much prefer to have the ELSE included as a standard element of the CASES block, instead of the first IF THEN clause, for reasons I worded in post #15.

You have a point. Then why not throw out the “old” CASES block? (assuming existing code using a block that’s no longer part of a library will continue to work, as any library blocks will be saved with the code - is that correct?).

Yes, that's true, unless there's a change to Snap! itself that makes the old library not runnable, as happened when we required manually enabling Javascript every time you load a project.

About building ELSE into the CASES block, I don't feel super strongly about it, but I'm still leaning toward No, for two reasons: (1) It would make users feel that they have to have a default case (as someone commented earlier in this thread), and (2) Changing a library requires changing its documentation, which is a hassle I'd rather avoid unless there's a super compelling reason to change something.

There’s no hurry. You can always reconsider when you’re going to review libraries anyway.

Circumventing the debate in whether the existing (imperative) CASES block should be replaced, I wrote a multi-branch conditional reporter, with built in DEFAULT, recursively implemented:

“Special cases” are to be defined as follows:

Now this works quite well, except for one curious (test) case:

… which reports “0” instead of (the expected) “NaN”.

I wonder why. See the “control” sprite within: Snap! Build Your Own Blocks.

Hmm. In the if/then/else, don't you mean RUN (REPORT VALUE)? The reason you think you don't is that in this particular case the DEFAULT input is a variable, so it gets unringified. Try putting X+1 in that input slot.

All I can think of offhand is that X in the if/report block isn't in the scope of the LET because the recursive call left its scope.

untitled script pic - 2023-03-07T022231.782

NaN is one of the "falsy" values in JS.
Some variable handling routines (VarFrame [ getVar, addVar])
coerce/fallback to 0 in this case ( source comment "// don't return null" ... ).

I was able to reproduce that. So … my code is OK, it’s a JavaScript peculiarity transpiring in Snap! Would it help if I file a bug report?

It's kind of intended (at least for null ...)

VariableFrame.prototype.getVar @ threads.js
 ... 
      return (value === 0 ? 0
                : value === false ? false
                        : value === '' ? ''
                            : value || 0); // don't return null

How about a PR with the nullish coalescing operator??