python - Is it "bad" to define closures at the top level, only to be called inside a function? If so: alternatives? -
i'm tagging 1 "language-agnostic" because i'm asking seems general principle, i'm using r , python examples.
i've written r script along lines of mwe:
## not work: plus_i <- function(x) x + times_i <- function(x) x * loop_i <- function(x) { for(i in 1:2) { x <- plus_i(x) x <- times_i(x) } x } loop_i(3)
but fails error in plus_i(x) : object 'i' not found
because of r's lexical scoping. couldn't hack way around eval
.
the python equivalent fails:
## not work: def plus_i(x): homecoming x + def times_i(x): homecoming x * def loop_i(x): # mutable objects beware in [1, 2]: x = plus_i(x) x = times_i(x) homecoming x loop_i(3)
in understanding, these programs work in dynamically scoped language, r , python both statically/lexically scoped. if that's case, somehow anti-paradigmatic or otherwise "bad" write r , python code this? matter of "explicit improve implicit", or go deeper?
edit: seems that, indeed, goes deeper. apparently lexical scoping inherent feature of closures. question still applies.
note plus_i
, times_i
not used outside of loop_i
in program. don't want define plus_i
, times_i
within loop_i
, because think hurts readability of code (which not simple in example). don't want create i
explicit function argument, because there several such i
's , 1 time again seems create code less readable , much more hard debug (by having maintain track of defined locally , passed in).
another alternative create new environment, define plus_i
, times_i
within it, , pass loop_i
. still feels off-label utilize of environments. edit: or, reassign environment(plus_i) <- environment()
if read through hadley's guide on functions, you'll understand there 4 environments maintain in mind every function:
the defining environment - function's code stored. the calling environment - environment function called from. the parent environment - function looks symbols if closure. the local scope - advertisement hoc environment created every time execute function, parent environment described above.in case, defining plus_i
, times_i
outside of loop, parent environment global environment -- additional symbols (like i
), , not find them. nudge functions along, forcefulness matter telling them look.
plus_i <- function(x) x + times_i <- function(x) x * loop_i <- function(x) { environment(plus_i) <- environment() # "here", in local scope environment(times_i) <- environment() # of loop_i, i! for(i in 1:2) { x <- plus_i(x) x <- times_i(x) } x } loop_i(3) # [1] 12
note not inadvertently alter parent environment of either function, because r implicitly creating re-create of each function within loop_i
due assignment.
in general, however, not specifying i
argument bad idea: if provide function "incomplete" referencing symbols cannot find in argument list or default parent environment, much harder others use. imagine if plus_i
several dozen lines of code 1 utilize of i
snuck in somewhere; how know function depends on i
? little scripts may ok not development hygiene long-term.
python r language-agnostic scope
No comments:
Post a Comment