Así que leí sobre esto, y es más o menos lo que significa: tomar un concepto abstracto y hacerlo concreto. O hay un proxy que representa el concepto abstracto. Por ejemplo, en Lisp, el concepto de abstracción y aplicación de procedimientos se reifica cuando usa lambdas.
La reificación en sí misma es un concepto amplio y no solo aplicable a los lenguajes de programación funcionales.
En Java, por ejemplo, hay tipos que están disponibles en tiempo de ejecución. Estos son tipos confiables. Es decir, existe una representación concreta del concepto abstracto del tipo, durante el tiempo de ejecución. Por el contrario, existen tipos no confiables. Esto es especialmente evidente durante el uso de genéricos en Java. En Java, los genéricos están sujetos al borrado de tipo, por lo que la información de tipo genérico no está disponible durante el tiempo de ejecución (a menos que el tipo parametrizado utilice comodines ilimitados).
Otro ejemplo es cuando intenta modelar un concepto. Por ejemplo, suponga que tiene una Group
clase y una User
clase. Ahora bien, hay ciertos conceptos abstractos que describen la relación entre los dos. Por ejemplo, el concepto abstracto de un User
ser miembro de un Group
. Para concretar esta relación, escribiría un método llamado isMemberOf
que diga si a User
es miembro de a Group
. Entonces, lo que ha hecho aquí es que ha cosificado (hecho real / explícito / concreto) el concepto abstracto de pertenencia a un grupo.
Otro buen ejemplo es una base de datos en la que tiene relaciones padre-hijo entre objetos. Puede describir esta relación en el concepto abstracto de árbol. Ahora suponga que tiene una función / método que toma estos datos de la base de datos y construye un objeto real Tree
. Lo que ha hecho ahora es cosificar el concepto abstracto de la relación parecida a un árbol entre padres e hijos en un objeto real Tree
.
Volviendo a los lenguajes funcionales en general, quizás el mejor ejemplo de cosificación sea la creación del propio lenguaje de programación Lisp. Lisp era una construcción teórica y completamente abstracta (básicamente una notación matemática para lenguajes de computadora). Permaneció así hasta que la eval
función de Lisp fue realmente implementada por Steve Russel en un IBM 704:
Según lo informado por Paul Graham en Hackers & Painters, p. 185, McCarthy dijo: "Steve Russell dijo, mira, ¿por qué no programo esta evaluación ... y yo le dije, ho, ho, estás confundiendo teoría con práctica, esta evaluación está destinada a la lectura, no para la informática. Pero siguió adelante y lo hizo. Es decir, compiló la evaluación en mi artículo en el código de máquina IBM 704, corrigiendo el error, y luego lo anunció como un intérprete Lisp, que ciertamente lo era. Así que en ese momento Lisp había esencialmente la forma que tiene hoy ... "
Entonces Lisp fue reificado de un concepto abstracto a un lenguaje de programación real.
Cosificación
La cosificación es una forma de instanciación. Cuando reifica un concepto, toma algo abstracto y lo hace concreto, al igual que la definición del diccionario que proporcionó.
Puede optar por reificar un tipo como un término que habita algún árbol de sintaxis abstracta de tipos posibles.
Puede cosificar un patrón de diseño creando una implementación de propósito general para algún lenguaje. Por ejemplo, algo como
template<typename T> class Singleton { public: static T& Instance() { static T me; return me; } protected: virtual ~Singleton() {}; Singleton() {}; }
reifica el patrón de diseño singleton como plantilla en C ++.
Puede convertir la idea de ordenación rápida de Hoare en una implementación en el lenguaje de programación que elija. En este sentido, dedico mucho tiempo a cosificar conceptos de la teoría de categorías al código Haskell.
Puede cosificar un idioma como intérprete de ese idioma. La idea de Larry Wall de Perl el lenguaje se reifica como el intérprete de Perl.
Los paquetes data-reify y vacuum reifican términos como gráficos que representan cómo se estructuran en la memoria con el intercambio.
Reflexión
La otra cara de la cosificación es la reflexión , que toma algo concreto y genera una abstracción, generalmente olvidando algunos detalles. Quizás quieras hacer esto porque la abstracción es más simple, o de alguna manera captura la esencia de lo que estás hablando.
La reflexión del sistema de tipos en Java, C #, etc. toma una clase concreta en un lenguaje de programación y le proporciona la estructura abstracta de una clase, lo que le da acceso a la lista de los miembros que proporcionan sus clases. Aquí estamos tomando la noción concreta de un tipo y generando un término abstracto que describe su estructura, descartando cualquier valor particular.
Al igual que cómo puede cosificar un lenguaje de programación en una implementación, algunas veces puede ir en la dirección opuesta. Aunque esto generalmente se considera una mala idea, puede tomar una implementación e intentar reflejar una especificación de lenguaje a partir de las propiedades deseables de su comportamiento. TeX fue implementado primero por Knuth, sin especificación. Cualquier especificación de TeX se ha reflejado en la implementación de Knuth.
(Más formalmente, si ve la reflexión como un functor olvidadizo que lo lleva de un dominio concreto a un dominio abstracto, entonces la reificación, idealmente, se deja adjunta a la reflexión).
El paquete de reflexión que mantengo proporciona un método de reificación que toma un término y produce un tipo que lo representa, luego un método de reflexión que le permite generar un nuevo término. Aquí el dominio 'concreto' es el sistema de tipos y el dominio abstracto son términos.
fuente
De la Wiki de Haskell :
fuente
Un uso que se me ocurre (¡estoy seguro de que hay otros!) Es convertir una clase en un diccionario. Tomemos la
Eq
clase (olvidándonos del/=
operador por el momento):class Eq a where (==) :: a -> a -> Bool
Si reificamos esta clase, se convierte en:
data EqDict a = EqDict (a -> a -> Bool)
que se puede construir, inspeccionar, etc. También es digno de mención que solo puede tener una
Eq
instancia por tipo, pero variosEqDict
valores. Pero la construcción automática de instancias (por ejemplo, obtener igualdad para listas cuando la tiene para elementos) no funciona; tendrá que construir elEqDict [a]
valor usted mismo.El proceso de reificación es tan simple como esto (para este caso):
reify :: Eq a => EqDict a reify = EqDict (==)
Una función que usa la
Eq
clase podría transformar algo como esto:-- silly example, doesn't really do anything findMatches :: Eq a => a -> [a] -> [a] findMatches x ys = [ y | y <- ys, x == y ] -- version using EqDict findMatchesDict :: EqDict a -> a -> [a] -> [a] findMatchesDict (EqDict f) x ys = [ y | y <- ys, f x y ]
Si desenvuelve el EqDict y simplemente pasa un
a -> a -> Bool
, obtendrá las..By
funciones, me gustaData.List.nubBy
y amigos, un truco similar para losOrd
clientes potencialesData.List.sortBy
.fuente
Incluso solo en el contexto de Haskell, el término se usa de manera muy amplia. El paquete reify de Andy Gill le permite tomar estructuras recursivas y convertirlas en gráficos explícitos. La publicación de Sigpfe sobre continuaciones describe cosificar la noción de "el resto del cálculo" en un valor que puede pasar. La plantilla Haskell tiene una función reify (ejecutada, junto con el código TH en general, en el momento de la compilación) que cuando se le da el nombre de un valor Haskell devuelve información disponible sobre él (donde se declara, tipo, etc.).
¿Qué tienen todos estos casos en común? Están hablando de tomar algo sobre lo que podemos razonar y conocer, pero que no podemos manipular directamente mediante programación, y convertirlo en un valor real de primera clase que podamos nombrar y transmitir como cualquier otro. Y esa es generalmente la intención que la gente quiere transmitir cuando usa la palabra.
fuente
Sé que existe el concepto de reificación en RDF. Como dijo Tim Bernes-Lee :
Supongo que es una especie de reflexión o introspección. ¡Espero que obtengas buenas respuestas aquí!
fuente