Discuss Scratch

Jonathan50
Scratcher
1000+ posts

Better scoping - let block

Better scoping - let block

The idea is a way to have local variables – not just ‘For this sprite only’ but for a script, or a specific part of a script.
This is done by adding a new block, let in:
whenclickedletfoobebarinsayfoofor2secssayfoofor2secs
The first say block prints ‘bar’.
The second say block will NOT say ‘bar’, as the foo variable isn't in the scope. The Scratch behaviour for undefined variables is to create a new ‘for this sprite only’ variable with the value of zero, so unless that behaviour is changed, the second say block should print zero.

Other possibilites
Instead of gray, it could be an orange variables block, like this:
letfoobebarinsayfoofor2secs
It would be useful if I could declare multiple local variables in a single let block, perhaps something like
letfoobebarinsayfoofor2secs
Each time you press the rightmost arrow, a new grey oval shape (but not really a reporter, as it isn't a block and can't be dragged out.) with '(variable name) be [variable value]' would appear.
Perhaps it should have an equals sign rather than ‘be’?
letfoo=barinsayfoofor2secs
I personally like the ‘be’ version better.

Workaround
There is a sort-of-workaround that can achieve the same results in many cases:
defineletfoobefooinsayfoofor2secssayfoofor2secswhenclickedletfoobebarinsayfoofor2secs
Of course, it doesn't matter what the custom block is called. But this is obviously tedious and often will NOT suffice:
definemyblock2barsayjoinfoo = foofor2secssayjoinbar = barfor2secsdefinemyblock1foosayfoofor2secsmyblock2bazwhenclickedmyblock1bar
In this case, since ‘foo’ is local to my block 1 and my block 2 is declared outside of my block 1 foo can't be accessed. (Lambda would fix this though! Lambda fixes pretty much everything!!)

Cases when local variables are needed and there is no workaround that doesn't require hacked blocks
There are cases when doing something in Scratch is simply not possible without local variables.

Say I have a custom block, named foo, that uses the variable ‘foo i’ for counting:
definefoosetfoo ito1sayHere's what fruit we have:for1.5secsrepeatlengthoffruitiffooi=lengthoffruitthensayjoinitemfooioffruit!for1.5secselsesayjoinitemfooioffruit...for1secschangefoo iby1
This works if used on a single thread at the same time, but if two threads run this block at the same time, it'll get completely messed up.
Here's the solution, which requires hacked blocks:
definefooinamesetinameto1sayHere's what fruit we have:for1.5secsrepeatlengthoffruitifinameofStage=lengthoffruitthensayjoiniteminameofStageoffruit!for1.5secselsesayjoiniteminameofStageoffruit...for1secschangeinameby1whenclickedfoofoo i 1whenclickedfoofoo i 2. . .
This is non-trivial, requires hacked blocks (which ST doesn't super approve of), and makes the custom block annoying to use.

This example would be messed up anyway because of the same sprite switching between saying things. So I'd need to move one script to another sprite.
But as there is no such thing as ‘global custom blocks’, I'd need to use broadcasts.
The problem here is that I'd need to use a global variable to pass ‘i name’, and as the global variable isn't local to the block, I'd have the same issue all over again, except this time it's not possible to solve at all without copying the block into the other sprite!!

Please post if you support, don't support, semi-support, and your reasons why.

Last edited by Jonathan50 (Oct. 25, 2016 01:03:53)

Mrcomputer1
Scratcher
500+ posts

Better scoping - let block

Support
Sigton
Scratcher
1000+ posts

Better scoping - let block

Can't you just use inputs as local variables?

Sigton
JonathanSchaffer
Scratcher
1000+ posts

Better scoping - let block

???
Zekrom01
Scratcher
1000+ posts

Better scoping - let block

seems confusing to people who do only programming in scratch, so semi-support.
fredfish2016
Scratcher
52 posts

Better scoping - let block

support
Zro716
Scratcher
1000+ posts

Better scoping - let block

Sigton wrote:

Can't you just use inputs as local variables?
He could, but the problem he's addressing is the lack of mutability. That is, once you assign a value to a block argument, you cannot change it. The other way around, if you use a local variable instead, there's no way to discard it after being used.

This idea is not new to me, and it has been suggested several times in the past; nonetheless, I still support some way of incorporating temporary variables. The C-block is a nice idea and allows one to discard variables after a point in the code (unlike Snap!). Supposing it doesn't introduce anything radically new to the Scratch editor interface, it is possible to implement smoothly.
declaretempvariablestemp1. . .end
For example, if you right click ‘temp1’, you have the option to delete the variable or rename it. If you right click the block, you have the option to add a new temp variable (aptly named “temp” with an increment).

Edit: I should explain why I chose this scheme instead of Jonathan50's. I want to reduce redundancy of code. The block should not do the assignment, only the declaration. See below.

When you want to modify the variable, you do this:
declaretempvariablestemp1settemp1tofoo the dropdown should recognize any temp variables for its scope. . .end
And using the variables is easy. Just like custom block definitions, you drag copies directly from the declaration. In total, this fulfills declaration, assignment, mutation, access, and garbage collection. In other words, it's how variables are supposed to be.

Last edited by Zro716 (March 31, 2016 14:13:39)

gdpr533f604550b2f20900645890
Scratcher
1000+ posts

Better scoping - let block

Sigton wrote:

Can't you just use inputs as local variables?

Sigton
Inputs cannot be reassigned in Scratch. Also, who would want to declare a bunch of unnecessary parameters just to get local variables?

Also, this is a duplicate. Original: https://scratch.mit.edu/discuss/topic/20661/ (idea # 3)

Last edited by gdpr533f604550b2f20900645890 (March 31, 2016 14:16:08)

fivesythe
New Scratcher
80 posts

Better scoping - let block

I like the idea of lexical scoping in Scratch. However, I don't think the exact wording of this block ('let…') works in the Scratch metaphor. Also, what if you wanted to assign multiple variables?

Zekrom01 wrote:

seems confusing to people who do only programming in scratch, so semi-support.
I don't get it. Isn't the whole point of Scratch to learn new stuff?
Zekrom01
Scratcher
1000+ posts

Better scoping - let block

fivesythe wrote:

I like the idea of lexical scoping in Scratch. However, I don't think the exact wording of this block ('let…') works in the Scratch metaphor. Also, what if you wanted to assign multiple variables?

Zekrom01 wrote:

seems confusing to people who do only programming in scratch, so semi-support.
I don't get it. Isn't the whole point of Scratch to learn new stuff?
Yes, but can't you do that in another language?

Last edited by Zekrom01 (March 31, 2016 15:00:14)

DaSpudLord
Scratcher
1000+ posts

Better scoping - let block

The way you described it is a bit confusing, but I do support this-
createlocalvarvariablevariableend
To create multiple local variables, you could just nest them-
createlocalvarvariable1variable1createlocalvarvariable2variable2endend

Last edited by DaSpudLord (March 31, 2016 15:39:54)

Jonathan50
Scratcher
1000+ posts

Better scoping - let block

Chibi-Matoran wrote:

Also, this is a duplicate. Original: https://scratch.mit.edu/discuss/topic/20661/ (idea # 3)
That's a different idea.

fivesythe wrote:

I like the idea of lexical scoping in Scratch. However, I don't think the exact wording of this block ('let…') works in the Scratch metaphor. Also, what if you wanted to assign multiple variables?
Another naming could work.

Sigton wrote:

Can't you just use inputs as local variables?

Sigton
Read the whole first post. I explain why it won't always work, and it's not mutable, as @Zro716 and @Chibi-Matoran. (But if you're doing Functional Programming you don't need mutation. But the other issues stop it from working.)
Jonathan50
Scratcher
1000+ posts

Better scoping - let block

DaSpudLord wrote:

The way you described it is a bit confusing, but I do support this-
createlocalvarvariablevariableend
To create multiple local variables, you could just nest them-
createlocalvarvariable1variable1createlocalvarvariable2variable2endend
Huh? Shouldn't you be able to click on the variable to rename it? I should at that to the first post.
BookOwl
Scratcher
1000+ posts

Better scoping - let block

Support. I like @Zro716's version the best, but the one in the OP is nice too.
Jonathan50
Scratcher
1000+ posts

Better scoping - let block

Zro716 wrote:

Sigton wrote:

Can't you just use inputs as local variables?
He could, but the problem he's addressing is the lack of mutability. That is, once you assign a value to a block argument, you cannot change it. The other way around, if you use a local variable instead, there's no way to discard it after being used.

This idea is not new to me, and it has been suggested several times in the past; nonetheless, I still support some way of incorporating temporary variables. The C-block is a nice idea and allows one to discard variables after a point in the code (unlike Snap!). Supposing it doesn't introduce anything radically new to the Scratch editor interface, it is possible to implement smoothly.
declaretempvariablestemp1. . .end
For example, if you right click ‘temp1’, you have the option to delete the variable or rename it. If you right click the block, you have the option to add a new temp variable (aptly named “temp” with an increment).

Edit: I should explain why I chose this scheme instead of Jonathan50's. I want to reduce redundancy of code. The block should not do the assignment, only the declaration. See below.

When you want to modify the variable, you do this:
declaretempvariablestemp1settemp1tofoo the dropdown should recognize any temp variables for its scope. . .end
And using the variables is easy. Just like custom block definitions, you drag copies directly from the declaration. In total, this fulfills declaration, assignment, mutation, access, and garbage collection. In other words, it's how variables are supposed to be.
But it's declaring them. It isn't as clear that the block is only in the scope of the C-shape. (And the way Scheme and Haskell do it is specifying the initial value.)
DaSpudLord
Scratcher
1000+ posts

Better scoping - let block

Jonathan50 wrote:

DaSpudLord wrote:

. . .
Huh? Shouldn't you be able to click on the variable to rename it? I should at that to the first post.
You type the variable name into the textbox to rename it.
Jonathan50
Scratcher
1000+ posts

Better scoping - let block

DaSpudLord wrote:

Jonathan50 wrote:

DaSpudLord wrote:

. . .
Huh? Shouldn't you be able to click on the variable to rename it? I should at that to the first post.
You type the variable name into the textbox to rename it.
Oh. That's what I thought. In the idea in OP then you can click on the variable to rename it.
DaSpudLord
Scratcher
1000+ posts

Better scoping - let block

Jonathan50 wrote:

DaSpudLord wrote:

Jonathan50 wrote:

DaSpudLord wrote:

. . .
Huh? Shouldn't you be able to click on the variable to rename it? I should at that to the first post.
You type the variable name into the textbox to rename it.
Oh. That's what I thought. In the idea in OP then you can click on the variable to rename it.
Oh yeah, that works too.
gdpr533f604550b2f20900645890
Scratcher
1000+ posts

Better scoping - let block

Jonathan50 wrote:

Chibi-Matoran wrote:

Also, this is a duplicate. Original: https://scratch.mit.edu/discuss/topic/20661/ (idea # 3)
That's a different idea.
Are you sure?

AonymousGuy wrote:


I think this is the better solution. How it would work is similar to custom blocks. Only the blocks inside of the C-Block could use the variables. The weird looking variables and lists that look like “+” are just a quick sketch of how the using block could create more than one variable. However, I think it should only be able to hold either variables or lists.

The inspiration for this idea came from a language I use called C#, in which you can say this:
void doStuff()
{
using (int x)
{
do stuff that uses int x
}
do stuff that doesn't use int x
}
I think that maybe these should also have different colors, and they should use the right-click functions to get the other blocks.

Last edited by gdpr533f604550b2f20900645890 (March 31, 2016 23:13:55)

Jonathan50
Scratcher
1000+ posts

Better scoping - let block

Chibi-Matoran wrote:

Jonathan50 wrote:

Chibi-Matoran wrote:

Also, this is a duplicate. Original: https://scratch.mit.edu/discuss/topic/20661/ (idea # 3)
That's a different idea.
Are you sure?

AonymousGuy wrote:


I think this is the better solution. How it would work is similar to custom blocks. Only the blocks inside of the C-Block could use the variables. The weird looking variables and lists that look like “+” are just a quick sketch of how the using block could create more than one variable. However, I think it should only be able to hold either variables or lists.

The inspiration for this idea came from a language I use called C#, in which you can say this:
void doStuff()
{
using (int x)
{
do stuff that uses int x
}
do stuff that doesn't use int x
}
I think that maybe these should also have different colors, and they should use the right-click functions to get the other blocks.
using != let
The let lets (pun not originally intended, but now it is ) you assign an initial value.

Powered by DjangoBB