Remove Variable declaration code

113 views
Skip to first unread message

Naresh Chaudhari

unread,
Jun 11, 2021, 6:47:22 AM6/11/21
to Blockly
Hi All, 
How to remove autogenerated code for variable?

When we drag any variable related to that code is generated... How to disable to generate this line code?

test = None
test = test

Capture.PNG

Thanks

Maribeth Bottorff

unread,
Jun 11, 2021, 9:06:49 PM6/11/21
to Blockly
The `test = test` line is generated from the blocks on your workspace.
The `test = None` is always inserted by the Python generator at the beginning of the code, for each variable in the code. This is so that variables are always defined before they are used. For example, if you just had blocks on your workspace such as
"print <test>" , then the "test" variable is used without being defined (in blocks).  If we didn't insert `test = None` at the beginning, you would get an error in Python. In general, we shouldn't allow users to construct code with syntax errors in Blockly. Therefore, I recommend that you do not do remove this.

That being said, you can always create a custom generator if you really want this behavior. You could use the Blockly.Python generator as a base. This particular behavior is handled in `Blockly.Python.init`. There is related behavior with scoping variables inside of functions in the procedures generators as well. There is a generator codelab here: https://blocklycodelabs.dev/codelabs/custom-generator/index.html 

Again though, I caution you in doing that as you will allow users to create code with errors. Is there a reason you want to remove this line? 

Maribeth

Coda Highland

unread,
Jun 18, 2021, 1:29:07 PM6/18/21
to blo...@googlegroups.com
This is a remarkably common request, and I suspect the main reason is a desire to have the generated code resemble what a human might have written. Historically, my thoughts have been that it should be possible to statically analyze the code to remove those declarations when they can be proved to be unnecessary, but this is a LOT of work for something that isn't hurting anything and that could break things if done wrong.

/s/ Adam

--
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/082df689-6841-45ab-930e-d973facf7a94n%40googlegroups.com.

Neil Fraser

unread,
Jun 18, 2021, 2:37:22 PM6/18/21
to blo...@googlegroups.com
Couldn't we solve this problem with regular expressions?



--

Coda Highland

unread,
Jun 18, 2021, 11:03:40 PM6/18/21
to blo...@googlegroups.com
No, regular expressions don't work for that. You have to implement some of the language semantics to be able to do it properly, and regular expressions are well-known to not be powerful enough to handle those kinds of interrelationships in text.

Consider potential false positives like "x = x + 1", or "x = y" if y hasn't been initialized yet -- for every read of the variable, you have to be able to statically prove that it had to have been initialized with an expression that was, itself, composed of only constants, already-initialized variables, and operators.

Functions make it worse. A function call could potentially modify global variables, so that means any function that refers to the variable you're trying to analyze would then need to have every one of ITS call sites analyzed to make sure it was never called before the variable was initialized. Conditionals also add complications if only one branch writes to the variable.

The safest approach would be to default to generating initializations for everything, then walk the block stacks and only remove the variables that are initialized to literals. This is simple (though still not something you can do with a regexp) but it would only remove the simplest cases of redundant assignments. That's why I say it's harder than it's worth -- the safe, easy approach isn't going to solve the full depth of the problem, and the more thorough way is ridiculously difficult.

/s/ Adam

 

Neil Fraser

unread,
Jun 19, 2021, 5:57:25 PM6/19/21
to blo...@googlegroups.com
Yes, regular expressions will always fail at any task that involves an AST (been dealing with a lot of this lately).  But my thought is that a false negative (not catching a case) is harmless and is what we do already.

Specifically, it's quite common for Blockly programs to start with something like this:

Screen Shot 2021-06-19 at 14.41.21.png
That results in:

var foo, bar;
foo = 42;
bar = 'Hello';

For this common but limited case, I think regular expressions could be used to statically reformat the generated code to be:

var foo = 42;
var bar = 'Hello';

The process would be:
  1. Find the unique var line that declares variables but has no definitions.
  2. Examine each non-blank line below the var to see if it is a definition of one of these variables.
  3. If it is a match, then add a var to it, and delete the variable from the earlier var line.
  4. If it isn't a match, then we're done.
  5. Delete the var line if it no longer has any variables.
Seems pretty straightforward.  Fits in Blockly.JavaScript.prototype.finish.  No, it doesn't cover close to every case, but it does eliminate some of the most common and most ugly cases.  Very similar constructs would be needed for Python and PHP.



Coda Highland

unread,
Jun 19, 2021, 7:54:03 PM6/19/21
to blo...@googlegroups.com
The problem is:

var foo, bar;
foo = bar;
bar = 42;

This MUST NOT become:

var foo = bar;
var bar = 42;

It's easy to use a regexp to identify opportunities to optimize it, but using them to distinguish between the safe and unsafe cases doesn't work.

/s/ Adam

Reply all
Reply to author
Forward
0 new messages