Le lingue digitate dinamicamente, come Ruby e JavaScript, eseguono qualsiasi tipo di controllo dinamico?

1

Se guardiamo alla definizione di "linguaggi di programmazione dinamicamente tipizzati" in Wikipedia, si dice:

Programming languages which include dynamic type-checking but not static type-checking are often called "dynamically-typed programming languages".

e

Dynamic type-checking is the process of verifying the type safety of a program at runtime. Implementations of dynamically type-checked languages generally associate each runtime object with a "type tag" (i.e., a reference to a type) containing its type information. This runtime type information (RTTI) can also be used to implement dynamic dispatch, late binding, downcasting, reflection, and similar features.

Ma il fatto è che, quando si usano Ruby e JavaScript, non vedo mai il tipo "controllato".

In un video che ho visto prima, l'autore diceva che static typed significa solo che il tipo di una variabile è definito / dichiarato e compilato, e non può cambiare, mentre il dynamic typed significa che il tipo di una variabile può cambiare in qualsiasi momento quando il programma è in esecuzione, e La vedo descrivere staticamente / dinamicamente digitato abbastanza chiaramente e semplicemente.

In realtà, secondo GoF, un tipo è semplicemente un insieme di interfacce, quindi come si può "controllare" il tipo, a parte se risponde a un particolare messaggio? Cioè, quando si usano le lingue digitate dinamicamente, in realtà non lo vedo "controllato" come in "Controllo dinamico dei tipi". O quando viene effettuato il controllo?

    
posta 太極者無極而生 10.01.2016 - 01:17
fonte

3 risposte

10

Javascript:

>>> 1()
TypeError: 1 is not a function

Rubino:

>>> 1 + ""
String can't be coerced into Fixnum

Questi sono entrambi casi semplici di errore di tipo dinamico. Molte lingue, tra cui quasi tutte le lingue dinamiche, ma anche, ad es., C # e Java, eseguono il "tipo tagging". Cioè, i runtime di questi ambienti devono, in effetti, collegare una rappresentazione di un tipo a ogni oggetto. Questo è diverso rispetto alla tipizzazione statica perché i tag di tipo esistono in fase di esecuzione e in almeno i linguaggi dinamici e imperativi come Ruby e Javascript una variabile può puntare a oggetti diversi con tipi diversi.

Il runtime deve, per implementare la semantica della lingua, controllare continuamente questi tag tipo. Ad esempio, nell'esecuzione dell'operazione + su due oggetti, questi linguaggi controllano i tag di tipo su entrambi gli oggetti per decidere cosa fare. Se entrambi gli oggetti sono contrassegnati come numerici, viene eseguita l'aggiunta (eventualmente dopo una conversione di tipo a un tipo numerico comune). Se entrambi gli oggetti sono contrassegnati come tag di tipo stringa, viene eseguita la concatenazione delle stringhe. (Quello che potrebbe esserti fatto braccetto è che Javascript eseguirà grandi quantità di conversioni di tipo runtime durante il normale funzionamento: sembra che non stia controllando i tag di tipo, perché non vengono generati errori di tipo, quando in realtà i tag di tipo sono essere controllato dappertutto per eseguire queste conversioni.)

Si noti che questo controllo del tag di tipo ha solo una vaga e per lo più fuorviante somiglianza con il controllo di tipo (statico). Il controllo statico del tipo controlla le proprietà dell'espressione prima del runtime mentre il controllo del tag di tipo controlla le proprietà del valore che l'espressione esprime in fase di esecuzione. Sia Ruby che Javascript eseguono il controllo del tag di tipo nel loro ambiente runtime di base (ad es. In + , - , invocazione funzione). Consentono inoltre all'utente di utilizzare la type-tag introspection . Cioè, consentono all'utente di verificare la tag di tipo di un valore in fase di runtime.

Actually, according to GoF, a type is simply a set of interface, so how can you "check" the type, other than whether it responds to a particular message?

Non ho familiarità con questa definizione, ma mi sembra fuorviante. Un tipo statico è un token che viene associato in base a una serie di regole di digitazione con espressioni in una lingua e viene utilizzato per definire quali espressioni sono semanticamente valide in quella lingua. Un "tipo dinamico" (o tag di tipo, come preferisco) è un valore che viene associato a oggetti nel runtime di una lingua. In un certo senso, entrambi sono legati alle interfacce. Nei linguaggi tipizzati staticamente, il tipo definisce quali espressioni può essere legalmente visualizzata un'espressione di quel tipo e quindi in tale misura determina un'interfaccia per quel tipo. Analogamente, i tag di tipo determinano, in parte, quali operazioni termineranno in un runtime "TypeError" prima ancora che l'operazione venga tentata.

Tuttavia, è fuorviante identificare il tipo / tag di tipo con la sua interfaccia nella maggior parte delle lingue dinamiche statiche. Essenzialmente tutti i linguaggi statici e dinamici sono in gran parte nomatamente e non strutturalmente tipizzati. Cioè, in un normale linguaggio tipizzato staticamente, se definisci un tipo YourCustomer e definisco MyCustomer , le espressioni dei due tipi non saranno intercambiabili. anche se le definizioni di YourCustomer e MyCustomer sono identiche fino alla denominazione. Allo stesso modo, se si definisce un oggetto Javascript con type-tag YourJSCustomer e io definisco un oggetto Javascript con type-tag MyJSCustomer , anche se questi due oggetti hanno le stesse proprietà e metodi altrimenti non saranno intercambiabili in faccia di introspezione con tag di tipo.

È vero che in molte lingue digitate dinamicamente, l'introspezione del tag di tipo non è sempre utilizzata e quindi YourJSCustomer e MyJSCustomer saranno intercambiabili in molti ambienti. Questo perché queste lingue consentono di sostituire o integrare il controllo del tag di tipo con il controllo degli attributi. Quindi, se chiami x.foo() in JS, Ruby, Python, & c., Cercherà l'attributo .foo sull'oggetto x . Ciò consente l'eliminazione di alcuni, ma in genere non tutti, il controllo del tag di tipo.

Si noti che nelle lingue tipizzate staticamente con la tipizzazione strutturale , è possibile avere YourCustomer e MyCustomer intercambiabili nella maggior parte / tutti i contesti. Questo dà una sensazione linguistica molto più vicina a un linguaggio come Javascript o Ruby. Ti suggerisco di guardare TypeScript per questo, che aggiunge un sistema di tipi a Javascript.

    
risposta data 10.01.2016 - 02:46
fonte
3

Quando descriviamo una lingua come tipo controllata, intendiamo che la lingua non ti consente di eseguire operazioni non valide per il tipo. Né le lingue tipizzate staticamente né dinamicamente ti consentono di moltiplicare insieme le stringhe, chiamare un numero al posto di una funzione, ecc. Una lingua senza controllo di tipo ti consente di fare tutte queste cose senza lamentarti.

Se lo fai controllando tutti i tipi in fase di compilazione, controllando i tipi in fase di esecuzione o vedendo se un oggetto risponde a un messaggio è un dettaglio di implementazione di ogni lingua. Tutte queste tecniche rientrano nella categoria di controllo dei tipi.

    
risposta data 10.01.2016 - 02:26
fonte
0

Secondo Eric Lippert un tipo è

... an abstract quantity that we can manipulate using rules. Like "if T is a type then T[] is also a type", and so on.

L'implementazione di come un compilatore o runtime del linguaggio implementa i Tipi è un'altra cosa. In un linguaggio compilato, come C o C # o Java, questo controllo avviene in fase di compilazione, e in Java e C # questi controlli avvengono anche in fase di esecuzione. Tuttavia, in javascript e Ruby, questi controlli avvengono (a mia conoscenza) esclusivamente in fase di esecuzione poiché non è richiesta alcuna compilazione.

so how can you "check" the type, other than whether it responds to a particular message?

I linguaggi dinamici trattano i tipi su ogni singola espressione che valuta poiché il runtime deve conoscere i tipi di oggetti che sta interpretando per sapere cosa fare a tutti!

Nelle altre buone risposte, vengono forniti alcuni esempi di espressioni mal formate, ma esistono anche altri esempi. Pensa a la differenza tra == e === in javascript per esempio.

console.log('5' == 5)  // true
console.log('5' === 5) // false

Il runtime javascript richiede di controllare il tipo di oggetti in fase di runtime al fine di rispettare le sue specifiche.

    
risposta data 10.01.2016 - 04:38
fonte

Leggi altre domande sui tag