Discuss Scratch
- Discussion Forums
- » Advanced Topics
- » Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
- badatprogrammingibe
-
500+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
- _nix
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
Oh, wow. This is really surprising. I'd call it a bug, or an incompatibility, but… I think its potential uses outweigh breaking any hypothetical project which relies on the value of a nonexistant input that shares the name with one of a custom block calling that one to be 0.
Edit: I haven't read far through it yet, but this paper on dynamic scoping (I think it even introduced/formalized the concept?) is interesting: http://galois.com/wp-content/uploads/2014/08/pub_JL_ImplicitParameters.pdf
Edit: I haven't read far through it yet, but this paper on dynamic scoping (I think it even introduced/formalized the concept?) is interesting: http://galois.com/wp-content/uploads/2014/08/pub_JL_ImplicitParameters.pdf
Last edited by _nix (Nov. 6, 2018 12:16:04)
- TheAspiringHacker
-
100+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
That paper doesn't invent dynamic scoping. It merely implements dynamic scoping in Haskell's type system. Dynamic scoping has been around long before Haskell; it's a feature of many Lisps. Oh, wow. This is really surprising. I'd call it a bug, or an incompatibility, but… I think its potential uses outweigh breaking any hypothetical project which relies on the value of a nonexistant input that shares the name with one of a custom block calling that one to be 0.
Edit: I haven't read far through it yet, but this paper on dynamic scoping (I think it even introduced/formalized the concept?) is interesting: http://galois.com/wp-content/uploads/2014/08/pub_JL_ImplicitParameters.pdf
Last edited by TheAspiringHacker (Nov. 6, 2018 15:49:53)
- MegaApuTurkUltra
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
Interesting…. Example:
https://scratch-mit-edu.ezproxyberklee.flo.org/projects/259998618/
https://mv-ezproxy-com.ezproxyberklee.flo.org/#259998618
Have you tested this over multiple threads / clones?
- jokebookservice1
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
My understanding is that dynamic scoping was recently removed, 13 days ago. I can't see this, though, in the latest published previews (e.g. llk.github.io/scratch-gui/develop, llk.github.io/scratch-vm). I'm not sure if the former has pulled in the latest VM changes yet, or if the latter even is updated ever.
Basically, the old (pre-13 day) algorithm was:
But my understanding of the new algorithm was:
So that change should change it from dynamic scoping to static scoping (if you want to call it that, you can't define a function inside another function so there really isn't any scoping at all).
If a custom block broadcasts to another script, that script can use the parameters of the custom block (i.e. dynamic scoping) – I'm not sure if this is different to 2.0 behaviour, that's something for someone to research.
I'm of the opinion that initially introducing dynamic scoping was not intentional, because the change was described as optimisation, or at least the issue of scoping wasn't mentioned:
Cross-linking with discussion on GitHub: LLK/scratch-vm#1729 “On matter of scoping and tail call optimisation.” by badatprogrammingibe
Basically, the old (pre-13 day) algorithm was:
- Go through all stack frames in reverse order of insertion (almost like a… stack!)
- If this is not a script with a custom block hat, keep traversing (i.e., skip next few steps)
- If this custom block has the relevant parameter, immediately report its value
- Else, continue traversing
- Once we've finished traversing, return 0
But my understanding of the new algorithm was:
- (Still) go through all stack frames in reverse order
- (Still) If this is not a script with a custom block hat, keep traversing (i.e, skip next few steps)
- (Diff) Immediately report either 0 or the value, depending on whether the custom block has the value
- (Still) If no custom hats were found, report 0
So that change should change it from dynamic scoping to static scoping (if you want to call it that, you can't define a function inside another function so there really isn't any scoping at all).
If a custom block broadcasts to another script, that script can use the parameters of the custom block (i.e. dynamic scoping) – I'm not sure if this is different to 2.0 behaviour, that's something for someone to research.
I'm of the opinion that initially introducing dynamic scoping was not intentional, because the change was described as optimisation, or at least the issue of scoping wasn't mentioned:
This was answered in a discussion offline:getParams searches for a params object in the stack. When it encounters a params object, it can check it for the parameter being searched for. After the defaults branch being merged, if its not there that implies the param is not from the current running procedure.
Since the parameter is not in the current procedure we can shortcut out of any more searching.
Cross-linking with discussion on GitHub: LLK/scratch-vm#1729 “On matter of scoping and tail call optimisation.” by badatprogrammingibe
Last edited by jokebookservice1 (Nov. 6, 2018 19:45:13)
- imfh
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
If you add any parameters to y it outputs 0 though… That is very interesting.
- _nix
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
removed, 13 days ago. I can't see this, though, in the latest published previews (e.g. llk.github.io/scratch-gui/develop, llk.github.io/scratch-vm). I'm not sure if the former has pulled in the latest VM changes yet, or if the latter even is updated ever.I would My understanding is that dynamic scoping was recently think scratch-gui has pretty much the latest scratch-vm changes (e.g. https://github.com/LLK/scratch-gui/pull/3604 was merged 5 days ago), but you're right, it doesn't seem like the changes the PR made are there. It does seem like it was made to deal with nearly this specific situation, per kchadha's comment you quoted.
- _nix
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
Oh! Good catch! This is of big significance, I'm sure. See, if a stackFrame doesn't have any parameters, If you add any parameters to y it outputs 0 though… That is very interesting.it's skipped:
for (let i = this.stackFrames.length - 1; i >= 0; i--) { ... const frame = this.stackFrames[i]; if (frame.params === null) { continue; } if (frame.params.hasOwnProperty(paramName)) { ... } return null; }
- jokebookservice1
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
Thanks! I think this is what's causing the issue If you add any parameters to y it outputs 0 though… That is very interesting.
EDIT: ninja'd with a more detailed post above
Last edited by jokebookservice1 (Nov. 6, 2018 20:24:19)
- _nix
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
linked – but of course, I wonder why they were put there to begin with.They were added as part of So I guess the solution here is to remove those three lines I the original stack frames PR, so I guess this was just overlooked in the recent PR we've been talking about (the one that removes dynamic scoping), maybe?
- jokebookservice1
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
So I guess the solution here is to remove those three lines I linked – but of course, I wonder why they were put there to begin with.
They are skipped in case the hat block isn't a custom block. As an example:
define proc (arg)
broadcast [do something v] and wait
when I receive [do something v]
say (arg ::custom-arg)
I just don't know if this is 2.0 behaviour?
- jokebookservice1
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
No, this isn't 2.0 behaviour. I'm also not sure if that would even trigger a stack frame (it probably wouldn't, idk).
Let's petition the ST to remove those three lines, I guess
Let's petition the ST to remove those three lines, I guess
Last edited by jokebookservice1 (Nov. 6, 2018 20:58:08)
- jokebookservice1
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
Okay, so scratch-flash (the 2.0 source code) also has the null check, but in it, we don't “continue”, instead we return “0”
Last edited by jokebookservice1 (Nov. 6, 2018 20:43:48)
- Jonathan50
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
Wow, that is odd. But it shouldn't be a problem (unless you rely on the value of custom block parameters being zero) since Scratch never had block structure/nested procedures in the first place. So why does getParam walk the stack at all?
Last edited by Jonathan50 (Nov. 6, 2018 22:36:20)
- CatIsFluffy
-
100+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
Someone trying to sneak in something useful for ATers?
- _nix
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
Nope. It's a bug. They actually meant to (effectively) remove it; they just missed Someone trying to sneak in something useful for ATers?a particular part in their recent change to remove it, so it wasn't quite removed properly

Edit: Well, I can't say for sure. I suppose the original PR adding stack frames may have intentionally had dynamic scoping (I just can't see why the code would be the way it is otherwise), but it's weird that they're removing it now then.
Last edited by _nix (Nov. 8, 2018 00:17:01)
- imfh
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
I hope they keep it. It shouldn't cause any problems especially if it only works when there are no parameters. The most confusing part would be if two custom blocks had similar parameters and that isn't a problem when one doesn't have parameters.
- JGames101
-
100+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
Three Days to go until Scratch 3 and it hasn't been removed yet 

- _nix
-
1000+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
You're right that it'll still be around for the release of 3.0 – but do Three Days to go until Scratch 3 and it hasn't been removed yet not rely on this bug sticking around: there is a WIP pull request (made by a Scratch Team member) to fix/remove it!

Last edited by _nix (Dec. 31, 2018 19:11:14)
- Andreto
-
100+ posts
Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.
Example:
https://scratch-mit-edu.ezproxyberklee.flo.org/projects/259998618/
https://mv-ezproxy-com.ezproxyberklee.flo.org/#259998618
I just want to know what you were doing when u found this out.
- Discussion Forums
- » Advanced Topics
-
» Scratch 3.0 has dynamic scoping, while scratch 2.0 doesn't.