6145052799dd99cc26450bd01b0326502a83b288
linguaggi.md
| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | +--- |
|
| 2 | +title: Linguaggi |
|
| 3 | +description: Corso di linguaggi UNIBO |
|
| 4 | +published: true |
|
| 5 | +tags: |
|
| 6 | +editor: markdown |
|
| 7 | +--- |
|
| 8 | + |
|
| 9 | +# Corso di Linguaggi |
|
| 10 | + |
|
| 11 | +Come vengono strutturati i linguaggi di programmazione. |
|
| 12 | + |
|
| 13 | +## Appunti |
|
| 14 | + |
|
| 15 | +- (./linguaggi/s02/20260219.md) - cosa sono le Variabili, scoping statico e dinamico |
linguaggi/s02/20260219.md
| ... | ... | @@ -10,32 +10,35 @@ dateCreated: 2026-02-19T06:38:48.738Z |
| 10 | 10 | |
| 11 | 11 | # Variabili |
| 12 | 12 | |
| 13 | -L’ambiente (in uno specifico blocco) può essere |
|
| 14 | -suddiviso in: |
|
| 15 | -– ambiente locale: associazioni create all’ingresso nel blocco - variabili locali - parametri formali |
|
| 16 | -– ambiente non locale : associazioni ereditate da altri blocchi |
|
| 17 | -– ambiente globale: quella parte di ambiente non locale relativo alle associazioni comuni a tutti i blocchi - dichiarazioni esplicite di variabili globali - dichiarazioni del blocco più esterno - associazioni esportate da moduli ecc. |
|
| 13 | +L’ambiente (in uno specifico blocco) può essere suddiviso in: |
|
| 14 | + |
|
| 15 | +- **Ambiente locale**: associazioni create all’ingresso nel blocco (es. variabili locali, parametri formali). |
|
| 16 | +- **Ambiente non locale**: associazioni ereditate da altri blocchi. |
|
| 17 | +- **Ambiente globale**: la parte di ambiente non locale relativa alle associazioni comuni a tutti i blocchi (es. dichiarazioni esplicite di variabili globali, dichiarazioni del blocco più esterno, associazioni esportate da moduli). |
|
| 18 | 18 | |
| 19 | 19 | ## Operazioni sugli oggetti denotabili |
| 20 | 20 | |
| 21 | -• Creazione |
|
| 22 | -• Accesso |
|
| 23 | -• Modifica (se l’oggetto è modificabile) |
|
| 24 | -• Distruzione |
|
| 21 | +Le operazioni fondamentali che si possono compiere su un oggetto sono: |
|
| 22 | + |
|
| 23 | +- Creazione |
|
| 24 | +- Accesso |
|
| 25 | +- Modifica (se l’oggetto è modificabile) |
|
| 26 | +- Distruzione |
|
| 25 | 27 | |
| 26 | -Creazione e distruzione di un oggetto non coincidono con creazione e distruzione dei legami per esso |
|
| 27 | -Alcuni eventi fondamentali |
|
| 28 | +> **Nota Bene:** Creazione e distruzione di un oggetto **non** coincidono necessariamente con la creazione e distruzione dei legami per quell'oggetto. |
|
| 29 | + |
|
| 30 | +### Eventi fondamentali nel ciclo di vita |
|
| 28 | 31 | |
| 29 | 32 | 1. Creazione di un oggetto |
| 30 | 33 | 2. Creazione di un legame per l’oggetto |
| 31 | -3. Riferimento all’oggetto, tramite il legame |
|
| 34 | +3. Riferimento all’oggetto (tramite il legame) |
|
| 32 | 35 | 4. Disattivazione di un legame |
| 33 | 36 | 5. Riattivazione di un legame |
| 34 | 37 | 6. Distruzione di un legame |
| 35 | 38 | 7. Distruzione di un oggetto |
| 36 | - Il tempo tra 1 e 7 è la vita (o il tempo di vita: lifetime) |
|
| 37 | - dell’oggetto |
|
| 38 | - Il tempo tra 2 e 6 è la vita dell’associazione |
|
| 39 | + |
|
| 40 | +- **Tempo di vita dell'oggetto (Lifetime):** Il tempo trascorso tra i punti 1 e 7. |
|
| 41 | +- **Tempo di vita dell'associazione (Legame):** Il tempo trascorso tra i punti 2 e 6. |
|
| 39 | 42 | |
| 40 | 43 | Nota: La vita di un oggetto non coincide con la vita dei legami per quell’oggetto |
| 41 | 44 | • Vita dell’oggetto più lunga di quella del legame:(variabile passata ad una proc per riferimento) |
| ... | ... | @@ -48,7 +51,7 @@ var A:integer; |
| 48 | 51 | P(A); |
| 49 | 52 | ``` |
| 50 | 53 | |
| 51 | -- area di mem allocata dinamicamente |
|
| 54 | +**Area di memoria allocata dinamicamente** (es. puntatori in C): |
|
| 52 | 55 | |
| 53 | 56 | ``` |
| 54 | 57 | int *X, *Y; |
| ... | ... | @@ -60,89 +63,149 @@ free (X); |
| 60 | 63 | X=null; |
| 61 | 64 | ``` |
| 62 | 65 | |
| 63 | -## Scope |
|
| 66 | +## Scope (visibilità) |
|
| 64 | 67 | |
| 65 | 68 | Una dichiarazione locale ad un blocco è visibile in quel blocco e in tutti i blocchi in esso annidati, a meno che non intervenga in tali blocchi una nuova dichiarazione dello stesso nome (che nasconde, o maschera, la precedente) |
| 66 | 69 | |
| 67 | -- in presenza di procedure (cioè di blocchi che sono eseguiti in posizioni diverse dalla loro definizione) |
|
| 68 | - – in presenza ambiente non locale (e non globale) |
|
| 70 | +Il problema della risoluzione di un riferimento non locale nasce in presenza di: |
|
| 71 | + |
|
| 72 | +- Procedure (ovvero blocchi eseguiti in posizioni diverse dalla loro definizione). |
|
| 73 | +- Ambiente non locale (e non globale). |
|
| 69 | 74 | |
| 70 | 75 | ``` |
| 71 | -{int x=10; |
|
| 72 | -void foo () { |
|
| 73 | - x++; |
|
| 76 | +{ |
|
| 77 | + int x = 10; |
|
| 78 | + |
|
| 79 | + void foo() { |
|
| 80 | + x++; |
|
| 74 | 81 | } |
| 75 | -void fie (){ |
|
| 76 | - int x = 0; |
|
| 77 | - foo(); |
|
| 82 | + |
|
| 83 | + void fie() { |
|
| 84 | + int x = 0; |
|
| 85 | + foo(); |
|
| 78 | 86 | } |
| 79 | -fie(); |
|
| 87 | + |
|
| 88 | + fie(); |
|
| 80 | 89 | } |
| 81 | 90 | ``` |
| 82 | 91 | |
| 83 | -quale x incrementa foo? |
|
| 92 | +Quale `x` viene incrementata da `foo`? La risposta dipende dalla regola di scope adottata dal linguaggio: |
|
| 84 | 93 | |
| 85 | -un riferimento non-locale in un blocco B puo essere risolto: |
|
| 94 | +- **Scope Statico**: Il riferimento è risolto nel blocco che include sintatticamente B. |
|
| 95 | +- **Scope Dinamico**: Il riferimento è risolto nel blocco che è stato eseguito immediatamente prima di B. |
|
| 86 | 96 | |
| 87 | -- nel blocco che include sintatticamente B (**scope statico**) |
|
| 88 | -- nel blocco che e eseguito immediatamente prima di B (**scope dinamico**) |
|
| 97 | +### Esempi di Output a confronto |
|
| 89 | 98 | |
| 90 | - |
|
| 99 | +**Con Scope Statico**: |
|
| 100 | +Il riferimento è legato alla struttura del testo. la chiamata di pippo usa sempre la x definita al suo stesso livello. |
|
| 91 | 101 | |
| 92 | -### Scope dinamico |
|
| 102 | +``` |
|
| 103 | +{int x = 0; |
|
| 104 | +void pippo(int n){ |
|
| 105 | + x = n+1; |
|
| 106 | +} |
|
| 107 | +pippo(3); |
|
| 108 | +write(x); # stampa 4 |
|
| 109 | +{ |
|
| 110 | +int x = 0; |
|
| 111 | +pippo(3); |
|
| 112 | +write(x); # stampa 0 |
|
| 113 | +} |
|
| 114 | +write(x); # stampa 4 |
|
| 115 | +``` |
|
| 93 | 116 | |
| 94 | -Un nome non locale e' risolto nel blocco attivato piu' di recente e non ancora disattivato. |
|
| 95 | - |
|
| 117 | +**Con Scope Dinamico:** |
|
| 118 | +Un nome non locale è risolto nel blocco attivato più di recente e non ancora disattivato. pippo usa la x del chiamante. |
|
| 96 | 119 | |
| 97 | -Scope statico: indipendenza dalla posizione |
|
| 98 | - |
|
| 99 | -Il corpo di foo e' parte dello scope della x piu esterna |
|
| 100 | -la chiamata di foo e' compresa nello scope della x piu interna |
|
| 101 | -foo puo essere chiamata in molti contesti diversi |
|
| 102 | -l'unico modo in cui foo puo essere compilata in modo univoco e' che il riferimento a x sia sempre quello piu esterno. |
|
| 120 | +``` |
|
| 121 | +{int x = 0; |
|
| 122 | +void pippo(int n){ |
|
| 123 | + x = n+1; |
|
| 124 | +} |
|
| 125 | +pippo(3); |
|
| 126 | +write(x); # stampa 4 |
|
| 127 | +{ |
|
| 128 | +int x = 0; |
|
| 129 | +pippo(3); |
|
| 130 | +write(x); # stampa 4 |
|
| 131 | +} |
|
| 132 | +write(x); # stampa 4 |
|
| 133 | +``` |
|
| 103 | 134 | |
| 104 | -La chiamata di foo interna a file e quella nel main accedono alla stessa variabile: la x esterna. |
|
| 135 | +### I principi dello Scope Statico |
|
| 105 | 136 | |
| 106 | -Scope statico: indipendenza dai nomi locali |
|
| 137 | +Lo scope statico si basa su due principi fondamentali: |
|
| 138 | +**1. Indipendenza dalla posizione:** |
|
| 139 | +Il corpo di `foo` è parte dello scope della `x` più esterna. L'unico modo in cui `foo` può essere compilata in modo univoco è che il riferimento a `x` sia sempre quello più esterno, indipendentemente da dove `foo` venga chiamata. |
|
| 107 | 140 | |
| 108 | - |
|
| 141 | +``` |
|
| 142 | +{int x = 10; |
|
| 143 | +void foo(){ |
|
| 144 | + x++; |
|
| 145 | +} |
|
| 146 | +void fie (){ |
|
| 147 | + int x = 0; |
|
| 148 | + foo(); |
|
| 149 | +} |
|
| 150 | +fie(); |
|
| 151 | +foo(); |
|
| 152 | +} |
|
| 153 | +``` |
|
| 154 | + |
|
| 155 | +**2. Indipendenza dai nomi locali:** |
|
| 156 | +La modifica del nome di una variabile locale in un blocco chiamante non deve influire sulla funzione chiamata. |
|
| 157 | + |
|
| 158 | +``` |
|
| 159 | +{int x = 10; |
|
| 160 | +void foo(){ |
|
| 161 | + x++; |
|
| 162 | +} |
|
| 163 | +void fie (){ |
|
| 164 | + int y = 0; |
|
| 165 | + foo(); |
|
| 166 | +} |
|
| 167 | +fie(); |
|
| 168 | +foo(); |
|
| 169 | +} |
|
| 170 | +``` |
|
| 171 | + |
|
| 172 | +Rinominare la locale da `x` a `y` dentro `fie`: |
|
| 109 | 173 | |
| 110 | -la modifica del locale x in y dentro fie: |
|
| 174 | +- Modifica la semantica del programma in scope dinamico. |
|
| 175 | +- **Non ha alcun effetto** in scope statico. |
|
| 111 | 176 | |
| 112 | -- modifica la semantica del programma in scope dinamico |
|
| 113 | -- non ha alcun effetto in scope statico |
|
| 177 | +**Nota sullo scope dinamico:** È utile per "specializzare" una funzione a runtime. Ad esempio, una procedura `visualizza` che renderizza a video può ereditare il colore rosso semplicemente definendo una variabile locale prima di chiamarla: |
|
| 114 | 178 | |
| 115 | -Scope dinamico: specializzare una funzione |
|
| 179 | +``` |
|
| 180 | +{var colore = rosso; |
|
| 181 | +visualizza(testo);} |
|
| 182 | +``` |
|
| 116 | 183 | |
| 117 | -visualizza e' una procedura che rende a colore sol video una certa forma |
|
| 118 | - |
|
| 184 | +#### Confronto: Statico vs Dinamico |
|
| 119 | 185 | |
| 120 | -Scope statico vs dinamico |
|
| 186 | +**Scope Statico:** |
|
| 121 | 187 | |
| 122 | -Scope statico: |
|
| 188 | +- Informazione completa dal testo del programma. |
|
| 189 | +- Le associazioni sono note a tempo di compilazione. |
|
| 190 | +- Garantisce i principi di indipendenza. |
|
| 191 | +- Concettualmente più complesso da implementare nel compilatore, ma più efficiente a runtime. |
|
| 192 | +- Linguaggi: Algol, Pascal, C, Java, Ada. |
|
| 123 | 193 | |
| 124 | -- informazione completa dal testo del programma |
|
| 125 | -- le associazioni sono note a tempo di compilazione |
|
| 126 | -- dunque: principi di indipendenza |
|
| 127 | -- concettualmente piu complesso da implementare ma piu efficiente (algol, pascal, C, java) |
|
| 194 | +**Scope Dinamico:** |
|
| 128 | 195 | |
| 129 | -Scope dinamico: |
|
| 196 | +- Informazione derivata dall'esecuzione. |
|
| 197 | +- Spesso causa di programmi meno "leggibili" e più difficili da debuggare. |
|
| 198 | +- Concettualmente più semplice da implementare, ma meno efficiente. |
|
| 199 | +- Linguaggi: Lisp (alcune versioni), Perl. |
|
| 130 | 200 | |
| 131 | -- informazione derivata dall'esecuzione |
|
| 132 | - – spesso causa di programmi meno ``leggibili’’ |
|
| 133 | - – concettualmente più semplice da implementare, ma meno efficiente |
|
| 134 | - – Lisp (alcune versioni), Perl |
|
| 201 | +**Approfondimento:** Le differenze emergono solo in presenza congiunta di ambiente non locale (e non globale) e procedure. Algol, Pascal, Ada e Java permettono di annidare blocchi di sottoprogrammi, cosa non possibile in C. Questo non vuol dire che la regola di scoping sia indifferente in C, le regole si applicano ugualmente a contesti globali/locali! |
|
| 135 | 202 | |
| 136 | -Differiscono solo in presenza congiunta di |
|
| 137 | -– ambiente non locale e non globale |
|
| 138 | -– procedure |
|
| 203 | +**Determinare l'ambiente** |
|
| 139 | 204 | |
| 140 | -Algol, Pascal, Ada, Java permettono di annidare blocchi di |
|
| 141 | -sottoprogrammi |
|
| 142 | -non possibile in C |
|
| 205 | +L'ambiente è dunque determinato da: |
|
| 143 | 206 | |
| 144 | -Questo non vuol dire che la regola di scoping (statico o |
|
| 145 | -dinamico) sia indifferente in C ! |
|
| 207 | +- Regola di scope (dinamico o statico). |
|
| 208 | +- Regole specifiche del linguaggio (es. obbligo di dichiarare la variabile prima di assegnarla).! |
|
| 146 | 209 | |
| 147 | 210 | Determinare l'ambiente |
| 148 | 211 | |
| ... | ... | @@ -185,3 +248,7 @@ FORTRAN: non ammette la ricorsione |
| 185 | 248 |  |
| 186 | 249 | |
| 187 | 250 |  |
| 251 | + |
|
| 252 | +``` |
|
| 253 | + |
|
| 254 | +``` |