Problema Funarg

Funarg  - prescurtare pentru „argument funcțional”; în informatică, problema funargue se referă la dificultatea implementării funcțiilor ca obiecte de primă clasă în limbaje de programare orientate spre stivă (în sensul cel mai larg, inclusiv toate limbajele în care parametrii sunt transferați la funcții prin intermediul stivei).

Complexitatea apare dacă corpul funcției se referă direct (de exemplu, nu prin trecerea parametrilor) la identificatori definiți în mediul în care este definită funcția, și nu în mediul apelului acesteia [1] . Rezumând următorul raționament, cele două soluții standard sunt de a interzice astfel de referințe sau de a crea închideri [2] .

Există două versiuni ale problemei: problema funarg ascendentă apare atunci când o funcție revine de la o anumită funcție, problema funarg descendentă apare atunci când o funcție  este transmisă ca parametru unei anumite funcții.

The Rising Funarg Problem

Când o funcție o apelează pe alta în timpul execuției normale a programului, starea locală a funcției apelante (inclusiv parametrii și variabilele locale) trebuie salvată, astfel încât execuția să poată continua după ce funcția apelată revine. În majoritatea programelor compilate, această stare locală este stocată pe stiva de apeluri într-o structură de date numită cadru de stivă . Acest cadru de stivă este împins pe stiva de apeluri atunci când funcția internă este apelată și eliminat de acolo când revine. Problema bubble funarg apare atunci când apelantul se referă la starea apelatului după ce acesta a revenit. Prin urmare, cadrul stivei care conține starea funcției apelate nu trebuie dealocat când revine, rupând paradigma de apelare a funcției orientate spre stivă.

Soluția pentru problema funargs bubbled este să plasați cadrul stivei pe heap în loc de stiva de apeluri, bazându-vă pe o formă de colectare a gunoiului pentru a vă asigura că resursele ocupate de cadrele stivei sunt eliberate atunci când nu mai sunt necesare. Lucrul cu cadre de stivă alocate pe heap este mult mai puțin eficient decât pe stivă, astfel încât această strategie poate reduce semnificativ performanța.

Dacă cantitatea de memorie ocupată de cadrele cu funcții de încadrare este mică, iar datele din aceste cadre nu se modifică, atunci cadrele cu funcțiile de încadrare pot fi transmise ca valori. Această caracteristică este predefinită pentru unele limbi (majoritatea limbilor funcționale și Java pentru metodele claselor interne anonime). Dar și pentru limbajele care vă permit să modificați datele funcțiilor care includ (de exemplu, C# ), unii compilatori eficienți implementează o abordare hibridă în care cadrul de stivă al funcției este plasat pe stiva de apeluri dacă compilatorul reușește să deducă prin analiza programului că funcția nu creează funarg ascendente și, în caz contrar, pe heap. Plasarea cadrului stivei pe grămada degradează în general performanța.

Problema funarg descendent

Un funarg descendent se poate referi și la starea unei funcții atunci când aceasta nu se execută. Totuși, deoarece, prin definiție, existența unui funarg în aval este limitată de timpul de execuție al funcției care îl creează, un cadru de stivă pentru acesta poate fi plasat pe stiva de apeluri. Cu toate acestea, funarg-urile de sus în jos implică o structură arborescentă de închideri și cadre care îngreunează concluziile umane despre starea programului.

Problema apare în programele în limbaje care permit ca funcții să fie transmise ca parametri, cum ar fi Pascal și Algol 68 .

Problema funarg de sus în jos face recursiunea cozii și codul de trecere a continuării mai dificil de compilat eficient .

Note

  1. Funcția FUNCȚIEI în LISP sau de ce problema FUNARG ar trebui numită problema mediului , de Joel Moses, în: ACM SIGSAM Buletin 17 (iulie 1970), pp. 13-27
  2. O soluție propusă la problema FUNARG , de Erik Sandewall, în: ACM SIGSAM Bulletin 17 (ian. 1971), pp. 29-42