¿Qué significan "cosificar" y "cosificar" en el contexto de la programación (funcional?)?

81

Leo mucho este término en blogs sobre haskell y programación funcional (especialmente en el blog de sigfpe ) pero no tengo ni idea de lo que significa. La mayoría de las veces me salgo con la suya sin saberlo, pero probablemente habría entendido los textos mucho mejor si lo hubiera sabido. Google no me ayudó. Me pierdo en lo técnico.

Además, el significado no técnico del mundo ("convertir el concreto abstracto") no me ayuda a entender lo que significa en la práctica cosificar algo en código.

Soy un poco lento con los conceptos de informática, por lo que los ejemplos prácticos con código serían buenos. :PAG

Rafael S. Calsaverini
fuente

Respuestas:

40

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 Groupclase y una Userclase. Ahora bien, hay ciertos conceptos abstractos que describen la relación entre los dos. Por ejemplo, el concepto abstracto de un Userser miembro de un Group. Para concretar esta relación, escribiría un método llamado isMemberOfque diga si a Useres 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 evalfunció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.  

Vivin Paliath
fuente
2
Parece que la cosificación existe en un continuo dependiendo de la situación. Si bien el lisp abstracto se reificó en un lenguaje de programación, un lenguaje de programación en sí mismo es un concepto bastante abstracto que comunica la computación, que debe reificarse aún más en código de máquina y finalmente en 1 y 0 y finalmente en señales eléctricas ... etc. Así, la cosificación es justamente lo opuesto (dual) de la abstracción.
CMCDragonkai
25

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.

Edward KMETT
fuente
21

De la Wiki de Haskell :

"Cosificar" algo es tomar algo que es abstracto y considerarlo como material. Un ejemplo clásico es la forma en que los antiguos tomaron conceptos abstractos (por ejemplo, "victoria") y los convirtieron en deidades (por ejemplo, Nike, la diosa griega de la victoria).

Un tipo cosificado es un valor que representa un tipo. El uso de tipos reificados en lugar de tipos reales significa que puede hacer cualquier manipulación con ellos que pueda hacer con valores.

Kynth
fuente
15

Un uso que se me ocurre (¡estoy seguro de que hay otros!) Es convertir una clase en un diccionario. Tomemos la Eqclase (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 Eqinstancia por tipo, pero varios EqDictvalores. Pero la construcción automática de instancias (por ejemplo, obtener igualdad para listas cuando la tiene para elementos) no funciona; tendrá que construir el EqDict [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 Eqclase 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 ..Byfunciones, me gusta Data.List.nubByy amigos, un truco similar para los Ordclientes potenciales Data.List.sortBy.

yatima2975
fuente
9

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.

sclv
fuente
2

Sé que existe el concepto de reificación en RDF. Como dijo Tim Bernes-Lee :

La cosificación en este contexto significa la expresión de algo en un idioma usando el idioma, de modo que se vuelva tratable por el idioma.

Supongo que es una especie de reflexión o introspección. ¡Espero que obtengas buenas respuestas aquí!

M. Dudley
fuente