Why change the text input?

I don’t really know what tag to put this is.
Snap v11 has a wide text input, but Snap v12 has the same exact texture as the ‘Any’ input.
Why? And on that note, what even is the difference between ‘any’ and ‘text’?

And on that note, what even is the difference between ‘any’ and ‘text’?

Because all the text-input Scratch blocks have default inputs (“hello” and so on), when we started designing the input types I wrongly thought that input slots that specifically expected text were always wide, i.e., that they had a special input type for not-number text. So I put separate entries for Text and Any in the long form input dialog. (Jens must have known better, but he didn’t correct me for some reason.)

Since Jens added first class colors as a type, that input dialog’s real estate is getting expensive. He demoted Object type to the gear menu in the corner, but that’s not a good solution, so I wouldn’t be surprised if Text type disappeared altogether, and Object reappeared. Then the first row would all be “non-procedure types in Snap! but not in Scratch.”

The only thing is, while Any is a very sensible input slot type, it doesn’t work as a value type; you wouldn’t want to ask IS __ AN ANY?, to which the answer would always be True. So far, all the types in the IS ___ A ___? menu are disjoint; every value belongs to exactly one type. So we can’t just forget about Text; it has to be one of the choices for IS A.

This whole issue is going to get way more complicated when/if we finally invent user custom input types, so you could have exact rationals that are stored internally as LIST 3 4 but are displayed as 3/4, and so on. I’m kind of dreading that design meeting, although I’m excited about custom types and have wanted them since forever.

This exists in the dev version of Snap, and as part of that introduces the only reason you’d want the text input type now that it isn’t landscape. You see, there is a new feature where you can right-click on a hat block and mark it to “enforce input types”. You can then mark reporters as returning a particular type in a similar way, and now your text input will behave as though it were static for all reporters that aren’t marked as returning a text (or unmarked).

Of course, this is all experimental and might not make it to any real Snap version.

Reporter/Command/Predicate/Hat vs Script and Stage/Sprite vs Agent are the two examples where this isn’t the case.

thanks for this explanation, @mark4sisb , I was just about to answer this myself but couldn’t have formulated it any better!

What I am dreading is having to document all the new features we’ve been experimenting with in recent dev versions, once it’s clear they make it into v12. What’s worse is, that the selection isn’t so much driven by “clean design” but by sheer demand and extremely tight deadlines. Currently it looks a lot like everything that’s in dev right now will be in there to stay, with one or two more things to come if / when I get the chance to implement them. Also, v12 might have to be released earlier than I hoped, because the curricula that need these features are scheduled to go live well before summer. Sigh.

In any case, one small addition to the subject of text input slots: We’ve so far never used them in any of Snap’s built-in text primitives, such as JOIN, SPLIT etc. But I wanted to change that for v12 without changing the looks of these blocks in existing projects, as they use the “any” type slots. That was the (more trivial) reason for me to change the text-type slots to look like “any”. In addition to user-defined data types with their own corresponding input slots there are also some more special input slot types, such as “unevaluated number”, with possibly even (many) more to come in the future. Have I sighed already?

So, not only can you specify return types for any custom reporter - including user-defined data types - and “enforce inputs types” for individual custom blocks (as is the case for the “tables” and “shapes” libraries), but you can also “enforce input types” globally for all blocks in a scene, including all the primitives. For this reason, all the primitives have internal return type declarations (which you can also access via metaprogramming, sigh, sigh, sigh!). Of course, because Snap! is not a statically typed language (and never will be, I promise!) some reporters have very broad “any” type declarations, such as variable getters and list accessors etc. etc. When you “enforce input types” globally for a scene, this basically disables most of the hyper-overloading that is among Snap’s most exciting features, so I’m not that terribly in love with it. OTOH it supports a wide range of specialized introductory puzzles and microworlds for various curricula that are going to use it.

Sigh! :slight_smile:

Here’s an older screenshot of some user-defined types, including Brian’s “rationals” example right at the top (by now there are special adt-input-slots for user defined data types):

Wait, where’s the “Melody” type? Sorry, I really want to try it out

not in any public library, sorry, it’s one my (many, many) experiments that helped me design this feature. The idea is that you can totally make your own data types with their own printforms and graphic visualizations.

Ah, OK.

I do share this sentiment. as a result, I was wondering, is there a way to only enforce certain slots of a block? I found it rather strange I can’t put an [id V] of () into a (([shape] V) input, same with lists in some cases if trying to make hyperblocks. Again, sorry if that falls into the category of “annoying question, wait until release to ask.”

a little offtopic: when snap 12 releases, could we collab to recreate it? I can make a new topic.

nope, sorry. The granularity is either per custom block or globally per scene.

yet, you can’t, and that’s entirely on purpose, because that’s a numerical operator which doesn’t match the “shape” input slot. But remember, you totally don’t have to enforce input types, and you probably don’t ever even want to do that! This is a feature for (scared instructivist educators who otherwise would use Code-dot-org instead of Snap!) certain kinds of narrowly-led novice puzzles, not for free spirited power-users like you.

Sure! I’m in

I understand!

nice!

Snap! is not a statically typed language (and never will be, I promise!)

Glad you said that – I was all set to blow my top. :~/

I understand that you’re constrained by German academic politics, but I kind of hate the extent to which major otherwise-undesirable features are growing for the sake of specific user communities. In a perfect world, there would be an extension called B&DSnap! or something. (And yes, I do remember, it’s not just the Germans; Dan has asked for this too.)

Maybe I just have unfounded prejudices. (About language features, not about Germans!) I like to think of Snap! as a Scheme, but it doesn’t bother me at all that it’s also an APL (and, of course, a Smalltalk from the beginning). But I can’t stand that it’s going to be also a Java.

The trouble, I guess, is that having a feature in the language invites users to use it. (I almost said “encourages” but I guess that’s too strong.) The purpose, I suppose, of the “(EDC)” in the names of the EDC libraries is to signal that typical users aren’t encouraged to use them. (But that hasn’t stopped the forum users…)

You, Jens, do sometimes try to discourage users from using some features by providing a horrible user interface when a good one would be possible. (I’m thinking about the metaprogramming stuff, and more specifically about input groups.) Maybe you can do that for the B&D feature?

To say it again: I love custom types! It’s type enforcement I don’t like. Your example of hyperblocks is a great example.

For what it’s worth, the right way to do type enforcement is first to build an ML-style algebra of types, to make it easy to build, on the fly, types such as “numberlist: number or empty list or list of numberlists.” And functions of types, so you can define “hyperize(T): T or empty list or lists of hyperize(T).”

P.S. The ID function doesn’t belong in that SQRT etc. portmanteau; its domain and range are Any, not Number.

Reporter/Command/Predicate/Hat vs Script and Stage/Sprite vs Agent are the two examples where this isn’t the case.

Right, that’s why they’re under that dividing line. They’re union types, not primitive types.

nono, the option to enforce input types isn’t German at all. But curriculum writers all over are asking us for more and better error messages in cases such as this one, in their beginners’ projects:

And one answer is to let them build beginners’ puzzles and microworlds that don’t offer to nest non-matching reporter types:

input type enforced

In fact, I’ve been getting very mixed feedback from German educators about this option, rather on the negative side :slight_smile:

I’ve tried this a bunch of times with various audiences, both adults and teenagers, for their first experience in Snap, and those experiences did encourage me to enable input type enforcement as a welcoming ramp-up when first using Snap!

This isn’t about B&D at all, but about letting educators design for successful learning experiences when you only have … (I kid you not) … 3 (three!) periods of programming in all of sixth grade. This is when you have to think really hard how those 3 periods are going to look like, what kids are going to take away. The easy answer is to tell the folks who make that curriculum framework to go to hell. Then they’ll use Code-dot-org. The hard part is to try to design meaningful project ideas that work in class and still expose children at least to a glimpse of a powerful idea without getting lost in tings like syntax or type errors. The great thing about blocks is that we’re the masters of context. We can do this, where text-based languages cannot. This is a benefit I’ll gladly play out.

asking us for more and better error messages in cases such as this one, in their beginners’ projects:

Hmm. “Expecting a list but getting a color” seems to me like a fine error message, except that we don’t give it (or any error) a context. That is, the user should see the exact block that gave the error, which they do in your picture, in which that block is used in isolation, but don’t when the block is part of a procedure. We should pop open a Block Editor showing the immediate context of the block with the error, and also some sort of display of the call stack.

I know, we’ve discussed this before, and you rightly say that that’s complicated because of multiprocessing; the sprite that errors may not be the one currently visible. But such problems can and should be solved.

Not letting the user put the color in the slot in the first place is, imho, not as good an error message. It would be slightly better if we visibly kicked the color out of the slot, instead of leaving it sitting in front of the slot. (Didn’t whatshisname the Blockly guy suggest that?) Then at least it would be a clear response to an error.

This is one of the paradigmatic examples of something we inherited from Scratch which is brilliant in Scratch’s context, namely, not scaring eight-year-olds away by (visually) yelling at them. But our target audience is old enough to handle an error message, and old enough to benefit from more powerful debugging tools.

For example, I would propose that an uncaught error should Pause rather than Stop the project, so that local environments are available for inspection.

I mean, why did this hypothetical user try to put a color in a list slot, anyway? Presumably they mean something by it! (If they’re just randomly putting things in slots for no purpose, they can use Scratch. :~) ) For example, I can imagine that they think a color is a list of three numbers, RGB or whatever, and want to extract one of those numbers. Or maybe they think the color is a costume, and are trying to extract one pixel from its list of pixels. In a perfect world, the error message would say “Were you trying to pull the red value from the color?” [We know which item they tried to extract from the non-list!] And so on. But I think even the error message we have is more helpful than no message at all. I mean, you say

curriculum writers all over are asking us for more and better error messages

and then you offer as a solution no message at all! No message at all is a great solution to the problem that Scratch wanted to solve, but it’s no solution to the problem you say these curriculum writers have.

My general principle is to catch errors as late as possible, because that helps the user’s understanding. For example, there are a few cases in the Berkeley Logo interpreter in which I know before calling a procedure that it’s going to cause an error when the procedure returns to its caller. But instead of giving an error message as soon as I detect that, I let the procedure run anyway. A technical reason for this is that the code before the procedure returns might have visible side effects, and giving the error message early would confuse the user’s model of evaluation because the stuff in the middle didn’t happen. (Similarly, I try to make tail call elimination invisible to users. If you trace the code, the tail calls happen in the naively expected way.) But, a larger point is that to me as a user, a runtime error message says “I tried to do what you said, but I couldn’t make sense of it,” whereas a compile-time error message (which is what disallowing the drop is, pretty much) says “you idiot, you should have known better than to try this a priori.”

God, I want to have this conversation with you at Robolot! But besides the money, another thing working to dissuade me is that the current status of my recovery from surgery is that I feel the need to use the toilet every couple of minutes (and then nothing comes out), and coping with that in my house is more tolerable than jumping in and out of meetings would be. My surgeon says this is an expected problem, which will fix itself some time between a week from now and a year from now. :~(

That must have been trouble causing! I hope you recover at the earliest!

(Off topic)

Thanks!

While using scratch, I found it extremely annoying to have no if (variable){ do smth} functionality. I also agree that moving closer in that direction is bad, but can’t the user just disable that?

I just realized, since there’s an option to enforce types globally in the whole scene for use in these curriculums, what’s the reason to have it on the shapes library as default? sorry if that doesn’t make sense, it is just a random thought I had.

Responding to the next post:

I am, and I honestly didn’t understand how that would apply to enforced types. but ehhhh whatever.

what is this?

If you’re over 13, look it up. Otherwise, never mind. ;~)

I feel like anyone will look it up on this platform, regardless of age. With that being said, a vast majority of Snap ! users are above 13. including me. But I feel like a better example could have been used. Again, we have different mindsets and I hate starting drama.