Announcement of lexical/local variable plugin

313 views
Skip to first unread message

Mark Friedman

unread,
Oct 4, 2021, 6:35:54 PM10/4/21
to blo...@googlegroups.com
I am delighted to announce the beta release of a new plugin that adds a set of Blockly blocks that support explicit blocks for declaring lexical (aka local) and global variables, as well as a dynamic UI for obtaining variable and parameter getters and setters and for renaming variables. It also updates the UI for existing blocks that are implicitly lexically scoped, i.e. function/procedure definitions and for-loops

For variable getter and setter blocks this plugin provides dropdowns which allow the user to change the variable name to any variable allowed by scope. The plugin will also mark any variable blocks that are moved out of their allowable scope.

The plugin also adds a dropdown for procedure call blocks, allowing the user to change the call to be any other procedure of the same basic shape (i.e. statement shape or expression shape).

This plugin is based on code originally written for MIT App Inventor.

The GitHub repo for the plugin is here.  That page has all the info in this announcement, as well as more details on usage.  It also credits the many people who worked on the App Inventor code that this is based on.


You can see a demo version of a Blockly app that has integrated this plugin here. The code for that demo is here and provides a decent example of how to integrate the plugin.

Here are some pictures of the new (or redefined) blocks:

Block type: 'local-declaration-statement' - The variable name will be scoped to be valid within the body of the blocklexvar.png
While hovering over the variable name:lexvar-with-flydown.png

Block type: 'global-declaration-statement' - An block which declares a global variable. The variable name is scoped to the entire program.globalvar.png

and while hovering over the variable name:globalvar-with-flydown.png

Block type: 'lexical_variable_set' -  Note that despite the block type name, the same block is used for global variables, local variables, loop variables and function/procedure parameters. The names that appear in the dropdown will change according to the placement of the block. I.e., it will show the variables that are in scope for that getter according to which blocks it is within.

set.pngset-with-dropdown.png

set-within-scope.png

Block type: 'lexical_variable_get' - Exactly analogous to the setter block.

get.pngget-with-dropdown.png

get-within-scope.png

Block type: 'controls_for'- A block which enables a for loop

for.pngfor-with-flydown.png

Block type: 'controls_forEach' - A block which enables a loop over the items in a list
forlist.pngforlist-with-flydown.png

Block type: 'procedures_defnoreturn'
procdef.pngprocdef-with-flydown.png

Block type: 'procedures_defreturn'
procdef-return.pngprocdef-return-with-flydown.png

Block type: 'procedures_callnoreturn' - Note that, though I don't show it here, the procedure name field is a dropdown which allows the user to select any procedure and the block will change to match that procedure's name and parameters.
proccall.pngproccall-inline.png

Block type: 'procedures_callreturn' - This has the same dropdown behavior as the previous procedure call block.
proccall-with-return.pngproccall-with-return-inline.png

I would love to hear feedback on the usability of the plugin, feature requests and, of course, bug reports.  If you end up using the plugin in a project of yours, please let me know. That way I can make sure that you know about any updates and can give you some priority on enhancements and bug fixes.

Enjoy!

-Mark

Beka Westberg

unread,
Oct 4, 2021, 6:57:12 PM10/4/21
to blo...@googlegroups.com
Wooo this is so exciting! Gosh it's so exciting that we can do scope now. I can't wait to see what kind of blocks people build :D

Thank you so much for putting the work in to turn this into a plugin! You're da bomb Mark!

--Beka

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/CAOk7GcS4LYqSnVSXH15ainYy9w-Z4FLrxNvbHPjdACh2SZt-GA%40mail.gmail.com.

Mark Friedman

unread,
Oct 4, 2021, 7:26:52 PM10/4/21
to blo...@googlegroups.com
Thanks, Beka!  I'm excited to see what people do too!

I should tell the rest of you that Beka is one of the people who contributed to the code that this plugin was based on (for MIT App Inventor).  So thanks for that, Beka! 

-Mark


Mark Friedman

unread,
Oct 4, 2021, 7:41:43 PM10/4/21
to blo...@googlegroups.com
BTW, can anyone see the pictures in the original post?  They appeared just fine while I was creating the email but now I don't see them properly.

-Mark

Mark Friedman

unread,
Oct 4, 2021, 8:09:27 PM10/4/21
to blo...@googlegroups.com
The pictures didn't make it through last time, so I'm trying again.

I am delighted to announce the beta release of a new plugin that adds a set of Blockly blocks that support explicit blocks for declaring lexical (aka local) and global variables, as well as a dynamic UI for obtaining variable and parameter getters and setters and for renaming variables. It also updates the UI for existing blocks that are implicitly lexically scoped, i.e. function/procedure definitions and for-loops

For variable getter and setter blocks this plugin provides dropdowns which allow the user to change the variable name to any variable allowed by scope. The plugin will also mark any variable blocks that are moved out of their allowable scope.

The plugin also adds a dropdown for procedure call blocks, allowing the user to change the call to be any other procedure of the same basic shape (i.e. statement shape or expression shape).

This plugin is based on code originally written for MIT App Inventor.

The GitHub repo for the plugin is here.  That page has all the info in this announcement, as well as more details on usage.  It also credits the many people who worked on the App Inventor code that this is based on.


You can see a demo version of a Blockly app that has integrated this plugin here. The code for that demo is here and provides a decent example of how to integrate the plugin.

Here are some pictures of the new (or redefined) blocks:

Lexical/local variable declarations

Block type: 'local-declaration-statement' - The variable name will be scoped to be valid within the body of the block.

A picture of a lexical variable block

While hovering over the variable name:

A picture of a lexical variable block with getter and setter blocks

Global variable declaration

Block type: 'global-declaration-statement' - An block which declares a global variable. The variable name is scoped to the entire program.

A picture of a global variable block

and while hovering over the variable name:

A picture of a global variable block with getter and setter blocks

Variable/Parameter setters and getters

Setter

Block type: 'lexical_variable_set' - Note that despite the block type name, the same block is used for global variables, local variables, loop variables and function/procedure parameters. The names that appear in the dropdown will change according to the placement of the block. I.e., it will show the variables that are in scope for that getter according to which blocks it is within.

A picture of a setter block A picture of a setter block with a dropdown A picture of a setter block within another block

Getter

Block type: 'lexical_variable_get' - Exactly analogous to the setter block.

A picture of a getter block A picture of a getter block with a dropdown A picture of a getter block within another block

Loops

For

Block type: 'controls_for' - A block which enables a for loop

A picture of a for block A picture of a for block

Block type: 'controls_forEach' - A block which enables a loop over the items in a list

A picture of a for block A picture of a for block

Functions/procedures

Function/procedure definition with no return value.

Block type: 'procedures_defnoreturn'

A picture of a procedure definition block

A picture of a procedure definition block with flydown

Function/procedure definition with a return value.

Block type: 'procedures_defreturn'

A picture of a procedure definition block with return value

A picture of a procedure definition block with return and with flydown

Function/procedure call with no value

Block type: 'procedures_callnoreturn' - Note that, though I don't show it here, the procedure name field is a dropdown which allows the user to select any procedure and the block will change to match that procedures name and parameters.

A picture of a procedure call block or A picture of a procedure call block

Function/procedure call with value

Block type: 'procedures_callreturn' - This has the same dropdown behavior as the previous procedure call block.

A picture of a procedure call block with a value or A picture of a procedure call block with a value

Gregory Dyke

unread,
Oct 9, 2021, 1:32:47 PM10/9/21
to blo...@googlegroups.com
Hi Mark

I'm really excited about this as I've been struggling with some blocks to loop over a list and create event listeners where I would like a closure in javascript.

I initially found it very confusing why the block is a C shape, and the "initialize ... in" did not help me (until I saw the example and then it was really obvious). I wonder if, to match the loop/if blocks, it might marginally less counter intuitive to write something like "with local variable initialized to XXX do STATEMENTS"?

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.

Beka Westberg

unread,
Oct 9, 2021, 2:37:32 PM10/9/21
to blo...@googlegroups.com
It looks like all of the text on the blocks uses MSG references, so you should actually be able to customize it for your application =) Just reassign the values of those properties before injecting the workspace and you should be good to go.

I hope that helps!
--Beka

Mark Friedman

unread,
Oct 9, 2021, 6:34:59 PM10/9/21
to blo...@googlegroups.com
Thanks, Beka!  That's exactly what I was going to tell him.

-Mark


Uwe K

unread,
Oct 12, 2021, 10:44:00 AM10/12/21
to Blockly
Thank you very much for turning your work into a plugin.
The way we do local variables involves Blockly core changes, it's good to see it can be done without touching core. Are you tracking a variable's scope by prefixing its name? I'd like to understand that better. I don't think we can integrate the plugin though, because we'd have to redo a lot of educational material and migrate existing projects. The flyout field seems very useful on its own, maybe it could also be a plugin.

Mark Friedman

unread,
Oct 12, 2021, 3:46:43 PM10/12/21
to blo...@googlegroups.com
On Tue, Oct 12, 2021 at 7:44 AM Uwe K <seldom...@gmail.com> wrote:
Thank you very much for turning your work into a plugin.

You're welcome!
 
The way we do local variables involves Blockly core changes, it's good to see it can be done without touching core. Are you tracking a variable's scope by prefixing its name? I'd like to understand that better.

The scope is determined by block containment.  You can see the code which computes the variables that are in scope here

I don't think we can integrate the plugin though, because we'd have to redo a lot of educational material and migrate existing projects.

I understand.  It's tough for teachers to switch to new material!
 
The flyout field seems very useful on its own, maybe it could also be a plugin.

I have plans to refactor things so that the fields can be used in other blocks.  See, for example, these two GitHub issues (here and here).  If you think you might really want to use the Flydown (or other) field, sooner rather than later, please let me know and I can try and prioritise it.

-Mark

Uwe K

unread,
Oct 13, 2021, 8:15:23 AM10/13/21
to Blockly
Thank you Mark. So all variable-creating block types have to be handled in the field's variable gathering code. I would surely forget to update that code when adding such a block type. Maybe blocks could implement a method like getMyDeclaredVariables instead, to make this easier to extend. Though I may forget using that one as well.
I don't know if or when I get to work on integrating the flydown field, so no rush. But thank you for the offer!

Uwe

Mark Friedman

unread,
Oct 13, 2021, 2:40:06 PM10/13/21
to blo...@googlegroups.com
On Wed, Oct 13, 2021 at 5:15 AM Uwe K <seldom...@gmail.com> wrote:
Thank you Mark. So all variable-creating block types have to be handled in the field's variable gathering code. I would surely forget to update that code when adding such a block type. Maybe blocks could implement a method like getMyDeclaredVariables instead, to make this easier to extend. Though I may forget using that one as well.

Yes, you are exactly right.  My description in one of the GitHub issues I cited, alludes to that but isn't explicit about it.  I mention making the code be table driven, keyed by block type, which would enable a block to register, say, its getMyDeclaredVariables method.  Having a fixed name, as you suggest, would also work.

-Mark

I don't know if or when I get to work on integrating the flydown field, so no rush. But thank you for the offer!

Uwe
On Tuesday, October 12, 2021 at 9:46:43 PM UTC+2 mark.f...@gmail.com wrote:
On Tue, Oct 12, 2021 at 7:44 AM Uwe K <seldom...@gmail.com> wrote:
Thank you very much for turning your work into a plugin.

You're welcome!
 
The way we do local variables involves Blockly core changes, it's good to see it can be done without touching core. Are you tracking a variable's scope by prefixing its name? I'd like to understand that better.

The scope is determined by block containment.  You can see the code which computes the variables that are in scope here

I don't think we can integrate the plugin though, because we'd have to redo a lot of educational material and migrate existing projects.

I understand.  It's tough for teachers to switch to new material!
 
The flyout field seems very useful on its own, maybe it could also be a plugin.

I have plans to refactor things so that the fields can be used in other blocks.  See, for example, these two GitHub issues (here and here).  If you think you might really want to use the Flydown (or other) field, sooner rather than later, please let me know and I can try and prioritise it.

-Mark

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.

Nimrod Shaulski

unread,
Mar 16, 2022, 10:34:10 AM3/16/22
to Blockly
Hi,
After looking at this addition, I have a small question:
The function block returning a value doesn't have a body (in opposed to the one that doesn't return a value). Is it a bug?
Also, is it possible to define variable in the function scope, or just under their "own" scope?

Thanks!

Mark Friedman

unread,
Mar 16, 2022, 6:34:39 PM3/16/22
to blo...@googlegroups.com
On Wed, Mar 16, 2022 at 7:34 AM Nimrod Shaulski <nimrod....@gmail.com> wrote:
Hi,
After looking at this addition, I have a small question:
The function block returning a value doesn't have a body (in opposed to the one that doesn't return a value). Is it a bug?

It's at least a missing feature!  It allows you to return an expression, but to be maximally useful you want more than that.  App Inventor has a block like the following that would be useful in tandem with the value returning function block:

controls_do_then_return.png
 
Please file a GitHub issue (here) for this.

Also, is it possible to define variable in the function scope, or just under their "own" scope?

Currently, just in their "own" scope.  You could maybe fake it by adding parameters to your function definition and just not care about their values in the function call.  They'll still have getter and setter blocks that you can use.

-Mark
 
Reply all
Reply to author
Forward
0 new messages