jstout wrote:
The visual aspects of a sub sprite should surely be independent, although I think that scripts could be usefully inherited.
John
Interesting -- I would guess that if you asked the typical Scratch user what they expect when they duplicate a sprite, costumes would be the first thing they'd mention!
There wouldn't be special SUPER COSTUME blocks any more than there will be SUPER-block blocks! I would expect the child to start its life with the parent's costume list, and with the parent's current costume number, but to be able to break away from either or both of those (in the case of the costume list, break away from each costume separately, I mean).
Offline
Jens wrote:
Assuming the prototype's local var named FOO shall be settable by all instances, make a local block for the prototype named SET FOO TO num.
... and then each child has to delete the local FOO that was created when the child was created. I guess that would work, although it doesn't really feel to me like sharing a variable. I guess we have a disagreement about what the natural expected behavior of a "naive" child -- one that doesn't take explicit steps to change its relationship with its parent -- should be. My expectation is "everything shared."
I've just figured out as I'm typing this that in a class/instance language like Smalltalk, it does feel more natural for an instance of a child class to share the variable names, but not the values, of an instance of the parent class. Maybe it's because my first OOP experience was with Object Logo that I feel like we're speaking different languages.
Okay here's our homework assignment for tonight, we're all going to read this paper so we know what we're talking about (me too!):
http://labs.oracle.com/self/papers/self-power.html
Then we can argue tomorrow...
Offline
Jens wrote:
this experimental image fixes some issues that were reported in yesterday's version. It also adds the specialized duplication mechanism ("spawning") for making prototype-based instances. Whats new:
1) You can now right click on a sprite and "spawn" it to create an instance, in which case you don't have to manually set its prototype anymore.
2) mousing over an instance in the sprite corral now displays the name of its prototype in the tool tip.
3) saving and reading projects that contain prototypes works.
Oh, and I've included a little demo project showing how class variables might be implemented in future BYOB.
Enjoy!
--Jens
And here are the image and the project
Offline
This may not be too concerned with BYOB's goals and future, but I'm curious to know how costumes would be inherited. Right now when you duplicate a sprite a new costume is created, though identical to the other. This is a huge waste of file size in a lot of cases.
If costumes were to be inherited, I wouldn't want a seperate instance of the same image. I would want them to be tied without duplication, so the costume data comes directly from the parent's costume list. I THINK this is what you guys have in mind, but I wanted to make sure I'm on the same page...
Offline
shadow_7283 wrote:
I THINK this is what you guys have in mind, but I wanted to make sure I'm on the same page...
Don't worry; I'm not sure Jens and I are on the same page, so you're almost guaranteed to agree with at least one of us!
Is it the inefficiency that worries you, or the user interface? As for efficiency, if we wanted the user interface to be that the child's copy is independent of the parent, we could actually implement it as copy-on-write, so that in the (most common) case in which the costume is never edited, the user will never test whether there are one or two copies and the copying will never happen.
So the real question is about the user interface. Let's say you have a sprite A, and you give it a child B. We mostly agree (except John?) that to start with, they have (what look like) the same costumes. The questions are: (1) what should happen if sprite A edits a costume? and (2) what should happen if sprite B edits a costume? My negotiating position is that (for costumes the same as for everything else a sprite owns) the answer to both questions is that both sprites see the change, unless one or the other sprite has explicitly broken the link. I am prepared to be argued down to the stance that if sprite A edits, they both see the change, but if sprite B edits, that implicitly severs the link.
But I'm aware that I tend to err on the side of simple, uniform rules at the expense, sometimes, of doing what users find most natural. As Jens has explained, he wants the rules for custom blocks to be different from the rules for variables. In principle, the rules for costumes could be the same as either of those, or even some third thing.
Offline
Okay, it took me two passes through the paper to realize that "prototype" and "parent" both exist in Self but aren't the same idea. I, at least, have been conflating these in my thinking (because, again, that's how it is in Object Logo) and I wonder whether the rest of us are too.
PS I'm not saying that BYOB has to follow Self in everything! But I think our discussions will benefit if we understand what Self did, and why.
PPS: I found this on page 17: "Unlike SELF, Lieberman’s prototypes include shared information as well. His clones inherit from their prototype, adding private slots on-demand." I think this is what I'm arguing for.
Last edited by bharvey (2011-01-14 00:02:29)
Offline
Excellent suggestion about learning from SELF. I'll dig into the papers over the weekend.
Just a first thought about inheritance: Being a lawyer I gotta tell you that inheritance usually only happens after the parent dies. My kids cannot wear the same clothes I do at the same time, and I certainly appreciate that when I turn my head to speak to them they don't automatically turn around (away from me!) themselves. Plus, I sincerely hope for them to outlive me.
So, maybe this whole "child - parent" metaphor isn't really all that great. What we're discussing, of course, isn't legal inheritance of estate, but some kind of genetic disposition that's passed on from one sprite to another (although this "bloodline" lingo doesn't make me feel any more comfortable).
Now back to reading what Hegel says about prototypes...
Last edited by Jens (2011-01-14 07:25:29)
Offline
Jens wrote:
Being a lawyer I gotta tell you that inheritance usually only happens after the parent dies.
Funny! I never thought of that before (not being a lawyer, I guess).
Maybe this is why cloning is such a popular metaphor.
Offline
Jens wrote:
bharvey wrote:
so, how do you make a class variable, that's settable by everyone in the class (all the siblings as well as the parent/prototype)?
No problem, since we've got message-passing via the OF block:
Assuming the prototype's local var named FOO shall be settable by all instances, make a local block for the prototype named SET FOO TO num.
Then within the instance: RUN (SET FOO TO () OF prototype) WITH INPUTS (n) to set the prototype's FOO value. Use the light blue (FOO OF prototype) reporter to query the shared value.
@Jens
I totally agree with this way of doing that I'm currently using with entire satisfaction. Brian argues that will lead to clone all methods belonging to the prototype. Personally I have fixed this problem in the following way : instead of having several methods for several actions needed for a sprite I use only one global method say FOO for several individual methods - a kind of "method repository". The needed action is selected by an appropriate input variable of FOO (Code). If a new "method" is needed you just have to add it to FOO and all cloned sprites will immediately "inherit" this change. It means that only ONE method per sprite (nothing prevents to have 2 or more "global methods" )
Syntax is : Foo Object Code Param1 Param2 Where Code is the name used to select the needed "method" like h for hide, s for show, gt 100 50 for goto 100 50 etc (FOO is equivalent to the function Ask Object Method Values mentioned into several Brian papers)
The only "theoretical" concern is that one can't add a new method to FOO by using a script. It has to be added "manually" into the FOO block ( IF Code = ... Do so and so). This issue has been debated at length in the past and it is well known that the design of Scratch/Byob does not permit to change a block externally. Who cares ?
Offline
bharvey wrote:
But I'm aware that I tend to err on the side of simple, uniform rules at the expense, sometimes, of doing what users find most natural. As Jens has explained, he wants the rules for custom blocks to be different from the rules for variables. In principle, the rules for costumes could be the same as either of those, or even some third thing.
Just like you thought that hotkeys should be customized through scripts, I would like to see something similar with inheritance (I guess I can still use that metaphor). By default in a section of a sprite's properties (maybe a new tab to go along with scripts, costumes, and sounds?), there should be various scripts specifying the attributes of the parent that are inherited. This would involve the creation of new blocks (say "inherit [costume] of [sprite]") to put in those scripts, which would be doubly useful since they could be used in a project's scripts.
Offline
shadow_7283 wrote:
This would involve the creation of new blocks (say "inherit [costume] of [sprite]") to put in those scripts, which would be doubly useful since they could be used in a project's scripts.
Indeed. Except I want the exception to go the other way, so the block would be "OWN <name>" meaning "give me my OWN copy of <name>" (although I guess blocks and variables and costumes can all have the same name, so it'd be "OWN <dropdown variable/block/etc> <name>"). And what you'd do is put a script in the parent/prototype sprite saying
WHEN CREATED
OWN <foo>
OWN <baz>
etc
Your way is interesting, though, since you could inherit different things from different parents. Multiple inheritance is widely regarded out in the real world as being too horrible to contemplate because there's no good general rule for how to handle the situation in which two parents have things of the same name, but in your version the user makes that decision explicitly for each inherited item. In that case, there's no need for the idea of prototyping at all, except that the prototype sprite will have the WHEN CREATED script that says where to get all the other things.
Or we can have the "do what I mean" approach, in which both your INHERIT block and my OWN block are provided, and we have different defaults for different kinds of things, so you inherit blocks but not variables or whatever, and you change the ones you don't like whichever way you want them.
@Jens: Maybe instead of OWN we can call it DISINHERIT? (Lawyer joke.)
Offline
I notice I'm talking even more than usual recently, but see, this sort of harangue was basically my contribution to 3.0, except that almost all of it was in email between me and Jens. It's being inflicted on the rest of you only because people like shadow and MathWizz are taking an interest.
Anyway, I was sitting here trying to figure out why John doesn't want children to inherit costumes. (Why, John?) But in the course of this mental conversation with myself it suddenly struck me that I'm not sure we all agree about something that to me has been too obvious to need saying: that cloning or inheritance or whatever we call it is going to replace the Scratch duplicate-sprite feature, and should therefore serve the purposes for which users now duplicate sprites.
So, do the rest of you agree about that? Or do you think that there should be two make-a-sorta-the-same-sprite features for different purposes?
@Jens: You shouldn't have buried the very pertinent example of children turning away from their parent inside a joke, because the more I think about it, the more I find that example compelling. (Unlike the one about costumes, which I interpret as wholly facetious.) So, okay, maybe the default for variables is not to share values. (But the child's initial value should be the same as the parent's, right? Please?)
Oh, two little UI features I want that'll help with siblings: (1) If not in presentation mode, and two or more same-costume sprites are superimposed, they should glow or something. (This is better than offsetting them because I want to be able to move them by turtle motion and end up in precisely calculated places.) (2) I think I may have said this before, but I want a menu choice in the sprite corral that causes the copy of the sprite onstage to pulse or something (I mean, get bigger and smaller half a dozen times). I can't tell you how many fifth grade boys have come to me with projects with ten identical tiny bullets one of which has a script different from the others. The menu label is "Identify."
Offline
Carl_ wrote:
Hi, I was adding OO support, but BYOB crashed while saving.
Looks like an interesting project. The screenshot isn't much help in debugging, though; could you report this at http:byobugs.com and attach the project (if you can save it before you run it) or, if that fails, pictures of the actual custom blocks from the Block Editor? Or at least more info on the nature of the crash; did you get an error message, or did it just hang? Thanks.
Offline
Carl_ wrote:
BTW You should really add support for custom input slot types.
How would the custom type be represented visually? If you don't want a special shape, it's easy enough to roll your own -- a type is just a predicate function.
TYPE <predicate> <value> IF [NOT [CALL <predicate> WITH INPUTS <value>]] SAY <Type error!> STOP SCRIPT
Then just call that first thing in the definition of your custom block. (Yeah, there should be a less kludgy way to get user-generated error reports.)
Offline
bharvey wrote:
Carl_ wrote:
Hi, I was adding OO support, but BYOB crashed while saving.
Looks like an interesting project. The screenshot isn't much help in debugging, though; could you report this at http:byobugs.com and attach the project (if you can save it before you run it) or, if that fails, pictures of the actual custom blocks from the Block Editor? Or at least more info on the nature of the crash; did you get an error message, or did it just hang? Thanks.
The picture wasn't meant for debugging. The nature of the crash was that BYOB hang, and suddenly closed (after some time, I don't know how long). I didn't get to test it.
bharvey wrote:
Carl_ wrote:
BTW You should really add support for custom input slot types.
How would the custom type be represented visually? If you don't want a special shape, it's easy enough to roll your own -- a type is just a predicate function.
Code:
TYPE <predicate> <value> IF [NOT [CALL <predicate> WITH INPUTS <value>]] SAY <Type error!> STOP SCRIPTThen just call that first thing in the definition of your custom block. (Yeah, there should be a less kludgy way to get user-generated error reports.)
I think that you should be able to define it as a list of labels, but it would be choosable in the input type editor. That would make them look better designed. For example, if I define the input type:
INPUT pair: (%value1 , %value2)
When I then later use it as a type, then it would return a list.
BLOCK list of pairs: %pairs... REPORT pairs
Basically, it would return a list of lists of values. I could also make another input like this:
INPUT all of %values...
Then it would return a list containing all the values in "values". It would be good if you want something like this:
BLOCK jagged list: %lists REPORT lists
That would basically have the same effect as a
(list (list 5 5 <>) (list 5 5 <>) <>)
but would be written as
(jagged list: all of 5 5 <> all of 5 5 <> <>)
It would be useful if you want to make an if/else-if/else-if/else block:
INPUT else if <pred> BLOCK if %pred %elseifs... %else (omitted for brevity)
Last edited by Carl_ (2011-01-15 15:06:36)
Offline
bharvey wrote:
Anyway, I was sitting here trying to figure out why John doesn't want children to inherit costumes. (Why, John?)
As I've typed this I think I''ve come to realise that I was originally wrong, but the thought processes might be useful, so I'll keep them in.
I think the reason is that if I have my 'parent' Alonzo, and I create a 'child' one, I want to be able to distinguish them on the corral. No, thinking about that, that's what I get if I duplicate a sprite and that's never bothered me. What is it? I think you said something about when I create an instance of a class in Smalltalk I don't get the values of any other instance of the class without running new/initialize and I think of costumes as one instance variable of a class.
Thinking about it I realise I'm thinking about BYOB in terms of Smalltalk. So when I create Alan with Alonzo as his prototype, I think of this as creating a subclass of Alonzo called Alan. The trouble with this way of thinking is you then want the equivalent of Smalltalk's new. I haven't tried it but if I filed in my Files/Clones changes (and they worked), what I'd expect to do is keep Alonzo and Alan (I've only just realised why Alonzo and Alan!) as sort of classes, and use the [clone me] and [clone me [] times] as the equivalent of new and new:. Each one then gets sent the CloneCreation message (new would really be a better message) and can do what it wants, including choosing a new costume, but then it needs to have some costumes from its 'class'. Oh dear, I've just argued myself out of my original position.
One of my motivations for making your cloning code visible to the user was that I wanted to be able to write the equivalent of StarLogoTNG's infection example. This just creates 75 (or whatever number you want) clones of itself, each of which then starts moving about (with a script it's 'inherited' from its 'parent/sibling') and interacting with all its sibling clones (and probably its 'parent/sibling' unless you [hide] it after doing the cloning). I won't (I think) be able to do that with prototyping. I'm thinking of the Alonzo/Alan relationship as a 'vertical' class type one (but with (highly) visible classes) and cloning as a 'horizontal' one.
I think you should ignore me until I've read about SELF!
John
Last edited by jstout (2011-01-15 18:34:00)
Offline
Well, I've read the paper on SELF and think I understand it a bit more, but will sleep on it and reread it tomorrow.
If I have understood about prototypes I have to stop thinking about them as classes and change my approach. I also assume we'll be getting a 'clone this prototype' mechanism later having read Jens' opening post.
Incidentally has anyone else had a problem loading tools.ypr? I get BYOB hanging up (Mac OS/X) after doing the reading, then the initialising eventually gives a Space is low Internal error, and I have to use kill from the shell to quit it.
John
Last edited by jstout (2011-01-15 18:36:16)
Offline
jstout wrote:
I won't (I think) be able to do that with prototyping.
Why not? Prototyping is (in terms of expressiveness, not computability, of course) a superset of class/instance OOP; if you want, you can have class sprites and instance sprites. I guess the question is just how the sprites communicate in your example. Jens points out how you can have class variables via local methods, although I'd like a more direct way to express that. You can do all the usual Scratchesque IF TOUCHING stuff.
If I have understood about prototypes I have to stop thinking about them as classes and change my approach.
Well, you don't have to, but rhe language will feel more Scratchlike, I think, if you do change. Class/instance OOP is great for the team of 500 programmers who carefully design a class hierarchy before writing any code. But if you're a kid, you start messing around with a sprite, give it some behavior, and then think "I want five more like that." Maybe not post-APCS high school kids, but kid kids will think in those terms.
By the way, I'm an idtot and so is Jens, for forgetting that we actually had the argument we're having now earlier, and worked out the right answer: When you say "Make a variable." the dialog box should have three radio buttons: "for all sprites," "for this sprite only," and "for this sprite and clones." The latter makes a class variable. Of course that doesn't solve the problem for system-provided variables such as costume number. For those, there will have to be context menu choices "for this sprite only" and "for this sprite and clones." (It won't make sense to make those truly global.)
Incidentally has anyone else had a problem loading tools.ypr? I get BYOB hanging up (Mac OS/X) after doing the reading, then the initialising eventually gives a Space is low Internal error, and I have to use kill from the shell to quit it.
Yes. Thanks for reporting this.
Offline
Carl_ wrote:
Code:
BLOCK jagged list: %lists REPORT lists
Hmm. I'm not totally convinced that there's anything missing from BYOB to let you do this sort of thing now. We have multiple-value inputs already, and they do construct a list of the input values, so you can write things like ALL OF and JAGGED LIST yourself. Maybe I'm not understanding something?
Offline
bharvey wrote:
Carl_ wrote:
Code:
BLOCK jagged list: %lists... REPORT listsHmm. I'm not totally convinced that there's anything missing from BYOB to let you do this sort of thing now. We have multiple-value inputs already, and they do construct a list of the input values, so you can write things like ALL OF and JAGGED LIST yourself. Maybe I'm not understanding something?
The idea is that the jagged list block has the input "all of". That makes it's input the input of the lists. If you press one of the arrows, then it'll get another segment which also has arrows. Basically, it makes sure that you always make a jagged list.
BTW. Remember the "edit" button, so stop doublepoasting, k?
Offline
@ bharvey
"Class/instance OOP is great for the team of 500 programmers who carefully design a class hierarchy before writing any code."
I like you to underscore this point. BYOP-OOP you are designing should keep the right balance between "raising the ceiling" and keeping the "user-friendlyness" of BYOP.
Refering to "Make a variable Box" : we could have 3 types of variable 1- global 2 - local 3 - "family" (or class ) variables. Good point. But DUPLICATE offers already more or less this feature as Local variables (and methods) are duplicated with DUPLICATE. But you can't MAKE by script a new Global/Local (or Familial) variable by script. You need to Make them "manually"
Putting all with together : "what about a script instruction to MAKE new variables". This instruction could offer a pick-list to "make a variable" either global, or local or familial. A new hat control "when created" could then execute one initialization script to MAKE, SET and DEFINE all the specific environment of the new sprite + methods + "scratch properties " (x, y, dir, costume, colour , show/hide etc).
ps : WHEN CREATED can already be simulated by WHEN CLICKED .
Offline
bharvey wrote:
jstout wrote:
I won't (I think) be able to do that with prototyping.
Why not? Prototyping is (in terms of expressiveness, not computability, of course) a superset of class/instance OOP;
I think what I was meaning, and said badly, is that I can't say at the moment, make me 75 sprites using this as a prototype without a lot of right click/duplicating? Don't we still need something like, if I've read it correctly, SELF's traits clonable, so I can say [do [] times [clone me]]? I seem to remember that Jens said this was the first stage, getting the theory right, and the GUI and other stuff may come later, so perhaps I'm just being impatient.
No, sorry, not thinking this through: nothing to do with traits clonable, but I would like to be able to say [clone me] or [clone me []] times as a block. I know, using an example you used earlier, I wouldn't be able to make my breakout wall in this way without having a <my clone number> reporter, perhaps returning 0 if not a clone, but similarly you wouldn't easily be able to do an infection, or brownian motion/gas simulation without it. I wouldn't go on about it but the code is in Scratch/BYOB so someone else has at least thought about it,
John
Last edited by jstout (2011-01-16 17:52:07)
Offline
Carl_ wrote:
The idea is that the jagged list block has the input "all of". That makes it's input the input of the lists. If you press one of the arrows, then it'll get another segment which also has arrows. Basically, it makes sure that you always make a jagged list.
Your "all of" sounds to me exactly like the LIST block. I guess what you/re asking is for BYOB to enforce that a particular input be a list of lists, rather than a list of other kinds of things.
But why do lists of lists deserve special treatment? There are bunches of blocks that take numbers as inputs, and in order for the operation to be sensible the number has to be a positive integer (like ITEM <> OF <>), but Scratch doesn't provide a special positive integer data type. If you write a PIGLATIN block that's expecting a word (a text string made of letters) as input, it'll likely do something confusing if given a sentence (a text string including spaces) instead. But there's no distinguished 'word' data type.
I'm guessing you first learned a strongly typed language such as Java. The trouble with such languages is that (1) they make it hard to create heterogeneous data structures, like a list whose elements can be of different types; (2) they get the types wrong anyway; "positive integer" is never one of them.
The right approach to typing, if you want to have a typed language, is runtime type checking; you let block definitions attach a predicate function to each input slot, and an error is signalled if the predicate reports false for a given input value. That way, the user can have "positive integer" as a type, or "jagged list," or "costume that's taller than it is wide," or anything you can imagine. This is much better than building more and more specific types into the language.
Offline