Discuss Scratch

technoboy10
Scratcher
1000+ posts

Snap! user discussion

@hm
Erm… I actually never started that project.

trans rights are human rights
Hardmath123
Scratcher
1000+ posts

Snap! user discussion

Well, someone did… (this is kinda embarrassing). Remember, you had to embed the XML in “text/snap!” <script> tags?
Hardmath123
Scratcher
1000+ posts

Snap! user discussion

BoltBait wrote:

You can read his message to me on my profile page. Basically he thinks I should switch to Snap because I complain too much.

Which is kind of true… you can't expect the ST to add lambda or call/cc to a language designed for 5th graders. That's why Brian and Jens made Snap!. You can't have both an easy learning curve and advanced features baked together; you'll end up with the best parts hidden from newbies and lots of “secrets”.

Besides, Snap!pers are used to complaining. You should have seen some of the rants on the old BYOB 3.1 Discussion Thread.

EDIT: This post is quite nice (back from early November). It summarizes why the ST tries to simplify their designs.

Last edited by Hardmath123 (May 22, 2013 01:57:12)

technoboy10
Scratcher
1000+ posts

Snap! user discussion

Hardmath123 wrote:

Well, someone did… (this is kinda embarrassing). Remember, you had to embed the XML in “text/snap!” <script> tags?
Nope, that wasn't me.

trans rights are human rights
Hardmath123
Scratcher
1000+ posts

Snap! user discussion

Drat! You think it was MathWizz?
MathWizz
Scratcher
100+ posts

Snap! user discussion

Are we talking about the player thing? I didn't make one and I'm not so sure I ever remember there being one…

running Chromium 42.0.2311.90 with Flash Player 15.0.0.189 on Arch Linux 3.19.5-1-ck
MathWizzJsScratch && sb.js & Amber (coming soon! maybe)
Hardmath123
Scratcher
1000+ posts

Snap! user discussion

n? blob? shadow? Anyone have the old thread's archive? I can ask jvvg, I guess…
Hardmath123
Scratcher
1000+ posts

Snap! user discussion

Found it! Shadow made it (but his link 404s), then JFB improved it and posted the code (I'll give it to you in a minute).

Page 238/251.

Last edited by Hardmath123 (May 22, 2013 03:28:18)

bharvey
Scratcher
1000+ posts

Snap! user discussion

Lucario621 wrote:

even if he is trusted

“Trusted” wasn't the point – he's not molestable (by definition), which is what all the rules are about. But, whatever.

Hardmath123
Scratcher
1000+ posts

Snap! user discussion

var projects = document.getElementsByTagName("script").filter(
                   function (script){ return script.getAttribute("type") = "text/snap"; }),
      worlds=[] 
projects.forEach(function (project){
   var  canvas = document.createElement("canvas"),
        world = new WorldMorph(canvas),
        ide = new IDE_Morph(),
        control = ide.controlBar,
        appModeButton = control.appModeButton,
        pauseButton = control.pauseButton
        flag = control.children.filter(
                  function (morph){ 
                                    return morph instanceof PushButtonMorph 
                                        && morph.action = 'runScripts';
                                  })[0],
        stop = control.children.filter(
                  function (morph){ 
                                    return morph instanceof PushButtonMorph 
                                        && morph.action = 'stopAllScripts';
                                  })[0],
        contents = project.innerHTML,
        start = contents.indexOf("!"),
        end = start ? contents.indexOf("!", start + 1) : 0,
        options = start ? contents.substring(start + 1, end).split(",") : [],
        projCode = start ? contents.substring(end + 1) : contents,
        hideEdit = options.contains("noEdit"),
        hideFlag = options.contains("noFlag"),
        hideStop = options.contains("noStop"),
        hidePause = options.contains("noPause"),
        controlBarHover = detect( options, 
                                  function (str){ return str.substring(0, 7) = "hover:" }
                                ).substring(7),
        oldHash = location.hash;
 
  project.parentNode.replaceNode(canvas, project);  
  //open project
  location.hash = "#open:" + projCode;
  ide.openIn(world);
  location.hash = oldHash;
  ide.isAppMode = true;
  //hide the buttons the user wants to hide
  if (hideEdit){
    appModeButton.hide();
  }
  if (hideFlag){
    flag.hide();
  }
  if (hideStop){
    stop.hide();
  }
  if (hidePause){
    pause.hide();
  }
  if (controlBarHover){
    var shownYPos = controlBar.topLeft().y, hiddenYPos;
    controlBar.setPosition(new Point( controlBar.topLeft().x,
                                      (shownYPos + 2) - controlBar.height()
                                    ));
    hiddenYPos = controlBar.topLeft().y;
    controlBar.fps = 12;
    controlBar.mouseEnter = function (){ 
      controlBar.step = function(){
        controlBar.setPosition(new Point( controlBar.topLeft().x, 
                                          controlBar.topLeft().y + controlBarHover
                                        ));
        if (controlBar.topLeft().y > shownYPos){
          controlBar.step = nop;
        } 
      };
    };
    
    controlBar.mouseLeave = function (){
      controlBar.step = function(){
        controlBar.setPosition(new Point( controlBar.topLeft().x, 
                                          controlBar.topLeft().y - controlBarHover
                                        ));
        if (controlBar.topLeft().y < hiddenYPos){
          controlBar.step = nop;
        } 
      };
    };
  }
  ide.runScripts
  worlds.push(world);
  
});
setInterval(loop, 1);
function loop(){
  worlds.forEach(function (world){
    world.doOneCycle();
  }
}
All credit to joefarebrother.

Edit: Replaced &…;s with actual symbols.

Last edited by Hardmath123 (May 22, 2013 04:08:53)

bharvey
Scratcher
1000+ posts

Snap! user discussion

Hardmath123 wrote:

you can't expect the ST to add lambda or call/cc to a language designed for 5th graders. That's why Brian and Jens made Snap!. You can't have both an easy learning curve and advanced features baked together; you'll end up with the best parts hidden from newbies and lots of “secrets”.

Umm.

IANJ, but I think I'm speaking for both of us when I say that we have always wanted to see “advanced” programming features in Scratch itself. I put “advanced” in quotes (the first time ) because recursion and higher order functions have always been in Logo, the predecessor language to Scratch (in the sense that the ST grew out of the original MIT Logo group). BYOB was a proof-of-concept.

In fact, although progress has been slower than we hoped initially, Scratch is moving in that direction. Custom commands in 2.0, custom reporters promised and coming soon; discussions under way about first class lists. They haven't budged yet on first class procedures, but I have hopes that our new slogan (just for conversations with the ST) “don't think lambda; think map” will convince them, especially once they have first class lists. When they say that raising the ceiling isn't their first priority, that doesn't mean they don't think about it at all.

I grant you we may never see call with current continuation in Scratch.

And I reject categorically the idea that providing advanced features would drive away beginners. Again this is based on the Logo experience, especially at the Lamplighter School in Texas, where a big K-6 Logo curriculum effort was funded by TI back when the TI 99/4 came out with the first Sprite (fast multi-turtle) Logo. Committees of teachers and Logo developers worked out which features would be introduced to kids at which ages. Within the first week, kindergarteners were getting third and fourth graders to teach them how to do the cool things the young kids saw on the older kids' screens.

What would drive away beginners would be making it difficult to do easy things in non-advanced ways. For example, now that Scratch 2.0 has recursion, it doesn't really need a REPEAT block. But nobody is suggesting that it be removed!


nXIII
Scratcher
1000+ posts

Snap! user discussion

Hardmath123 wrote:

var projects = document.getElementsByTagName("script").filter(
                   function (script){ return script.getAttribute("type") = "text/snap"; }),
      worlds=[] 
projects.forEach(function (project){
   var  canvas = document.createElement("canvas"),
        world = new WorldMorph(canvas),
        ide = new IDE_Morph(),
        control = ide.controlBar,
        appModeButton = control.appModeButton,
        pauseButton = control.pauseButton
        flag = control.children.filter(
                  function (morph){ 
                                    return morph instanceof PushButtonMorph 
                                        && morph.action = 'runScripts';
                                  })[0],
        stop = control.children.filter(
                  function (morph){ 
                                    return morph instanceof PushButtonMorph 
                                        && morph.action = 'stopAllScripts';
                                  })[0],
        contents = project.innerHTML,
        start = contents.indexOf("!"),
        end = start ? contents.indexOf("!", start + 1) : 0,
        options = start ? contents.substring(start + 1, end).split(",") : [],
        projCode = start ? contents.substring(end + 1) : contents,
        hideEdit = options.contains("noEdit"),
        hideFlag = options.contains("noFlag"),
        hideStop = options.contains("noStop"),
        hidePause = options.contains("noPause"),
        controlBarHover = detect( options, 
                                  function (str){ return str.substring(0, 7) = "hover:" }
                                ).substring(7),
        oldHash = location.hash;
 
  project.parentNode.replaceNode(canvas, project);  
  //open project
  location.hash = "#open:" + projCode;
  ide.openIn(world);
  location.hash = oldHash;
  ide.isAppMode = true;
  //hide the buttons the user wants to hide
  if (hideEdit){
    appModeButton.hide();
  }
  if (hideFlag){
    flag.hide();
  }
  if (hideStop){
    stop.hide();
  }
  if (hidePause){
    pause.hide();
  }
  if (controlBarHover){
    var shownYPos = controlBar.topLeft().y, hiddenYPos;
    controlBar.setPosition(new Point( controlBar.topLeft().x,
                                      (shownYPos + 2) - controlBar.height()
                                    ));
    hiddenYPos = controlBar.topLeft().y;
    controlBar.fps = 12;
    controlBar.mouseEnter = function (){ 
      controlBar.step = function(){
        controlBar.setPosition(new Point( controlBar.topLeft().x, 
                                          controlBar.topLeft().y + controlBarHover
                                        ));
        if (controlBar.topLeft().y > shownYPos){
          controlBar.step = nop;
        } 
      };
    };
    
    controlBar.mouseLeave = function (){
      controlBar.step = function(){
        controlBar.setPosition(new Point( controlBar.topLeft().x, 
                                          controlBar.topLeft().y - controlBarHover
                                        ));
        if (controlBar.topLeft().y < hiddenYPos){
          controlBar.step = nop;
        } 
      };
    };
  }
  ide.runScripts
  worlds.push(world);
  
});
setInterval(loop, 1);
function loop(){
  worlds.forEach(function (world){
    world.doOneCycle();
  }
}
All credit to joefarebrother.

Edit: Replaced &…;s with actual symbols.
That'll TypeError because NodeLists aren't arrays. Try [].filter.call(document.getElementsByTagName(“script”), …)
EDIT: Ugh, postmarkup just isn't as good as FluxBB.

Last edited by nXIII (May 22, 2013 04:27:17)


nXIII · GitHub
blob8108
Scratcher
1000+ posts

Snap! user discussion

bharvey wrote:

now that Scratch 2.0 has recursion, it doesn't really need a REPEAT block.
Wait, so does 2.0 have that tail-call optimisation thingy?

tosh · slowly becoming a grown-up adult and very confused about it
bharvey
Scratcher
1000+ posts

Snap! user discussion

blob8108 wrote:

Wait, so does 2.0 have that tail-call optimisation thingy?

Oh. I have no idea. I just meant, it's possible to express an iteration using recursion, but that doesn't mean that adding recursion commits you to leaving iterative forms out of the language.

Hardmath123
Scratcher
1000+ posts

Snap! user discussion

bharvey wrote:

Hardmath123 wrote:

you can't expect the ST to add lambda or call/cc to a language designed for 5th graders. That's why Brian and Jens made Snap!. You can't have both an easy learning curve and advanced features baked together; you'll end up with the best parts hidden from newbies and lots of “secrets”.

Umm.
I always cringe when I see you say this.



I reject categorically the idea that providing advanced features would drive away beginners. Again this is based on the Logo experience, especially at the Lamplighter School in Texas, where a big K-6 Logo curriculum effort was funded by TI back when the TI 99/4 came out with the first Sprite (fast multi-turtle) Logo. Committees of teachers and Logo developers worked out which features would be introduced to kids at which ages. Within the first week, kindergarteners were getting third and fourth graders to teach them how to do the cool things the young kids saw on the older kids' screens.

That's interesting.

When I first got BYOB, I got it only because you could make your own blocks. That's it. I neither knew about nor cared about stuffing scripts into other blocks, and if someone had told me it was possible, I would either dismiss them as weird or see it as an odd hack, nothing more. I resisted using lambdas because I didn't understand them, and when someone gives you a block representing a very abstract concept that sounds like trickery on paper, you just don't use it. It feels weird, and even you have to admit that lambda is not an intuitive concept when you start programming. (I'm not saying it shouldn't be, I'm just reporting that it isn't.)

What would drive away beginners would be making it difficult to do easy things in non-advanced ways.

Scratchers are remarkably resourceful; give them a feature and you'll never know what the community will come up with. What I'm afraid of is that the slightly more advanced Scratchers would start using lambda in all sorts of cool and unnecessary ways, and you'll end up with the Scratch equivalent of (I know Jens is going to agree with me at this point ) IIFE.

People can and will write unreadable code wherever possible, and this is no exception. Right now, it is very hard to obfuscate your scripts, it is very easy to understand what someone else is doing, and it is very easy to remix. I want it to stay that way, otherwise the “advanced” Scratchers will bury the artists, musicians, animators, and game designers in a huge pile of garbled junk, asking people to input callbacks and bind event listeners to their simple libraries. And not all Scratchers are great programmers.

I can't stand that — any program should be designed so that getting it to work takes the minimum possible instruction. Additional specifications are secondary and should be programmed in that way. That's why I will never take to (Obj-)C(++|#) programming; there's just too much garbage which could be cleaned up if the language wasn't so strict (I'm resisting complaining about strictly typed variables).

I ranted on another thread about how, to properly play a sound with JavaScript, you need like 20 lines of funny code with all sorts of event listeners tacked on to weird concepts like “audio contexts”.

Scratch needs one block that is immediately obvious: “play sound”.

That's why I love Scratch.
nXIII
Scratcher
1000+ posts

Snap! user discussion

Hardmath123 wrote:

you'll end up with the Scratch equivalent of (I know Jens is going to agree with me at this point ) IIFE.
The only reasons to use closures that you immediately call are:
  • To establish a new scope
  • To enable strict mode in a safe manner

They're not a bad thing: the first overcomes a limitation of JavaScript, and the second is for backward compatibility. If you added closures to Scratch but not a way to establish a scope in a more natural way, you would get something like calling closures immediately.

nXIII · GitHub
Hardmath123
Scratcher
1000+ posts

Snap! user discussion

Well, not IIFE directly, but I can imagine people writing very convoluted code where some huge lambda is executed with an input that is the value of another huge lambda, and figuring out just what exactly is going on is a pain to everyone except the programmer.

I like how Scratch programs are inherently “flat”: no weird nestings.

Last edited by Hardmath123 (May 22, 2013 21:16:18)

nXIII
Scratcher
1000+ posts

Snap! user discussion

Hardmath123 wrote:

I like how Scratch programs are inherently “flat”: no weird nestings.
I don't agree—to me, custom blocks add “nesting,” whereas with closures just appear right in the script…

nXIII · GitHub
Hardmath123
Scratcher
1000+ posts

Snap! user discussion

Well, which looks better?

function handleDrop(event) {
    
}
dropzone.addEventListener("drop", handleDrop, false);
dropzone.addEventListener("drop", function(event) {
        
    },
    false
);

Note that handleDrop itself will probably also have some nested loops and whatever, and then the FileREader object will have a callback.

Last edited by Hardmath123 (May 22, 2013 21:26:07)

bharvey
Scratcher
1000+ posts

Snap! user discussion

Hardmath123 wrote:

People can and will write unreadable code wherever possible, and this is no exception. Right now, it is very hard to obfuscate your scripts, it is very easy to understand what someone else is doing, and it is very easy to remix.

I disagree. I think Scratch 1.4 projects of any significant size are all “obfuscated” by huge long linear scripts brought on by the lack of a modularization capability, i.e., custom blocks. It's too soon to know what real users' Scratch 2.0 projects will look like, but I'm hoping they'll be more readable, not less, because of what (if you can remember that far back) was in some circles considered a scarily advanced feature pre-2.0. Of course people can deliberately write unreadable code in any language, but the whole point of “advanced” features is precisely that they let you articulate what you mean instead of struggling with language limitations. So, for example,

map (( ) + (3)) over (input)

is just more perspicuous than

script variables (index) (result)
set to (list)
set to (0)
repeat (length of (input))
change by (1)
add ((item (index) of (input)) + (3)) to (result)
report (result)

Now, to be fair, using lambda to invent Church numerals is way fun! But nobody suggests that we should tell newbies to do arithmetic that way in practice, and nobody would write a program that uses arithmetic only incidentally using Church numerals unless maybe for the specific purpose of torturing a younger sibling.

I resisted using lambdas because I didn't understand them, and when someone gives you a block representing a very abstract concept that sounds like trickery on paper, you just don't use it. It feels weird, and even you have to admit that lambda is not an intuitive concept when you start programming.

But, did the fact that BYOB(3) had lambda stop you benefitting from custom blocks? That's the question here, not whether you understood all of BYOB at once.

Scratch beginners typically don't understand or use lists. And they make cool projects without them. But eventually some of them learn, and if the language didn't have lists, they wouldn't.

Same with you and lambda. Honestly, aren't you a better person and more awesome programmer now than you were before? Even if you don't find a use for lambda every day, it's there when you need it, and you know how. And they (can) even help you understand OOP better, because they make scope of variables less of a hidden mystery.

P.S. You aren't just any old person. You're a mathematician. To you, lambda shouldn't feel weird; it should make you feel like the ugly duckling finally finding a home. It turns programming into math!

Last edited by bharvey (May 22, 2013 23:25:40)


Powered by DjangoBB