Alcance en Lenguajes Dinámicos

Trabajo Práctico 2

tp02-2019.pdf

Ejemplos

J - Ejemplo 1

NB. Duplica los elementos de un vector en forma consecutiva
NB. y los ubica en un nuevo vector llamado dupli.
duplicado =: 3 : 0 NB. define un verbo monádico duplicado
tope =. (# y) - 1
i =. 0
dupli =. '' NB. Inicializa un vector vacío.
while.  i <: tope do.
  dupli =. dupli, i { y
  dupli =. dupli, i { y
  i =. i + 1
end.
dupli
)

J - Ejemplo 2

  coname'' NB. Coname muestra donde estoy parado
  names'' NB. no muestra nada por que no definí ningún verbo en este ámbito
  a=: 2
  b=:1
  a+b
  names'' NB. muestra los verbos monádicos definidos 
  cocurrent'asd' NB. Creo el nuevo ámbito
  coname''
  a=: 20
  b=: 10
  a+b  NB. estoy parado en asd, trabajo con los locales al ámbito definido
  names'' NB. tengo definido los mismos verbos pero en otro ámbito.
  
  NB. Si estamos en otro ámbito y queremos volver al ámbito base se realiza
  cocurrent'base' NB. En caso de estar en otro ámbito
  NB. Si queremos borrar todo
  clear'' NB. Borra todo

J - Ejemplo 3 - Suma Condicional

cocurrent'local1' 
a=:1
b=:2
cocurrent'local2' NB. Creo el nuevo ámbito
a=:10
b=:20
f0=: 3 : 0
 if. 5 <: y do. cocurrent'local1' end.
  a+b
)

f0 &.> 1 2 6 7

Perl - Ejemplo 4 - My

---La instrucción "my" crea una copia local de la variable x, válida solo dentro de ese ámbito. Así la salida da como resultado 3 5 5 5 porque existe la variable x definida fuera del ámbito de "my", de lo contrario arrojaría error de ejecución-----------------------------------------------------------------------------------------------------------

 $x = 5;
{
  my $x = 3;
  print "Adentro, \$x = $x\n";
  print "Adentro, \$::x = $::x\n";
}
print "Afuera, \$x = $x\n";
print "Afuera, \$::x = $::x\n";

Perl - Ejemplo 5 - Closures

#!/usr/bin/perl -w
package paquete1; # Se declara un paquete para restringir el ámbito del programa a este paquete
sub b {  # Se declara una subrutina (función) llamada b
    return sub {  # Se retorna una subrutina anónima (closure) que contiene el código ejecutable "print $x"
       print $x;       
    }
}
sub a {   # Se declara una subrutina (función) llamada a
       my $x=2;  # Se declara una variable llamada $x, local a la subrutina a
       &$c();  # Se ejecuta el contenido de la variable $c
      }
$x = 1; # Se declara una variable llamada $x, correspondiente al ámbito global del programa
$c = b; # Se invoca a la subrutina b y se asigna lo que retorna (el Closure) a la variable $c
&$c(); # Se ejecuta el contenido de la variable $c (el Closure)
a(); # Se invoca a la subrutina a

# La ejecución de este programa comienza con la primera instrucción ejecutable del programa principal ($x=1)
# Se asigna el valor 1 a la variable global $x
# Se Invoca a la subrutina b, que devuelve el Closure
# Se ejecuta el Closure en el ambiente global, la única variable en la tabla de símbolos es $x, por lo que se imprime 1
# Se ejecuta la subrutina a
# La subrutina a declara la variable local $x
# Se ejecuta el Closure desde a, se imprime 2, porque debido al ámbito o alcance dinámico de Perl, el Closure encuentra la variable local de a antes que la global
# ¿Que sucede si se quita la palabra clave local?
# ¿Que sucede si se reemplaza la palabra clave local por la palabra clave my?

Python - Ejemplo 6 - Closures

# -*- coding: UTF-8
y=1 #se declara una variable llamada y en el ámbito global y se le asigna el valor 1
def a(): # Se define una función llamada a
    x = 2 # Se declara una variable llamada x en la función a y se le asigna el valor 2
    def b(): # Se define una función llamada b
        print x # Se imprime el valor de la variable x alcanzada por b según el ámbito estático de python
        print y # Se imprime el valor de la variable y alcanzada por b según el ámbito estático de python
    return b  # Se retorna b como Closure
z=a() # Se invoca a la función a y su resultado (el closure) se le asigna a la variable z
z()  # Se invoca a z (al closure contenido en z)
def c(): # Se define una función llamada c
    x = 3  # Se declara una variable llamada x en la función c y se le asigna el valor 3
    z() # Se invoca a z (al closure contenido en z)
y=2 # Se le asigna el valor 2 a la variable y del ámbito global    
c() # Se invoca a la función c

# Este programa imprime 2 1 2 2