Discuss Scratch
- Discussion Forums
- » Suggestions
- » "return" option for function creation
- decorp
-
Scratcher
100+ posts
"return" option for function creation
Functions are an integral part of programming, so it's no surprise that Scratch lets you define your own custom blocks which let you reuse bits of code. However, one feature that's missing is the ability to have a custom block return a value. I'm sure the forums are already saturated with such a request, but here's my proposal on how to integrate this feature as seamlessly and with as little confusion to new scratchers as possible.
A new option would be added to the Make a Block popup called ‘Block returns value:’

To discourage users from using the custom reporter block when it's not needed, the check box would be small and unintrusive, like the one for ‘run without screen refresh.’
This would turn the block itself into a reporter, like this:
And the define block would be turned into a capped and hatted C-block something like this, with the return at the end:
(The C-block would would ideally be fused with the hat, but no blocks like that currently exist.)
This would make these blocks useful for not only reusing code, but also for performing more complex calculations which return an output based on the inputs. The block would then be used just like any other reporter block, returning the defined value.
You might argue that a similar result can be achieved by simply creating a new variable dedicated to the custom block, and setting its value when the block is run, like so:
However, this method may actually be even more confusing, as you have to first run the block, then get the value of the variable after running it, creating situations where it may not be clear exactly which variables are attached to which functions, users may forget to run the block before using the variable, or the workspace can become cluttered with more blocks and variables than are necessary. For example:
Yes, if the first two blocks were to set the variables return_add and return_subtract respectively, this would work as intended. But normally, the same result would be achieved in a much more straightforward manner:
Note that in most circumstances, this would be used for more complex calculations than simple arithmetic. This also does not guarantee reducing the number of variables needed to achieve the desired outcome - however, it does encourage containing variables to the custom blocks that they're associated with, akin to how local variables only exist within the scope of the function they're created in (although this isn't the case with scratch, these variables may not end up being used outside of the scope of the custom block in the first place.) The only benefit to the first method is that users will be able to reuse the result of a function many times without the extra performance cost of running it every time they need it - However, that isn't lost with the addition of returns, and defeats the purpose of using a return value in the first place. There is a time and a place for both.
One downside to this feature could be the possibility of confusing users when code in the reporter block is run and produces more external changes than just returning a value. For example. one might have a function for adding two numbers together, but they also throw in a move () steps block, making the sprite move whenever the reporter block is used. This is a behavior some scratchers may not expect or be used to. A solution could be to undo any code that was run inside the block while leaving return value, but that may also confuse those who expect code in the block to be run like normal. That is also unrealistic for a function. In reality, it would be easy to get used to the first circumstance, and that is what normally happens when a function is run, so it can be a valuable lesson to teach about how functions work.
Another issue arises with how the engine will handle switching on or off a return value after the block has already been made. Blocks can't change their shape dynamically, so the simple solution to this is to disallow changing this setting if the block is currently in use, much like one can't delete a custom block if it's being used.
Some of you may be wondering if booleans would be able to be returned as well. This would also be a useful feature, but it also depends on whether the scratch team can develop a simple way to choose and change the type of a return value.
This may be a little bit hard to understand for beginners, but it is also a very important part of the basics of programming. It might be too advanced for scratch, but it also makes things even simpler in a lot of ways. Let me know what you think!
Here's a final example of how this feature could be used:
A new option would be added to the Make a Block popup called ‘Block returns value:’

To discourage users from using the custom reporter block when it's not needed, the check box would be small and unintrusive, like the one for ‘run without screen refresh.’
This would turn the block itself into a reporter, like this:
(block name :: custom)
And the define block would be turned into a capped and hatted C-block something like this, with the return at the end:
(The C-block would would ideally be fused with the hat, but no blocks like that currently exist.)
define block name
{
} return () :: custom cap
This would make these blocks useful for not only reusing code, but also for performing more complex calculations which return an output based on the inputs. The block would then be used just like any other reporter block, returning the defined value.
You might argue that a similar result can be achieved by simply creating a new variable dedicated to the custom block, and setting its value when the block is run, like so:
define add (x) + (y)
set [return_add v] to ((x)+(y))
However, this method may actually be even more confusing, as you have to first run the block, then get the value of the variable after running it, creating situations where it may not be clear exactly which variables are attached to which functions, users may forget to run the block before using the variable, or the workspace can become cluttered with more blocks and variables than are necessary. For example:
add (1) + (2) :: custom
subtract (1) + (2) :: custom
say (return_add) for (2) secs
say (return_subtract) for (2) secs
Yes, if the first two blocks were to set the variables return_add and return_subtract respectively, this would work as intended. But normally, the same result would be achieved in a much more straightforward manner:
say (add (1) + (2) :: custom) for (2) secs
say (subtract (1) - (2) :: custom) for (2) secs
Note that in most circumstances, this would be used for more complex calculations than simple arithmetic. This also does not guarantee reducing the number of variables needed to achieve the desired outcome - however, it does encourage containing variables to the custom blocks that they're associated with, akin to how local variables only exist within the scope of the function they're created in (although this isn't the case with scratch, these variables may not end up being used outside of the scope of the custom block in the first place.) The only benefit to the first method is that users will be able to reuse the result of a function many times without the extra performance cost of running it every time they need it - However, that isn't lost with the addition of returns, and defeats the purpose of using a return value in the first place. There is a time and a place for both.
One downside to this feature could be the possibility of confusing users when code in the reporter block is run and produces more external changes than just returning a value. For example. one might have a function for adding two numbers together, but they also throw in a move () steps block, making the sprite move whenever the reporter block is used. This is a behavior some scratchers may not expect or be used to. A solution could be to undo any code that was run inside the block while leaving return value, but that may also confuse those who expect code in the block to be run like normal. That is also unrealistic for a function. In reality, it would be easy to get used to the first circumstance, and that is what normally happens when a function is run, so it can be a valuable lesson to teach about how functions work.
Another issue arises with how the engine will handle switching on or off a return value after the block has already been made. Blocks can't change their shape dynamically, so the simple solution to this is to disallow changing this setting if the block is currently in use, much like one can't delete a custom block if it's being used.
Some of you may be wondering if booleans would be able to be returned as well. This would also be a useful feature, but it also depends on whether the scratch team can develop a simple way to choose and change the type of a return value.
This may be a little bit hard to understand for beginners, but it is also a very important part of the basics of programming. It might be too advanced for scratch, but it also makes things even simpler in a lot of ways. Let me know what you think!
Here's a final example of how this feature could be used:
define get position (num) pixels in front of me
{
set [original position x v] to (x position)
set [original position y v] to (y position)
move (num) steps
set [final position x v] to (x position)
set [final position y v] to (y position)
go to x: (original position x) y: (original position y)
} return (join(join(final position x) [, ]) (final position y)) :: custom cap
say (get position (10) pixels in front of me :: custom ring)
Last edited by decorp (Sept. 13, 2021 01:16:42)
- ScolderCreations
-
Scratcher
1000+ posts
"return" option for function creation
I like this idea, it would be useful. Support. Things like this are in Python and JavaScript, so there's no reason why they shouldn't be in Scratch.
- Discussion Forums
- » Suggestions
-
» "return" option for function creation