jmoenig / Snap

a visual programming language inspired by Scratch
http://snap.berkeley.edu
GNU Affero General Public License v3.0
1.47k stars 739 forks source link

split by blocks doesn't handle non-block rings #3350

Open brianharvey opened 1 month ago

brianharvey commented 1 month ago

Untitled script pic (2)

Untitled script pic (3)

This shouldn't lose information. I think it should report a list containing just foo, no ring, but I'll settle for anything that lets me extract the value.

I came across this because I'm trying to write the blocks-all-the-way-down version of CALL.

ego-lay-atman-bay commented 1 month ago

I personally don't see a reason do this. You can call it to get the text.

untitled script pic (3)

However I do believe it would be nice to be able to determine if something is a ringed string. Currently the <is [] a [] ?> block can't detect them. untitled script pic (4)

brianharvey commented 1 month ago

Yeah that's the point; you don't know it's a blockless ring until you SPLIT it, and you don't want to CALL something that might take forever or have side effects. So SPLIT should tell you what's in it, same as for any other ringed input.

ego-lay-atman-bay commented 1 month ago

Bow that I think about it, maybe split by block should return a list, where the first item is the ring, and the second item is the string. Currently the second item (first slot) in a split ring, is the script inside the ring, which will never be a string, so it can work with the current behavior.

brianharvey commented 1 month ago

Whatever, I don't care what the notation is, as long as it's unambiguous.

jmoenig commented 1 month ago

No, this is right. Ringifying literal data is not something we're officially supporting, just a side quirk. SPLIT blocks is for ... blocks, not for data.

brianharvey commented 1 month ago

No, because we're officially supporting reporter IF written in Snap!, which means we're supporting trispi script pic That's the whole reason we invented Unevaluated input types!

So, I don't want to argue about whether this counts as a bug, but I do want to argue that ringed data are something we're proud of and should support fully.

jmoenig commented 1 month ago

But that's totally besides the point. Syntax analysis is about splitting blocks into their parts, and about joining together such parts to make blocks, not data artifacts. Rings don't have editable input slots in Snap. You cannot type numbers or text into rings. What you're getting by splitting this piece of data that you're fabricating with you're unev reporters isn't something that you can construct either manually or programmatically to be used as syntax part of a program, it's data. You cannot use it inside a script, it's not supported inside the scripting area. Please stop being thick about wanting to trick me into supporting metaprogramming to let you build constructs that you cannot construct in the scripting area, I'm upset by that.

brianharvey commented 1 month ago

I'm upset about "trick." I don't know what ulterior motive you think I have.

To say that nothing is syntax except blocks is like saying that in a text language nothing is syntax except procedure calls. Typical text languages have tons of syntax. A syntax-light language, such as Scheme, has four kinds of syntax: literals, symbols (variable references), procedure calls, and special forms.

That's true for us, also. Because of unevaluated input slots, we don't have many special forms, but we do have one: DEFINE, a/k/a Make a block. You had to invent a ton of metaprogramming mechanism to cover that.

As for symbols, you kind of cheat (not that I'm complaining!) by treating all variable blobs as calls to one generic-variable block that takes the variable name as an input. But that generic block doesn't exist in the surface language; each variable is its own block. You understand the virtues of extracting the symbol from the variable block syntax, so you're willing to treat that case specially.

I believe that when you think it through, you'll see that literals are just like variables in that sense: It's useful to represent them in syntax trees as if the literal were input to a nonexistent generic-literal block that's just like the nonexistent generic-variable block.

Evaluation is a recursive process. Its natural base cases are atomic expressions, namely, literals and symbols. You want its base case to be a block whose inputs are literals, rather than the literals themselves. Yes, you can make that work; students do it all the time. But as a result their code is twice as long as it has to be.

Maybe all of the above is a complete misunderstanding on my part. But if so, it's an honest misunderstanding, not a "trick."