linguaggi/s02/sottoprogrammi_ed_eccezioni.md
... ...
@@ -0,0 +1,289 @@
1
+# Sottoprogrammi
2
+
3
+Un linguaggio senza parametri puo'esistere? Si (es. assembly)
4
+
5
+## Astrazione
6
+
7
+- identificare proprietà importanti di cosa si vuole descrivere
8
+- concentrarsi sulle questioni rilevanti e ignorare le altre
9
+- cosa è rilevante dipende dallo scopo del progetto
10
+
11
+Voglio asseganare a un gruppo di istruzioni un nome e fare fare a questo gruppo di istruzioni delle op su dei paramentri che passo. Il codice diventa piu astratto e piu leggibile
12
+
13
+Nota: I LP sono essi stessi astrazioni del calcolatore sottostante
14
+
15
+Astrazione sul controllo e sui dati
16
+
17
+### Astrazione sul controllo
18
+
19
+Sono per es: sottoprogrammi, blocchi, parametri
20
+
21
+```
22
+double P (int x) {
23
+ double z;
24
+ /* CORPO DELLA FUNZIONE
25
+ return expr;
26
+}
27
+```
28
+
29
+![sottoprogrammi_ed_eccezioni_2026-03-10_14-08-26](assets/imgs/sottoprogrammi_ed_eccezioni_2026-03-10_14-08-26.png)
30
+
31
+### Astrazione del controllo
32
+
33
+Fornisce astrazione funzionale al progetto:
34
+
35
+- ogni componente fornisce servizi al suo ambiente
36
+- la sua astrazione descrive il comportamente esterno
37
+- e nasconde i dettagli interni necessari a produrlo
38
+
39
+Interazione limitata al comportamento esterno
40
+
41
+Comunicazione attraverso:
42
+
43
+- parametri
44
+- ambiente globale (ma distrugge l’astrazione)
45
+
46
+### Astrazione sui dati
47
+
48
+Tipo di dato = valori e operazioni (`integer = [-maxint..maxint]` e ` {+,-,*,div,mod}`)
49
+La rappresentazione (implementazione) dei dati delle operazioni inaccessibile all’utente, perché protetta da una capsula che la isola
50
+
51
+> Nota: impossibile nel linguaggi più vecchi
52
+>
53
+> - FORTRAN, Pascal, C
54
+
55
+### Parametri
56
+
57
+Terminologia
58
+
59
+- dichiarazione/definizione `int f (int n) {return n+1}` n si dice parametro formale
60
+ ![sottoprogrammi_ed_eccezioni_2026-03-10_14-14-25](assets/imgs/sottoprogrammi_ed_eccezioni_2026-03-10_14-14-25.png)
61
+
62
+Nota: Una funz comunica con il chiamante (return)
63
+
64
+#### Modalita' di passaggio dei parametri
65
+
66
+Per valore:
67
+
68
+- il val dell'attuale e'assegnato al formale, che si comporta come una var locale
69
+- pragmatica: main -> proc
70
+- attuale qualsiasi; modifiche al formale non passano all'attuale
71
+
72
+Per riferimento:
73
+
74
+- viene passato un riferimento (indirizzo) all'attuale; i riferimenti al formale sono referimenti all'attuale (aliasing)
75
+- pragmatica: main <-> proc
76
+- attuale: variabile; modifiche al formale passano all'attuale
77
+
78
+##### Es passaggio per valore:
79
+
80
+```c
81
+void foo (int x) { x = x+1; }
82
+ …
83
+ y = 1;
84
+ foo(y+1);
85
+```
86
+
87
+dopo foo y vale comunque 1.
88
+
89
+- Il formale x è una var locale (sulla pila)
90
+- Alla chiamata, l’attuale y+1 è valutato ed il valore è assegnato al formale x
91
+- Nessun legame tra x nel corpo di foo e y nel chiamante
92
+- Al ritorno da foo, x viene distrutto (tolto dalla pila)
93
+- Non è possibile trasmettere info da foo al chiamante mediante il parametro
94
+- Costoso per dati grandi: copia
95
+- Java, Scheme, Pascal (default), C e Java (unico modo);
96
+
97
+##### Es: passaggio per riferimento
98
+
99
+```c
100
+void foo (reference int x){ x = x+1;}
101
+ …
102
+ y = 1;
103
+ foo(y);
104
+```
105
+
106
+dopo foo y vale 2.
107
+
108
+- viene passato un riferimento (indirizzo; puntatore)
109
+- Il formale x è un alias di y
110
+- L’attuale deve essere un L-valore (“una variabile”)
111
+- Al ritorno da foo, viene distrutto il (solo) legame tra x e l’indirizzo di y
112
+- Trasmissione bidirezionale tra chiamante e chiamato
113
+- Efficiente nel passaggio, ma indirezione nel corpo
114
+- Pascal (var); in C simulato passando un puntatore…
115
+
116
+### Passaggio per risultato:
117
+
118
+simile al passaggio per riferimento.
119
+
120
+```c
121
+void foo (result int x) {x = 8;}
122
+ …
123
+ y = 1;
124
+ foo(y);
125
+```
126
+
127
+- Il formale x è una var locale (sulla pila)
128
+- Al ritorno da foo, il valore di x è assegnato all’attuale y
129
+- Nessun legame tra x nel corpo di foo e y nel chiamante
130
+- Al ritorno da foo, x viene distrutto (tolto dalla pila)
131
+- Non è possibile trasmettere info dal chiamante a foo mediante il parametro
132
+- Costoso per dati grandi: copia
133
+- Ada: out
134
+
135
+### Passaggio per valore/risultato:
136
+
137
+Insieme valore+risultato.
138
+Pragmatica: main ↔ proc
139
+
140
+Esiste(-va) in Algol-W:
141
+void foo (value-result int x)
142
+{ x = x+1; }
143
+…
144
+y = 8;
145
+foo(y);
146
+qui y vale 9
147
+• Il formale x è a tutti gli effetti una var locale (sulla pila)
148
+• Alla chiamata, il valore dell’attuale è assegnato al formale
149
+• Al ritorno, il valore del formale è assegnato all’attuale
150
+• Nessun legame tra x nel corpo di foo e y nel chiamante
151
+• Al ritorno da foo, x viene distrutto (tolto dalla pila)
152
+• Costoso per dati grandi: copia
153
+• Ada: in out (ma solo per dati piccoli; per dati grandi passa riferimento)
154
+
155
+### Valore e riferimento: morale
156
+
157
+Passaggio per valore:
158
+• semantica semplice: il corpo non ha necessità di conoscere come la procedura verrà chiamata (trasparenza referenziale)
159
+• implementazione abbastanza semplice
160
+• potenzialmente costoso il passaggio; efficiente il riferimento al parametro formale
161
+• necessità di altri meccanismi per comunicare main ← proc
162
+• Passaggio per riferimento:
163
+• semantica complessa; aliasing
164
+• implementazione semplice
165
+• efficiente il passaggio; un po’ più costoso il riferimento al parametro formale (un indiretto)
166
+
167
+### Valore, e non riferimento
168
+
169
+I vantaggi del passaggio per valore:
170
+
171
+- in particolare la trasparenza referenziale suggeriscono linguaggi con passaggio solo per valore
172
+ più meccanismi separati per ottenere il passaggio per
173
+ riferimento:
174
+ puntatori in C
175
+ variabili in modello a riferimento (tipi classe) in Jav
176
+
177
+### Passaggio per nome
178
+
179
+Regole di copia:
180
+
181
+- una chiamata alla procedura P e' la stessa cosa che eseguire il corpo di P dopo aver sostituito i parametri attuali al posto dei parametri formali
182
+
183
+La macro espansione viene realizzata in modo semanticamente corretto
184
+In algol-w era il default:
185
+
186
+```algol
187
+
188
+int y;
189
+void foo (name int x) {x= x + 1; }
190
+…
191
+y = 1;
192
+foo(y);
193
+```
194
+
195
+foo esegue `y=y+1`
196
+
197
+Caso piu complicato
198
+![sottoprogrammi_ed_eccezioni_2026-03-10_14-56-59](assets/imgs/sottoprogrammi_ed_eccezioni_2026-03-10_14-56-59.png)
199
+conflitto di variabili!
200
+Le due variabili `y` e `y` rossa sono diverse. fie incrementa l'attuale (y) attraverso il formale x e crea e distrugge la nuova y rossa
201
+
202
+Soluzione:
203
+Viene passata una coppia: `<exp, amb>`
204
+• `exp` è il parametro attuale (testo, non valutato)
205
+• `amb` è l’ambiente di valutazione (in scoping statico)
206
+• Ogni volta che il formale è usato, `exp` è valutata in `amb`
207
+
208
+![sottoprogrammi_ed_eccezioni_2026-03-10_15-02-00](assets/imgs/sottoprogrammi_ed_eccezioni_2026-03-10_15-02-00.png)
209
+
210
+Altro esempio:
211
+
212
+```java
213
+void fie (int x, int y) {
214
+ x = x+1;
215
+ y = 1;}
216
+…
217
+int i = 1;
218
+int[] A = new int[5];
219
+A[1]=4;
220
+fie (i,A[i]);
221
+```
222
+
223
+![sottoprogrammi_ed_eccezioni_2026-03-10_15-10-03](assets/imgs/sottoprogrammi_ed_eccezioni_2026-03-10_15-10-03.png)
224
+Passaggio per nome
225
+il corpo della proc viene riscritto al posto della chiamata e sostituisco le var con quelle in input
226
+
227
+La i e `A[i]` sono valutate nel main (il loro amb)
228
+
229
+quand arrivo al punto A[i] (ovvero y) = 1 visto che prima i e' stato incrementato allora andro' a modificare anche la i di A[i] quindi diventa A[2] = 1
230
+
231
+```
232
+f(nome x)
233
+ y = x
234
+ y = x
235
+ y = x
236
+
237
+z = 1
238
+f(z++)
239
+```
240
+
241
+con passaggio per nome la sostituzione viene fatta ogni volta che viene trovato il param corrispondente
242
+
243
+quindi diventa:
244
+
245
+```
246
+f(nome x)
247
+ y = z++
248
+ y = z++
249
+ y = z++
250
+
251
+z = 1
252
+f(z++)
253
+```
254
+
255
+quindi y diventa 4 (o 3, in base a quando viene fatto z++)
256
+
257
+#### Implementazione passaggio per nome
258
+
259
+Come passare la coppia <exp,env>?
260
+– un puntatore al testo di exp
261
+– un puntatore di catena statica (sullo stack) al record di
262
+attivazione del blocco di chiamata
263
+
264
+cioè una chiusura (perché chiude un’espressione: elimina le sue variabili libere legandole nell’ ambiente del chiamante)
265
+
266
+Le chiusure servono a passare funzioni come argomenti ad altre
267
+procedure
268
+Parametro per nome = funzione nascosta senza argomenti che valuta il parametro nell’ambiente del chiamante (un thunk, nel gergo Algol)
269
+
270
+![sottoprogrammi_ed_eccezioni_2026-03-10_15-23-46](assets/imgs/sottoprogrammi_ed_eccezioni_2026-03-10_15-23-46.png)
271
+
272
+### Funzioni di ordine superiore
273
+
274
+Alcuni linguaggi permettono di:
275
+– passare funzioni come argomenti di procedure
276
+– restituire funzioni come risultato di procedure
277
+• Entrambi i casi: come gestire l’ambiente della funzione ?
278
+• Caso più semplice
279
+– Funzioni come argomento
280
+– Occorre un puntatore al record di attivazione all’interno della pila: passa una chiusura !
281
+• Caso più complicato
282
+– Funzione restituita da una chiamata di procedura
283
+– Occorre mantenere il record di attivazione della funzione
284
+restituita: disciplina a pila non funziona!!
285
+
286
+![sottoprogrammi_ed_eccezioni_2026-03-10_15-31-11](assets/imgs/sottoprogrammi_ed_eccezioni_2026-03-10_15-31-11.png)
287
+
288
+in scope dinamico la x dentro la f puo velere 7 (se pero si valuta lo scope di f quando viene chiamata e non quando viene passata) quindi guardo il suo ambiente quando viene chiamata non passata. Questa regola si chiama regola di shallow binding
289
+Altrimenti (nel caso in cui io valuti l'ambiente della funz quando essa viene passata e non quand o viene chiamata), ovvero alla riga `g(f)` quindi la x vale 5. Questa regola si chiama deep binding