2008/9/15 Hernan Wilkinson [EMAIL PROTECTED] > > >>> Sinceramente no entiendo lo que pones. Creo que estamos hablando de cosas >>> distintas. Lo que yo quise poner es: un proxy (aProxy) instancia de la clase >>> Proxy (por ejemplo) es un objeto. Por ser objeto y no clase ni nada similar, >>> se encuentra en el "nivel" de los objetos. >>> >> >> Mmmh, no. >> >> Un proxy es una clase. >> > > "unProxy" no es una clase, es un Objecto. Por otro lado tenes la clase > Proxy de la cual "unProxy" será instancia. No importa comparar la clase > Proxy con "unTrait", hay que comparar "unProxy" con "unTrait" para que tenga > sentido la comparación y tampoco tiene sentido comprar la clase Proxy con el > comportamiento Trait (según está definido en el metamodelo de Squeak). > Definitivamente estamos hablando de cosas distintas. > Tu confusión me recuerda al de una persona que me dijo que la programación > orientada a objetos debería llamarse programación orientada a clases porque > lo único que uno hacía era modificar clases... sin ánimo de ofender, me > parece que tenés la misma confusión... y por eso decís que un proxy es un > clase... >
Me parece que esta discusiòn se està volviendo demasiado conceptual. Para mì todo objeto pertenece a una clase y toda clase tiene que ser instanciada alguna vez, aunque sea como un singleton. Ok, estoy obviando las clases abstractas porque ellas no participan del sistema, en el sentido de que nunca ejecutan, sòlo estàn para reducir la cantidad de còdigo repetido, otras personas pueden tener otra opiniòn, ok, aùn asì esas clases no participan del sistema. Respecto de la persona que dijo programaciòn orientada a clases, creo que deberìa llamarse programaciòn usando jerarquìas de tipos, ya que tipo y clase son finalmente lo mismo. Un "tipo de objetos" es una "clase de objetos", y los que dicen que no es asì y hacen distinciones banales sòlo intentan confundir el lenguaje para evitar que la gente piense, ya que los que pueden pensar no pueden expresar sus pensamientos (el lenguaje es confuso) y los que pueden expresarse no pueden pensar (los pensamientos usan el lenguaje, de modo que si te expresas en un lenguaje confuso tus pensamientos terminan siendo confusos)... [Asumir que hay mala intenciòn porque alguien introduce confusiones semànticas es anecdòtico. Puede ser algo que se produce sòlo sin intervenciòn humana ni divina, pero un hecho concreto es que la confusiòn existe...] Ahora bien, si vamos a tener una conversaciòn con sentido, necesitamos abstraernos del lenguaje de màquina. Me da lo mismo còmo implementas un trait, un proxy, etc. Me da lo mismo, lo siento. Para que la discusiòn tenga sentido, quiero saber què haces con un proxy y con un trait. Para agilizar la conversaciòn voy a dar mi definiciòn, esperando por supuesto que tù des la tuya a continuaciòn y sin ànimo de ofender a nadie. Proxy: Clase que permite agregar comportamiento a otras clases sin usar herencia, sino usando composiciòn, de modo que la clase X preexistente adquiere el comportamiento del Proxy P cuando esta clase se encuentra envuelta en el proxy P. Trait: Clase que permite agregar comportamiento a otras clases sin usar herencia, sino usando composiciòn, de modo que las clase X es creada como un trait T del cual se extiende y se redefninen algunos de sus mètodos. Estoy diciendo que un trait es una clase, y esto lo hago solamente porque asumo que estoy usando proxies para implementar Traits. No es necesariamente asì porque los traits se pueden implementar con ayuda del compilador y convertirse en objetos de primera clase al igual que las clases. Da lo mismo, reemplaza clase por objeto y la definiciòn sigue funcionando. No big deal. > > >> Cada vez que creas un proxy diferente es una clase diferente. >> > > No entiendo por qué querrías un clase distinta cada vez que necesitas un > proxy si puede ser implementado en una sola clase, por lo menos en > Smalltalk... me parece que vos tenes tu cabeza puesta en Java y por eso > tenemos estas diferencias. > Ok, cuando digo "creas" me refiero a "escribes", no a "instancias". El còdigo que escribo una vez se puede instanciar millones de veces. Si creo windows lo pueden montar en millones de computadores, eso es irrelevante. Lo importante es el còdigo que escribo porque al fin y al cabo en un proyecto eso es lo que hay que administrar, en el sentido de que el còdigo haga lo que se quiere hacer (implementar funcionalidades, resolver bugs) y que no haya còdigo repetido ya que eso hace que el sistema sea màs difìcil de mantener. Menos còdigo => menos costo. > > >> >> > >> >>> Un trait, por supuesto que es un objeto, pero se encuentra en un >>> "nivel" distinto a los objetos "comúnes" o "concretos" (como el string >>> "hola" o el número "1" o el aProxy). >>> >> >> Si estudiaras Lisp te darías cuenta que no. >> > > jaja, gracias por el concejo, se Lisp y se exactamente lo que digo y es > como lo dije. Cuando hablo de "nivel" lo hago de manera conceptual y > conceptualmente no es lo mismo hablar del número 1 que del concepto Número. > Si no me crees, andá a protestarle a Platón o Aristóteles. > Bueno, pasa lo mismo con las clases. Hay objetos que son clases y por lo tanto pueden hacer cosas como instanciar nuevos objetos que son instancias de sì mismas. No por eso dejan de ser objetos... De la misma manera en Lisp se peude pasar como parámetro una función. En Smalltalk se puede pasar como parámetro una clase. Al hacer la distinciòn que estàs haciendo es como construir una muralla imaginaria dibujando en el suelo con tiza donde deberìa estar la muralla. Si alguien la atraviesa, te enojas y como Romulo tratas de asesinas a Remo, pero en realidad la muralla no existe. Esa es la enseñanza profunda de Lisp y de Smalltalk y que a un montòn de gente le cuesta un mundo entender. Por ejemplo en el mundo EJB existen los EJB containers que se preocupan de coordinar el two phase commit entre las bases de datos. El tipo que creó Spring trabajò definiendo las especificaciones J2EE y los vendors se impusieron respecto de que sòlo los EJB containers podrìan manejar el two phase commit, siendo que para eso basta con que exista una clase que le indique a cada base de datos hacer commit y listo. Bastaba una clase, en Java o en Smalltalk, da lo mismo. Lo que es verdad es verdad independiente del lenguaje. Y resulta que muchos se sorprendieron de que Spring pudiera funcionar como un administrador de 2 phase commit sin ser un contenedor EJB. Y màs encima open source. Hubo una vez un arquitecto de software de Everis que trabjaba en Lan airlines y que explicaba que el contenedor no tenìa nada que ver, sino que las bases de datos se comunicaban "por debajo" usando protocolos propietarios... es decir, todos piensan que las explicaciones estàn en otros lados, que no puede ser tan fàcil. Se engañan a sì mismos pensando que todo es complicado y que es mucho màs complicado que lo que saben ellos, aunque estàn a un paso de entender lo que les falta entender. Creo que tambièn le presentan un mundo complicado a la gente que trata de usar traits. Puede que estè equivocado pero no lo creo. Es el mismo fenòmeno de "las ropas nuevas del emperador", en el que sòlo los inteligentes podìan ver los trajes y por eso el emperador andaba en pelotas, pero nadie se atrevía a decirlo para no ser tildado de idiota. Està demàs decir que tu lenguaje hacia mì en este foro deja entrever que piensas eso de mi. No te preocupes, no me molesta. De hecho ya te perdonè antes de entrar a este foro, porque el efecto de las ropas nuevas del emperador domina esta industria, siempre estamos conversando con gente que se supone que es inteligente pero no se hace las preguntas correctas. En este caso, todos saben que programar es difìcil, que las bases de datos son difìciles, que los sistemas operativos son difìciles, que los lenguajes de programaciòn son difìciles, que la orientaciòn a objetos es difìcil, que los traits son diìciles, pero en la realidad a lo sumo son complicados, no intrìnsecamente difíciles. Fìjate que lo que empezò esta discusiòn fue que dije que traits era un tipo de proxy porque hacìan lo mismo y eso despierta enojo en algunas personas que les gustarìa pensar que las cosas con màs complicadas de lo que realmente son, porque ahì està su negocio. Y esa complicación viene de que las implementaciones son poco claras, asì como las primeras implementaciones de EJB, compatibles con CORBA, la soluciòn correcta para el problema equivocado... Hoy en dìa existe H2 que es un motor de base de datos escrito en Java. Al parecer no es difìcil, pero creo que podrìa ser mucho màs fàcil. ¿Mencionè que hice un sistema usando EJB proxy? Eso significa 15 programadores que no tenìan idea de EJB, lo ùnico que sabìan era que los paràmetros de los EJB tenàin que pasar una prueba de Junit que se llamaba SerilizableTest y que lo ùnico que hacìa era verificar que los objetos fueran serializables, porque ese es uno de los requisitos de los paràmetros de los EJBs para que puedan viajar por la red (en realidad los paràmetros o son serializables o son EJBs, don't get me started)... Y la prueba estaba escrita una vez, usando tests abstractos se podìa hacer la prueba con una lìnea de còdigo. Lo que estoy tratando de transmitir es que al final todo es simple. No importa si vas a hacer algo complicado o usar algo complicado, simplemente te aseguras de usar la parte que necesitas y de probar que funciona como lo necesitas con Junit o Sunit y luego subdivides el problema razonablemente, asegurànte con pruebas que todo sigue funcionando cuando lo vas ensamblando y listo. Desde el puto de vista de la academia, obviamente lo que digo no importa, lo importante es descubrir cosas nuevas y publicarlas, no ponerse a construir màs variaciones de lo mismo. > > >> Sólo en lenguajes como VB existen esas distinciones irrelevantes... >> >> >>> En realidad se encuentra en un "meta-nivel" (un nivel que describe el >>> nivel de los objetos, por eso meta) y es por eso que nunca podrían ser >>> iguales. >>> >> >> Mmmhh. EN el caso de las meta clases te lo compro. De hecho nunca puedes >> tener acceso a las metaclases a menos que uses reflection. Y aún así nunca >> he visto una aplicación útil. Ok, la he visto, pero era un caso muy >> puntual... >> > > Que lástima. Hay mucha utilizadad en el metamodelo y las metaclases. > Incisto, tenemos una base de conocimiento muy distinta por lo que veo. > A eso me referìa. Me da la impresiòn que fueras un profesor universitario o un investigador. Porque si se puede descubrir algo nuevo y publicarlo, te parece bien. Si en forma pràctica los proxies y los traits hacen lo mismo, te da lo mismo. Eso porque Turing ya demostrò que todos los lenguajes turing equivalent son capaces de hacer lo mismo, de modo que no hay nada que publicar. Si se puede construir Smalltalk desde cero usando traits tambièn te da lo mismo, gracias a Turing. El ùncio problema que tengo con la academia es que se dedican en un 90% de los casos a demostrar la importancia del agua para la navegaciòn, que es demostrar que los traits se peuden implementar con ayuda del compilador. ¿Porque no hacerlo primero con Proxies? Y mi pregunta es puramente pràctica. Si puedo hacer algo con Proxies, me demoro probablemente 5 minutos en hacer lo mismo que otra persona se demora 5 años usando compiladores. Puedo encontrar y resolver los problemas mucho màs ràpdio. Y luego, cuando tengo una implementación razonable, la puedo convertir en una especificaciòn para los compiler writers, de modo que hagan el trabajo una vez y bien. ¿Quizàs el problema es que no se maximiza el nùmero de papers? Yo tengo una teorìa de para què sirve la sociedad. Unos construyen edificios, otros construyen software, otros hacen comida, otros transportan, al fin y al cabo sòlo hay unos pocos que tienen funciones un poco màs avanzadas y que hacen cosas que no tienen beneficios inmediatos y son los que escriben papers y hacen avanzar el conocimiento en el mundo. El problema es que no tienen incentivos para trabajar ni màs ràpido ni mejor, por lo ùnico que se les mide es papers publicados y cuántas refernecias existen. El problema con esto es que a menso que peudan escribir 100 papers diarios, se encuentran limitados por papers en àreas del conocimiento en lso que la mayorìa cree que el conocimiento se encuentra, pero por definiciòn el nuevo conocimiento nadie sabe dònde se encuentra porque por eso es conocimiento "nuevo". Es como la ondas gravitacionales o el large hadorn collider, màs que ciencia, parecen oràculos, saben de antemano lo que van a encontrar y para su decepciòn no encuentran lo que estaban buscando, porque en realidad la ùnica manera de que encuentren conocimiento nuevo es que encuentren decepciòn. Es decir, si quieres encontrar la fìsica, la naturaleza que define al universo, estudia algo que entiendas perfectamente, observa con atenciòn y encuentra perturbaciones que no son explicadas por el modelo actual. Eso necesariamente te darà insight acerca de fenòmenos nuevos que tendràs que explciar con nuevas teorìas... Y aterrizándolo al caso de los traits, lo que necesitamos son màs experimentos de lo que pasa cuando implementas sistemas completos usndo traits, para ver què ocurre, màs que encontrar cada año un pequeño avance respecto de lograr un 5% màs de velocidad por una tècnica a nivel de compilador. Creo, en mi humilde opiniòn. > > >> >>> Los traits son como clases, y de la misma manera que no puedo comparar >>> un Proxy con una clase, no puedo comparar un Proxy con un trait. Esto es lo >>> que quise decir. >>> >> >> Pero si hacen lo mismo. Y ambos son clases. Sólo que uno es más ordenado y >> el otro es más desordenado... >> > > Un trait no es una clase, sino podríaa haber instancias de él (por ejemplo) > y no las hay. > Buen punto. De hecho va con la definciòn que habìa hecho yo. Me contradije y me pillaste. Gracias. Estoy aprendiendo. El hecho de que utlilice una clase de Smalltalk o de Java para implementarlo es irrelvante porque es sòlo un mecanismo. Gracias, como dije anteriormente el lenguaje es confuso. > Si estudias el metamodelo de Squeak 3.10 vas a ver que un trait no es una > clase y hasta está diferenciado en la jerarquía de Behavior de Class. > Interesante. > Tampoco hacen lo mismo! Si lees bien la definición del patrón Proxy vas > a ver que no tiene nada que ver con la definición de Trait. Que se yo, hasta > acá llegué tratando de explicarte que son cosas distintas, si después de > leer las definiciones que te comento seguís insistiendo que son iguales allá > vos... > Ok, me referìa a que conceptualmente hacen lo mismo porque agregan comportamiento mediante composiciòn. Quizàs tu definiciòn es otra. > > >>> >>>> >>>>> Por ejemplo, un proxy adolece del problema del "identidad" mientras >>>>> que eso ni se puede pensar en un trait. >>>>> >>>> >>>> Eso de la identidad, a mi parecer, es màs un detalle de implementaciòn >>>> que un feature que quiera que tenga el lenguaje. No necesito que cada >>>> objeto >>>> exista una sola vez en la memoria, ni me importa. Si el compilador o el >>>> runtime son capaces de ahorrar memoria, bien. Significa que estàn bien >>>> hechos, pero si complica el modelo de programaciòn es una basura y hay que >>>> botarlo. >>>> >>> >>> No es a lo que me refiero, intuyo que estás confundiendo identidad con >>> cantidad de objetos necesarios para representar el mismo ente. >>> >> >> No. Hace unos 10 o 15 años atrás se volvieron todos locos con eso de la >> identidad y creo que fue una de las cosas que casi hicieron fracasar a la >> orientación a objetos. Es irrelevante para nosotros y sólo a un fanático de >> Lisp le podría interesar. >> > > ? > Y sì viste. En esa època empezò eso de las bases de datos orientadas a objetos y realmente muy poca gente entendìa la orientaciòn a objetos. Las bases de datos relacionales tienen un fuerte componente conceptual llamado àlgebra relacional, que por cierto no lo respetan, son un verdadero hack, pero si lo respetan en un 90%, ya es genial. Remìtete a los papers de Codd y Date para màs informaciòn. El tema de la identidad al parecer era la manera en que los fanàticos de la OOP pretendìan vencer a las bases de datos relacionales. En tèrminos OOP, darle persistencia a los objetos en RAM. En retrospectiva, serìa como guardar la imagen de Smalltalk, no es algo muy robusto. > > >> >> >>> Cuando hablo del problema de identidad me refiero a que una vez que el >>> proxy forwardea el mensaje al objeto proxeado, "self" pasa a estar bindeado >>> con el objeto proxeado >>> >> >> Que buen spanglish ;-) Si mi profesora de castellano me viera :)) >> > > ? > > >> >> >>> y si no hay manera que el proxy se entere que se envía un mensaje que >>> el también tiene intención de "controlar". >>> >> >> Granted. Ese es un problema, pero los "constructores de proxies" saben >> eso, o por lo menos eso espero. ¿Traits lo soluciona? >> > > Traits no lo soluciona porque no tiene el problema... es otra cosa... > Què cuadrado. Ok, entonces para ponerlo en terminos que entiendas, ¿un trait puede hacer "self doSomething" y ejecuutarlo adecuandamente sin generar "sorpresas" para el programador? > > >> >> >>> Esto no sucede en lenguajes de prototipación con delegación como Self, >>> donde implementar un proxy o cualquier tipo de wrapper es trival. >>> >> >> Qué interesante. >> >> >>> A eso me refería y lo ponía como ejemplo de lo que aclaré en el párrafo >>> anterior. >>> >> >> Bueno en ese caso supongo que bastaría con arreglar el compialdor de >> Smalltalk para que sea "proxy aware". >> > > El compilador no tiene nada que ver con los proxies... en fin, es una > discusión sin sentido me parece... hasta acá llegue. > ok, veo que tenemos poca paciencia. El compilador no tiene nada que ver con los proxies asì como tampoco tiene nada que ver con las clases o con los traits. En la medida en que el runtime no es capaz de resolver las clases y los traits, se vuelve un problema del compilador. Por ejemplo en Smalltalk un proxy se resuelve usando el runtime mediante el mecanismo "doesNotunderstand". En el caso de Java no existe ese mecanismo, por lo que el compilador sì debe saber què es un proxy para introducir la clase. Aquellos que hemos implementado intèrpretes y compiladores de Lisp sabemos de lo que estamos hablando. Cuando queremos implementar ciertas funcionalidades en Lisp (y estoy hablando de cosas bàsicas) es necesario que el compilador o el intèrprete tenga acceso a generar còdigo còmo si el programador lo hubiera escrito, y eso es tan evidente, porque efectivamente manipulas los objetos en memoria usando transformaciones seguras (en el sentido que no corrompen el sentido del programa), pero bien tendràn que tomar un master para entender lo que estoy diciendo. El punto que estoy tratando de explicar es que si el compilador puede hacer algo que podrìa estar en el runtime, y si en Smalltalk un proxy se puede impleemntar en runtime con un mecanismo tan simple, y si todos los lenguajes son turing equivalent, entonces ¿no se podrìa decir que el mejor lenguaje es aquel que siendo turing equivalent tiene el mìnimo de mecanismos proveìdos por el compilador y el màximo proveìdo por el runtime? Saludos y espero no haber ofendido a nadie, Guillermo. --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] http://www.clubSmalltalk.org -~----------~----~----~----~------~----~------~--~---
