17  Lexical Scoping

17.1 Lexical scoping

Code
fn_mean = function(x, ...) {

    # fn_n = function(x, na.rm = FALSE) ifelse(na.rm, length(na.omit(x)),
    # length(x)) xn = fn_n(x, ...)

    xsum = sum(x, ...)
    xmean = xsum/xn
    return(xmean)

}

17.2 Data

Code
A = c(NA, 12, 15, 14, 18)

17.3 Error

Code
fn_mean(A, na.rm = TRUE)
Error in fn_mean(A, na.rm = TRUE): object 'xn' not found

17.4 No error due to lexical scoping

Code
xn = 1000
fn_mean(A, na.rm = TRUE)
[1] 0.059

17.5 Scoping rules

Python’s scoping rules are different from R’s, and Python does not have the same level of flexibility when it comes to capturing variables from external scopes.

Code
def fn_mean(x, **kwargs):
    
    global xn
    
    na_rm = kwargs.get('na_rm', None)
    
    if na_rm:
        x = x[~np.isnan(x)]
        
    # xn = len(x)
    xsum = np.sum(x)
    xmean = xsum / xn
    return xmean

# Example usage:
xn = 1000
A = np.array([11, 12, np.nan, 14, 15])
fn_mean(A, y=y, na_rm=True)