Logo is the first programming language I ever learned as a child. I recently found out that Logo supposedly uses dynamic scoping, which came as a surprise to me because I always thought it just used global variables. This made me wonder if perhaps I didn't understand what dynamic scoping meant.
I thought that with dynamic scoping, a variable would go on a global stack, so then when you called another method the variable would still be visible. (So far, like a global variable.) Then, if you declared a new variable with the same name, this would be pushed on the global stack, hiding the original variable. (At this point, still not much different than assigning a new value to a global variable.) And lastly, when you exited the method, that new assignment would be popped off the stack, and the variable would revert to its original value. (This seems like the key part that makes it dynamic scoping, as opposed to just reassignment of global variables.)
So having heard that Logo used dynamic scoping, I expected this program:
to test1
make "x "foo
print (se [In test1: ] :x)
test2
print (se [Back in test1: ] :x)
end
to test2
print (se [In test2: ] :x)
make "x "bar
print (se [Still in test2: ] :x)
end
test1
to have this output:
In test1: foo
In test2: foo
Still in test2: bar
Back in test1: foo
But when I run it in FMSLogo, it actually has this output:
In test1: foo
In test2: foo
Still in test2: bar
Back in test1: bar
This actually matches what I remember from when I was a kid, and is consistent with what I'd expect if there's a single global variable named x
. But I don't see how this is dynamic scoping -- the variable never goes out of scope!
So why do references, like this one for instance, claim that Logo uses dynamic scoping?