Sto progettando un linguaggio e mi stavo chiedendo come incorporare riferimenti simili a C ++ per quanto riguarda la loro posizione nel sistema di tipi. Penso che siano utili per operazioni come indicizzazione e dereferenziazione ( v[i]
restituisce un riferimento che può essere assegnato a, *pointer_type<a>
restituisce un riferimento a un a
che si comporta come un a
).
Nominalmente in C ++, un tipo di riferimento come int&
e il suo tipo originale int
sono due tipi distinti. Tuttavia, ritengo che questo sia incoerente con il resto del sistema di tipi: un int&
può essere sostituito per int
e a volte si comportano come se fossero dello stesso tipo, ea volte no, senza conversioni esplicite (che è uno dei motivi per cui i riferimenti sono utilizzati in primo luogo.
La mia soluzione sarebbe che i binding e gli argomenti delle funzioni abbiano essenzialmente un "tipo secondario", o piuttosto un'altra qualifica con regole speciali, determinando se sono riferimenti o meno. Ci sarebbero due tipi in questo sistema di tipi secondari: ref
e non- ref
(default), e queste etichette verrebbero scritte in posti dove sarebbero presenti altre etichette simili come const
(o mut
) - principalmente quando si introducono nuovi collegamenti o in tipi di funzioni.
Quindi, insieme agli errori di disallineamento di tipo classico, il compilatore avrebbe segnalato qualcosa come meccanismo di associazione non corrispondente . Ad esempio ciò accadrebbe se il programmatore tentasse di inserire una funzione che accetti un singolo intero per riferimento in un elenco di funzioni che lo accettano per copia ( ref a -> b
vs. a -> b
). Anche se le funzioni avrebbero lo stesso tipo : a -> b
, i meccanismi di associazione sono incompatibili (perché se vengono passati gli lvalues che verranno successivamente assegnati, potrebbe verificarsi un comportamento non compatibile imprevisto).
Questa soluzione ha senso o è meglio avvolgerla nel sistema dei tipi e soffrire di incoerenze? Ci sono alcuni effetti collaterali negativi che non sto anticipando?
Per chiarire: i punti toccanti tra questi due sistemi di tipi avrebbero regole speciali. Ad esempio, ci sarebbero conversioni implicite da ref
a non- ref
mantenendo il tipo invariante.