jmoenig / Snap

a visual programming language inspired by Scratch
http://snap.berkeley.edu
GNU Affero General Public License v3.0
1.5k stars 745 forks source link

Ask Reporter Block #276

Closed cycomachead closed 10 years ago

cycomachead commented 10 years ago

This is a bit of a shift from Scratch, but I think something that entices good programming.

Can we make an ask block which is a reporter and returns the answer instead of getting a global variable? I'm thinking about how other languages work...

Python:

    a = raw_input('Hi:\t')

Ruby:

   a = gets 'Hello!'

C:

  scanf("Hey!", &var);
MMSequeira commented 10 years ago

The current solution, amounting to the use of a global variable, is problematic. But I'm afraid adding a state changing reporter would introduce other problems. Perhaps the problem would be minimized if each object (actor or stage) had its own answer variable?

nathan commented 10 years ago

Perhaps the problem would be minimized if each object (actor or stage) had its own answer variable?

That's even more confusing because there's only one prompt, and ASKing from a different object replaces the current prompt instead of adding one for that object.

cycomachead commented 10 years ago

I didn't think this block would modify state. It would be independent of the current answer variable -- or that was my expectation. (Though this could get a little messy as well.)

MMSequeira commented 10 years ago

If the block asks a question, it changes the state, even if temporarily. Also, it is objects that do the asking, even if they share the same prompt. If I tell an object to ask a question, it is natural for the answer to belong to that object. It does not have to be confusing. The monitor would show the object the answer belongs to, as happens with other object attributes.

nathan commented 10 years ago

If I tell an object to ask a question, it is natural for the answer to belong to that object.

The ANSWER block represents user input, like the KEY PRESSED and MOUSE X blocks, which belongs to the user and not any particular object. Scratch makes those kinds of blocks global.

xtitter commented 10 years ago

The ask block doesn't put up a speech bubble, but a global bar at the bottom.

Can you say more about what you mean by state changing? I don't understand. Users will set a local or global variable to the return value of an ask block.

The reporter would be an 'and wait' style block... I can't think of any other reporters that do this? Well, the http reporter is similar perhaps.

Nate fat-thumb Titterton On Dec 12, 2013 2:36 AM, "Manuel Menezes de Sequeira" < notifications@github.com> wrote:

If the block asks a question, it changes the state, even if temporarily. Also, it is objects that do the asking, even if they share the same prompt. If I tell an object to ask a question, it is natural for the answer to belong to that object. It does not have to be confusing. The monitor would show the object the answer belongs to, as happens with other object attributes.

— Reply to this email directly or view it on GitHubhttps://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-30405143 .

MMSequeira commented 10 years ago

The stage and what sprites are certainly parts of the state. If a sprite is doing the asking, a speech bubble is shown, as well as the bar at the bottom. The http block reports the result of a get. Gets usually don't change state.

On Thu, Dec 12, 2013 at 2:48 PM, Nate Titterton notifications@github.comwrote:

The ask block doesn't put up a speech bubble, but a global bar at the bottom.

Can you say more about what you mean by state changing? I don't understand. Users will set a local or global variable to the return value of an ask block.

The reporter would be an 'and wait' style block... I can't think of any other reporters that do this? Well, the http reporter is similar perhaps.

Nate fat-thumb Titterton On Dec 12, 2013 2:36 AM, "Manuel Menezes de Sequeira" < notifications@github.com> wrote:

If the block asks a question, it changes the state, even if temporarily. Also, it is objects that do the asking, even if they share the same prompt. If I tell an object to ask a question, it is natural for the answer to belong to that object. It does not have to be confusing. The monitor would show the object the answer belongs to, as happens with other object attributes.

— Reply to this email directly or view it on GitHub< https://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-30405143>

.

— Reply to this email directly or view it on GitHubhttps://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-30428057 .

http://www.coderdojo-lx.pt/

MMSequeira commented 10 years ago

I meant "what sprites say".

On Thu, Dec 12, 2013 at 2:57 PM, Manuel Menezes de Sequeira < mmsequeira@gmail.com> wrote:

The stage and what sprites are certainly parts of the state. If a sprite is doing the asking, a speech bubble is shown, as well as the bar at the bottom. The http block reports the result of a get. Gets usually don't change state.

On Thu, Dec 12, 2013 at 2:48 PM, Nate Titterton notifications@github.comwrote:

The ask block doesn't put up a speech bubble, but a global bar at the bottom.

Can you say more about what you mean by state changing? I don't understand. Users will set a local or global variable to the return value of an ask block.

The reporter would be an 'and wait' style block... I can't think of any other reporters that do this? Well, the http reporter is similar perhaps.

Nate fat-thumb Titterton On Dec 12, 2013 2:36 AM, "Manuel Menezes de Sequeira" < notifications@github.com> wrote:

If the block asks a question, it changes the state, even if temporarily. Also, it is objects that do the asking, even if they share the same prompt. If I tell an object to ask a question, it is natural for the answer to belong to that object. It does not have to be confusing. The monitor would show the object the answer belongs to, as happens with other object attributes.

— Reply to this email directly or view it on GitHub< https://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-30405143>

.

— Reply to this email directly or view it on GitHubhttps://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-30428057 .

http://www.coderdojo-lx.pt/

http://www.coderdojo-lx.pt/

jmoenig commented 10 years ago

Has anybody ever tried this:

png-1

and then used more than a single one of these, for example, click on both:

two questions

and watch what happens. (I'm actually rather proud of myself, that this works nicely, wasn't easy to do...).

xtitter commented 10 years ago

That is excellent.... Mostly: I can make it do the wrong thing with

badask

and, making a second call to my ask reporter while the first is executing. Fairly perverse, although I can think of situations where it might occur (something that checks the validity of input by asking some online service...)

More importantly to me is that basically no one thought to make this reporter ask block. Not one of the Berkeley CS10 students, or the TAs like Michael, or me/etc. That global 'answer' sitting right there in the palette is too strong of a trigger, or something. And, in some CS10 projects, it makes for very poor code.

I am quite worried about the ways that Snap encourages bad programming -- a larger topic to discuss more fully.

I'd like to propose breaking from the Scratch roots in this case! Although, I'm not sure how earlier projects could continue working... Would replacing the command ask with a reporter ask that, as a side-effect sets the global answer variable, work? Scripts can't have a reporter in a sequence of blocks, though, can they? Or, would it be possible to automagically replace every command-ask with a (set 'answer' to (reporter-ask 'msg')) in existing projects, along with the creation of the global variable answer? That sounds hard, but a great solution. To me, anyway.

cycomachead commented 10 years ago

More importantly to me is that basically no one thought to make this reporter ask block. Not one of the Berkeley CS10 students, or the TAs like Michael, or me/etc. That global 'answer' sitting right there in the palette is too strong of a trigger, or something. And, in some CS10 projects, it makes for very poor code.

Yeah, the reason that I like the idea of an ask reporter is because every time people use an ask block we tell students that immediately following ASK should be SET var to (answer)

Would replacing the command ask with a reporter ask that, as a side-effect sets the global answer variable, work? Scripts can't have a reporter in a sequence of blocks, though, can they? Or, would it be possible to automagically replace every command-ask with a (set 'answer' to (reporter-ask 'msg')) in existing projects, along with the creation of the global variable answer? That sounds hard, but a great solution. To me, anyway.

This was also my thought.

jmoenig commented 10 years ago

Nate,

it's really funny that no one at Berkeley ever thought of this:

png-1

I remember when I was implementing the ASK primitive two years ago together with Brian at Paul Goldenberg's house this was exactly what we were imagining everybody to do right away! And not only does it work, it's also safe to use, and will never succumb to any race condition, because the thread is locked between the ASK and the REPORT block.

If you don't want your students to build the ASK reporter themselves (even though it's almost the archetypical example for a reporter block, right?) you can provide it in a library, or in a stub project, in which you can also hide the existing two primitives:

hide primitives

So, what I'm really interested in is why nobody thought of this, and what got in the way. Also, I'd love to know more about "bad programming style". We should definitely discuss this!

brianharvey commented 10 years ago

I wouldn't say nobody thought of it. It's only quite recently that we have primitive hiding, so until now the discussion has been (mostly implicitly) about whether having both versions is good enough, or whether instead it's necessary to get rid of the command.

The meta-issue is to what extent we want to shift from a sequential-centric language (which is what Scratch is) toward a more functional-centric language (like Scheme). (I don't think anyone would suggest that we have a purely functional language like ML or Haskell.)

As a thought experiment, let's pretend that the beginning of this thread had been a suggestion to eliminate the list command blocks (ADD, INSERT, REPLACE, DELETE). We don't need them, you know, and they only encourage students to program sequentially. I think people would be less sanguine about that idea, partly because when you take efficiency into account there are reasons to keep the commands.

I guess the question is whether having the command version of ASK pulls students into sequential programming, making it harder to learn to think functionally.

brianharvey commented 10 years ago

P.S. Primitive hiding doesn't really do the trick. It's great for things like the Hour of Code page in which you embed a Snap! instance that has a project preloaded. But in this discussion we're talking about student-initiated term projects, mainly, I think. We'd need a feature in which starting Snap! or using File>New would load a project from a fixed location in the local filesystem. And that would mean that if you visit a friend and run Snap! on his computer it'd be different from what you get on your computer.

xtitter commented 10 years ago

I pretty much agree with Brian, on the above points. Basically, we'll try to find a way amongst the competing constraints to do the best we can. If there are different audiences that Snap is being designed for -- I'd argue there are, but am willing to be convinced otherwise -- then it very well might make sense to have different palette-sets and/or other core settings for the different audiences.

My emphasis might be different that Brian's. While I see the sequential/functional divide, I think Snap! can bridge that. An experienced programmer would want both available; programmers that are learning in formal settings (my bally-wick) can get instruction that leads them one direction or another, or forces them to use certain blocks over another in specific activities.

The big way Snap encourages bad programming, IMO, is through global variables (and other resources -- e.g., broadcast event names). Global variables are useful for certain audiences -- novices who write smallish programs, I guess -- but really harm students being asked to build bigger programs, do complicated things, etc.

I really can't see any situation where a global answer variable is better than reporter-ask. I see plenty of places where destructive list blocks are ok -- far fewer than BJC students use them, mind you! I think we can handle list stuff with curriculum, but I could be wrong...

Broadcast is between the two, imo. Its the "pub-sub" design pattern, I think, but a bad one with global message names (no oop, I guess?) or parameters. Its easy to understand, though, which is good, and novices can get started with multi-sprite stuff quickly enough. (Is use of broadcast within a sprite ever a good idea? -- I don't think so). But we have real functions -- which Scratch still doesn't have -- there aren't many times students should use broadcast over custom blocks. And when we get oop, there will be even fewer places to use broadcast. I think we should break from Scratch's design choice here. I guess what mostly bothers me is that the blocks are so prominent, even above looping and conditionals!

xtitter commented 10 years ago

Oh, and as I mentioned above, I can get the reporter-ask to break (due to race conditions).

http://snap.berkeley.edu/snapsource/snap.html#present:Username=nate&ProjectName=reporter-ask%20race%20condition

click the first 'bad-ask', type "ONE" and click the checkbox to submit.

Then, within a few seconds, click the second bad-ask, type "TWO", and click the checkbox.

The first bad-ask, at least for me, returns "TWO".

nathan commented 10 years ago

I really can't see any situation where a global answer variable is better than reporter-ask.

ASK Where should I go? AND WAIT IF ANSWER = north … IF ANSWER = south … IF ANSWER = east … IF ANSWER = west …

I think that's the kind of thing it was designed for.

nathan commented 10 years ago

or parameters

There's a feature where you can send any value as a message with BROADCAST, so you can send a list and then unpack the event name/arguments using the MESSAGE block in a WHEN I RECEIVE any message script. None of that makes any sense, and you have to use conditionals to switch on the message name, but at least it's possible.

nathan commented 10 years ago

there aren't many times students should use broadcast over custom blocks

Even though each can be abused to mimic the other, they have decidedly different purposes.

The power of broadcasts/event listeners/the pub-sub pattern is that the sender doesn't know or care what happens when it makes a broadcast. It allows you to decouple what triggers an event in one sprite from how other sprites respond; and it makes it much easier to change or add behavior later on without changing the part of the program where event occurs.

This is in contrast to the purpose of custom blocks, where the sender cares very much what happens when it calls the block. Procedures specify a very specific process for the purpose of reuse, whereas events specify a place for others to respond to a message without the sender specifying or depending upon how they respond.

jmoenig commented 10 years ago

Nate,

yes, you can make a reporter block in Snap that has side-effects, changes state and yields to other threads while it executes, your version of BAD ASK is a - somewhat constructed - example for this. But can also create this very simple ASK reporter I showed you that will avoid all race conditions. My first question would be: Isn't this ASK reporter I showed exactly what you want ASK to be? In your ideas world we'd only have that reporter and get rid of the other ones, right?

Thanks for divulging more into what you consider bad programming style. I definitely think it's worth understanding these issues and I agree that maybe we should let Snap diverge more from Scratch in some places, and I'm open to suggestions, after all, the whole point of BYOB/Snap! was to be different from Scratch in crucial ways.

But I also agree with Nathan (and very much so) on the issue of global broadcasts. I think Nathan really gets it right when he points out that the broadcast mechanism helps you decouple sprites or "modules" in a powerful and effective way that goes beyond invoking functions. My only concern with broadcast is that IMO there probably shouldn't be a "broadcast AND WAIT" block, as that one really does encourage (and even imply) abusing it for "subprocedures".

I also agree with you that global variables can be problematic, but in Snap we have much wider and more fine-grained control over variable scope and - most importantly - we have temporary variables which Scratch doesn't (personally I find the SCRIPT VARIABLES block to be the one thing I miss most in Scratch).

The real (technical) issue here are shared resources. The timer is such a shared resource. There is only a single timer in all of Snap and every sprite can access (and reset!) it. Of course it would be useful if every sprite also had its own private timer, and I sometimes find myself getting trapped when I forget about the timer being a singleton. The other shared resource is the prompter (the thing that pops up a question and lets the user enter a reply). There is only a single instance of the prompter and, like the timer, it is shared by all objects. My point is, shared resources are really common in computing, right? I mean, the mouse, the keyboard, the screen, the command line (in Scheme...) are all shared resources, right? So the issue that certain things are "global" (not really "global", you know, just shared among the objects in a single browser tab, not all over the world :-)) is not really a peculiarity of Snap or Scratch.

The other big thing that keep coming up is whether you like command blocks at all. In the functional paradigm a command block shouldn't exist, there would only be reporters, you could nest them and put them into lists which could directly eveluate as scripts. I think that's a very interesting model to explore (a visual Scheme), but it might also be somewhat less accessible for novices (besides being somewhat less "transferrable" to other programming languages). So, yeah, let's keep discussing this issue and how we can make Snap! better.

Thanks!

MMSequeira commented 10 years ago

Shared resources are not as problematic when they are immutable. I guess the timer might be immutable. Sprites needing to measure the passage of time would store the value of the timer at the beginning, instead of reseting the shared timer.

Also, the smaller the scope of the sharing, the better. A sprite shares a lot of state amongst its own scripts. This is as it should be: Snap! is still very much object-oriented, even if it also favors other programming paradigms. Sharing a mutable resource only within a sprite is preferable to sharing it globally. The "asker" is shared globally, since there is only one available, really. But the answer does not have to be shared globally. Each sprite can have its own. Even better, the answer might be an upvar in the ask command, making it script local.

This issue occurs in other cases. For instance, why not make the message an upvar in a special hat block for receiving any message? It is currently globally shared, which makes it hard to use correctly.

On Tue, Dec 17, 2013 at 7:40 AM, Jens Mönig notifications@github.comwrote:

Nate,

yes, you /can/ make a reporter block in Snap that has side-effects, changes state and yields to other threads while it executes, your version of BAD ASK is a - somewhat constructed - example for this. But can also create this very simple ASK reporter I showed you that will avoid all race conditions. My first question would be: Isn't this ASK reporter I showed exactly what you want ASK to be? In your ideas world we'd only have that reporter and get rid of the other ones, right?

Thanks for divulging more into what you consider bad programming style. I definitely think it's worth understanding these issues and I agree that maybe we should let Snap diverge more from Scratch in some places, and I'm open to suggestions, after all, the whole point of BYOB/Snap! was to be different from Scratch in crucial ways.

But I also agree with Nathan (and very much so) on the issue of global broadcasts. I think Nathan really gets it right when he points out that the broadcast mechanism helps you decouple sprites or "modules" in a powerful and effective way that goes beyond invoking functions. My only concern with broadcast is that IMO there probably shouldn't be a "broadcast AND WAIT" block, as that one really does encourage (and even imply) abusing it for "subprocedures".

I also agree with you that global variables can be problematic, but in Snap we have much wider and more fine-grained control over variable scope and - most importantly - we have temporary variables which Scratch doesn't (personally I find the SCRIPT VARIABLES block to be the one thing I miss most in Scratch).

The real (technical) issue here are shared resources. The timer is such a shared resource. There is only a single timer in all of Snap and every sprite can access (and reset!) it. Of course it would be useful if every sprite also had its own private timer, and I sometimes find myself getting trapped when I forget about the timer being a singleton. The other shared resource is the prompter (the thing that pops up a question and lets the user enter a reply). There is only a single instance of the prompter and, like the timer, it is shared by all objects. My point is, shared resources are really common in computing, right? I mean, the mouse, the keyboard, the screen, the command line (in Scheme...) are all shared resources, right? So the issue that certain things are "global" (not really "global", you know, just shared among the objects in a single browser tab, not all over the world :-)) is not really a peculiarity of Snap or Scratch.

The other big thing that keep coming up is whether you like command blocks at all. In the functional paradigm a command block shouldn't exist, there would only be reporters, you could nest them and put them into lists which could directly eveluate as scripts. I think that's a very interesting model to explore (a visual Scheme), but it might also be somewhat less accessible for novices (besides being somewhat less "transferrable" to other programming languages). So, yeah, let's keep discussing this issue and how we can make Snap! better.

Thanks!

— Reply to this email directly or view it on GitHubhttps://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-30731557 .

http://www.coderdojo-lx.pt/

cycomachead commented 10 years ago

I agree about the message upvar. Actually, there's a lot of use for hats and upvars, but I'm going to write that issue later this week after some finals.

Though Snap has lots of features to encourage good programming practices, the UI doesn't always encourage them. This is somewhat the case with Script vars (which I agree are great) because debugging with script vars is generally much slower than using globals, at least for larger projects.

Michael Ball http://www.michaelballphoto.com Photos & iPhone Apps!

On Tue, Dec 17, 2013 at 2:47 AM, Manuel Menezes de Sequeira < notifications@github.com> wrote:

Shared resources are not as problematic when they are immutable. I guess the timer might be immutable. Sprites needing to measure the passage of time would store the value of the timer at the beginning, instead of reseting the shared timer.

Also, the smaller the scope of the sharing, the better. A sprite shares a lot of state amongst its own scripts. This is as it should be: Snap! is still very much object-oriented, even if it also favors other programming paradigms. Sharing a mutable resource only within a sprite is preferable to sharing it globally. The "asker" is shared globally, since there is only one available, really. But the answer does not have to be shared globally. Each sprite can have its own. Even better, the answer might be an upvar in the ask command, making it script local.

This issue occurs in other cases. For instance, why not make the message an upvar in a special hat block for receiving any message? It is currently globally shared, which makes it hard to use correctly.

On Tue, Dec 17, 2013 at 7:40 AM, Jens Mönig notifications@github.comwrote:

Nate,

yes, you /can/ make a reporter block in Snap that has side-effects, changes state and yields to other threads while it executes, your version of BAD ASK is a - somewhat constructed - example for this. But can also create this very simple ASK reporter I showed you that will avoid all race conditions. My first question would be: Isn't this ASK reporter I showed exactly what you want ASK to be? In your ideas world we'd only have that reporter and get rid of the other ones, right?

Thanks for divulging more into what you consider bad programming style. I definitely think it's worth understanding these issues and I agree that maybe we should let Snap diverge more from Scratch in some places, and I'm open to suggestions, after all, the whole point of BYOB/Snap! was to be different from Scratch in crucial ways.

But I also agree with Nathan (and very much so) on the issue of global broadcasts. I think Nathan really gets it right when he points out that the broadcast mechanism helps you decouple sprites or "modules" in a powerful and effective way that goes beyond invoking functions. My only concern with broadcast is that IMO there probably shouldn't be a "broadcast AND WAIT" block, as that one really does encourage (and even imply) abusing it for "subprocedures".

I also agree with you that global variables can be problematic, but in Snap we have much wider and more fine-grained control over variable scope and - most importantly - we have temporary variables which Scratch doesn't (personally I find the SCRIPT VARIABLES block to be the one thing I miss most in Scratch).

The real (technical) issue here are shared resources. The timer is such a shared resource. There is only a single timer in all of Snap and every sprite can access (and reset!) it. Of course it would be useful if every sprite also had its own private timer, and I sometimes find myself getting trapped when I forget about the timer being a singleton. The other shared resource is the prompter (the thing that pops up a question and lets the user enter a reply). There is only a single instance of the prompter and, like the timer, it is shared by all objects. My point is, shared resources are really common in computing, right? I mean, the mouse, the keyboard, the screen, the command line (in Scheme...) are all shared resources, right? So the issue that certain things are "global" (not really "global", you know, just shared among the objects in a single browser tab, not all over the world :-)) is not really a peculiarity of Snap or Scratch.

The other big thing that keep coming up is whether you like command blocks at all. In the functional paradigm a command block shouldn't exist, there would only be reporters, you could nest them and put them into lists which could directly eveluate as scripts. I think that's a very interesting model to explore (a visual Scheme), but it might also be somewhat less accessible for novices (besides being somewhat less "transferrable" to other programming languages). So, yeah, let's keep discussing this issue and how we can make Snap! better.

Thanks!

— Reply to this email directly or view it on GitHub< https://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-30731557>

.

http://www.coderdojo-lx.pt/

— Reply to this email directly or view it on GitHubhttps://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-30741374 .

jmoenig commented 10 years ago

Michael, do you know that you can show script vars as watchers onstage using the SHOW VAR block? (and that executing the HIDE VAR block without an input hides all temporary variable watchers on script vars).

cycomachead commented 10 years ago

Yeah, but that process (while MUCH better than BYOB :)), is still much slower / more difficult than checkmarks for globals, or being able to simply have a variable in the scripting area and click it while paused.

Michael Ball http://www.michaelballphoto.com Photos & iPhone Apps!

On Tue, Dec 17, 2013 at 3:10 AM, Jens Mönig notifications@github.comwrote:

Michael, do you know that you can show script vars as watchers onstage using the SHOW VAR block? (and that executing the HIDE VAR block without an input hides all temporary variable watchers on script vars).

— Reply to this email directly or view it on GitHubhttps://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-30742783 .

MMSequeira commented 10 years ago

I did not know that! Great! How about using the Github wiki to start documenting Snap!?

No dia Terça-feira, 17 de Dezembro de 2013, Jens Mö nignotifications@github.com escreveu:

Michael, do you know that you can show script vars as watchers onstage using the SHOW VAR block? (and that executing the HIDE VAR block without an input hides all temporary variable watchers on script vars).

— Reply to this email directly or view it on GitHubhttps://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-30742783 .

http://www.coderdojo-lx.pt/

brianharvey commented 10 years ago

This is a great discussion -- I wish we were having it in the Snap! developer forum thread. :/ Let me throw in a few random comments.

  1. I am as much of a functional programming fan as anyone, but I think we should not conflate "functional" with "good" and "sequential" with "bad." Even Scheme, God's language, is not purely functional. It has the ability to put a sequence of procedure calls in a function body, and the ability to mutate variables and lists. There are situations in which Scheme programmers use global variables for non-constants (e.g., typically the first thing in a call/cc receiver is SET! (global) CONT).
  2. Jens, could we have a show/hide context menu item in the SCRIPT VARIABLE variables? That would be much easier than having to program in a SHOW VARIABLE block.
  3. My first reaction to the suggestion of a MESSAGE upvar in the WHEN I RECEIVE hat block was very positive, but on second thought, this would make sense only if the script were reentrant. (The problem you're trying to solve is that a second, different message is broadcast before you've finished processing the first one!) That might be nice, but it's a long discussion and a difficult implementation.
  4. I think it's misleading to use the name "variable," as some have done in this thread, for niladic reporters. MESSAGE, TIMER, etc. are not variables -- you can't SET them. (As a special case, you can zero TIMER, but not with the SET block.) So you can be against global variables without being against these.
  5. The tone of this discussion will change a lot once we get 4.1 OOP going. Then it'll be straightforward to send a request to a specific sprite.
  6. We can't eliminate BROADCAST AND WAIT without losing the ability to import Scratch projects. But maybe we could find a way to "deprecate" blocks? Put them in a separate palette? We'd do this simultaneously with introducing OOP. Maybe we could even deprecate the "Make a variable" button. :)
  7. One thing we could do to make Nate happier, although it would be really drastic and we shouldn't do it lightly, would be to make "for this sprite only" the default for variables. That wouldn't eliminate any capabilities, but would make users decide consciously that a particular variable has to be shared.
  8. I get two weeks of no school starting next week, and I'm going to use them to update the manual, I promise!
nathan commented 10 years ago

We can't eliminate BROADCAST AND WAIT without losing the ability to import Scratch projects.

I'm not really sure we should eliminate it at all. It's pretty useful, and the workaround isn't trivial as it requires you to change every script that receives the message.

Scimonster commented 10 years ago

One thing we could do to make Nate happier, although it would be really drastic and we shouldn't do it lightly, would be to make "for this sprite only" the default for variables. That wouldn't eliminate any capabilities, but would make users decide consciously that a particular variable has to be shared.

Ooh, yes!

BROADCAST AND WAIT is pretty useful, and also complex, as @nathandinsmore said. I wouldn't want to rewrite it manually each time.

But I also agree with Nathan (and very much so) on the issue of global broadcasts. I think Nathan really gets it right when he points out that the broadcast mechanism helps you decouple sprites or "modules" in a powerful and effective way that goes beyond invoking functions. My only concern with broadcast is that IMO there probably shouldn't be a "broadcast AND WAIT" block, as that one really does encourage (and even imply) abusing it for "subprocedures".

Even BROADCAST AND WAIT is good for modules. A great example is for adding hooks. Do something, run hooks, then continue.

xtitter commented 10 years ago

Yes, good discussion.

I tend to doubt that the broadcast mechanism in Snap get used for good -- modular design -- than for bad in student programs. In functionless Scratch it was a convenient solution for cross-sprite control flow, but Snap can grow in ways Scratch couldn't.

But, it is easy to use and solves some problems quickly. I misspoke above if I intimated that I'd like it removed -- I'd just like it deemphasized for my audience, especially broadcast and wait. We are currently getting it out of the early parts of our BJC curriculum, if we get "tell" soon enough.

(And I'm not doctrinaire by nature! I don't want command blocks removed! I write Java programs with loads and loads of state -- its all scoped as tightly as can be, but my Scheme side turns away in shame).

Making new variables sprite-local by default is fine, but much of the BJC student's code sits inside a single sprite, so it wouldn't change anything there. I'd be happy with a more functional 'script variable' block, where the local vars could be set -- a (local variable (a) as (init)) block -- so that making a local variable was as easy as making a global, or at least easier.

kach commented 10 years ago

From my 10-year-old self's experience teaching himself Scratch:

I don't doubt that functional programming is the "right"—or, at least, mathematical—way to code. But when you start out, you don't know about scope, or lambda, or applicative order evaluation. And you shouldn't care (or, more importantly, have to care).

When you're a beginner, global variables make a lot of sense (think: "Why can't I access x from the Stage? What does 'local' mean? Why would I want this variable hidden to other objects? I know I won't reuse this name anywhere else…"). My favorite Scratch programs aren't huge monstrous-but-excruciatingly-organized masses of code, they're usually simple scripts that do interesting things. And simple Scratch scripts don't need to be written in a perfect, optimized way. Since Scratch doesn't have a very strong sense of modules (yet!), you can have globals floating around without causing any damage. Contrast this to, say, JavaScript, where the use of various libraries and stuff make defining one-letter globals scary—though if you were writing a few lines of node to automagically move some files or whatever, it's perfectly fine.

I digressed a bit there, but I stand by my premise that both Scratch and Snap! should be liberal-arts-major-proof: you shouldn't need to know some computer science beforehand to write a simple program; writing the program should teach you the computer science (so a student should eventually realize that OOP/cloning will need some sort of object-specific variable and discover local variables/let bindings/whatever). So my opinion here is to default to global variables, have a global answer, etc.

Whew. On to broadcasts: they are incredibly useful. You teachers probably don't realize how important it is to Scratchers to be able to make animations, and broadcast is the perfect block for animations. When you want to start a new scene, you don't want to call a procedure just for that scene. You just want to trigger a new process. Granted, Scratch makes you think linearly. But stories are linear! You don't have recursive stories. So for Scratch, broadcast is essential, and so Snap! should support this feature.

I guess you all (bh, Nate, Jens) haven't really learned CS from Scratch, so you don't immediately see the distinction between writing a module/library/Morphic.js-level-code and writing a short program to do something simple—the latter doesn't need as much care or foresight as the prior. Even though that foresight is necessary to learn someday, it shouldn't be forced upon you. That's why I prefer Python over Java for a casual script: Java has too much boilerplate, it enforces making the program in a way that it is hugely scalable.

Sidenote: I think the one good thing about @jpaley's class and the AP curriculum is that they teach you to deal with huge mounds of code with lots of libraries, and they also teach you how to solve problems with Scheme, but they do them separately.

brianharvey commented 10 years ago

Don't worry -- we're not going to get rid of global variables.

I think that the ability to hide primitives, which Jens used to hate but has now embraced, will solve a lot of the problems seen by curriculum writers such as Nate. It would be very convenient if logged-in users with a project called STARTUP had that project loaded on entering Snap! and in response to File>New. Then teachers could distribute startup files to their students that would customize Snap! for their classes automagically.

That way, for example, BJC students could see only reporter ASK in the Sensing palette, but immigrants from Scratch would see what they're accustomed to.

I think that plus the TELL-with-dropdown-sprite-list interim semi-OOP thing would make BJC developers happy.

cycomachead commented 10 years ago

I do agree with what @Hardmath123 says about Snap being easy.

I also don't think Sprite scoped variables are the best thing to default to because it's not very clear that they are scoped in the UI. But, like Nate said, I don't think it would affect too much for BJC students. Personally, I do think it makes sense to leave those global, but I don't have a strong opinion.

To the point about broadcasts and animation -- that /is/ the reason we use Snap, or at least a huge part. And broadcast is definitely a great way to do that, especially for starting out. However, as more and more students use snap in the classroom they are creating larger and more complex projects.

The model I think about for Snap is this: Snap should definitely allow terrible and easy programming -- since pretty much every language does. However, it should encourage where possible, but definitely allow better programming practice and to create more expandable projects.

I do like the startup file idea, but there's lots of work that would need to happen to make that work well. (Especially since importing even a small project is somewhat slow, and custom blocks are always stuck at the bottom.)

Side point: Do we have /any/ data about who uses Snap, where they use it and what they use Snap for? A lot of that info would be immensely helpful in deciding where to go with Snap because it would give us more info about the audience. It would be interesting to know, too, about what types of projects people are using Snap for...

brianharvey commented 10 years ago

I think we can basically assume that the users of Snap! are BJC students and teachers (including various BJC-lite offerings), plus a handful of Scratch-mod enthusiasts. There are others, but to a first approximation we should make design decisions based on what BJC needs. Plus, of course, trying to be the perfect language. :-)

cycomachead commented 10 years ago

I think we can basically assume that the users of Snap! are BJC students and teachers (including various BJC-lite offerings), plus a handful of Scratch-mod enthusiasts. There are others, but to a first approximation we should make design decisions based on what BJC needs. Plus, of course, trying to be the perfect language. :-)

That was my thought as well! Though, I still want to push for browser stats and OS versions because that can be a huge boon towards guiding development and testing.

joefarebrother commented 10 years ago

My thoughts of the issues: 1)Ask reporter: I think it is a good idea to have an ask reporter, scratch projects which are rely on the command can be given a global variable, and all instances of the ask command can be silently replaced with set [global answer v] to (ask reporter [...]). 2)Broadcast and wait: It should not be removed, because it is relied on by so many projects and the workaround is non trivial. It is easy, in comparison, to implement broadcast from broadcast and wait (hint: launch), but this is not a good idea because broadcast does not cause bad habits relating to custom blocks. Broadcast and wait should bee taught in such a way as to not encourage the replacement of custom blocks, but rather as a pub/sub event system; for example I can think of a situation where you might want to provide a hook in the program, that is agnostic as to if it will do anything and what it will do. I can also think of situations where it could be the basis of an event system, for example "the user clicked a button; broadcast 'button clicked' and wait, if no other sprite cares nothing will happen and if they do they can handle it", although I think broadcasts need parameters, and the when i receive hat needs an upvar to hold the parameters. Scratch (currently) needs broadcasts because custom blocks are only sprite-local, so broadcasts are the only form of modularity. Another use for broadcasts in scratch is to store the name of a broadcast in a variable and write general-purpose scripts that broadcasts it; while i've never seen another project do it, it has come up in the design for my scheme interpreter in scratch (which I need to give myself time to work on!!!) in snap! we don't need that as we have lambda. Another thing I think about broadcasts is it will be better if they weren't global; there could be different "groups" of sprites that can access different broadcasts. In scratch I get around this with prefixes, this is not ideal for large stuff such as my scheme interpreter. 3)Global state: I do agree that variables should be local by default, to naturally guide the programmer into more modular programming, but I think the GUI needs to do more to distinguish global from local variables; even just a horizontal line as in scratch will suffice for now. I think there should also be a more sophisticated form of scoping; there could be different groups which can access different variables. The reset timer block should be deprecated (if not outlawed and carry a penalty fine of £31415926.53 for using it:)) because it IS harmful to programming style; there is nothing you can do really about the race condition of some other thread using reset timer whilst in a section that requires timing and simply has to assume that the timer won't jump from 1337 seconds to 0 when relying on it becoming 1340 within 3 seconds but it actually taking a little over 22 minutes. Also back to the subject of variables, script variables is like let, but there needs to be an analogue of ML's and Haskell's where as well because it makes things a lot clearer with things like auxiliary methods in scripts; what's better:

script variables aux
set aux to lambda {
... lots of code here ...
}
run aux with inputs (... a few things...)

where it's easy to miss that last block, or

run aux with inputs (... a few things ...)
where aux = lambda {
... lots ...
}

where it's clear from the start how the axillary function is used? I know it's easy to make this block, but when you need to have two axillary things you have to either make this block with two variables with almost exactly the same code, or have loads of ugly nested c blocks. This means we need a way to have multiple instances of a group of arguments in a custom block. 4)Functional vs procedural Snap should encourage functional programming, as I believe the majority of programmers will never otherwise encounter. However, the tricky part it that it shouldn't discourage imperative programming either, and it is not a paradigm that should be labelled as "bad" (no programming idea should be (Microsoft-hate removed by me :))) (I agree with Randall Monroe parenthesized expressions ending with emotions look unbalanced :)). While global state and other imperative evils should be discouraged, the idea of mutable objects is a very useful one. I think linked lists and dynamic arrays should be different data types externally as well as internally because otherwise this encourages the mixing of the two paradigms in an unhealthy way. For example in a project I'm working on some of the lists are supposed to be functional ones and some are meant to be imperative ones, and it's a little hard to keep track of which is which. I think it also allows for a slightly more efficient implementation by removing the wrappers around JS arrays internally.

jpaley commented 10 years ago

On Wed, Dec 18, 2013 at 12:26 PM, joefarebrother notifications@github.comwrote:

4)Functional vs procedural Snap should encourage functional programming, as I believe the majority of programmers will never otherwise encounter. However, the tricky part it that it shouldn't discourage imperative programming either, [snip]

Aye, there's the rub. The problem I see is that if assignment is available, students may try to work around attempts to teach topics such as recursion. Scheme is nice in that it forces a particular way of thinking; Python allows that way of thinking, but doesn't naturally drive it. I base this on watching students with experience in imperative programming languages address recursion as opposed to how students who are "uncorrupted" (lacking a better word) write clean code.

I'm not taking a position one way or the other on how Snap! should handle these things. I just think it will, on average, be harder to teach functional programming when assignment is there from the get-go.

kach commented 10 years ago

([meta] You follow the Github issues? Eek, I should be more careful what I say on here. :P)

The problem is that you can't do things like animate a sprite in a purely functional environment. Moving sprites around is inherently imperative.

nathan commented 10 years ago

The problem is that you can't do things like animate a sprite in a purely functional environment. Moving sprites around is inherently imperative.

http://en.wikipedia.org/wiki/Functional_reactive_programming ;)

EDIT: Or monads.

kach commented 10 years ago

But… that's like QC. Yucky. "Move 10 steps, turn left, say 'hi', turn left, move 10 steps" should be represented as a sequence of commands because that's what it is. (I mean you could just put all commands in a list for sequential evaluation, but that doesn't seem right.)

(Also, what's with the weird new avatar?)

brianharvey commented 10 years ago

On 12/19/13 2:22 PM, jpaley wrote:

Scheme is nice in that it forces a particular way of thinking;

Actually, it doesn't. Scheme has SET!, SET-CAR!, SET-CDR!, VECTOR-SET!, etc.

I think this is all about curriculum, not language features. We should discuss (but not on the Snap! github, probably) whether BJC should be rearranged and rethought so that we build custom blocks from the beginning, and use SCRIPT VARIABLES as the only form of variable building for the first few units.

A very radical possible Snap! change that nevertheless wouldn't break anything would be to reorder the variables palette so that the MAKE A VARIABLE button is down next to MAKE A BLOCK.

xtitter commented 10 years ago

A very radical possible Snap! change that nevertheless wouldn't break anything would be to reorder the variables palette so that the MAKE A VARIABLE button is down next to MAKE A BLOCK.

I think this should wait for a wider-ranging palette refactoring.

Another issue wrt global variables is that the Snap UI makes it easier to debug with global/sprite variables over script and custom-block local variables... in that watchers are the primary way (only way?) students inspect state.

cycomachead commented 10 years ago

I think this should wait for a wider-ranging palette refactoring.

Another issue wrt global variables is that the Snap UI makes it easier to debug with global/sprite variables over script and custom-block local variables... in that watchers are the primary way (only way?) students inspect state.

Yes, and yes, and yes, and yes. ...oh, and yes! I definitely think we should have a discussion on cleaning up the palette and making those two next to each other. :)

brianharvey commented 10 years ago

We already have a plan for this (right, Jens?): add a show/hide option to the context menu of variable blobs.

brianharvey commented 10 years ago

This is a great discussion but it's no longer a Snap! issue, so closing.

cycomachead commented 10 years ago

Fortunately its always here as a reference. :)

Michael Ball From my iPhone http://michaelballphoto.com

On Jul 10, 2014, at 1:29 PM, brianharvey notifications@github.com wrote:

Closed #276.

— Reply to this email directly or view it on GitHub.

joefarebrother commented 10 years ago

Scheme is nice in that it forces a particular way of thinking; Actually, it doesn't. Scheme has SET!, SET-CAR!, SET-CDR!, VECTOR-SET!, etc.

Well it naturally drives it while still making imperitive stuff possible if needed.

On 10 July 2014 20:46, Michael Ball notifications@github.com wrote:

Fortunately its always here as a reference. :)

Michael Ball From my iPhone http://michaelballphoto.com

On Jul 10, 2014, at 1:29 PM, brianharvey notifications@github.com wrote:

Closed #276.

— Reply to this email directly or view it on GitHub.

— Reply to this email directly or view it on GitHub https://github.com/jmoenig/Snap--Build-Your-Own-Blocks/issues/276#issuecomment-48661834 .