El otro extremo es decir que dos programas son equivalentes si calculan la misma función (o muestran el mismo comportamiento observable en entornos similares). Pero estos no son buenos: no todos los programas que verifican la primalidad son iguales. Podemos agregar una línea de código sin efecto en el resultado y todavía lo consideraríamos el mismo programa.
Esto no es un extremo: la equivalencia del programa debe definirse en relación con una noción de observación.
La definición más común en la investigación de PL es la equivalencia contextual. En equivalencia contextual, la idea es que observemos los programas usándolos como componentes de programas más grandes (el contexto). Entonces, si dos programas calculan el mismo valor final para todos los contextos, entonces se consideran iguales. Dado que esta definición cuantifica todos los contextos posibles del programa, es difícil trabajar directamente. Entonces, un programa de investigación típico en PL es encontrar principios de razonamiento compositivo que impliquen equivalencia contextual.
Sin embargo, esta no es la única noción posible de observación. Por ejemplo, podemos decir fácilmente que la memoria, el tiempo o el comportamiento de potencia de un programa es observable. En este caso, se mantienen menos equivalencias de programa, ya que podemos distinguir más programas (por ejemplo, mergesort ahora se puede distinguir de quicksort). Si desea (por ejemplo) diseñar lenguajes inmunes a los ataques de canales de tiempo, o diseñar lenguajes de programación limitados por el espacio, entonces este es el tipo de cosas que debe hacer.
Además, podemos elegir juzgar algunos de los estados intermedios de un cálculo como observables. Esto siempre sucede para los idiomas concurrentes, debido a la posibilidad de interferencia. Pero es posible que desee tomar esta vista incluso para lenguajes secuenciales, por ejemplo, si desea asegurarse de que ningún cómputo almacene datos sin cifrar en la memoria principal, entonces debe considerar las escrituras en la memoria principal como observables.
Básicamente, no existe una noción única de equivalencia del programa; siempre es relativo a la noción de observación que elija, y eso depende de la aplicación que tenga en mente.