martes, junio 22, 2004

Variables lifecycle

Ante una pregunta inocente sobre la "elegancia" de utilizar

  String s = null;
  while (true) {
    s = "...";
  }

o

  while (true) {
    String  s = "...";
  }

a un experto en la materia (EV), la respuesta fué la siguiente:

En realidad sería asi: los corchetes {} marcan un scope. Adentro de ese scope la variable existe, afuera no. Fijate que es lo mismo que al entrar a un método, solo que no llama la atención porque uno se acostumbra a verlo de otro modo:

  void m() {
    int a = 0
    String s = ""
  }


a y s valen dentro del {} que delimita el cuerpo del método. Pero los {} se pueden usar "sueltos" para agrupar scopes. Esto es válido (e inútil):

  void m() {
    {
      int a = 0;
      String p = "";
    }
  }


También se puede hacer esto:

  void m() {
    String s;
    {
      int a = 0;
      // aca existen "a" y "s"
    }
    {
      String p = "";
      // aca adentro "a" no existe; pero "s" sí.
    }
  }


Las operaciones de la VM son las mismas cuando abre cualquier corchete, ya sea el del cuerpo de la función, el cuerpo de un while o corchetes sueltitos: alocar espacio para las variables locales a ese {} en el stack al abrir, y liberarlo al cerrar.

Ya que estamos, una disgresión. Ya que entre {} hay un bloque de código autónomo, por que corno no se puede hacer esto?:

  Code c = {int a=0; System.out.print.... }


y despues

  c.evaluate();


Sería muy lindo que los {} sean objetos también. Smalltalk tiene eso y es absolutamente la única razón (a mi juicio) por la cual el Smalltalk es tan cómodo.
Esas cosas se llaman "clausuras" de código, y elegantizan mucho los programas. En programación funcional también existen y son muuy útiles. Son como tener funciones en stand-by. El tema es que la implementación óptima es muy compleja, por eso los lenguajes "industriales" no los implementan.

1 comentario:

Anónimo dijo...

Bueno, y al final? Cual es la mejor manera?
String s = null;
while (true) {
s = "...";
}

o

while (true) {
String s = "...";
}

Porque en el segundo caso estamos creando un objeto nuevo en cada iteración... es mas performante?