Convenção de nomenclatura para funções com efeitos colaterais? [fechadas]

9

Ouvi alguém dizer que sua linguagem tem uma convenção em que os nomes de funções que mudam de estado devem terminar com um ponto de exclamação. Estou tentando escrever um código mais funcional e gosto da ideia de, de alguma forma, marcar funções de acordo com seu status de efeito colateral, ou seja, nenhum, efeitos colaterais internos, efeitos colaterais externos (eu desconheço a terminologia correta do FP, mas você entendeu a esperança).

Obviamente, é fácil para mim criar meu próprio esquema de nomeação, mas eu queria saber se esses esquemas / convenções já existem antes de eu fazer o Homebake.

edit: Obrigado por todas as respostas, foi exatamente isso que eu estava procurando e achei todas genuinamente úteis. Eu provavelmente deveria ter mencionado que estou refatorando algum javascript antigo, portanto, enquanto as linguagens de tipo estaticamente podem forçar uma diferença entre o código com e sem efeitos colaterais, terei que confiar em uma convenção de nomenclatura autoimposta.

edit2: Quanto aos mods que fecham isso como principalmente baseados em opiniões, tenho que discordar. Eu estava perguntando o que, se houver, convenções eram de uso comum - isto é, por definição de alguém, uma questão de fato, não de opinião!

técnico
fonte
1
É provável que isso varie entre os idiomas e seja muito orientado para a opinião.
David Arno
1
Por exemplo, a convenção de Scala é declarar métodos sem parênteses (bem como propriedades), a menos que tenham efeitos colaterais. Mas você não pode usar isso em nenhum outro idioma que eu conheça. O ponto de exclamação parece horrível para mim; existem muitos outros usos para esse símbolo, e eu acho que ele está sendo usado para marcar métodos que distraem.
Robert Harvey
2
@RobertHarvey Eu acredito que Scheme é uma linguagem que usa essa convenção, e a convenção existe porque o operador para alterar o estado de uma variável é !(não seria sintaticamente válido alterar o estado de uma variável sem esse operador, se a memória servir ), então é realmente uma convenção bastante sensata nesse idioma .
Servy
3
O @Servy Standard Scheme possui set!para alterar uma variável, mas nenhum !operador independente . A convenção existe porque o Lisp tem um histórico de uso de símbolos em identificadores para transmitir significado devido a muito poucas restrições sobre o que é um identificador válido. A falta de restrições existe devido ao foco do Lisp em macros e idiomas específicos do domínio.
Jack
1
Ruby também usa a !convenção (por exemplo, para downcasee downcase!), mas indica "perigo" mais geralmente do que "efeitos colaterais".
Andrew

Respostas:

8

Siga a separação de comando e consulta . Funções que retornam valores não têm efeitos colaterais, funções que têm efeitos colaterais não retornam valores.

Também ajuda a nomear funções que retornam valores após o que retornam, isto é, um substantivo ou adjetivo. Enquanto as funções com efeitos colaterais devem ser nomeadas após o efeito que executam, ou seja, um verbo.

Então, por exemplo, myArray.sort()tem um efeito colateral, classifica a matriz. Portanto, ele não retorna nada e é nomeado após um verbo. Enquanto isso, myArray.sorted()retorna uma cópia classificada de myArray. Portanto, não tem efeitos colaterais e recebe o nome da coisa que retorna.

Para sua informação, a ideia acima (substantivos / adjetivos para funções puras e verbos para funções produtoras de efeitos colaterais) é um padrão no Swift 3.

Nomear funções e métodos de acordo com seus efeitos colaterais

  • Aqueles sem efeitos colaterais devem ler como frases substantivas.
  • Aqueles com efeitos colaterais devem ler como frases verbais imperativas.

( https://swift.org/documentation/api-design-guidelines/#strive-for-fluent-usage )

Daniel T.
fonte
4

O problema fundamental é que os efeitos colaterais não são capturados no sistema de tipos. O uso de uma convenção de nomenclatura de funções é um substituto inadequado para a verificação estática. Existem algumas maneiras de contornar isso.

Haskell usa mônadas para capturar efeitos colaterais em um contexto. A bindoperação monádica compõe funções impuras, assim como o operador de composição de funções normais compõe funções puras. As leis da mônada garantem que esse operador atue de forma análoga à composição regular.

Outra rota é separar puro de impuro, separando totalmente expressões de comandos . Essas são duas categorias sintáticas totalmente diferentes que não podem ser misturadas. Expressões têm tipos que nos permitem compor termos. Uma expressão, por definição, não pode depender de nenhum atribuível (ela não tem acesso à loja ). Os comandos não têm um tipo no sentido tradicional e não podem retornar um valor. Eles só podem interagir com o programa modificando a loja.

Observe que linguagens "funcionais" convencionalmente seguras para o tipo podem não seguir nenhum desses paradigmas. Por exemplo, OCaml e SML não diferenciam adequadamente funções puras de impuras.

Nenhuma dessas soluções é perfeita e ainda é uma área ativa de pesquisa.

Gardenhead
fonte
note que o haskell também possui unsafePerformIO
jk.
Não estou profundamente familiarizado com Haskell. A maioria dos idiomas seguros fornece uma maneira de subverter o sistema de tipos como último recurso. Além disso, seu nome de usuário torna difícil para mim tomar qualquer coisa que você dizer seriamente: D
gardenhead
@jk unsafePerformIO pode ser desconsiderado com segurança neste contexto. É uma escotilha de escape que não deve ser usada por código regular e vem com advertências e avisos significativos . Ele não deve ser usado com código de efeito colateral.
Andres F.
@AndresF. meu argumento era que inseguro * é uma convenção de nomenclatura para coisas bem inseguras em Haskell, que praticamente significa coisas que produzem efeitos colaterais, embora também sejam usadas apenas pela própria implementação e não pelo código do usuário
jk.
3

Chamar métodos ou funções parece uma ideia fantástica, pois pode ajudar a eliminar os tempos em que o código introduz um nível de insegurança. Joel Spolsky investiga essa idéia bastante em seu artigo Fazendo o Código Errado parecer Errado ( http://www.joelonsoftware.com/articles/Wrong.html ), onde recomenda o uso de uma versão menos conhecida da notação húngara para criar certas idéias mais transparentes dentro do sistema.

O idioma ao qual você está se referindo é quase certamente Scheme (consulte http://download.plt-scheme.org/doc/html/guide/set_.html para um exemplo fácil). Eu não estou ciente de nada global.

O Java prefixa os métodos de propriedade com gete setpara cumprir parcialmente esse objetivo, mas não estou ciente de nenhuma das convenções comuns do tipo que você menciona fora do mundo Lisp que não estão (como @gardenhead apontou) incorporadas no sistema de tipos.

Eu acho que, em geral, você é bastante seguro ao criar uma diretriz de estilo para sua equipe, principalmente se você lida com algo com muita simultaneidade, onde os efeitos colaterais são ainda mais perigosos do que comumente.

Por tudo o que vale, posso pensar em algumas maneiras de implementar isso em linguagens do tipo ALGOL. Um simples pode ser um prefixo, como sugerido por Spolsky - digamos s_para operações com estado e l_para operações sem estado.

Uma idéia mais moderna pode ser colocar palavras como prefixos ou sufixos. Talvez calculateseja uma função pura, mas mutateCalculationé a impura.

Finalmente, há um grau em que muito disso deve ser tratado pela separação de preocupações - somente a camada que atualiza o banco de dados deve ser capaz de atualizar o banco de dados, por exemplo. Nesse caso, é bastante óbvio que você precisa se preocupar com efeitos colaterais em camadas com estado.

Michael
fonte
Obrigado pela resposta. Concordo que em um mundo ideal isso deve ser tratado principalmente pela separação de preocupações. Meu principal caso de uso para uma convenção de nomenclatura é separar e refatorar o código antigo que não foi necessariamente escrito com a elegância e as melhores práticas em mente! (talvez algumas vezes por mim para trás no dia antes que eu tenho religião!)
technicalbloke
Ah, e esse artigo de Joel Spolsky é fantástico, obrigado pelo link!
technicalbloke