[edit]See post 3 for updated version based on dardoro's modification in post 2
I've a few blocks that have optional options (such as in the MQTT library) and I was getting fed up with having to write boiler-plate code to deal with the slots being expanded or not
Here is the issue
If you expand all the options - you get all the defaults
But if you don't - you get nothing
But if add in my helper block
then you get the defaults even with nothing expanded
and if you do expand - it merges in any changed values
The helper block only works if the you name your last variable slot "options" but could be adapted for other uses
I had good fun learning how to use the
following some help from Brian in another thread:)
I love this; I wrote something similar a long time ago in Logo. Berkeley Logo provides eval-twice macros, so the helper can report a list with a LOCAL command (like SCRIPT VARIABLES) followed by a bunch of MAKE commands (like SET). Since it's not a block language I didn't have prompts like "red" etc., but the user could use keywords to choose the inputs to provide. The calling procedure did this:
Imho the reported list should always be of length 4 (in this example), the max number of subslots, with defaults merged in to fill blanks. (If the user doesn't want that for some slot, they'll leave that default empty.)
#options = the number of options (specified by the caller)
#defaults = number of defaults (defined with the custom block)
maxslots = the maximum number of slots (defined with the custom block)
One might have expected both #options and #defaults can’t exceed maxslots, but in Snap! such is not enforced. This does, indeed, create the possibility of having hidden defaults (that will, however, never be prompted).
Continuing this reasoning, I can imagine a systematic approach in which exclusively optional input parameters are used: each ith parameter’s “name” is specified in the ith line of expand, and it may have a default value (specified in the ith line of defaults).
Oh, well, perhaps this is more or less what other were already hinting at.
One thing I wish I could do, which'll never happen, is an input with a default that's entirely invisible, not even an arrowhead, except when the block is used in a recursive call.
I know I can do more or less the same thing using a recursive helper to the user-visible main procedure, but that's unsatisfying when we don't have internal definitions.
So I want REVERSE to have a hidden input whose initial value is the empty list, but onto which I can cons something on each recursive call. The user of REVERSE should never give a value for RESULT, which should start with an empty list every time the user calls it.