@@ -58,13 +58,13 @@ il programmatore Scala li dichiara in oggetti singleton.
58
58
59
59
### Compiliamo l'esempio
60
60
61
- Per compilare l'esempio, useremo ` scalac ` , cioè il compilatore Scala.
61
+ Per compilare l'esempio useremo ` scalac ` , il compilatore Scala.
62
62
` scalac ` lavora come la maggior parte dei compilatori: prende un file
63
63
sorgente come argomento, eventuali opzioni e produce uno o più object
64
64
file come output. Gli object file sono gli standard file delle classi
65
65
di Java.
66
66
67
- Se salviamo il file precedente come ` HelloWorld.scala ` , lo compiliamo
67
+ Se salviamo il file precedente come ` HelloWorld.scala ` e lo compiliamo
68
68
con il seguente comando (il segno maggiore `>' rappresenta il prompt
69
69
dei comandi e non va digitato):
70
70
@@ -77,27 +77,27 @@ sezione.
77
77
78
78
### Eseguimo l'esempio
79
79
80
- Una volta compilato il programma pu \` o esser facilmente eseguito con il
80
+ Una volta compilato il programma può esser facilmente eseguito con il
81
81
comando scala. L'uso è molto simile al comando java ed accetta le stesse
82
82
opzioni. Il precedente esempio può esser eseguito usando il seguente
83
- comando che produce l 'output atteso:
83
+ comando. L 'output prodotto è quello atteso:
84
84
85
85
> scala -classpath . HelloWorld
86
86
87
87
Hello, world!
88
88
89
89
## Interazione con Java
90
90
91
- Uno dei punti di forza di è quello di rendere semplice l’interazione con
92
- codice Java. Tutte le classi del package ` java.lang ` vengono importate di
93
- default, le altre richiedono l’esplicito import.
91
+ Uno dei punti di forza di Scala è quello di rendere semplice l’interazione con
92
+ codice Java. Tutte le classi del package ` java.lang ` sono importate di
93
+ default mentre le altre richiedono l’esplicito import.
94
94
95
95
Osserviamo un esempio che lo dimostra. Vogliamo ottenere la data
96
96
corrente e formattarla in accordo con la convezione usata in uno
97
97
specifico paese del mondo, diciamo la Francia. (Altre regioni, come la parte
98
- di lingua francese della Svizzera utilizzano le stesse convenzioni.)
98
+ di lingua francese della Svizzera, utilizzano le stesse convenzioni.)
99
99
100
- Le librerie delle classi Java definiscoono potenti classi di utilità, come
100
+ Le librerie delle classi Java definiscono potenti classi di utilità come
101
101
` Date ` e ` DateFormat ` . Poiché Scala interagisce direttamente con Java, non
102
102
esistono le classi equivalenti nella libreria delle classi di Scala--possiamo
103
103
semplicemente importare le classi dei corrispondenti package Java:
@@ -114,16 +114,16 @@ semplicemente importare le classi dei corrispondenti package Java:
114
114
}
115
115
}
116
116
117
- L’istruzione import di Scala è molto simile all’equivalente in Java,
117
+ L’istruzione import di Scala è molto simile all’equivalente in Java
118
118
tuttavia, risulta essere più potente. Più classi possono essere importate
119
- dallo stesso package includendole in parentesi graffe come nella prima linea
119
+ dallo stesso package includendole in parentesi graffe come nella prima riga
120
120
di codice precedentemente riportato. Un’altra differenza è evidente
121
121
nell’uso del carattere underscore (` _ ` ) al posto dell’asterisco (` * ` ) per
122
122
importare tutti i nomi di un package o di una classe. Questo perché
123
123
l’asterisco è un identificatore valido (e.g. nome di un metodo), come
124
124
vedremo più avanti.
125
125
126
- Inoltre, l’istruzione import sulla terza linea importa tutti i membri
126
+ Inoltre, l’istruzione import sulla terza riga importa tutti i membri
127
127
della classe ` DateFormat ` . Questo rende disponibili il metodo statico
128
128
` getDateInstance ` ed il campo statico ` LONG ` .
129
129
@@ -145,7 +145,7 @@ Apparentemente sembra un piccolo dettaglio sintattico ma, presenta delle
145
145
importanti conseguenze. Una di queste sarà esplorata nella prossima
146
146
sezione.
147
147
148
- A questo punto, riguardo l’integrazione con Java abbiamo notato che è
148
+ A questo punto, riguardo l’integrazione con Java, abbiamo notato che è
149
149
altresì possibile ereditare dalle classi Java ed implementare le interfacce
150
150
direttamente in Scala.
151
151
@@ -155,7 +155,7 @@ direttamente in Scala.
155
155
Scala è un linguaggio orientato agli oggetti (_ object-oriented_ ) puro nel
156
156
senso che * ogni cosa* è un oggetto, inclusi i numeri e le funzioni. In questo
157
157
differisce da Java che invece distingue tra tipi primitivi (come ` boolean `
158
- e ` int ` ) e tipi referenziati. I\noltre , Java non permette la manipolazione
158
+ e ` int ` ) e tipi referenziati. Inoltre , Java non permette la manipolazione
159
159
di funzioni come fossero valori.
160
160
161
161
### I numeri sono oggetti
@@ -200,9 +200,9 @@ cardini di un interessante paradigma di programmazione chiamato
200
200
Come esempio semplice del perché può risultare utile usare le funzioni
201
201
come valori consideriamo una funzione timer che deve eseguire delle
202
202
azione ogni secondo. Come specifichiamo l’azione da eseguire?
203
- Logicamente, come una funzione. Questo tipo di passaggio di funzione è
203
+ Logicamente come una funzione. Questo tipo di passaggio di funzione è
204
204
familiare a molti programmatori: viene spesso usato nel codice delle
205
- interfacce utente, per registrare le funzioni di call-back richiamate
205
+ interfacce utente per registrare le funzioni di call-back richiamate
206
206
quando un evento si verifica.
207
207
208
208
Nel successivo programma la funzione timer è chiamata ` oncePerSecond ` e
@@ -226,7 +226,7 @@ frase “time flies like an arrow” ogni secondo.
226
226
}
227
227
}
228
228
229
- Notare che per stampare la stringa, usiamo il metodo ` println ` predefinito
229
+ Notare che per stampare la stringa usiamo il metodo ` println ` predefinito
230
230
invece di quelli inclusi in ` System.out ` .
231
231
232
232
#### Funzioni anonime
@@ -253,7 +253,7 @@ invece di *timeFlies* e appare come di seguito:
253
253
254
254
La presenza delle funzioni anonime in questo esempio è rivelata dal
255
255
simbolo ` => ` che separa la lista degli argomenti della funzione dal
256
- suo corpo. In questo esempio la lista degli argomenti è vuota e di fatti,
256
+ suo corpo. In questo esempio la lista degli argomenti è vuota e di fatti
257
257
la coppia di parentesi sulla sinistra della freccia è vuota. Il corpo della
258
258
funzione ` timeFlies ` è lo stesso del precedente.
259
259
@@ -262,7 +262,7 @@ funzione `timeFlies` è lo stesso del precedente.
262
262
Come visto precedentemente Scala è un linguaggio orientato agli oggetti e
263
263
come tale presenta il concetto di classe. (Per ragioni di completezza
264
264
va notato che alcuni linguaggi orientati agli oggetti non hanno il concetto
265
- di classe ma, Scala non è uno di questi.) Le classi in Scala sono dichiarate
265
+ di classe; Scala non è uno di questi.) Le classi in Scala sono dichiarate
266
266
usando una sintassi molto simile a quella usata in Java. Un'importante
267
267
differenza è che le classi in Scala possono avere dei parametri. Questo
268
268
concetto è mostrato nella seguente definizione dei numeri complessi.
@@ -285,20 +285,19 @@ del segno uguale dei metodi e deducendo che per entrambi si tratta di
285
285
valori di tipo ` Double ` .
286
286
287
287
Il compilatore non è sempre capace di dedurre i tipi come nel caso precedente;
288
- purtroppo non c’è una regola semplice capace di dirci quando sarà in grado e
289
- quando no. Nella pratica questo non è un problema poiché il compilatore sa quando
290
- non è in grado di stabilire il tipo che non è stato definito
288
+ purtroppo non c’è una regola semplice capace di dirci quando sarà in grado di
289
+ farlo e quando no. Nella pratica questo non è un problema poiché il compilatore
290
+ sa quando non è in grado di stabilire il tipo che non è stato definito
291
291
esplicitamente. Come semplice regola i programmatori Scala alle prime armi
292
292
dovrebbero provare ad omettere la dichiarazione di tipi che sembrano semplici
293
- da dedurre per osservare il comportamento del compilatore. Dopo qualche tempo il
294
- programmatore avrà la sensazione di quando è possibile omettere il tipo
295
- e quando no.
293
+ da dedurre per osservare il comportamento del compilatore. Dopo qualche tempo si
294
+ avrà la sensazione di quando è possibile omettere il tipo e quando no.
296
295
297
296
### Metodi senza argomenti
298
297
299
298
Un piccolo problema dei metodi ` re ` e ` im ` è che, per essere invocati, è
300
299
necessario far seguire il nome del metodo da una coppia di parentesi tonde
301
- vuote, come mostrato di seguito :
300
+ vuote, come mostrato nel codice seguente :
302
301
303
302
object ComplexNumbers {
304
303
def main(args: Array[String]) {
@@ -329,8 +328,8 @@ la classe `scala.AnyRef` è implicitamente usata.
329
328
330
329
In Scala è possibile eseguire la sovrascrittura (_ override_ ) dei metodi
331
330
ereditati dalla super-classe. È pertanto necessario specificare esplicitamente
332
- il metodo che si sta sovrascrivendo usando il modificatore ` override ` , al fine
333
- di evitare sovrascritture accidentali. Come esempio estendiamo la nostra classe
331
+ il metodo che si sta sovrascrivendo usando il modificatore ` override ` per
332
+ evitare sovrascritture accidentali. Come esempio estendiamo la nostra classe
334
333
` Complex ` ridefinendo il metodo ` toString ` ereditato da ` Object ` .
335
334
336
335
class Complex(real: Double, imaginary: Double) {
@@ -341,7 +340,7 @@ di evitare sovrascritture accidentali. Come esempio estendiamo la nostra classe
341
340
}
342
341
343
342
344
- ## Case Classes e Pattern Matching
343
+ ## Classi Case e Pattern Matching
345
344
346
345
Un tipo di struttura dati che spesso si trova nei programmi è l’albero.
347
346
Ad esempio, gli interpreti ed i compilatori abitualmente rappresentano i
@@ -356,23 +355,24 @@ costanti intere e variabili intere. Due esempi di tali espressioni sono
356
355
` 1+2 ` e ` (x+x)+(7+y) ` .
357
356
358
357
A questo punto è necessario definire il tipo di rappresentazione per
359
- dette espressioni e, a tale proposito, l’albero è la più naturale, dove
360
- i nodi sono le operazioni (nel nostro caso, l’addizione) e le foglie
361
- sono i valori (costanti o variabili).
358
+ dette espressioni e, a tale proposito, l’albero è la più naturale, con
359
+ i nodi che rappresentano le operazioni (nel nostro caso, l’addizione) mentre
360
+ le foglie sono i valori (costanti o variabili).
362
361
363
- In questo albero è abitualmente rappresentato usando una super-classe
362
+ In Scala questo albero è abitualmente rappresentato usando una super-classe
364
363
astratta per gli alberi e una concreta sotto-classe per i nodi o le
365
364
foglie. In un linguaggio funzionale useremmo un tipo dati algebrico per
366
- lo stesso scopo. Scala fornisce il concetto di _ case classes_ che è qualcosa
367
- che si trova nel mezzo delle due rappresentazioni. Mostriamo come può essere
368
- usato per definire il tipo di alberi per il nostro esempio:
365
+ lo stesso scopo. Scala fornisce il concetto di _ classi case_ (_ case classes_ )
366
+ che è qualcosa che si trova nel mezzo delle due rappresentazioni.
367
+ Mostriamo come può essere usato per definire il tipo di alberi per il nostro
368
+ esempio:
369
369
370
370
abstract class Tree
371
371
case class Sum(l: Tree, r: Tree) extends Tree
372
372
case class Var(n: String) extends Tree
373
373
case class Const(v: Int) extends Tree
374
374
375
- Il fatto che le classi ` Sum ` , ` Var ` e ` Const ` sono dichiarate come case classes
375
+ Il fatto che le classi ` Sum ` , ` Var ` e ` Const ` sono dichiarate come classi case
376
376
significa che rispetto alle classi standard differiscono in diversi aspetti:
377
377
378
378
- la parola chiave ` new ` non è necessaria per creare un’istanza di queste
@@ -398,7 +398,7 @@ qualche *ambiente* (_environment_) di valutazione. Lo scopo dell’environment
398
398
` x+1 ` valutata nell’environment con associato il valore ` 5 ` alla
399
399
variabile ` x ` , scritto ` { x -> 5 } ` , restituisce ` 6 ` come risultato.
400
400
401
- Inoltre dobbiamo trovare un modo per rappresentare gli environment.
401
+ Inoltre, dobbiamo trovare un modo per rappresentare gli environment.
402
402
Potremmo naturalmente usare alcune strutture dati associative come una
403
403
hash table ma, possiamo anche usare direttamente delle funzioni! Un
404
404
environment in realtà non è altro che una funzione con associato un
@@ -413,7 +413,7 @@ altri casi.
413
413
414
414
Prima di scrivere la funzione di valutazione diamo un nome al tipo di
415
415
environment. Potremmo usare sempre il tipo ` String => Int ` per gli environment
416
- ma, semplifichiamo il programma se introduciamo un nome per questo tipo
416
+ ma semplifichiamo il programma se introduciamo un nome per questo tipo
417
417
rendendo anche i cambiamenti futuri più facili. Questo è fatto in con la
418
418
seguente notazione:
419
419
@@ -464,18 +464,18 @@ e nominare varie parti del valore per valutare il codice che ne fa uso.
464
464
465
465
Un programmatore object-oriented esperto potrebbe sorprendersi del fatto
466
466
che non abbiamo definito ` eval ` come * metodo* della classe e delle sue
467
- sottoclassi. Potremmo averlo fatto, perchè Scala permette la definizione di
467
+ sottoclassi. Potremmo averlo fatto perchè Scala permette la definizione di
468
468
metodi nelle case classes così come nelle classi normali. Decidere quando
469
469
usare il pattern matching o i metodi è quindi una questione di gusti ma,
470
470
ha anche implicazioni importanti riguardo l’estensibilità:
471
471
472
472
- quando si usano i metodi è facile aggiungere un nuovo tipo di nodo
473
473
definendo una sotto classe di ` Tree ` per esso; d’altro canto, aggiungere
474
- una nuova operazione per manipolare l’albero è noioso, richiede la
474
+ una nuova operazione per manipolare l’albero è noioso e richiede la
475
475
modifica di tutte le sotto classi ` Tree ` ;
476
476
- quando si usa il pattern matching la situazione è ribaltata:
477
477
aggiungere un nuovo tipo di nodo richiede la modifica di tutte le
478
- funzioni in cui si fa pattern matching sull’albero, per prendere in
478
+ funzioni in cui si fa pattern matching sull’albero per prendere in
479
479
esame il nuovo nodo; d’altro canto, aggiungere una nuova operazione
480
480
è semplice, basta definirla come una funzione indipendente.
481
481
@@ -489,8 +489,8 @@ operazione:
489
489
derivazione, zero altrimenti,
490
490
3 . la derivata di una costante è zero.
491
491
492
- Queste regole possono essere tradotte quasi letteralmente in codice Scala,
493
- per ottenere la seguente definizione:
492
+ Queste regole possono essere tradotte quasi letteralmente in codice Scala e
493
+ ottenere la seguente definizione:
494
494
495
495
def derive(t: Tree, v: String): Tree = t match {
496
496
case Sum(l, r) => Sum(derive(l, v), derive(r, v))
@@ -504,17 +504,17 @@ matching. Prima di tutto l’istruzione `case` per le variabili ha un
504
504
controllo fa si che il pattern matching è eseguito solo se l’espressione
505
505
è vera. Qui viene usato per esser sicuri che restituiamo la costante ` 1 `
506
506
solo se il nome della variabile da derivare è lo stesso della variabile
507
- di derivazione ` v ` . La seconda nuova feature del pattern matching qui
507
+ di derivazione ` v ` . La seconda nuova caratteristica del pattern matching qui
508
508
introdotta è la * wild-card* , scritta ` _ ` , che corrisponde a qualunque
509
509
valore, senza assegnargli un nome.
510
510
511
- Non abbiamo esplorato del tutto la potenza del pattern matching ma, ci
511
+ Non abbiamo esplorato del tutto la potenza del pattern matching ma ci
512
512
fermiamo qui per brevità. Vogliamo ancora osservare come le due
513
- precedenti funzioni lavorano in un esempio reale. A tale scopo,
513
+ precedenti funzioni lavorano in un esempio reale. A tale scopo
514
514
scriviamo una semplice funzione ` main ` che esegue diverse operazioni
515
515
sull’espressione ` (x+x)+(7+y) ` : prima calcola il suo valore
516
516
nell’environment ` { x -> 5, y -> 7 } ` , dopo calcola la
517
- derivata relativa a ` x ` e poi ad ` y ` .
517
+ derivata relativa ad ` x ` e poi ad ` y ` .
518
518
519
519
def main(args: Array[String]) {
520
520
val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y")))
@@ -525,7 +525,7 @@ derivata relativa a `x` e poi ad `y`.
525
525
println("Derivative relative to y:\n " + derive(exp, "y"))
526
526
}
527
527
528
- Eseguendo questo programma, otteniamo l’output atteso:
528
+ Eseguendo questo programma otteniamo l’output atteso:
529
529
530
530
Expression: Sum(Sum(Var(x),Var(x)),Sum(Const(7),Var(y)))
531
531
Evaluation with x=5, y=7: 24
@@ -534,7 +534,7 @@ Eseguendo questo programma, otteniamo l’output atteso:
534
534
Derivative relative to y:
535
535
Sum(Sum(Const(0),Const(0)),Sum(Const(0),Const(1)))
536
536
537
- Esaminando l’output, notiamo che il risultato della derivata dovrebbe
537
+ Esaminando l’output notiamo che il risultato della derivata dovrebbe
538
538
essere semplificato prima di essere visualizzato all’utente. La
539
539
definizione di una funzione di semplificazione usando il pattern
540
540
matching rappresenta un interessante (ma sorprendentemente
@@ -586,7 +586,7 @@ tipo `Object` in Java dato che è altresì il super-tipo dei tipi base come
586
586
587
587
Per rendere confrontabili gli oggetti di una classe è quindi sufficiente
588
588
definire i predicati con cui testare uguaglianza ed minoranza e unire la
589
- precedente classe ` Ord ` . Come esempio, definiamo una classe ` Date ` che
589
+ precedente classe ` Ord ` . Come esempio definiamo una classe ` Date ` che
590
590
rappresenta le date nel calendario Gregoriano. Tali date sono composte dal
591
591
giorno, dal mese e dall’anno che rappresenteremo tutti con interi. Iniziamo
592
592
definendo la classe ` Date ` come segue:
@@ -613,7 +613,7 @@ Arriviamo alla seguente definizione:
613
613
o.day == day && o.month == month && o.year == year
614
614
}
615
615
616
- Questo metofo fa uso di due metodi predefiniti ` isInstanceOf ` e ` asInstanceOf ` .
616
+ Questo metodo fa uso di due metodi predefiniti ` isInstanceOf ` e ` asInstanceOf ` .
617
617
Il primo, ` isInstanceOf ` , corrisponde all’operatore ` instanceOf ` di Java e
618
618
restituisce true se e solo se l’oggetto su cui è applicato è una istanza del
619
619
tipo dati. Il secondo, ` asInstanceOf ` , corrisponde all’operatore di cast in
@@ -652,7 +652,7 @@ informati dei problemi relativi alla mancanza della programmazione
652
652
generica nel loro linguaggio, un’imperfezione risolta in Java 1.5.
653
653
654
654
La programmazione generica riguarda la capacità di scrivere codice
655
- parametrizzato dai tipi. Per esempio, un programmatore che scrive una
655
+ parametrizzato dai tipi. Per esempio un programmatore che scrive una
656
656
libreria per le liste concatenate può incontrare il problema di decidere
657
657
quale tipo dare agli elementi della lista. Dato che questa lista è stata
658
658
concepita per essere usata in contesti differenti, non è possibile
@@ -662,7 +662,7 @@ restrittivo.
662
662
663
663
I programmatori Java hanno fatto ricorso all’uso di ` Object ` , che è il
664
664
super-tipo di tutti gli oggetti. Questa soluzione è in ogni caso ben lontana
665
- dall’esser ideale, poiché non funziona per i tipi base (` int ` , ` long ` , ` float ` ,
665
+ dall’esser ideale perché non funziona per i tipi base (` int ` , ` long ` , ` float ` ,
666
666
ecc.) ed implica che molto type casts dinamico deve esser fatto dal
667
667
programmatore.
668
668
@@ -690,8 +690,8 @@ tipi numerici, `false` per il tipo `Boolean`, `())`per il tipo `Unit`
690
690
e ` null ` per tutti i tipi oggetto.
691
691
692
692
Per usare la classe ` Reference ` è necessario specificare quale tipo usare per
693
- il tipo parametro ` T ` , il tipo di elemento contenuto dalla cella. Adr esempio,
694
- per creare ed usare una cella che contiene un intero, si potrebbe scrivere il
693
+ il tipo parametro ` T ` , il tipo di elemento contenuto dalla cella. Ad esempio,
694
+ per creare ed usare una cella che contiene un intero si potrebbe scrivere il
695
695
seguente codice:
696
696
697
697
object IntegerReference {
@@ -712,5 +712,5 @@ poiché è stata dichiarata per memorizzare un intero.
712
712
Questo documento ha fornito una veloce introduzione del linguaggio Scala e
713
713
presentato alcuni esempi di base. Il lettore interessato può continuare, per
714
714
esempio, leggendo il documento * Scala By Example* che contiene esempi molti più
715
- avanzati e, consultare al bisogno la documentazione
715
+ avanzati e consultare al bisogno la documentazione
716
716
* Scala Language Specification* .
0 commit comments