Alcance dinámico en la programación R

R es un lenguaje de programación de código abierto que se usa ampliamente como software estadístico y herramienta de análisis de datos. R generalmente viene con la interfaz de línea de comandos. R está disponible en plataformas ampliamente utilizadas como Windows, Linux y macOS. Además, el lenguaje de programación R es la última herramienta de vanguardia. Las reglas de alcance para R son la característica principal que lo diferencia del lenguaje S original. El lenguaje R utiliza alcance léxico o alcance estático. Una alternativa común es el alcance dinámico.

Concepto detrás del alcance dinámico

Considere la siguiente función:

R

f <- function(x, y){
   x^2 + y/z
}

Esta función tiene 2 argumentos formales x e y. En el cuerpo de la función, hay otro símbolo z. En este caso, z es una variable libre. Las reglas de alcance de un lenguaje determinan cómo se asignan los valores a las variables libres. Las variables libres no son argumentos formales y no son variables locales (asignadas dentro del cuerpo). El alcance léxico en R significa que los valores de las variables libres se buscan en el entorno en el que se definió la función. Buscar el valor de la variable libre significa:

  • Si el valor del símbolo no se encuentra en el entorno en el que se definió una función, la búsqueda continúa en el entorno principal.
  • La búsqueda continúa por la secuencia del entorno principal hasta que los usuarios llegan al entorno de nivel superior; este suele ser el entorno global (área de trabajo) o el espacio de nombres de un paquete.
  • Si no se puede encontrar el valor de un símbolo dado una vez que ha llegado el entorno vacío, se genera un error. El valor de la variable libre se da en la siguiente imagen.

 Por lo general, una función se define en el entorno global para que el valor de las variables libres solo se encuentre en el espacio de trabajo del usuario; sin embargo, en R uno puede tener funciones definidas dentro de otras funciones. Por ejemplo, eche un vistazo al siguiente código. 

R

make.power <- function(n){
  pow <- function(x){
    x = x^n
  }
  pow
}
 
cube <- make.power(3)
square <- make.power(2)
print(cube(3))
print(square(3))

Salida

[1] 27
[1] 9

La función potencia toma el argumento x y eleva la potencia n. Eso hace que la función pow regrese dentro del valor de la función. n es una variable libre y se define en la función pow. ¿Qué hay en un entorno funcional? 

R

ls(environment(cube))
[1] "n"   "pow"          

R

get("n", environment(cube))
[1] 3

R

ls(environment(square))
[1] "n"   "pow"

R

get("n", environment(square))
[1] 2

Consideremos otro ejemplo:

R

y <- 10
 
# creating a function f which takes argument x
f <- function(x){
  # y is free variable
  y <- 2 
   
  # g function is also a free variable
  # not defined in the scope of function
  y^2 + g(x) 
}
 
g <- function(x){
  # y is free variable
  # value of y in this function is 10
  x*y
}

¿Cuál es el valor de y en este caso? 

  • Con el alcance léxico, el valor de y en la función g se busca en el entorno en el que se definió la función, en este caso, el entorno global, por lo que el valor de y es 10.
  • Con el ámbito dinámico, el valor de y se busca en el entorno desde el que se llamó a la función (a veces denominado entorno de llamada ).
  • En R, el entorno de llamada se conoce como marco principal. Entonces el valor de y sería 2.

Cuando una función se define en el entorno global y posteriormente se llama desde el entorno global, entonces el entorno de definición y el entorno de llamada son los mismos. Esto a veces puede dar la apariencia de alcance dinámico. 

R

g <- function(x){
  a <- 3
  # in this case x is function a formal argument and
  # a is local variable and
  # y is free variable
  x + a + y
}
 
# printing value of g(2)
print(g(2))

Si llamamos a g(2) dará un error como el siguiente:

Salida

Error in g(2) : object 'y' not found

Después de asignar valor a y llame a g(2) de la siguiente manera: 

R

g <- function(x){
  a <- 3
  x + a + y
}
 
# assigning value to y
y <- 3
 
# print g(2)
print(g(2))

Salida

[1] 8

Publicación traducida automáticamente

Artículo escrito por viv_007 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *