Scheme's LET

Preamble
This is continuing a serious discussion started in the topic "Multiple upvars". The original topic was closed by (@)jens "as it has degenerated from the original question into - yet another - frenzy about boasting speculative JavaScript fantasies". I have no opinion on that, but LET's keep this discussion on-topic anyway.

Body
My request for Snap! is an equivalent of Scheme's LET special form. LET creates and initializes a local variable. In Snap!, since untitled script pic (19) doesn't support variable initialization, the closest equivalent of LET is:

untitled script pic (18)

... which is quite a bit more verbose.

I tried to write a LET-function myself, with an upvar and a C-shape command,

as defined: RPS algorithm developer script pic; as used: RPS algorithm comparator script pic (1)

This DIY-LET has three downsides though (compared to Scheme's LET):

  1. It can't create any number of variables (if one wants two variables a 2-variable version of LET needs to be written, etc.)
  2. The scope of the upvar is not restricted to the ACTION inside the C-shape. This is a general characteristic of upvars, and it is applicable to the SCRIPT VARIABLES special form too; I feel this ought to be reconsidered (I'll create a separate topic on this).
  3. When one moves a reporter or variable anywhere near the C-shape and its contents, a rectangular white veil will appear; if one accidentally releases the left mouse button, the reporter / variable will nestle itself inside the C-shape, throwing out the existing contents. This is a general characteristic of C-shapes within custom blocks, which IMO deserves reconsideration as well (another separate topic to come).

Recap
What I suggest is a modification of untitled script pic (19), such that it will support initialization of variables, perhaps something like: untitled script pic (21).

P.S.
I'm well aware that @joecooldoo created a LET-function earlier, with its own limitations and complicated underlying code: [[Multiple Input LET VAR BE Block]], as did @sarpnt in the aforementioned topic on "Multiple upvars". IMO these examples only show that there is a demand for a LET-like special form to be incorporated into Snap!

IMO The issue with this issue (which is long outstanding BTW) is that the issue isn't considered important enough to be implemented :slight_smile:

The current, most well used implementation is

NodeRED script pic

If you want to declare and initialise more than one, then you just have to add another in

So, IMO, for that reason - its not a top priority - it would be very nice to have a clever one liner but it would be a non-trivial thing to implement

Not that Jens couldn't do it of course :slight_smile: its just he's got other priorities :slight_smile:

This is just from my perspective having been around for a while :slight_smile:

This sounds like something that should be doable as a macro. I'll look into it.

There is an old plain :snap: , proof of concept project with some ideas.


Eq. combined upvar/getter/setter let be.2 script pic (14)
Used this way
let be.2 script pic (15)
let be.2 script pic (16)


Or just variadic initializer let be.2 script pic (12)

let be.2 script pic (13)


Variadic upvars with "Create variable" library & XML hack
let be.3 script pic

That's an interesting solution - thanks for sharing it!

the create variable library makes some VERY weird script variables. they break all sorts of scoping rules since they're created in a custom block, but need to be outside that block. iirc they go into other blocks and don't stay in environments like other variables.

I fail to see what the up arrow or : contribute - this version that deletes them appeals to me
let be.3 script pic

@toontalk: agreed, the up arrow is merely cosmetic.
And @cymplecy ’s version ( next post - this is an edit :wink: ) may be the clearest.

I would say they try to contribute some intention as to what the block is meant to mean :slight_smile:

This would be my preferred look

NodeRED script pic (1)

I like "be" but I don't like up arrow since that is pretty cryptic.

i don't like the "let" block here, the block seems like it's just a variadic that does nothing.
this would also be extremely confusing in the pallete, since neither make sense by themselves.
i'd rather a reporter (let ((x)) = []) that returns the value put into it, an IGNORE control block with a variadic anything input, and the LET block i've made before.
the reporter can be put into any expression to get the variable from it easily, possibly for debugging or to grab part of a conditional in a loop.
the IGNORE block is already used in many libraries for various reasons.
the LET block i've made is a single block in the pallete, and allows splitting a list into many named variables.

How about this solution?

It’s a symbiosis of a basic block and an extension block type, much like:

untitled script pic 23 (from the Multi-branch conditional library).

A nice improvement. The ultimate version would automatically insert a blank be reporter when one extends it by clicking on the > button.

i don't like the multibranch library either, both of these for similar reasons:

  • the let block doesn't do anything with the BE inputs put into it, reporters should report
  • the block isn't symmetrical, with the first BE standing out
  • the let block is still a variadic that does nothing, except for the first item
  • the BE block is still unclear
  • nothing really implies well that these blocks are meant to be used together and only together
  • you can't take out the first BE to put somewhere else, but you can take out the others to set a position with it like in the third reporter of that image
  • it's a hassle to use because you need to expand the variadic before you can place the BE

for the multibranch library, the ELSE block doesn't even report anything

Perhaps @bh can pull that off with a macro …

Good idea, that'll be a good test case.