> Oh and with regard to first-class functions, I remember Lyn's GRASP language having an interesting way of doing that (although that wasn't a blocks language, so it may not apply). I'll see if I can find that later this evening (once I'm on my other computer) and post back.
Ok, I've dug up
Lyn's master's thesis on Grasp, because I don't really like the way Snap! handles first class procedures (ie the grey ring). In my view, with Snap! you're basically wrapping an instance of a procedure activation in a special construct to get a reference to the procedure
definition the activation references, which is super weird.
The Grasp language has a much clearer separation between procedure activations (aka procedure calls, procedure invocations) and procedure definitions. When you start learning Grasp, you only have access to procedure activations (called "machines" in Grasp). Then as you advance you start to create procedure definitions (called "blueprints"). These blueprints can then be activated by an "abstract machine" which is equivalent to Scheme's `apply` procedure. (5.4.1 and 5.4.6 in Lyn's thesis)
I think having the separate notions of procedure activation and procedure definition with different visual representations is very important when you're trying to make this advanced concept intuitive. Otherwise it's hard to understand the difference between a definition and an activiation. IE how the former is a first-class data type and the latter is not.
As Lyn notes in his thesis (7.1.2):
"A problem with text-based languages such as Scheme is that syntactic
patterns do not necessarily indicate a semantic relationship. This is the basis for
the "procedure as pattern" bug in which the programmer attaches undue
importance to the syntactic similarities between the forms for defining a
procedure and for invoking it. Since the visual representations in the Grasp system are intentionally chosen to convey the structure of the computational
elements, reasoning based on visual similarities is valid in Grasp."
I think Snap! has fallen into a similar "procedure as pattern" trap by creating syntactic symilarities between their procedure activations and references to procedure definitions.
I think some clearer notations would be:
- Having to "apply" every instance of a procedure definition, instead of referencing activations directly (but this would get quite verbose).
- Having separate blocks for procedure activations and references to procedure definitions (but this expands your number of blocks).
But then again, maybe the design of Grasp doesn't really apply to blocks-based programming. And afaik Grasp was never tested with students either, so it may not be the best place to look for wisdom hehe.
If anyone has thoughts on this I'd love to discuss more :D It was super fun to dig up this old research hehe.
Best wishes,
Beka