La tipizzazione forte <=> non riguarda solo il continuum su quanto o quanto poco dei valori vengono forzati automaticamente dalla lingua per un tipo di dati a un altro, ma quanto fortemente o debolmente vengono digitati i valori reali . In Python e Java, e principalmente in C #, i valori hanno i loro tipi impostati in pietra. In Perl, non tanto - ci sono davvero solo una manciata di tipi di valore diversi da archiviare in una variabile.
Apriamo i casi uno per uno.
Pitone
Nell'esempio di Python 1 + "1"
, l' +
operatore chiama il __add__
tipo for int
assegnandogli la stringa "1"
come argomento, tuttavia ciò comporta NotImplemented:
>>> (1).__add__('1')
NotImplemented
Quindi, l'interprete prova a __radd__
usare str:
>>> '1'.__radd__(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__radd__'
Se fallisce, l' +
operatore fallisce con il risultato TypeError: unsupported operand type(s) for +: 'int' and 'str'
. In quanto tale, l'eccezione non dice molto sulla tipizzazione forte, ma il fatto che l'operatore +
non costringa i suoi argomenti automaticamente allo stesso tipo, è un puntatore al fatto che Python non è il linguaggio più debolmente tipizzato nel continuum.
D'altra parte, in Python 'a' * 5
è implementato:
>>> 'a' * 5
'aaaaa'
Questo è,
>>> 'a'.__mul__(5)
'aaaaa'
Il fatto che l'operazione sia diversa richiede una tipizzazione forte, tuttavia il contrario di *
forzare i valori in numeri prima di moltiplicarli non renderebbe necessariamente i valori debolmente digitati.
Giava
L'esempio Java String result = "1" + 1;
funziona solo perché, per comodità, l'operatore +
è sovraccarico di stringhe. L' +
operatore Java sostituisce la sequenza con la creazione di un StringBuilder
(vedi questo ):
String result = a + b;
// becomes something like
String result = new StringBuilder().append(a).append(b).toString()
Questo è piuttosto un esempio di tipizzazione molto statica, senza alcuna reale coercizione - StringBuilder
ha un metodo append(Object)
che è specificamente usato qui. La documentazione dice quanto segue:
Aggiunge la rappresentazione in formato stringa Object
dell'argomento.
L'effetto complessivo è esattamente come se l'argomento fosse convertito in una stringa dal metodo String.valueOf(Object)
e i caratteri di quella stringa fossero quindi aggiunti a questa sequenza di caratteri.
Dove String.valueOf
allora
Restituisce la rappresentazione in formato stringa dell'argomento Object. [Restituisce] se l'argomento è null
, quindi una stringa uguale a "null"
; in caso contrario, obj.toString()
viene restituito il valore di .
Quindi questo è un caso di assoluta coercizione da parte del linguaggio, delegando ogni preoccupazione agli oggetti stessi.
C #
Secondo la risposta di Jon Skeet qui , l'operatore +
non è nemmeno sovraccarico per la string
classe - simile a Java, questa è solo la comodità generata dal compilatore, grazie sia alla tipizzazione statica che a quella forte.
Perl
Come spiega la perldata ,
Perl ha tre tipi di dati integrati: scalari, array di scalari e array associativi di scalari, noti come "hash". Uno scalare è una singola stringa (di qualsiasi dimensione, limitata solo dalla memoria disponibile), un numero o un riferimento a qualcosa (che verrà discusso in perlref). Le matrici normali sono elenchi ordinati di scalari indicizzati per numero, che iniziano con 0. Gli hash sono raccolte non ordinate di valori scalari indicizzati dalla chiave di stringa associata.
Perl tuttavia non ha un tipo di dati separato per numeri, valori booleani, stringhe, valori null, undefined
s, riferimenti ad altri oggetti ecc. - ha solo un tipo per tutti questi, il tipo scalare; 0 è un valore scalare tanto quanto "0". Una variabile scalare impostata come stringa può davvero trasformarsi in un numero e da lì in poi si comporta diversamente da "solo una stringa", se si accede in un contesto numerico. Lo scalare può contenere qualsiasi cosa in Perl, è tanto l'oggetto quanto esiste nel sistema. mentre in Python i nomi si riferiscono solo agli oggetti, in Perl i valori scalari nei nomi sono oggetti modificabili. Inoltre, il sistema del tipo orientato agli oggetti è incollato sopra a questo: ci sono solo 3 tipi di dati in perl - scalari, elenchi e hash. Un oggetto definito dall'utente in Perl è un riferimento (che è un puntatore a uno dei 3 precedenti) bless
ed a un pacchetto - puoi prendere qualsiasi valore e benedirlo a qualsiasi classe in qualsiasi momento tu voglia.
Perl ti consente anche di modificare le classi di valori per capriccio - questo non è possibile in Python dove per creare un valore di una classe è necessario costruire esplicitamente il valore appartenente a quella classe con object.__new__
o simili. In Python non puoi davvero cambiare l'essenza dell'oggetto dopo la creazione, in Perl puoi fare qualsiasi cosa:
package Foo;
package Bar;
my $val = 42;
# $val is now a scalar value set from double
bless \$val, Foo;
# all references to $val now belong to class Foo
my $obj = \$val;
# now $obj refers to the SV stored in $val
# thus this prints: Foo=SCALAR(0x1c7d8c8)
print \$val, "\n";
# all references to $val now belong to class Bar
bless \$val, Bar;
# thus this prints Bar=SCALAR(0x1c7d8c8)
print \$val, "\n";
# we change the value stored in $val from number to a string
$val = 'abc';
# yet still the SV is blessed: Bar=SCALAR(0x1c7d8c8)
print \$val, "\n";
# and on the course, the $obj now refers to a "Bar" even though
# at the time of copying it did refer to a "Foo".
print $obj, "\n";
quindi l'identità del tipo è debolmente legata alla variabile e può essere cambiata attraverso qualsiasi riferimento al volo. In effetti, se lo fai
my $another = $val;
\$another
non ha l'identità di classe, anche se \$val
fornirà comunque il riferimento benedetto.
TL; DR
Ci sono molte più cose sulla tipizzazione debole in Perl che non solo le coercizioni automatiche, ed è più che i tipi dei valori stessi non sono messi in pietra, a differenza del Python che è un linguaggio tipizzato in modo dinamico ma molto fortemente tipizzato. Che Python dà TypeError
su 1 + "1"
è un'indicazione che la lingua è fortemente tipizzato, anche se il contrario di fare qualcosa di utile, come in Java o C # non preclude loro di essere fortemente tipizzati lingue.