In che modo un sistema di tipo statico influisce sulla progettazione di un linguaggio basato su prototipo?


15

L' articolo di Wikipedia sui linguaggi basati su prototipi contiene il seguente paragrafo:

Quasi tutti i sistemi basati su prototipi si basano su linguaggi interpretati e tipizzati in modo dinamico. Tuttavia, i sistemi basati su linguaggi tipicamente statici sono tecnicamente fattibili.

In che modo un sistema di tipo statico impone restrizioni o introduce complessità nel linguaggio basato sui prototipi e perché esistono linguaggi prototipo più tipicamente dinamici?


2
+1 e preferito: ci sto riflettendo da un po 'di tempo, e non ho riscontrato problemi straordinariamente difficili con un sistema di tipo strutturale . In effetti, questo mi disturba così tanto che voglio andare avanti e provare a creare un linguaggio basato su prototipo tipicamente statico solo per vedere quali problemi ci sono ...

Sto iniziando questo processo da solo per lo stesso motivo :)
Joe,

Risposte:


6

Il confine tra un tipo fondamentale e un oggetto è sfocato e spesso introdotto artificialmente. Ad esempio, in C una struct è solo un mucchio di record, solo un tipo non oggetto derivato. In C ++, una struct è una classe con tutti i campi pubblici, un oggetto. Tuttavia, C ++ è quasi totalmente compatibile all'indietro con C ... qui il bordo è davvero morbido.

Per la programmazione basata su prototipi è necessario disporre di oggetti mutabili in fase di esecuzione. DEVONO essere di tipo soft perché ogni volta che cambia in fase di esecuzione, una classe di un tipo cambia in un'altra - il suo tipo cambia.

Tuttavia, è possibile mantenere i tipi di oggetti non fondamentali e derivati ​​come statici. Ma ciò introduce una strana disparità, gli oggetti sono di tipo soft, i non oggetti sono di tipo statico e tra i due deve essere stabilito un hard barier. Dovresti essere in grado di trasformare una struttura? Una stringa? Numero dovrebbe essere una classe o un tipo fondamentale, o un insieme di tipi fondamentali, int / float / bignum / etc?

È solo più naturale e facile da imparare, usare e scrivere per avere questa uniforme, tutti i tipi sono mutabili o nessun tipo è mutabile in fase di esecuzione. Se dichiari che un solo tipo (Oggetto) è mutabile, finisci con il mal di testa e i problemi di entrambi i mondi.

Il tipo statico è:

  • più facile da implementare
  • più veloce / più efficiente
  • più sicuro
  • più facile da mantenere / documentare grandi sistemi a causa dell'astrazione.

Il tipo dinamico è:

  • più veloce per scrivere,
  • più conciso
  • lingua più facile da imparare
  • più indulgente per errori di progettazione.

Mescolando i due, sacrifichi molto.

  • L'implementazione diventa più difficile di qualsiasi delle due precedenti.
  • la velocità dipende se usi i tipi soft o no ... Se lo fai, è basso, se non lo fai, perché scegliere la lingua?
  • type safety è fuori dalla finestra per tutti i tipi di oggetti.
  • seguire come un tipo si trasforma in un altro è un compito piuttosto difficile. Documentarlo - molto difficile.
  • Hai ancora bisogno di fare tutta la contabilità con tipi fondamentali, che uccide la concisione e la velocità di scrittura
  • La complessità della lingua è più elevata (più difficile da imparare) rispetto a quella "specifica",
  • il "perdono" di un carattere dinamico viene sostituito dalla tendenza ad alcuni errori molto delicati nei tipi di attributo non corrispondenti.

1
Mente di fornire un esempio del motivo per cui gli oggetti devono essere "mutabili" (suppongo che tu voglia dire addizione e rimozione di attributi, non cambiarli, dato che di solito non è correlato alla digitazione).

@delnan: non proprio, nella programmazione basata su prototipi puoi scavare nelle viscere di un oggetto come ritieni opportuno, rimuovere, aggiungere, sostituire, coprire, sia metodi che attributi su un'istanza live. Questo è il punto e una sostituzione molto conveniente e flessibile per modificare oggetti attraverso rigide regole di eredità classica. Se una lingua utilizza una classe come tipo, non è possibile modificarne la struttura al volo se il tipo non è soft.
SF.

1
Io non la penso così. Secondo la stessa logica, si potrebbe sostenere che la programmazione basata su classi richiede le stesse libertà consentite dai linguaggi dinamici basati su classi. No, i prototipi statici con sistemi di tipo strutturale annoterebbero gli oggetti con un elenco dei suoi membri e ricorsivamente i loro tipi, e controllerebbero staticamente che questi membri esistano (e abbiano il tipo giusto) richiedendo che tutti i membri vengano dati alla creazione dell'oggetto o presenti in il prototipo e semplicemente non includendo un modo per rimuovere i membri. Il risultato mi sembra ancora piuttosto un prototipo e garantisce che ogni membro sia sempre presente.

@delnan: hai appena descritto l'eredità classica attraverso la composizione. Sì, sembra piuttosto un prototipo ed è un modo (molto seccato) di fare una programmazione basata su prototipi in un linguaggio modello ereditario classico. Elimina solo il 90% del divertimento, eliminando i suoi maggiori vantaggi (e rimuovendo contemporaneamente i maggiori pericoli). Sì, nella vecchia analogia del tiro al piede, pb.p completo ti aiuterà a sparare ad entrambe le gambe con un cucchiaino. Se non ti piace questo tipo di potere, è meglio attenersi all'eredità classica.
SF.

1
Confondi "dinamico" con "prototipi". Queste libertà che non si fondono bene con i sistemi di tipo statico non sono caratteristiche dei prototipi, sono caratteristiche del dinamismo. Naturalmente l'aggiunta della tipizzazione statica impedisce loro, ma non fanno parte dei prototipi (questo è IMGO principalmente mancanza di classi a favore della clonazione di oggetti per agire come genitori). Questo dinamismo è ortogonale ai prototipi. Tutti i linguaggi prototipo popolari li includono, ma sono indipendenti dai prototipi come affermato in precedenza. Considera questo frammento in un linguaggio immaginario: pastebin.com/9pLuAu9F . Come non sono i prototipi?

3

La difficoltà è piuttosto semplice da vedere: prendendo la vista degli oggetti come dizionari di metodi o come cose che rispondono ai messaggi, osserva quanto segue sui linguaggi OO comuni tipicamente digitati:

  • Tutte le chiavi / i messaggi del dizionario sono generalmente dichiarati in anticipo, usando identificatori dichiarati staticamente.

  • Alcuni set di messaggi vengono dichiarati in anticipo e gli oggetti sono associati a questi set per determinare a quali messaggi rispondono.

  • Le relazioni di inclusione di un insieme di messaggi che sono un sottoinsieme di un altro sono dichiarate staticamente ed esplicitamente; non dichiarato ma i sottoinsiemi logici non sono validi.

  • Il controllo del tipo tenta di garantire che tutti i messaggi vengano inviati solo agli oggetti che rispondono ad essi.

Ognuno di questi è in una certa misura in conflitto con un sistema basato su prototipi:

  • I nomi dei messaggi potevano essere dichiarati in anticipo, sotto forma di "atomi" o stringhe internate o quant'altro, ma poco altro; la plasticità degli oggetti significa che assegnare tipi ai metodi è scomodo.

  • È senza dubbio la caratteristica essenziale di un sistema basato su prototipi che insiemi di messaggi sono definiti da ciò a cui un oggetto risponde, piuttosto che viceversa. Sarebbe ragionevole assegnare alias a particolari combinazioni in fase di compilazione, ma devono essere possibili set di messaggi determinati in fase di runtime.

  • Il vero impatto di questi due successi colpisce con relazioni di inclusione, in cui dichiarazioni esplicite sono completamente inattuabili. L'ereditarietà nel senso del sottotipo statico e nominale è antitetica a un sistema basato su prototipo.

Il che ci porta al punto finale, che non lo facciamo realtà vogliamo cambiare. Vorremmo comunque assicurarci che i messaggi vengano inviati solo agli oggetti che rispondono ad essi. Tuttavia:

  • Non possiamo sapere staticamente quali messaggi possono essere raggruppati insieme.
  • Non possiamo sapere quali raggruppamenti sono sottoinsiemi di altri.
  • Non possiamo sapere quali raggruppamenti sono possibili.
  • Non possiamo nemmeno specificare quale tipo di argomenti vengono inviati insieme a un singolo messaggio.
  • Fondamentalmente abbiamo scoperto che non possiamo specificare molto di nulla nel caso del tutto generale.

Quindi, come può essere risolto? O in qualche modo limitare la piena generalità (il che è spiacevole e può uccidere rapidamente qualsiasi vantaggio derivante dall'uso di un sistema basato su prototipi in primo luogo) o rendere il sistema di tipi molto più fluido ed esprimere vincoli anziché tipi esatti .

Il sistema di tipi basato sui vincoli porta rapidamente alla nozione di sotto-tipizzazione strutturale , che in un senso molto libero può essere considerata l'equivalente statico della "tipizzazione anatra". Gli ostacoli maggiori qui sono che tali sistemi sono molto più complicati da controllare, e sono meno conosciuti (il che significa poco lavoro precedente da studiare).

In sintesi: è possibile, è solo più difficile fare di un sistema di tipo statico nominale o di un sistema dinamico basato su metadati di runtime, e quindi poche persone si preoccupano.


1

Credo che un modo per ottenere un linguaggio basato sul prototipo e tipicamente statico sarebbe quello di basare il linguaggio su modelli e concetti.

I concetti erano una volta una funzionalità pianificata per C ++ 0x. Il codice generico nei modelli C ++ è già di fatto "tipicamente anatra". L'idea di Concepts è quella di essere in grado di dire alcune cose sui membri richiesti e le caratteristiche dei tipi, senza richiedere o implicare un modello di ereditarietà di classe alla base di quella relazione (perché doveva lavorare con codice modello esistente che era già "tipizzato in modo statico" ).

In un linguaggio basato da zero su Modelli e Concetti, sarebbero i Concetti basati su prototipi e i Modelli ti libererebbero dal preoccuparsi di qualsiasi modello di classe che possa o meno essere utilizzato per implementare i tipi di valori.

A parte i trucchi dell'utilizzo della compilazione graduale per consentire al linguaggio di essere il proprio meta-linguaggio, queste derivate prototipiche di Concetti sarebbero necessariamente immutabili una volta create. Tuttavia, l'obiezione che ciò non è basato sul prototipo è un'aringa rossa. Sarebbe semplicemente un linguaggio funzionale. Una dinamica lingua prototipo di base che è anche funzionale, ha almeno tentato .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.