risposta

3

Beh, ci sono un sacco di siti web che parlano di pro e contro, quindi non ci vado.

Un linguaggio interessante con alcune caratteristiche che assomigliano vagamente allo scope dinamico è XSLT; anche se i modelli e le variabili XSLT e simili sono con scope lessicale, XSLT è ovviamente tutto basato su XML - e la posizione corrente nell'albero xml è "portata dinamicamente" nel senso che il nodo di contesto è globale e quindi le espressioni XPath non vengono valutate secondo lo scopo lessicale di XSLT ma secondo la sua valutazione dinamica.

7

Mathematica è un'altra lingua con ambito dinamico, tramite il costrutto Block. Questo è in realtà abbastanza utile quando si lavora con le formule. Esso consente di scrivere le cose come

In[1]:= expr = a*t^2 + b*t+ c; 

In[2]:= Block[{a = 1, b = -1, c = 2}, Table[expr, {t, 5}]] 
Out[2]= {2, 4, 8, 14, 22} 

che non avrebbe funzionato affatto se variabili come a e t stato limitato l'ambito lessicale. Funziona particolarmente bene con il sistema di riscrittura delle regole di Mathematica, che, tra le altre cose, lascerà variabili non valutate (come espressioni simboliche) se non ha una definizione esistente per loro.

Mathematica può simulare lo scoping lessicale con il costrutto Module, ma ciò che realmente fa è riscrivere l'espressione in termini di nuovo simbolo presumibilmente univoco (puoi causare scontri se prevedi quale sarà il prossimo simbolo univoco, che è facile nella maggior parte dei casi). Questo significa

Module[{x = 4}, 
    Table[x * t, {t, 5}]] 

sarà trasformato in qualcosa di simile:

Block[{x$134 = 4}, 
    Table[x$134 * t, {t, 5}] 

Emacs Lisp, in una delle sue librerie, ha un costrutto (in realtà una macro Lisp) chiamato lexical-let che tira esattamente lo stesso trucco simulare lo scoping lessicale.

Ci sono vantaggi prestazionali per lo scoping lessicale reale durante la compilazione del linguaggio che non si ottiene con i finti lessicali di ELisp o Mathematica, poiché è necessario un mapping tra la variabile dinamica e il suo valore corrente, che significa fare ricerche (attraverso una tabella hash o un elenco di proprietà o qualcosa del genere) e ulteriori livelli di riferimento indiretto.

EDIT: Se si dispone soltanto variabili lessicali, è possibile falso visibilità dinamica memorizzando il valore originale di una variabile globale, lessicale entrando nella portata e garantendo che il vecchio valore viene ripristinato all'uscita di applicazione. Al fine di garantire ciò, avrete bisogno di qualcosa come Lisp's UNWIND-PROTECT o un blocco finally. Ho visto questo fatto usando anche distruttori C++, principalmente come esercizio.

9

Le lingue con ambito dinamico sono molto più facili da implementare. Per accedere a variabili che non si trovano nell'attuale record di registrazione/stack frame, si segue semplicemente i link di controllo. I collegamenti di accesso statico/lessicale non sono quindi necessari, rendendo i frame dello stack più piccoli.

Le variabili dinamiche possono essere "imprevedibili" in fase di esecuzione, poiché è necessario conoscere in quale ordine gli stackframes effettivi devono sapere quale variabile verrà utilizzata. Questa informazione non è disponibile semplicemente guardando la struttura statica del codice. Si potrebbe facilmente essere scoperti se l'effettivo grafico delle chiamate del programma non è facile da prevedere al momento dell'implementazione.Ecco perché la maggior parte delle lingue oggi ha scope statico (la maggior parte dei sistemi di eccezione, tuttavia, è dinamica in quanto è la più pratica).

Tuttavia, in alcuni casi, le variabili con ambito dinamico sono molto utili. Ad esempio, quando si reindirizza l'output, è possibile utilizzare le variabili dinamiche per impostare l'output standard per il codice locale e tutto il codice richiamato da lì.

(let ((*standard-output* *some-other-stream*)) 
(stuff)) 

In questo esempio common-lisp (da Seibel), standard output è destinato a un altro flusso per la durata della forma let, (all'interno delle sue parentesi racchiudono). Quando l'esecuzione lascia il let, torna a qualunque cosa fosse in anticipo. Vedi http://gigamonkeys.com/book/variables.html Peter Seibels gratis e ottimo libro, Practical Common Lisp, per una buona discussione. In Seibels le parole:

Le associazioni dinamiche rendono le variabili globali molto più gestibili, ma è importante notare che consentono comunque un'azione a distanza. Associare una variabile globale ha due effetti a distanza: può modificare il comportamento del codice a valle e apre anche la possibilità che il codice a valle assegni un nuovo valore a un legame stabilito più in alto nello stack. È necessario utilizzare le variabili dinamiche solo quando è necessario sfruttare una o entrambe queste caratteristiche.

3

L'ambito dinamico è/era più facile da implementare con gli interpreti. La maggior parte dei primi interpreti Lisp utilizzava scope dinamiche. Dopo diversi anni, è stato scoperto che lo scope lessicale aveva un vantaggio, ma in primo luogo è stato implementato principalmente nei compilatori Lisp. Sono apparse diverse implementazioni che hanno implementato l'ambito dinamico nel codice interpretato e lo scope lessicale nel codice compilato. Alcuni hanno fornito un costrutto linguistico speciale per fornire chiusure. I dialetti Lisp come Scheme e Common Lisp richiedevano quindi che non ci fosse differenza tra codice interpretato e compilato e quindi le implementazioni basate interpretate dovevano implementare anche lo scope lessicale.

Le implementazioni Earlytalk implementavano l'ambito dinamico. Tutti i tipi di implementazioni di dialetti Lisp hanno implementato il dynamic scope (Interlisp, UCI Lisp, Lisp Machine Lisp, MacLisp, ...).

Quasi tutti i nuovi dialoghi Lisp degli ultimi 20 anni utilizzano lo scope lessicale di default o anche esclusivamente. Diverse pubblicazioni hanno descritto in dettaglio come implementare il Lisp con scope lessicale - quindi non ci sono scuse per non usare scope lessicale.

2

Tutti i linguaggi della shell (bash, ksh, ecc.) Utilizzano l'ambito dinamico.

Problemi correlati