É uma boa ideia manter o cálculo dos valores (expressões) separado da execução das ações (instruções). Queremos um controle preciso sobre onde e quando as ações serão executadas (como exibir mensagens), mas ao calcular valores, preferimos trabalhar em um nível mais abstrato e não ter que nos preocupar com o cálculo desses valores.
Uma função que calcula apenas um valor de retorno, usando apenas os argumentos fornecidos, é chamada pura .
Uma "função" que executa uma ação é na verdade um procedimento que tem efeito .
Quaisquer efeitos causados durante o cálculo de um valor são chamados efeitos colaterais , e é melhor evitá-los sempre que possível ("Eu só precisava dessa sequência, não sabia que isso iria prejudicar o banco de dados!").
Para minimizar a chance de efeitos colaterais, devemos evitar enviar muitos dados para nossos procedimentos ou colocar qualquer cálculo neles; se algum cálculo precisar ser realizado antecipadamente, geralmente é melhor fazê-lo separadamente em uma função pura e passar apenas o resultado necessário ao procedimento. Isso mantém claro o objetivo do procedimento e reduz a chance de ser reutilizado posteriormente como parte de um cálculo (a função pura pode ser reutilizada).
Pelo mesmo motivo, devemos evitar o processamento de resultados dentro de um procedimento. É melhor retornar o resultado (se houver) nossa ação e executar qualquer processamento subsequente com funções puras.
Se seguirmos essas regras, poderemos terminar com um procedimento como o sayHello
qual não precisa de dados e não tem resultado. Portanto, a melhor interface para isso é não ter argumentos e não retornar um valor. É preferível, por exemplo, chamar "console.log" no meio de algum cálculo.
Para reduzir a necessidade de efeitos durante o cálculo, podemos fazer cálculos que retornam procedimentos ; por exemplo. se precisarmos decidir sobre uma ação a ser tomada, podemos ter uma função pura, escolher um procedimento e devolvê-lo, em vez de executá-lo diretamente.
Da mesma forma, para reduzir a necessidade de cálculo durante os procedimentos, podemos fazer com que os procedimentos tomem outros procedimentos como parâmetros (possivelmente o resultado de uma função); por exemplo. tomando uma variedade de procedimentos e executando um após o outro.