La desfuncionalización en programación es una técnica para transformar un programa en tiempo de compilación , reemplazando funciones de orden superior con una llamada a una sola función de aplicar una función a un argumento.
Fue descrito por primera vez por John Reynolds en 1972 [ 1] . Dado que cualquier programa contiene un número finito de abstracciones funcionales, cada una de ellas puede reemplazarse por un identificador único, y cada aplicación de una función abstracta en dicho programa puede reemplazarse por una llamada de función de la función de aplicación con el identificador del resumen. funciona como el primer parámetro. En este caso, la función de aplicación selecciona operaciones por el identificador de la función abstracta y las realiza sobre los argumentos restantes (los argumentos originales de la función abstracta).
Una dificultad de esta técnica es que la abstracción funcional puede referirse a variables libres . En tal situación, λ-lifting , la transformación de variables libres en cierres , debe realizarse antes de realizar la desfuncionalización , de modo que cualquier variable libre utilizada por la abstracción funcional se pase como argumento a la función de aplicación. Además, si se admite el vaciado como un valor de primera clase , se deben crear nuevas estructuras de datos para representar los valores capturados.
En lugar de usar una sola función de aplicación para manejar todos los casos, se pueden usar varias técnicas de análisis de flujo de control (incluida la distinción simple entre diferentes tipos de arities (número de argumentos) o firmas de tipos ) para separar la aplicación en varias funciones especializadas. Además, el lenguaje de programación puede admitir punteros de función , que pueden ser más eficientes que el enfoque de envío.
Además de usarse en compiladores para lenguajes de programación funcionales que usan funciones de orden superior, la desfuncionalización también se ha explorado como un método para transformar mecánicamente un intérprete en una máquina abstracta . La desfuncionalización también está relacionada con la técnica de representar funciones con objetos de función en la programación orientada a objetos (como alternativa al uso de cierres).
Para el tipo de datos de árbol [2] :
datos Árbol a = Hoja a | Nodo ( Árbol a ) ( Árbol a )el siguiente programa está desfuncionalizado:
contras :: a -> [ a ] -> [ a ] contras x xs = x : xs o :: ( b -> c ) -> ( a -> b ) -> a -> c o f g x = f ( g x ) aplanar :: Árbol t -> [ t ] aplanar t = caminar t [] caminar :: Árbol t -> [ t ] -> [ t ] caminar ( Hoja x ) = cons x caminar ( Nodo t1 t2 ) = o ( caminar t1 ) ( caminar t2 )Para ello, todas las funciones de orden superior ( cons, o, y walk) se sustituyen por un valor de tipo Lam, y en lugar de una llamada directa a función, se utiliza una función applyque procesa valores de este tipo:
datos Lam a = LamCons a | LamO ( Lam a ) ( Lam a ) aplicar :: Lam a -> [ a ] -> [ a ] aplicar ( LamCons x ) xs = x : xs aplicar ( LamO f1 f2 ) xs = aplicar f1 ( aplicar f2 xs ) cons_def :: a -> Lam a cons_def x = LamCons x o_def :: Lam a -> Lam a -> Lam a o_def f1 f2 = LamO f1 f2 flatten_def :: Árbol t -> [ t ] flatten_def t = aplicar ( walk_def t ) [] walk_def :: Tree t -> Lam t walk_def ( Hoja x ) = cons_def x walk_def ( Nodo t1 t2 ) = o_def ( walk_def t1 ) ( walk_def t2 )