Conforme Wikipedia:
Na programação de computadores, uma função pode ser descrita como pura se ambas as afirmações sobre a função se mantiverem: A função sempre avalia o mesmo valor de resultado, dados os mesmos valores de argumento. O valor do resultado da função não pode depender de nenhuma informação ou estado oculto que possa mudar à medida que a execução do programa prossegue ou entre diferentes execuções do programa, nem pode depender de nenhuma entrada externa de dispositivos de E / S. A avaliação do resultado não causa nenhum efeito colateral ou saída semanticamente observável, como mutação de objetos mutáveis ou saída para dispositivos de E / S.
Gostaria de saber se é possível escrever uma função que calcule se uma função é pura ou não. Exemplo de código em Javascript:
function sum(a,b) {
return a+b;
}
function say(x){
console.log(x);
}
isPure(sum) // True
isPure(say) // False
if (rand(1000000)<2) return WRONG_ANSWER
, investigar a função várias vezes para obter um comportamento consistente não ajudará. Mas, se você tiver acesso à definição da função, a prova é trivial.say
as chamadasconsole.log
que é impuro, assim,say
é impuro também.Respostas:
Sim, é possível, dependendo do idioma.
Em JavaScript, você pode saber se uma função é pura pelos seguintes critérios:
Ele lê apenas parâmetros e locais;
Ele apenas escreve locais;
Em pessoas não locais, chama apenas funções puras;
Todas as funções que chama implicitamente são puras, por exemplo
toString
; eEle grava propriedades de habitantes locais apenas se eles não forem alias de habitantes locais.
O alias não é possível determinar em JavaScript no caso geral, porque você sempre pode procurar propriedades de um objeto dinamicamente (
object["property"]
). Desde que você nunca faça isso e tenha a fonte de todo o programa, acho que o problema é tratável. Você também precisaria de informações sobre quais funções nativas têm efeitos colaterais, comoconsole.log
quase tudo o que envolve o DOM.O termo "puro" também pode usar alguns esclarecimentos. Mesmo em uma linguagem de programação puramente funcional, tipicamente estática, onde todas as funções são referencialmente transparentes, uma função ainda pode falhar ao finalizar. Então, quando falamos sobre
id :: a -> a
, o que realmente estamos dizendo não é:Mas sim:
Porque uma implementação válida de
id
éerror "Not implemented!"
. Como Peteris aponta, essa não totalidade pode ser vista como uma espécie de impureza. Koka é uma linguagem de programação funcional - com sintaxe modelada em JavaScript - que pode inferir possíveis efeitos como divergência (não terminação), transparência referencial, lançamento de exceções e ações de E / S.fonte
toString
é puro para qualquer objeto usado como string.function a (o) { return o.method(); }
- na verdade, não podemos responder a isso, porque depende de qual parâmetroo
é passado. Além disso, não podemos explicar o que acontece se uma função pura anteriormente certificada for alterada para uma implementação não pura, o que é sempre um problema em potencial com o javascript.Não. Você pode verificar facilmente se uma função executa apenas operações "de segurança pura", conforme descrito na resposta de Jon Purdy, mas isso não é suficiente para responder à pergunta da IMO.
Considere esta função:
Obviamente, se não
someCheck
é puro, também épossiblyPure
. Mas, sesomeCheck
é puro e retornatrue
para todo valor possível dex
,possiblyPure
é puro, pois o caminho do código não puro é inacessível!E aqui vem a parte difícil: determinar se
someCheck
retorna ou não verdadeiro para cada entrada possível. Tentar responder a essa pergunta imediatamente leva você ao reino do problema de parada e de problemas indecidíveis semelhantes.EDIT: Prova de que é impossível
Existe alguma incerteza se uma função pura deve terminar em todas as entradas possíveis. Mas em ambos os casos, o problema de parada pode ser usado para mostrar que a verificação de pureza é impossível.
Caso A) Se uma função pura for necessária para terminar em todas as entradas possíveis, você precisará resolver o problema de parada para determinar se a função é pura ou não. Como isso é conhecido por ser impossível, por essa definição, a pureza não pode ser calculada.
Caso B) Se uma função pura tiver permissão para não terminar em algumas entradas, podemos construir algo assim: Vamos supor que
isPure(f)
calcule sef
é uma string que define uma função pura.Agora,
isPure
é necessário determinar se af
parada deve ou não ser sua própria fonte como entrada. Seupf
parar , não é puro; se não terminar,upf
é puro sef
é puro.Se
isPure
funcionasse como esperado (retorna resultados corretos e termina em cada entrada), teríamos resolvido o problema de parada (*)! Uma vez que se sabe que isso é impossível,isPure
não pode existir.(*) para funções JavaScript puras, o que é suficiente para resolvê-lo também para a máquina de turing.
fonte
Esta questão de stackoverflow tem uma resposta de yfeldblum que é relevante aqui. (E tem um voto negativo por algum motivo que não consigo entender. Seria má etiqueta para votar em algo que tem 3 anos?) Ele dá uma prova de que se uma função é pura é redutível ao problema de interrupção em um comentário.
Eu acho que, do ponto de vista prático, não seria muito difícil para alguns idiomas se você deixar a função retornar sim, não ou talvez. Eu estava assistindo a um vídeo sobre Clojure alguns dias atrás, e o palestrante havia feito uma contagem de instâncias de impureza em uma base de código, procurando por cerca de 4 strings diferentes (como "ref"). Devido à ênfase de Clojure na pureza e segregação de coisas impuras, foi trivial, mas não era exatamente o que você estava procurando.
Então, teoricamente impossível, praticamente possível se você ajustar um pouco a questão, e acho que o quão difícil seria dependeria muito da linguagem. Linguagens mais simples / limpas, com foco na imutabilidade e na boa reflexão, seriam mais fáceis.
fonte
bottom
é um valor válido de primeira classe, não merece ser discriminado dessa maneira.Ótima pergunta.
O melhor que você pode fazer na prática, assumindo que não há capacidade de ouvir ações de E / S para chamar a função quantas vezes for possível. Então veja se o valor de retorno é consistente.
Mas você não pode fazer isso em geral. Pode-se argumentar que os programas sem interrupção não são puros e não podemos decidir o problema da interrupção.
fonte
void
função seria "pura", o que é claramente falso.Não é possível no caso geral. Veja o problema de parada . Resumidamente, é impossível escrever um programa que, dada uma função e entrada arbitrárias, determine se o programa será interrompido ou executado para sempre. Se funcionar para sempre, não é uma função pura que se ajusta à definição que você deu.
fonte
bottom
valor.