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
-~----------~----~----~----~------~----~------~--~---

Responder a