Defuncționalizarea în programare este o tehnică de transformare a unui program în timpul compilării , înlocuind funcțiile de ordin superior cu un apel la o singură funcție de aplicare a unei funcții unui argument.
A fost descris pentru prima dată de John Reynolds în 1972 [ 1] . Deoarece orice program conține un număr finit de abstracții funcționale, fiecare dintre ele poate fi înlocuită cu un identificator unic, iar fiecare aplicație a unei funcții abstracte într-un astfel de program poate fi înlocuită cu un apel de funcție al funcției aplicației cu identificatorul abstractului. funcţionează ca prim parametru. În acest caz, funcția de aplicație selectează operațiuni prin identificatorul funcției abstracte și le execută pe argumentele rămase (argumentele originale ale funcției abstracte).
O dificultate pentru această tehnică este că abstracția funcțională se poate referi la variabile libere . Într-o astfel de situație, λ-lifting — transformarea variabilelor libere în închideri — trebuie efectuată înainte de efectuarea defuncționalizării , astfel încât orice variabilă liberă utilizată de abstractizarea funcțională să fie transmisă ca argument funcției aplicației. De asemenea, dacă spălarea este acceptată ca valoare de primă clasă , atunci trebuie create noi structuri de date pentru a reprezenta valorile capturate.
În loc să folosiți o singură funcție de aplicație pentru a gestiona toate cazurile, diferite tehnici de analiză a fluxului de control (inclusiv distincția simplă între diferite tipuri de arii (număr de argumente) sau semnături de tip ) pot fi utilizate pentru a separa aplicația în mai multe funcții specializate. De asemenea, limbajul de programare poate suporta indicatori de funcție , care pot fi mai eficiente decât abordarea de expediere.
Pe lângă faptul că este folosită în compilatoare pentru limbaje funcționale de programare care utilizează funcții de ordin superior, defuncționalizarea a fost, de asemenea, explorată ca metodă de transformare mecanică a unui interpret într- o mașină abstractă . Defuncționalizarea este legată și de tehnica reprezentării funcțiilor cu obiecte funcție în programarea orientată pe obiecte (ca alternativă la utilizarea închiderilor).
Pentru tipul de date arbore [2] :
date Arborele a = Frunza a | Nod ( Arborele a ) ( Arborele a )următorul program este defuncționalizat:
contra :: a -> [ a ] -> [ a ] contra x xs = x : xs o :: ( b -> c ) -> ( a -> b ) -> a -> c o f g x = f ( g x ) aplatiza :: Arborele t -> [ t ] aplatiza t = mers t [] plimbare :: Arborele t -> [ t ] -> [ t ] mers ( Frunza x ) = cons x mers ( Nodul t1 t2 ) = o ( mers t1 ) ( mers t2 )Pentru a face acest lucru, toate funcțiile de ordin superior ( cons, o, și walk) sunt înlocuite cu o valoare de tip Lamși, în loc de un apel direct al funcției, este utilizată o funcție applycare procesează valori de acest tip:
date Lam a = LamCons a | LamO ( Lam a ) ( Lam a ) se aplică :: Lam a -> [ a ] -> [ a ] se aplică ( LamCons x ) xs = x : xs se aplică ( LamO f1 f2 ) xs = se aplică f1 ( se aplică 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 :: Arbore t -> [ t ] flatten_def t = aplica ( walk_def t ) [] walk_def :: Arbore t -> Lam t walk_def ( Leaf x ) = cons_def x walk_def ( Nodul t1 t2 ) = o_def ( walk_def t1 ) ( walk_def t2 )