Uma função que obtém um valor de outra função é considerada pura?


9

Estou tentando descobrir uma maneira de lidar com valores de variáveis ​​padrão ao criar funções sem efeitos colaterais e acabamos com o seguinte:

function getDefaultSeparator() {
    return ':';
}

function process(input, separator) {
    var separator = separator || getDefaultSeparator();

    // Use separator in some logic

    return output;
}

O separador padrão será usado em outras funções e só quero defini-lo em um local.

Se essa é uma função pura, qual é a diferença de usar apenas uma constante global DEFAULT_SEPARATOR?


5
Não há nenhuma diferença material, a menos que você esteja planejando usar a função como um espaço reservado para adicionar alguma lógica mais tarde.
21416 Robert Harvey

3
Possível duplicata de Uma função é imediatamente impura se receber uma função como parâmetro? . A pergunta não é uma duplicata exata, mas a resposta deve ser a mesma. ("Depende da pureza da outra função.")
jpmc26

11
Usar uma constante global não torna uma função impura. O uso de um valor global que você assume é constante.
chepner

Btw, você pode curry process(com ordem de parâmetro invertida) e, em seguida, especializar a função curried paravar processDefault = process(":")
bob

Respostas:


22

Uma função que obtém um valor de outra função é considerada pura?

Isso depende do que a outra função faz e do que a função de chamada faz. A impureza é infecciosa, a pureza não.

Chamar uma função pura não altera a pureza da função de chamada. Chamar uma função impura automaticamente torna a função de chamada impura também.

Portanto, no seu exemplo, isso depende da pureza da parte que você deixou de fora: se isso é puro, toda a função é pura.

Se essa é uma função pura, qual é a diferença de usar apenas uma constante global DEFAULT_SEPARATOR?

Nada. Uma função que sempre retorna o mesmo valor é indistinguível de uma constante. De fato, é exatamente assim que as constantes são modeladas no cálculo λ.


2
"Chamar uma função impura automaticamente torna a função de chamada impura também" Você tem certeza disso? AFAICS, chamar uma função impura não torna automaticamente o chamador impuro, embora isso possa acontecer.
Deduplicator

2
@ Reduplicador: depende da quantidade de análise estática que você pode (não se preocupe) em fazer. Claro, se houver uma função funcque tenha efeitos colaterais quando você passa 0, mas não quando você passa 1, então você pode dizer razoavelmente que, embora funcela mesma seja "impura", uma função chama-a como func(1)(e ignorando o valor de retorno, vamos digamos) não é necessariamente impuro. A chamada funcé suficiente para "manchar" o chamador como potencialmente impuro, mas uma função contaminada pode, de alguma maneira, provar-se pura, afinal. Pelo menos em javascript, onde puro / impuro não está definido no idioma.
21416 Steve Joplin

6

Sim, essas são duas funções puras (assumindo que a parte elidida também é pura) porque:

  1. O resultado depende apenas dos parâmetros.
  2. Não tem efeitos colaterais.

Observe que, se getDefaultSeparator()não fosse uma função pura, nenhum dos dois seria process()puro.

No Javascript, não há diferença significativa entre usar uma função pura ou uma constante e ambos podem ser usados ​​por função pura, desde que a capacidade do Javascript de redefinir funções ou alterar os valores das constantes seja evitada.

Um conceito-chave por trás de funções puras é que elas podem ser substituídas pelo valor que retornam sem afetar os resultados do programa.


1

Como os outros estão dizendo, com certeza, ainda é uma função pura.

No entanto, vamos falar sobre os problemas de design. Você está certo ao tentar fazer algo para manter o código DRY, colocando o valor em apenas uma vez. Além disso, o que acho que também deve ser considerado é o nível de acoplamento apropriado.

O uso de uma função oferece mais flexibilidade para alterar a implementação, ou seja, a abordagem da função oferece acoplamento mais flexível que uma variável global.

A questão é se alguém precisa ou não?

Se os consumidores e o provedor estiverem no mesmo módulo, e o provedor for privado do módulo, é difícil argumentar que esse nível de acoplamento flexível é necessário, devido ao fato de que, se o provedor exigir atualização de uma variável privada para uma método privado, uma simples refatoração dentro do módulo pode ser aplicada aos consumidores ao mesmo tempo. O uso de um método / função antes que você realmente precise pode se enquadrar no YAGNI.

Mesmo que o (s) consumidor (es) e o fornecedor estejam em módulos diferentes, ainda assim, os módulos são versionados juntos (por exemplo, você usa um minifyer, para que os módulos do consumidor e do fornecedor estejam no mesmo arquivo), o YAGNI também pode se aplicar.

Por outro lado, se, por exemplo, o produtor estiver em uma biblioteca ou pacote ou módulo de API com versão separada do (s) consumidor (es), o uso da função poderá ser apropriado. Nesse caso, devemos observar a longevidade da API e princípios como OCP.

(Em outra nota, se o seu código for de tamanho significativo, eu incentivaria o uso de módulos com campos e métodos, em vez de variáveis ​​e funções globais.)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.