As you know, many programming languages, especially dynamically typed ones like JavaScript, Python and Scheme, have the property that any function call may or may not return a value. Blockly makes it difficult to express such a concept, as it more-or-less forces you to choose whether a given block type has an output or not.
A number of Blockly-based systems that I've seen have dealt with this in various ways. One is to have a sort of expression->statement block that more-or-less eats the return value of a block. Then you could have all your function call blocks return a value and surround it by an expression->statement block when you need to use it in a statement context. Another technique would be to have two versions of a block for each function call; one with an output and one without.
Each of these approaches seems a little clunky to me. The first because it adds additional effort and extra blocks to the program. The second because it doubles the number of blocks in your toolbox. Each approach also has a "syntactic" mismatch with the underlying textual programming language. In the textual language it's the context that determines the behavior, not the syntax of the function call.*
I think what I would really like to see are what I'll call "chameleon" blocks, which could change shape (i.e. switch from expression to statement) depending on where it's placed. I'm imagining a block which could change shape appropriately as you drag it near value inputs or statement connection points. I've thought about having a context menu item on the block which would make the switch, but that still seems too clunky to me.
I'm writing this in the hope that maybe some of you have thought about this (or are now thinking about it) and have some ideas for how it could be done, ideally without having to fork Blockly or create a custom renderer. Maybe something that hooks into the InsertionMarkerManager or BlockDragger.
Thanks in advance.
-Mark
* Ok, that's not entirely true. Some textual programming languages (e.g. BASIC, Fortran and COBOL) do force you to use syntax to distinguish the calls but AFAIK most newer languages do not.