Get number of slots in variadic input

Snap has metaprogramming, and you can analyze scripts, even creating your own codification library. It's all thanks to the (split [] by [blocks]) block.

Well, there is a problem, you cannot get the number of slots in a variadic input. This is a big issue because you cannot recreate the block, or add something to a variadic input, all because there's no way to find where variadic inputs start and end.

This is the main reason why I've never really made my own blocks to text to blocks library, all because it's impossible to get the number of slots in a variadic input.

Just today I was thinking of how it could be possible, but then I remembered codification actually has that ability. I decided to use that to create this block.

better split blocks script pic (4)

This block reports the split blocks with every single input, but variadic inputs are much better.

The reason why the number of slots is in the first item of the list for a variadic input, it's because this is the format the snap uses to be able to create blocks with a custom number of slots in a variadic input. Why the primitive (split [] by [blocks]) doesn't report this in the first place, is beyond me.

This being the same format that snap uses to create blocks, it allows you to just put it into a join block, and get the original block back.

If you would like to play with this block, here's a project.

Awesome! That's cool, that we could have implemented split blocks in Snap! rather than as primitive.

Do you have to create a codification for each individual block? (I'll read the code but not tonight.)

The block uses (split [] by [blocks]), I'm just using codification to get the number of slots in a variadic input (that's the whole point of this block). And yes, I do set the codification of the block for each variadic input (the user doesn't have to do anything).

Here's how it works.

I start by setting

(item is a single space)

I grab the slot of the block, so I can know if a slot is a variadic input. I loop through each slot, if it's a variadic input, I set the block codification to <#1> (the number is replaced by the input number). If I get the codification of the block, I only get


Where each space is an input (no matter what was in it), and a comma to split by it. If the code is blank, then there's 0 inputs.

I do use the (split [] by [blocks]) to get the input values, but I transform that list to get the result.

Ok, I know none of that made sense, it's late, so here's the code.

I'm also now realizing, I didn't need the comma, I can just give each item a single character, then split the result by letter, and get the length.

Very clever solution :slight_smile:

I do think it could be made a lot simpler if we stuck to the Snap! block design restriction mentioned by Jens

Then these two pieces of information would let us reconstruct the number of slots
untitled script pic (9)
untitled script pic (10)

1st one lets us know total number of slots
2nd one lets us identify which is static and then we can work out number of slots in the variadic one

My problem with your solution is that the only time I've used metaprograming is inside my Snap! -> OpenSCAD project

And since that uses codification - your solution wouldn't work :frowning:

But I do like how you've made your reporter. :slight_smile:

BTW, have you used or seen in a real project, a custom reporter that doesn't align with the official Snap! restriction?

Woah! this is exactly what I thought the primitive split by blocks would do, and it works perfectly with the custom # of inputs! Can I use this for my Snapblocks converter (with credit)?

Honestly that's what inspired me to make this. Go ahead, use it (that's why I shared it here).

Yes, I've seen it in the SciSnap v2 library.

It's not a restriction, it's a suggestion that no one knew until jens said that (seriously, I don't think I've ever seen it mentioned before, and given that bh was also surprised, that reinforces this claim).

Plus, if we have the ability to put multiple variadic inputs in a block, you shouldn't expect people to only use one, expect people to use 10 in a single block, mixed with regular non-variadic inputs.

Yeah, that is the big problem with my solution. I did have an idea to save the current mapping for the block, then restore it after, but I ran into the problem where I can't get the mapping (or at least, no clever solutions popped into my head until now).

Of course if you know what code mapping the block changes, then you can reset it after the block runs.

Oh, and if you guys need it, here's everything that the block sets.

And of course the block (and blocks inside the block's inputs).

Oh I see, you dynamically codify each block as it comes up! That's very clever. I was imagining that you had to manually codify all the blocks in the project ahead of time, the way you do if you're using codification as in the Examples codification project.

I don't understand this:

The second menu of MAP TO CODE has options COLLECTIONS, VARIABLES, PARAMETERS, not LIST, ITEM, DELIMITER; those are the options for the first menu.

I like your improved SPLIT BY BLOCKS format. I wonder if we could convince Jens to do it that way in the primitive version?

Oh yeah, oops. I had accidentally put the item variable in the first slot before, and I looked at the first slot. I guess when I moved the item variable to the correct slot, I didn't check the list.

edit: I just updated the project (and script pics in the first post) with this fix.

I KNOW RIGHT!!! It's supported by the join block, so why not also report it?

Well this is an oversight. I just realized this block cannot detect input lists.

Although I was able to fix this easily, because I noticed that the value was nothing when there were no slots, but it was replaced with a block if it's an input list (still with 0 slots).

The script pics in the first post, and the project have been updated.

I'm confused. What comes after "input list:" has to be a list, no?

Yeah, but you can stick any block in as an input list, that's really what I was testing (and I didn't bother making it actually runnable).

I updated the block to make sure to handle the case where a code header was set. Apparently since setting the code header to nothing doesn't reset the code header (why?), I was able to just grab the last line in the code (which, thankfully, will always be what I need to get the variadic inputs).