Open jcaldw737 opened 4 years ago
Good question! Right now pulldowns are only static. Allowing for dynamic menus has long been on our list of features to add, and recently @bromagosa has pioneered a workable solution that we're planning to put into the next major release later this summer in time for (preparation for) the next school year.
Depending on how urgent you need it I could be talked into releasing that feature earlier. Mind you, it would be solution that requires the author of such a block to use the JavaScript function
block, so it wouldn't be something we'd expect students to come with themselves. But teachers and creators of so-called microworlds could use it to make blocks for libraries.
Can you reveal a little more about your plan?
I work with elementary school students as a volunteer. And I have "moved" a subset of a few commands to the Motion tab to make things simpler for them. Also added some simplifying blocks.
Here's a link
https://tinyurl.com/ezSNAP2019
Now I am working on expanding to include variables for more experienced students. (Will probably put this on the Looks tab .)
Since I don't think I can create a variable via a custom block, I am planning to have, say, 5 blocks created already. The situation would look like
In the above example the student has used a custom block to name each of the first 3 variables, and another custom block to assign values to the first two blocks. Those blocks would look like
name(1:, height) set(height,200)
there would be another custom block to get the value of the variable. It would be a function and look like get(height) and would return 200
Each of those custom blocks needs a pulldown list. The name block could have a fixed list of 1:, 2:, 3:, 4:, 5:
But the others need to show whatever names the student has used, in this case height, weight, distance
I believe I can do this via lists, but I can't do the non-static pulldowns.
Hmm... I think you might be able to do all of this - including the "dynamic" menus if you try using variables instead of lists after all, but I'm not sure. Are you aware of the library that lets you create variables programmatically? This might address your issue, because once you've created a variable - using the custom blocks in the library - its name also appears in the drop-down menu of the setter block:
Do you think this might help with your project?
Thanks so much! let me give that a try - will have to be tonight.
Thanks so very much for the block that creates variables. That will improve our system - especially by getting rid of having a fixed number of user variables.
We need to have our blocks on a small number of tabs, say Motion or Looks - one reason is to keep things simpler for our young users of varying skills - we work with pretty much the entire class. But we also want to keep users off the Variables page - so they will be less likely to mess with our system variable(s) and blocks like "global variables"
To "move" a block, like "set", I need to create a "front end" that has the same inputs as the "real" block. So I need to create non-static pulldowns. Btw, in the case of "set" I could also filter out any system variables so it will be less likely that the user will change them.
So that is my case for releasing dynamic menus sooner.
Hi @jcaldw737 ,
But you already can do it! You can't make all the dynamic drop-down menus that you want... but you can use some dynamic menus... and the "variables dropdown menu" is one of this. Then, doing...
You can make it!
Joan
Wow! Thanks so much!
Following your example, I can now get a pulldown with the variable names as choices.
But when I try to pass that to set I get this:
@jcaldw737 You can make the set block use the value of var with the run block:
Using it you can put variables in for all the inputs that are normally drop downs, such as the first input to the set block.
Hi! Oh yes, I made a mistake :(
You don't need to drag and drop because that var is just inside your "set block" dropdown. But it is not the way, because "that bar" is then a new instance... not a pointer of the real global var. But we can do it!
Joan
Thanks @KingDavid12 ,
I was typing the same solution. Great!
Joan
pls see screen capture below. menu test 1 works. menu test 2 gives an error:]:
a variable of name " does not exist in this context
@jcaldw737 The run block doesn't just replace all the inputs, it fills in the empty ones. It only sees the dropdown as empty. In menu test 2 you need to delete the zero so the box is empty.
What can I say, except "THANKS TO ALL OF YOU - AGAIN!!!"
This item is closed, but perhaps just a question: if anyone knows of a block that deletes variables, that information would be greatly appreciated.
Hi @jcaldw737 , I've made a new block to delete variables, and edited the "variables creator" to be able to choose between global and sprite variables.
Sharing this library...
Joan
Wonderful, @jguille2! Hey, Joan, why don't you add another reporter block that lets you query the value of a variable by its name and then issue a pull-request to add those to our existing library? That would be perfect, if you get around to it. Thanks!
Thank you, Joan! And the reporting block which returns the value of a variable given its name is needed here very much.
Indeed, thank you, Joan. That's been on my to-do list forever...
Hi everybody! After your comments, a new proposal:
Here with the reporter block. And also, I've added a check to the "delete block" and it does nothing (no error) if there is not any var with that name.
@jmoenig If you want to edit our official library, some questions...
Ok. Sharing last proposal...(please, test it)
Joan
This is great. I wonder if it wouldn't be good to have a SET _ TO block with a text input for the first slot, even though it can be done with RUN, because that's an obscure feature not everyone knows about. This would sort of complete the algebra of variables. And it's a library, so we don't have to fight for palette slots. :)
Ok, then "Set" your decisions :smile: (@brianharvey and @jmoenig )
An extra set block could be
with the existing variables dropdown, but not readOnly, is this right?
If we add this block, I have only one question. What must it do when there is no variable with that name? Using directly "run - set" would make errors... I think it's better to do nothing i that case (no variable with that name). I wait your thoughts... Joan
Red halo if no such variable.
This will be great!
Hi @brianharvey and @jmoenig ,
Let's go... I don't want to be annoying with this... but it's important to fix clearly these behaviors (you know custom libraries are difficult to maintain, because old projects keep old definitions, and this is not transparent).
So, points to decide:
and
Extra Note. Depending your decisions, I would suggest an extra feature, that will make happy those who wanted to create and set variable values in one go. Yes, they can do it with all these new blocks, but maybe it can be beatiful doing...
and also
and, of course, keeping the basic use to create a variable without any value.
That's all!
Joan
Joan -
You didn't ask for my opinions, but here they are anyway :) and please forgive me if I make too bold a use of the word "we"
variable reporter will show red halo for wrong names. yes
But what about new "set var to ",- it seems to me that we need to be consistent in that if trying to report an nonexistent variable gives an error, then trying to set an nonexistent variable should also give an error
And a question about "create var" block. I certainly agree that we shouldn't overwrite, but doesn't the user need some feedback if we don't do anything? - so I vote for an error
Validate block names at my proposal no comment since I don't understand this point
creating and setting variables in one block certainly seems like an excellent feature.
Hi @jcaldw737 , Your opinions are welcomed and also appreciated. Thanks. But, of course, I need Brian and Jens validation to do the job :smile:
Your opinions about errors are coherent... but I try to prevent these errors (and then, broken programs) if they are not needed. In this sense, maybe "set var to " could break with error if that var doesn't exist (not to autocreate that variable). But maybe "create var " could do nothing (without errors).
"Validate block names at my proposal" is about the block text expressions: "set var to ", "create var "... (see my block pics). And especially is about the "var" (and not "variable") expression. This is to make blocks shorter and to differentiate them from primitives ("set to ")
Joan
Thank you for the info. I am looking forward to using your blocks. They will lead to a great benefit to my students!
I'm always afraid of procedures that just do nothing. I can't tell whether that means I succeeded or failed! Personally I'd rather have an error message. (But of course it's not an error to make a sprite-local variable with the same name as an existing global.)
About SET: This is a case in which my goal of Snap! being a Logo and my goal of Snap! being a Scheme conflict. In Scheme it's an error to SET a variable that doesn't exist in the current scope. In Logo, there is a single command MAKE that creates a global variable, if there is no variable in the current scope, and then in either case sets its value. So I don't have strong feelings either way. :-) But I guess my inclination is to treat the no-such-variable case as an error, because I hate to encourage people to use global variables.
And that train of thought makes me wonder if we don't also need a SCRIPT VARIABLES block with variadic Text input slot in this library.
I'm okay with VAR instead of VARIABLE.
And that train of thought makes me wonder if we don't also need a SCRIPT VARIABLES block with variadic Text input slot in this library.
That would only be useful if VAR and SET VAR were to not follow lexical scoping (which can be done by using JavaScript, I think.) Also, this (aside from script variables) is a Panther feature, but I don't see how it's useful when one has associative lists.
Hi, Jonathan.
I agree that this entire discussion is somewhat superfluous because you can use an alist instead. But several people have been arguing for it. It's a library -- maybe we should include an alist-based implementation!
I don't understand your point about scoping. Once you make a variable from its name, it behaves like any other variable. It's true that we then can't compile out the variable lookups, so we lose one of the virtues of lexical scope. Is that what you mean?
Hi Joan,
- And finally, translations. I'll add Catalan and Spanish translations. This library has already Portuguese (@MMSequeira if you want to check this, write on new texts (only see pictures) and I'll also add them). If somebody wants to add others (German?)
Here goes the library with the blocks translated to Portuguese: variablesLibPlusPT.xml.zip.
The options in the new variable creation block are still in English. Is it possible to translate slot menu options? I did not find any way of doing it.
Manuel
Hello! Ok, that wasn't quite accurate. It wouldn't be useful for a script to make script variables with names which aren't known in advance unless they can be used, like with THING and MAKE in Logo (or if you were to add hybrid scoping perhaps you'd shadow a variable used in another procedure.)
Right, the idea is that SET and the new proposed VAR would take the name as input. It's no more or less true for script variables than for global variables that the feature of creating them doesn't do any good if you can't then read and write them.
Presumably people won't really literally type names into these blocks; the input would be computed, so you could, for example, make 26 variables named A through Z programmatically.
Yes, but since they are procedures, they wouldn't report or assign to a variable local to the caller unless they didn't follow lexical scoping.
Hi Manuel (@MMSequeira ,
Oops! I thought I had answered your post... but it was not been sended :(
First, thanks! I will pick up your translation for the "final" lib before PR it.
And I think there is no way to translate dropdown input options. It's not easy, because there is not only a visualization issue, it is just about the real content of a variable.
Continue, Joan
@Jonathan50 Oh, now I see what you mean! Right, if those were procedures written in Snap! they wouldn't have access to their caller's variables, so they have to be special forms with special evaluation rules. That's true already for the regular SET and variable reporters.
Since this is a library we're talking about, the JS code will be inside a Snap! wrapper, so yes, the JS has to back out one level of procedure calling. Thanks for reminding me -- I'm getting old.
Ok, I will include script vars behavior. The idea is to do the same primitives are doing now. So, the scope evaluation is from down to top (script -> sprite -> global). I we have variables with the same name at different scopes, blocks will consider the first encounter (the lower scope one).
Joan
Can we do the following?
After we have allowed users to fill in items in a list, then run another block where the choices in a pulldown for an input name come from that list?