consider the nested functions:
def a():
def b():
def c():
def d():
def t():
I know:
- t can call a and vv
- a can also call b and d
- b can call d, a and c
- d can call b and a
- c can call b
so the following stack implementation:
bottom up: t a t a d a b c
is fine as t calls a, a calls t and so on.
- can c call a (more than 1 level up)?
- can c call t (something its not nested in)?
- can a call c (more than 1 level inwards)?
- can c call d?
and what about for dynamic scoping?
couldnt find anything regarding this problem
kiyo-koji is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
It’s pretty simple:
- inner scopes can see anything higher up that they’re nested within, recursively (further than one level)
- outer scopes cannot “reach into” nested scopes
c
can see everything here, because it’s nested within b
, which is nested within a
, which is nested within the global scope, and everything else is within one of those scopes.
t
cannot see into a
, nor can d
see into b
.
Logically speaking, a def
statement defines a function when it is executed. Meaning, b
is being defined while a
is being executed, and when a
finishes, b
goes out of scope and ceases to exist. So b
doesn’t even exist unless a
is actively running, which means t
cannot access b
inside a
even if it wanted to.
(The actual implementation probably doesn’t work like that, and we’ll leave arguments like “what if I call t
from a
” aside. Just keep this is-defined-while-running in mind to help clarify whether you should be able to reach into functions.)
With dynamic scoping it all depends on how things are called. In dynamic scoping the call stack defines what’s visible to functions. Anything on the call stack is accessible. So if you call a
→ d
→ c
→ t
, then t
has access to everything else.