L'altro estremo è dire che due programmi sono equivalenti se calcolano la stessa funzione (o mostrano lo stesso comportamento osservabile in ambienti simili). Ma questi non sono buoni: non tutti i programmi che controllano la primalità sono uguali. Possiamo aggiungere una riga di codice senza alcun effetto sul risultato e lo considereremmo comunque lo stesso programma.
Questo non è un estremo: l'equivalenza del programma deve essere definita in relazione a una nozione di osservazione.
La definizione più comune nella ricerca PL è l'equivalenza contestuale. In equivalenza contestuale, l'idea è che osserviamo i programmi usandoli come componenti di programmi più grandi (il contesto). Quindi, se due programmi calcolano lo stesso valore finale per tutti i contesti, vengono giudicati uguali. Poiché questa definizione si quantifica su tutti i possibili contesti di programma, è difficile lavorare direttamente. Quindi un tipico programma di ricerca in PL è quello di trovare principi di ragionamento compositivo che implicano equivalenza contestuale.
Tuttavia, questa non è l'unica nozione possibile di osservazione. Ad esempio, possiamo facilmente affermare che il comportamento di memoria, tempo o potenza di un programma è osservabile. In questo caso, valgono meno equivalenze di programma, poiché possiamo distinguere più programmi (ad esempio, mergesort è ora distinguibile da quicksort). Se si desidera (diciamo) progettare linguaggi immuni agli attacchi dei canali di temporizzazione o progettare linguaggi di programmazione limitati nello spazio, questo è il tipo di cosa che si deve fare.
Inoltre, possiamo scegliere di giudicare osservabili alcuni degli stati intermedi di un calcolo. Questo accade sempre per le lingue concorrenti, a causa della possibilità di interferenze. Ma potresti voler prendere questa visione anche per i linguaggi sequenziali, ad esempio, se vuoi assicurarti che nessun calcolo memorizzi i dati non crittografati nella memoria principale, allora devi considerare le scritture nella memoria principale come osservabili.
Fondamentalmente, non esiste un'unica nozione di equivalenza del programma; è sempre relativo alla nozione di osservazione che scegli, e dipende dall'applicazione che hai in mente.