I'm somewhat undecided about the benefits of being able to let a sprite 'sense' another sprite's variables.
The upside is that it makes some operations easier to code and eliminates the need to manage a lot of global variables.
The downside is, that this effectively breaks Scratch's modularity and shareability by hardwiring both sprites (the 'sensing' sprite and the 'sensed' one) together and making it impractical to share such a 'sensing' sprite from one project to another using the export / import feature. As a result, Scratch projects relying on this new command block can quickly become one big entangled and very complex 'spaghetti'-mess.
Another downside is, that this takes away much of the distinction between variables which are visible for all sprites ('gobal') and those which can be accessed by the sprite for which they are declard only ('local').
I'd rather be able to let a sprite define which of its own variables it wants to be seen by other sprites.
What are your thoughts on this issue?
Offline
I see your point about sharing, but disagree on the "messy entanglement". I did a few "big" Scratch projects, whined about variables in the forums (because the huge list of variables gets so hard to manage in the "variable pane"). I made some suggestions about pull-downs for variables and renaming variables (still good ideas, I think) and then pretty much gave up on Scratch except for trying to be helpful by answering forum questions with simple demos.
I got excited about Scratching again after learning that the sensing block could "look" at another sprite's variables. With some initial planning about what variables will be needed and which sprites will just need be able to "know" a variable's value and which will have to be able to change the value, it's possible to drastically reduce the number of global variables.
My latest effort is getting very big (I'm into writing video games), and I have only a handful of "globals". I rarely even look at the variable pane after setting up the local variables that the current sprite will need. Using the new "sensing" block obviously does away with the need for a lot of variables that had to be global so other sprites could "read" them, but it also "exposes" custom "properties" (local variables). I find this enormously convenient, and easy to use, instead of searching thru a list of globals, I only need to select the name of the other sprite of interest and pull down its list of goodies.
It seems to me like this is a very nice intro to the idea of properties like other languages that young Scratchers will eventually work with; "Set (mylocalVariable) to (enemyPlane.Velocity)". It would be nice to be able to access the global variables in the same way.
I've mentioned the "danger" of globals in a couple of forum posts, advising folks to only use a global if you absolutely need to have more than one sprite be able to change the value. I think a lot of Scratchers are using things like "Wait until (someglobal) < 1", and getting unexpected results because more than one sprite is able to change the global. Tracking down "who" is changing it can really be difficult.
I haven't tried to do much sharing of Sprites, other than the "graphic" part, but it seems that if a sprite was looking at a global variable in its original project and you exported it and pulled it into a new project that didn't have that variable defined, you would be faced with the same broken "link". A meaningful variable name or a good comment could make it easy to "reconnect" the sprite into the new project. Imagine pulling in a sprite, then looking at it when it doesn't work right and finding this broken sensing "reference":
Set (myLocal) to "Sense (?) of (?)" 'Comment: This variable stores the enemy plane's Velocity, used to decide if afterburners are needed to catch up.
or
Set (myLocal_EnemyPlaneVelocity) to "Sense (?) of (?)"
Even without a comment, figuring out what to "connect" to would be easy.
So, I like the new variable sensing ability a lot. I'm happy with it as it is, I haven't yet seen the list of locals get so big that I'd want to be able to limit it.
-MrEd
Offline
Like Jens, I was worried that exposing other sprites' local variables would break the information-hiding that is so central to making modular programs.
Like Mr. Ed, I found that being able to examine the position and other state variables of other sprites simplified and cleaned up my code considerably.
In my C++ programming, I often find it useful to equip my classes (the closest equivalent c++ has to sprites) with functions that allow read-only access to the internal state. Scratch is doing this automatically now for much of the state of the sprite (not the graphics effects, pen settings, instrument #, hide/show status, level, speech balloon, ...).
I've decided that scratch is better off now with fewer global variables and with read-only access to other sprite's state. I would like the block moved from "sensing" to "variables" and have all the variable blocks use the same pull-down menu interface. Setting and changing would only allow access to global variables and this-sprite variables, but the block currently in sensing could replace all the variable blocks.
(There would need to be a new block to control the display of variables.)
Offline
Kevin, I like your idea of moving the variable-sensing block to the variables section and use the same pull-down menu interface. I agree that it would make Scratch more consistent.
I'm still not convinced, however, about read-only access to *every* local variable in every sprite. One concept I very much like in Scratch is being able to share and remix mostly everything you create. Not only whole projects but also sprites (I even think that being able to share single scripts would be a great benefit to Scratch).
The whole 'blocks' interface implies modularity in every layer of Scratch. You can simply snap an unsnap blocks and scripts to make your sprites do someting. Likewise you can exchange sprites (almost like 'blocks') by exporting them from one project and dropping them into another one. If your sprite accesses a global variable, this variable will automatically be generated in the target project if it's not already there. Not so, if you're 'sensing' other sprites' local variables. Therefore it can be pretty hard to map and keep track how sprites are interlinked to each other if you're extensively using variable-sensing. Especially if projects become big, i.e. use a lot of sprites.
Also, sometimes local variables are purely 'internal', such as counters, indexes or partial results. Exposing them (even read-only) doesn't seem wise to me, because it confuses the sprite's public interface. What I'd really love to be able to do is have one sprite 'ask' something of another sprite, and have the other sprite 'answer' a result.
in sprite1: set variable to (ask 'something' from 'sprite2') in sprite2: when I'm asked 'something' answer (a number)
Per default the 'ask'-block could assume 0 as an answer, if the receiving sprite e.g. does not implement an answer.
This would let the programmer really control the sprite's public interface without the need for direct access to other sprites internals. It would also make creating big projects a lot easier, I think.
Offline
While I have been enjoying the new access to other sprites local variables, I do agree that it is probably too much information exposure. I like your idea of having a more formal information passing mechanism but I don't think we need an actual argument list, which I think is what you are proposing. Rather, it could be something as simple as a checkbox next to the variable in the variable list (Shared/Not shared) with the default being Not Shared. This would allow the programmer to hide internal variables yet expose variables that are needed by other sprites. There would be no need to change existing access syntax.
I don't think this would damage sprite reusability any more than asking for argument values that may or may not be supplied. If the values were not being supplied, what would you do? You would have to open up one or both sprites and make some changes. How is that any better than making use of another sprites local variables, provided they were formally exposed?
Offline
I like the Shared/NotShared idea, as it could help limit the list and what is intended would be clear to beginners.
I haven't experimented to see what an "unconnected" Sensing block looks like or what it returns (I'm guessing "zero").
Perhaps the reuse issue could be addressed (at least partially) by highlighting an "unconnected" Sensing block in some way. Something like the way Fatal errors cause a script or block to get a red "halo" might work. Flashing yellow halo around the block?
Off topic a bit: It bugs me that a Fatal error just locks the script without letting the programmer know what is wrong. The first time I encountered a Fatal error, I'd constructed a loop that caused a variable to "blow up". The problem was pretty obvious, as the variable display was on screen and I could watch it go from a reasonable number, to really big, to scientific notation until it finally "blew". I'm sure new programmers will run into divide by zero errors, and end up wondering why their script went all red.
It would be nice to have a message (maybe like a tool-tip) for the unconnected block "warning" (and the Fatal error). Jen's concern that re-connecting may be difficult is correct, but I think the same could be true of Global variables that a Sprite brings into your project. What happens if you have already used the name of the new global (with some other meaning) or it isn't clear what the new Global represents? In either case (Sensing block or Global variable), the only way I see to make things easier is to use descriptive variable names or put in good comments.
-Mr Ed
Offline
I already encountered something strange trying to import a sprite that used global variables. It came in okay, and it created the globals to go along with it. But none of them worked right; they acted like two sets of local variables with the same names. I had to manually pull each reference to a global variable from the script and then drag in what looked to be the exact same variable from the variable list and stick it back in the script before it would work right. Weird.
I agree that fatal errors could certainly be handled more gracefully than the current "red halo". It isn't very informative!
Offline
Jens's idea, to have "ask <something> from <sprite>" and
"When I'm asked <something>"
....
reply <value>
is a nice way to do a sort of function call.
It could be combined with Paddle2See's Shared/NotShared checkbox (though perhaps the checkbox would need a different name), by having the Shared checkbox equivalent to a script
When I'm asked <variable name>
reply <variable>
Offline
if variable sprite 4 (whatever u want) = 500
broadcast 500 = health
Offline
Heybrian, I don't understand your post. Could you please explain what you mean.
Paddle2see wrote:
I already encountered something strange trying to import a sprite that used global variables. It came in okay, and it created the globals to go along with it. But none of them worked right; they acted like two sets of local variables with the same names.
Yeah, I noticed this, too. I found out, that saving the project to disk resolved this issue and made the globals work alright.
Kevin, you're absolutely right about my suggestion basically being a call for a simple function feature (without parameters) in Scratch. Allowing sprites to 'respond' / 'answer' to requests by other sprites could not be restricted to answering its local variables, but also let them answer derived computational results, i.e. one sprite could have the script for a certain algorithm and provide this knowledge to other sprites.
Offline
The (Set myVariable to "Ask <something> from <othersprite>") idea is intriguing.
(It reminds me of a post I saw in the forums about "private broadcasts", which could be something very similar (Broadcast <message> to <otherSprite>). I'm skeptical about the "private broadcast" idea, because you can already achieve that by just not having a "receive" in the sprites that don't need to listen, but I suppose it would help debugging.)
Anyway, it wouldn't be much of a stretch to have: (Set myVariable to "Ask <something> from <otherSprite> using <myOtherVarible>") with a cooresponding "Reply" block in the other sprite.
While the Scratchers contributing to this post can all see the utility of these, I'm afraid we're wishing for more than the developers want Scratch to have in it, given the intended target audience. It's fun to speculate and discuss, but are we discussing "Scratch++"? I'd actually buy Scratch++, but if it was available, what would become of Scratch?
It would be interesting to get some more input from the developers on "where we would go with Scratch if you dreamers can figure out a reasonable way to implement it" vs "stuff you shouldn't even bother fantasizing about". We could concentrate on helping to figure out intuitive ways to implement the stuff that is likely.
IMHO: good candidates would be Share/NotShare for locals, Variable renaming, Variable "Pull-Downs", some simple Debug tools and Comments (already desired and in the works) among other ideas in this thread and others (credits to all here as well as others).
-Mr Ed
Last edited by EdnaC (2008-01-16 13:21:29)
Offline
EdnaC wrote:
I'd would be interesting to get some more input from the developers on "where we would go with Scratch if you dreamers can figure out a reasonable way to implement it" vs "stuff you shouldn't even bother fantasizing about". We could concentrate on helping to figure out intuitive ways to implement the stuff that is likely.
I agree with you 100% on this, Mr. Ed. While the academic exercise is fun, how much of what we talk about is even in the developer's vision of Future Scratch? Some feedback from the develpment team would be very helpful here.
Offline
I have been thinking some more about 'asking' and 'answering' in Scratch. Here are my current thoughts on how these blocks would look and what they might be doing:
'ask'-block
this would be a round green numerical block with two drop-down lists, one for a 'question' name (a simple string like a broadcast) and another one for the target sprite (self, stage or any other sprite). Basically like the current round blue variable sensing block, only that it wouldn't directly access the target sprite's internals but kindly request the target sprite to provide a (numerical) answer instead, and also be able to direct a question to itself.
'answer'-block
this would be a yellow event-hat titled 'when I'm asked' followed by a drop-down list of question-strings (like message names). Its body would look like a forever-loop, with the 'answer' command already in place at the bottom, followed by a round numerical argument place holder with '0' as default. (Is this clear?). The space in between the event-hat and the bottom-answer ('nested block') could be either left empty or used to perform stuff needed for the answer.
I must admit, though, that so far I haven't been able to come up with a really conclusive example demonstrating any advantages of this function-mechanism over the current direct variable-sensing block other than soothing my uneasyness regarding public exposure of a sprite's internals, so perhaps I should just ignore my trained OO dogmas and accept that Scratch is something altogether different....
Offline
I think that Jens's "ask" and "answer" blocks are a good metaphor for function calls—clearer to kids than the broadcast/receive. One problem is that there must be exactly one "when I'm asked" script in a sprite for any question that a sprite can be asked.
Some things to think about:
Should questions and messages be the same or different name spaces? Different programming languages have taken different approaches to this question. In some (like FORTRAN), functions that return values are distinguished from procedures that don't return values. In others (like C), all functions and procedures are in the same name space, and in still others (like C++), the type of returned value and arguments is effectively part of the name. My initial, gut reaction is to agree with Jens that messages and questions should be separate name spaces.
Should you have to fall through the "when I'm asked" script to return an answer, or should you be able to "answer" from any part of the script. This is essentially the question of whether there is a "return" statement in the language. Personally, I find that "return" statements make for simpler, cleaner code, but it would be easy for beginners to forget to put in "answer" blocks. Perhaps the best compromise is to have Jens's idea of a built-in "answer" at the end of the the "when I'm asked", but to allow the programmers to have other answer blocks inside.
Offline
kevin_karplus wrote:
One problem is that there must be exactly one "when I'm asked" script in a sprite for any question that a sprite can be asked.
Excellent point, Kevin! How could this constraint possibly be addressed?
One way I can think of (probably the easiest one, since Scratch is a dynamic environment) could be to only display those question names in the drop-down list of a "when I'm asked" hat block which aren't already in use in that particular object (sprite or stage). However, there would also have to be some mechanism to reset its name-string to nil when it is being copied within the same object or into another object already answering to that question.
Another way could be to just disregard this constraint and use whichever result is returned last. This would, of course, lead to random results, but would in effect be the same as broadcasting a message and waiting, until possibly numerous scripts triggered by that message each set the value of the same global variable.
I'm kind of leaning towards the latter, because it wouldn't rely on some hidden functionality in the Scratch IDE but instead leave handling within the Scratch programming language itself and up to the programmer.
I also like your idea of allowing separate 'answer' blocks. One problem I see with these is, how to ensure that they could only be used within a script triggered by a "when I'm asked' event hat.
You know, this kind of discussion is exciting, because since Scratch is now (officially, it seems) open-source, we might actually experiment with implementing some of these concepts ourselves, once we feel convinced by the results of this "academic excercise" [Paddle2see].
Offline
Jens wrote:
You know, this kind of discussion is exciting, because since Scratch is now (officially, it seems) open-source, we might actually experiment with implementing some of these concepts ourselves, once we feel convinced by the results of this "academic excercise".
That's a very good point that somehow slipped my mind. I'll start learning SmallTalk immediatly!
Offline
Is the intent for the open source team to develop the "mitScratch" that is distributed via this site?
Or will the open source team develop something different so that there is "Scratch by MIT" and the new language ( "Scratch++ " or "SuperScratch")?
Offline
Hey Mr. Ed,
I don't know of any 'open source team'. (wanna join? <nudge>, just kidding...)
Myself, I'm not about to develop anything, let alone a different version of Scratch. I admire the 'real' Scratch by MIT way too much, and have way too little time on my hands to dive into a big programming project (besides knowing way too little about real programming anyway).
But I do love participating in discussions like this one with bright people like you
from around the world, and I believe the 'Advanced Topics' section in the forums is just the right place for this. I've also seen discussions like this one lead to new ideas within Scratch itself, though this shouldn't neccessarily be their primary objective.
Another thing that intrigues me is not just to speculate about the feasibility of some wild idea, but to actually go ahead and try it for real. That's why I enjoy playing with the Scratch source code. I don't want to (and certainly cannot) make Scratch any better than MIT, but I love experimenting. After all, what harm can be done by that?
And I found fiddling with the source code to be far easier than I expected. Since it is all Squeak, everything can be read, evaluated, inspected and modified on the fly while the system is up and alive, without any compile-link-run cycles. If there's an error, nothing will blow up in your face or kill your computer. Instead the worst that'll ever happen is a friendly pink walkback window notifying you about which part of your code it doesn't understand, and letting you fix that immediately *in itself* without even having to restart the application afterwards. Besides, there are no hidden 'secrets' in the source code accessible only to initiated gnostics, but absolutely *everything* is there for you to read and understand, even the virtual machine. This is a fascinating (and courageous) degree of openness I have observed only in very few other so called open-source projects.
To sum it up, I'd claim that discussing Scratch-ideas and playing hands-on with the Scratch source code is one way to express appreciation for Scratch!
Having said this, any more thoughts about localized data-retention, public visibility of local/private variables or function-calls? ...
Offline
I have trouble imagining a consistent way to do "function calls". It seems to me that this points in the direction of building your own block more than something that is specific to a sprite. Something like a forever block, but with a blank for a "name" and a blank for "gets value" at the top of the block and a space for "reply with" at the bottom. But would the reply be a variable that is part of the block (an extra-local variable)? What would be allowed within a built block?
My latest project got me started pondering 2+ dimensions, and I'm thinking more about how nice it would be to have more control of and information about the "layer" that a sprite is on. This is something that could be done with what exists now in Scratch (I think). If there are as many layers as there are sprites, which I'm guessing is the case, you should be able to know which layer a sprite is on and be able to "insert" it at a different level in the stack. Some kind of display might be needed to help make sense of it. As it is now, who's on top is about all that can be controlled.
-MrEd
Offline
MrEd, there are several threads on layers and ways to improve them on the forum. You might want to search the forum for them and add your thoughts to that discussion.
I think that Jens's ask/answer mechanism is a good way to introduce the notion of function calls without needing all the GUI for custom blocks (though custom blocks are also a good idea). The reply from an 'answer" need not ever be a variable. For example
say <ask sprite what quadrant?>
when I'm asked what quadrant?
if x position> 0 and y position >0
answer 1
if y position >0
answer 2
if x position >0
answer 4
answer 3
Offline
Hi, all.
A quick terminology point:
Although the source code for Scratch is available so that people can experiment, it is not "open source". Usually "open source" implies a project built by community effort, one that actively seeks code contributions. Scratch is more like a product from a company (although in this case, it's free and the "company" is an academic institution).
There is definitely a place for experimental variations of Scratch--that's the whole point of making the source code available.
Please note that, to avoid confusion, the licence requires that experimental variations must not be called "Scratch" or even have "Scratch" in their name. For example, the name "Scratch++" is not allowed (although the idea of an advanced variation of Scratch is intriguing and I hope someone pursues it).
-- John
Last edited by johnm (2008-01-20 10:42:37)
Offline
MrEd wonders if the MIT Scratch team is likely to adopt the ask/answer proposal.
We make Scratch design decisions as a team, and my opinion is just one input into the decision process. That said, here's what I think.
Personally, I love language design, I love object-oriented languages, and I enjoy thinking about possible language features even if they never get implemented.
But in deciding what features to add to Scratch, I'm cautious and conservative. Scratch is wildly successful at getting a wide range of people to program, including many who do not think of themselves as "programers" and who would have no interest Java, Python, Squeak, C++, or any other professional programming language. It would be a shame to introduce features that make Scratch less fun and friendly to such people, even if those features would be useful to more advanced users. After all, there are many cool languages available once you've discovered that programming is fun, but Scratch is one of the few that welcomes beginners and invites them to make that discovery.
Many of us professional programmers got started by playing with BASIC as kids. Today we consider BASIC a "badly designed" programming language but I had fun with it. In fact, BASIC was actually a great intro to programming. It's perfect for writing programs of a few dozen lines. You can get started quickly and then learn additional commands incrementally. It's model of computation is very clear. And by the time you hit it's limitations, you know enough both to learn your next programming language and to appreciate the additional features that make it easier to write larger and more modular programs.
Scratch is the modern equivalent of BASIC. It lacks many of the features found in modern object-oriented programming languages, such as being able to send a messages to specific a object and get its reply (which is what Jen's "ask/answer" proposal does), being able to control the visibility of variables and methods, classes, inheritence, exceptions, and so forth. Those are all powerful features, but I dont think they belong in Scratch.
However, as I said, I enjoy thinking about potential language features even if they never get implemented, and I hope many of you do, too. I value these discussions, and we do sometimes incorporate ideas from such discussions into Scratch. In fact, the block that reports a sprite's instance variable grew out of a forum discussion.
So, discuss on!
-- John
Last edited by johnm (2008-01-20 10:40:25)
Offline
Thanks for responding, johnm. My first programming language was BASIC and its easy accessiblity created a lifetime love of programming for me. I agree fully that new features should only be introduced to Scratch only after extensive deliberation. I heard it said once that a design is perfect when nothing more can be taken away. The beauty of Scratch is it's simplicity. But it is fun to think about potential improvements and I expect we'll keep doing it. I personally would love character strings...but I don't want to hijack the thread (sorry kevin, I'll take it elsewhere!).
Offline
Thanks, John, for your clarification on terminology. I assumed 'open source' to denote just readability of source code (like an academic paper) regardless of its license, i.e. not neccessarily including the right or feature to mod it into something else. I still think that letting others look look over your shoulder and allowing them to discuss your code in public is about the boldest and most daring step a programmer can undertake!
By the way, I started out with BASIC, too, and it got me hooked onto programming as well!
What got me starting this thread was actually not a wish for an 'ask/answer' command block pair, but my ambivalence towards the existing "sense a sprite's local variable" mechanism and its side-effect, which is that it reduces shareability of sprites between Scratch-projects.
One way to have a sprite retrieve another sprite's state would be to let the target sprite decide if and what it wants to answer, instead of directly accessing its internals.
The (only) method to accomplish this before the new "variable-sensing" block was introduced, was to broadcast a message to all Scratch objects and let the one of interest 'answer' to a global variable. This method still works perfectly well, the downside being the need for two globals: a (global) message name and a global variable.
Now there is an additional method (the sensing block), so nothing is lost and much is gained. The new method is powerful, because it eliminates the need for both, the global variable and the message name, in order to exchange data between sprites. The downside is, that this method ties two sprites together in a way, that makes it hard to plug them apart and remix them.
It's sort of like glueing Lego bricks together.
A third way to exchange data between objects would be to allow sprites to answer to messages other than by accessing a shared/global variable (my initial 'ask/answer' thought). It occurs to me now, however, that letting one sprite direct a 'question' towards another wouldn't solve the 'shareability'-problem, because it still needs the target sprite to be 'introduced' (visible) to the requesting one first, which ties both together in exactly the same manner that I'd like to see resolved.
So, I guess, if one wanted to implement a way for sprites to exchange data avoiding a shared variable or a direct link, one way to do it might be to introduce 'globally answerable questions' to Scratch. Something like:
<ask 'a question' to all>
This would be a yellow, round numerical reporter block of the 'control' category, since it would be a 'controlled' value. It would correspond to:
<when I'm asked 'a question'
...
answer (aNumber) >
The downsides of such a mechanism would be manyfold:
1) It needs an additional command block (the new event-hat).
Plus, as Kevin pointed out,
2) there's a namespace decision to be made, and
3) there's the problem what to do if more than one script answers to a question.
In sum, the regained modularity would lead to an increased complexity, and therefore might not be worth it (but isn't it fun to fantasize about its possible other benefits nonetheless?).
Offline
Jens wrote:
I'm somewhat undecided about the benefits of being able to let a sprite 'sense' another sprite's variables.
The upside is that it makes some operations easier to code and eliminates the need to manage a lot of global variables.
The downside is, that this effectively breaks Scratch's modularity and shareability by hardwiring both sprites (the 'sensing' sprite and the 'sensed' one) together and making it impractical to share such a 'sensing' sprite from one project to another using the export / import feature. As a result, Scratch projects relying on this new command block can quickly become one big entangled and very complex 'spaghetti'-mess.
Another downside is, that this takes away much of the distinction between variables which are visible for all sprites ('gobal') and those which can be accessed by the sprite for which they are declard only ('local').
I'd rather be able to let a sprite define which of its own variables it wants to be seen by other sprites.
What are your thoughts on this issue?
you can.
<if><(<{variable}>)> <=>(20)>
Last edited by Heybrian (2008-01-21 12:43:22)
Offline