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.