La trasparenza referenziale è una delle pietre angolari della programmazione funzionale che ci consente di applicare il ragionamento equativo al nostro codice. Tuttavia lo fa a un costo per le prestazioni, mediante l'uso di oggetti immutabili.
Alcuni linguaggi di programmazione funzionale come Idris risolvono questo problema di prestazioni tramite l'uso di Tipi di unicità e Tipi presi in prestito per consentire aggiornamenti sul posto degli oggetti (effetti collaterali) finché l'effetto complessivo è come se stessimo ancora utilizzando oggetti immutabili.
Idris mi porta a pensare a C. Quando si programma in C senza alcun riferimento (riferimento zero), allora tutti i riferimenti zero potrebbero essere considerati trasparenti?
Vale a dire. Se si programma in C l'aggiornamento di tutte le variabili in atto con effetti collaterali, mentre si utilizza solo lo spazio di stack (nessun puntatore, nessun heap), quindi hai raggiunto la trasparenza referenziale? E puoi applicare ancora il ragionamento equazionale al tuo codice?
Devo ammettere che non ho pensato affatto alle variabili globali, e questo si spezzerà RT.
Ecco un esempio di quello che ho immaginato:
#include <stdio.h>
struct A5 {
int x[5];
};
A5 basicSort5(A5 nums) {
int n = 5;
for (int i = 0; i < n-1; ++i) {
for (int j = i+1; j < n; ++j) {
if (nums.x[i] > nums.x[j]) {
int tmp = nums.x[i];
nums.x[i] = nums.x[j];
nums.x[j] = tmp;
}
}
}
return nums;
}
int main() {
A5 nums = {7,3,2,8,9};
A5 sortedNums = basicSort5(nums);
for (int i = 0; i < 5; ++i) {
printf("%i\n", sortedNums.x[i]);
}
return 0;
}
basicSort5
è referentially transparent (e thread safe) perché non sta usando riferimenti. Lo stesso identico codice in Java non è referenzialmente trasparente perché costringe tutto a essere un riferimento.
Dovrei estendere questa domanda al C ++. Perché credo che se si utilizza la semantica di spostamento e il codice in uno stile tipizzato in modo lineare, si mantiene RT e si ottengono anche i vantaggi prestazionali dei tipi unici di Idris. E se commetti un errore nella codifica in stile tipizzato lineare, devi solo indossare il costo di una memcpy e mantenere comunque RT. Voglio solo che questa teoria sia confermata.
Penso di aver fatto un errore. Move semantic ti aiuterà solo se sto usando lo spazio heap nascosto all'interno di una classe. Avrò sempre una sorta di copia in corso, anche se è un puntatore a 4 byte.