uqbar-project / wollok

Wollok Programming Language
GNU General Public License v3.0
60 stars 16 forks source link

Referencias cíclicas rompen con error ilegible en algunos casos #1957

Closed julian-berbel closed 3 years ago

julian-berbel commented 3 years ago

Si escribimos el siguiente código en un archivo:

class Entrenador{
  var equipo
}

class Equipo {
  var entrenador
}

const unEquipo = new Equipo(entrenador = unEntrenador)

const unEntrenador = new Entrenador(equipo = unEquipo)

y en la consola escribimos:

unEntrenador

rompe con el siguiente error:

ERROR [main] (WollokChecker.java:111) - Checker error : java.lang.StackOverflowError
ERROR [main] (WollokChecker.java:125) - defineClass1 (ClassLoader.java:-2)
ERROR [main] (WollokChecker.java:125) - defineClass (ClassLoader.java:756)
ERROR [main] (WollokChecker.java:125) - defineClass (SecureClassLoader.java:142)
ERROR [main] (WollokChecker.java:125) - defineClass (URLClassLoader.java:468)
ERROR [main] (WollokChecker.java:125) - access$100 (URLClassLoader.java:74)
ERROR [main] (WollokChecker.java:125) - run (URLClassLoader.java:369)
ERROR [main] (WollokChecker.java:125) - run (URLClassLoader.java:363)
ERROR [main] (WollokChecker.java:125) - doPrivileged (AccessController.java:-2)
ERROR [main] (WollokChecker.java:125) - findClass (URLClassLoader.java:362)
ERROR [main] (WollokChecker.java:125) - loadClass (ClassLoader.java:418)
ERROR [main] (WollokChecker.java:125) - loadClass (Launcher.java:352)
ERROR [main] (WollokChecker.java:125) - loadClass (ClassLoader.java:351)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreter.java:319)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreterEvaluator.java:145)
ERROR [main] (WollokChecker.java:125) - _evaluate (WollokInterpreterEvaluator.java:268)
ERROR [main] (WollokChecker.java:125) - _evaluate (WollokREPLInterpreterEvaluator.java:21)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokLauncherInterpreterEvaluator.java:267)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokInterpreterEvaluator.java:1)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreter.java:302)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreterEvaluator.java:145)
ERROR [main] (WollokChecker.java:125) - _initializeReference (WollokInterpreterEvaluator.java:905)
ERROR [main] (WollokChecker.java:125) - initializeReference (WollokInterpreterEvaluator.java:1057)
ERROR [main] (WollokChecker.java:125) - ensureInitialization (WollokInterpreterEvaluator.java:893)
ERROR [main] (WollokChecker.java:125) - _evaluate (WollokInterpreterEvaluator.java:300)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokLauncherInterpreterEvaluator.java:269)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokInterpreterEvaluator.java:1)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreter.java:302)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreterEvaluator.java:145)
ERROR [main] (WollokChecker.java:125) - accept (WollokInterpreterEvaluator.java:881)
ERROR [main] (WollokChecker.java:125) - accept (WollokInterpreterEvaluator.java:1)
ERROR [main] (WollokChecker.java:125) - forEach (Iterable.java:75)
ERROR [main] (WollokChecker.java:125) - initializeObject (WollokInterpreterEvaluator.java:884)
ERROR [main] (WollokChecker.java:125) - apply (WollokInterpreterEvaluator.java:674)
ERROR [main] (WollokChecker.java:125) - apply (WollokInterpreterEvaluator.java:1)
ERROR [main] (WollokChecker.java:125) - operator_doubleArrow (ObjectExtensions.java:139)
ERROR [main] (WollokChecker.java:125) - newInstance (WollokInterpreterEvaluator.java:677)
ERROR [main] (WollokChecker.java:125) - _evaluate (WollokInterpreterEvaluator.java:601)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokLauncherInterpreterEvaluator.java:243)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokInterpreterEvaluator.java:1)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreter.java:302)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreterEvaluator.java:145)
ERROR [main] (WollokChecker.java:125) - _evaluate (WollokInterpreterEvaluator.java:268)
ERROR [main] (WollokChecker.java:125) - _evaluate (WollokREPLInterpreterEvaluator.java:21)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokLauncherInterpreterEvaluator.java:267)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokInterpreterEvaluator.java:1)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreter.java:302)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreterEvaluator.java:145)
ERROR [main] (WollokChecker.java:125) - _initializeReference (WollokInterpreterEvaluator.java:905)
ERROR [main] (WollokChecker.java:125) - initializeReference (WollokInterpreterEvaluator.java:1057)
ERROR [main] (WollokChecker.java:125) - ensureInitialization (WollokInterpreterEvaluator.java:893)
ERROR [main] (WollokChecker.java:125) - _evaluate (WollokInterpreterEvaluator.java:300)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokLauncherInterpreterEvaluator.java:269)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokInterpreterEvaluator.java:1)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreter.java:302)
ERROR [main] (WollokChecker.java:125) - eval (WollokInterpreterEvaluator.java:145)
ERROR [main] (WollokChecker.java:125) - accept (WollokInterpreterEvaluator.java:881)
ERROR [main] (WollokChecker.java:125) - accept (WollokInterpreterEvaluator.java:1)
ERROR [main] (WollokChecker.java:125) - initializeObject (WollokInterpreterEvaluator.java:884)
ERROR [main] (WollokChecker.java:125) - forEach (Iterable.java:75)
ERROR [main] (WollokChecker.java:125) - apply (WollokInterpreterEvaluator.java:674)
ERROR [main] (WollokChecker.java:125) - apply (WollokInterpreterEvaluator.java:1)
ERROR [main] (WollokChecker.java:125) - operator_doubleArrow (ObjectExtensions.java:139)
ERROR [main] (WollokChecker.java:125) - newInstance (WollokInterpreterEvaluator.java:677)
ERROR [main] (WollokChecker.java:125) - _evaluate (WollokInterpreterEvaluator.java:601)
ERROR [main] (WollokChecker.java:125) - evaluate (WollokLauncherInterpreterEvaluator.java:243)

Un código equivalente utilizando la notación de object

object unEntrenador inherits Entrenador(equipo = unEquipo) {}

no rompe.

Similarmente, si se instancia unEntrenador sin el equipo y se le settea el equipo a posteriori no rompe tampoco.

Me parece entendible que rompa, pero sería ideal que imprima un error más claro para los estudiantes.

fdodino commented 3 years ago

Bueno, estuve jugando un toque con el LazyWollokObject, una simpática implementación que permite por ejemplo que estos tests ahora funcionen:

image

¿qué opinan? @npasserini @nscarcella @PalumboN @lspigariol @tesonep @asanzo

asanzo commented 3 years ago

200

fdodino commented 3 years ago

jajaj, igual rompí un montón de tests... tengo que investigarlo un poco más a ver si se puede puentear las inicializaciones que fallan y transformarlas en diferidas.

fdodino commented 3 years ago

bueno, parece que no era tan complicado... o se solucionó corriendo 10 kilómetros y sentándome en la compu mucho tiempo después, jajaja...

fdodino commented 3 years ago

Ahora sí @asanzo , llegué con lo justo para tu regalo de cumpleaños:

image

🎂

fdodino commented 3 years ago

Y es maravilloso cómo el diagrama dinámico me ayudó a comprender que mi primera solución generaba una lista de objetos innecesaria (hasta que se encontraba con el Stack Overflow). Llegué a una solución más limpia sin tener que cargarme al stack de la JDK.

asanzo commented 3 years ago

Ahhhhh si todo se solucionara corriendo 10km.... .... yo sería desempleado.

¡¡¡jajajajj GRACIAS DODINE!!!!

PalumboN commented 3 years ago

:clap: :clap: :clap: :clap: :clap: