No java.util.function
pacote do Java 8 , temos:
- Função : Pega um argumento, produz um resultado.
- Consumidor : Aceita um argumento, não produz nada.
- Fornecedor : Não aceita argumentos, produz um resultado.
- ... : Outros casos de manipulação de primitivas, 2 argumentos, etc ...
Mas preciso lidar com o caso " não aceita argumentos, não produz nada ".
Não há nada para isso java.util.functionnal
.
Então, a questão é:
Qual é o nome de ' uma função que não aceita argumentos e não retorna nada '?
No Java 8, sua definição seria:
@FunctionalInterface
public interface InsertANameHere {
void execute();
}
O executor já existe e tem outro objetivo: " Um objeto que executa tarefas Runnable enviadas ". A assinatura não corresponde a ( execute(Runnable):void
) e nem sequer é uma interface funcional .
O executável existe, mas está fortemente vinculado ao contexto de segmentação:
- O pacote
java.lang
não éjava.util.function
. - O javadoc declara: " A interface Runnable deve ser implementada por qualquer classe cujas instâncias sejam executadas por um encadeamento ".
- O nome "Runnable" sugere algum código em execução dentro de um thread.
java
functional-programming
java8
superbob
fonte
fonte
Runnable
está desatualizado neste momento, porque um Runnable também é usado por outras classes além deThread
(Executor
por exemplo).Runnable
s só pode ser.run()
porThread
s. Na verdade eles estão muito comumente usado para exatamente o propósito descrito na perguntajava.util.function
pacote.Respostas:
A escolha de Java de fazê-lo dessa maneira com um nome separado para cada aridade foi estúpida. Não vale exatamente a pena emular. No entanto, se você precisar por uma questão de consistência ou se estiver escrevendo um código de biblioteca muito genérico, as sugestões do Konrad são boas. Eu posso jogar
Procedure
no ringue.Usar um paradigma pseudo-funcional não significa que os princípios normais de nomeação devam sair pela janela. As interfaces devem quase sempre receber o nome do que fazem , não de alguma idéia sintática genérica. Se as funções forem colocadas em uma pilha de desfazer, elas deverão ser nomeadas
UndoFunction
. Se eles são chamados a partir de eventos da GUI, devem ser nomeadosGUIEventHandler
. Amigos não permitem que amigos perpetuem convenções de nomenclatura incorreta.fonte
Procedure
está bem também. Para o contexto, estou desenvolvendo uma biblioteca genérica que precisa lidar com esse tipo de "estrutura".Procedure
dos meus dias pascal. AProcedure
tem efeitos colaterais, aFunction
não. Como você não retorna um valor, a única coisa que ele pode fazer é ter um efeito colateral.ProcedureRIR<T1,T2>
paravoid proc(T1, int, T2)
e também para outros tipos - provavelmente criando a maioria deles sob demanda, em vez de tentar empinar em todas as combinações possíveis de tipos.If the functions are placed into an undo stack, they should be named UndoFunction.
Há uma diferença entre nomear a função e atribuir um tipo diferente. Em estilo funcional você não criaria umUndoFuncton
tipo porque agora você não pode passá-lo paraflip
,curry
,compose
,filter
,map
, etc. Na minha opinião , que é a verdadeira razão a decisão do Java para dar funções com diferentes arities nomes diferentes é estúpido. Claro, se você estiver usando efeitos colaterais, chame o que for; você já jogou composição pela janela e também não está usando funções.No mundo java, é chamado
Runnable
. No mundo C #, é chamadoAction
.Mas, existe um nome melhor que se encaixa perfeitamente em uma visão maior das coisas.
A visão mais ampla das coisas ocorre mais tarde, quando você decide que, além da sua interface funcional sem parâmetros, também precisa ter interfaces funcionais semelhantes que aceitem um, dois ou mais argumentos ou que retornam um valor. Quando isso acontecer, você desejará que os nomes de todas essas entidades sejam isomórficos e correspondam entre si.
Portanto, em Java, eu tenho meu próprio conjunto de interfaces funcionais que chamo de
Procedure
s, definidas da seguinte maneira:... (você entendeu a foto.)
E também tenho um conjunto semelhante de interfaces chamado
Function
s, definido de maneira semelhante, com o primeiro parâmetro genérico sendo o tipo de retorno:Então, o que quero dizer aqui é que esse
Procedure
é um nome muito bom porque se encaixa perfeitamente em uma visão mais ampla das coisas. Se você decidir posteriormente ter interfaces funcionais semelhantes com métodos que aceitam argumentos ou retornam um valor, você o encontrará.NOTA: Eu basicamente concordo com a afirmação de Karl Bielefeldt de que "os princípios normais de nomeação não devem sair pela janela" e que "as interfaces quase sempre devem receber o nome do que fazem, não de alguma idéia sintática genérica". Mas note que mesmo ele permite "quase sempre". Às vezes, são necessários procedimentos e funções (essencialmente anônimos), e é isso que o OP está perguntando e é isso que estou respondendo.
Alteração 2017-11-10:
Você pode perguntar, por que em
Function1<R,T1>
vez deFunction1<T1,R>
? Poderia ser de qualquer maneira, mas tenho preferência pelos valores de retorno à esquerda, porque gosto de seguir a convenção de nomenclatura 'converter de' (destino de origem) em oposição à 'converter para' (origem para -destinação). (O que é mais um acidente do que uma convenção, na verdade, no sentido de que provavelmente ninguém nunca pensou nisso, porque, se tivessem pensado nisso, teriam chegado à convenção de 'conversão de'. )Li sobre isso em Joel Spolksy - Fazendo o código errado parecer errado , é um artigo muito longo, que eu recomendo a leitura na íntegra, mas se você quiser pular direto para o caso em questão, procure por 'TypeFromType', mas para forneça TL; DR, a idéia é que
myint = intFromStr( mystr )
é muito melhor do quemyint = strToInt( mystr )
, porque no primeiro caso os nomes dos tipos estão próximos dos valores associados, para que você possa ver facilmente que o 'int' corresponde ao 'int' e o 'str' corresponde ao 'str'.Então, por extensão, tenho a tendência de ordenar as coisas da maneira que elas aparecerão no código.
fonte
Function1<T1, R>
?Por que não
Command
? Dado que ele não recebe dados e não retorna dados, mas assumindo que chamá-los causa algum efeito (caso contrário, seria realmente inútil), imagino que seja praticamente a única coisa que pode fazer - acionar uma ação, fazer alguma coisa acontecer.Falando nisso, também há um
Action
delegado genérico no .NET. Ao contrário do JavaConsumer
, pode levar de 0 a 16 argumentos; em outras palavras, a versão mais simples não é necessária - consulte o MSDN .E como o nome não implica que haja algo para "consumir", também parece ser uma boa escolha de nome.
fonte
Command
é bom. Pode ser confundido com o padrão de comando, mas pode ser a solução.Action
mais do queCommand
. Um comando soa mais como algo que é recebido e avaliado, enquanto uma ação é executada por seus efeitos colaterais.execute()
método tradicionalmente nomeado . 0_o '