Qual é o nome de uma função que não aceita argumento e não retorna nada? [fechadas]

58

No pacote java.util.function do Java 8, temos:

  • Função : aceita um argumento e produz um resultado.
  • Consumidor : Aceita um argumento, não produz nada.
  • Fornecedor : não aceita argumentos, produz um resultado.
  • ... : outros casos lidando com primitivos, dois argumentos, etc.

Mas eu preciso lidar com o caso " não aceita argumento, não produz nada ".

Não há nada para isso em 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();
}

Executor já existe e tem outra finalidade: " Um objeto que executa tarefas executáveis submetidas ". A assinatura não corresponde ( execute(Runnable):void ) e nem sequer é uma interface funcional .

Runnable existe, mas está strongmente ligado ao encadeamento contexto:

  • O pacote é java.lang , não java.util.function .
  • O javadoc declara: " A interface Runnable deve ser implementada por qualquer classe cujas instâncias se destinam a ser executadas por um thread ".
  • O nome "Runnable" sugere algum código em execução dentro de um thread.
por superbob 20.03.2015 / 11:56
fonte

3 respostas

61

A escolha do Java de fazer isso com um nome separado para cada aridade era estúpida. Não é exatamente digno de 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 devem sair pela janela. Interfaces quase sempre devem ser nomeadas de acordo com o que elas fazem, não depois de alguma idéia sintática genérica. Se as funções forem colocadas em uma pilha de desfazer, elas devem ser nomeadas UndoFunction . Se eles forem chamados de eventos da GUI, eles devem ser nomeados GUIEventHandler . Amigos não permitem que amigos perpetuem convenções de nomenclatura incorretas.

    
por 20.03.2015 / 14:03
fonte
27

No mundo do java, é chamado Runnable . No mundo C #, é chamado Action .

Mas, há um nome melhor que se encaixa bem dentro de uma visão mais ampla das coisas.

A visão mais ampla das coisas vem depois, quando você decide que além da sua interface funcional sem parâmetros, você também precisa ter interfaces funcionais semelhantes que aceitem um, dois ou mais argumentos, ou que retornem um valor. Quando isso acontecer, você desejará que os nomes de todas essas entidades sejam isomórficos e correspondam entre si.

Então, em Java, eu tenho meu próprio conjunto de interfaces funcionais que eu chamo de Procedure s, definido da seguinte forma:

public interface Procedure
{
    void invoke();
}

public interface Procedure1<T1>
{
    void invoke( T1 argument1 );
}

... (você começa a foto.)

E eu 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:

public interface Function<R>
{
    R invoke();
}

public interface Function1<R,T1>
{
    R invoke( T1 argument1 );
}

Então, meu ponto aqui é que Procedure é um nome muito bom porque se encaixa bem em uma visão mais ampla das coisas. Se mais tarde você decidir ter interfaces funcionais semelhantes com métodos que aceitam argumentos ou retornam um valor, você encontrará isso.

NOTA: eu basicamente concordo com a afirmação de Karl Bielefeldt de que "os princípios normais de nomenclatura devem [não] Saia pela janela "e que" As interfaces devem quase sempre ser nomeadas de acordo com o que elas fazem, não depois de alguma idéia sintática genérica. " Mas note que até ele permite "quase sempre". Às vezes, há a necessidade de procedimentos e funções (essencialmente anônimos), e é isso que o OP está pedindo, e é isso que estou respondendo.

Alteração 2017-11-10:

Você pode perguntar por que Function1<R,T1> em vez de Function1<T1,R> ? Poderia ir de qualquer forma, mas eu tenho uma preferência por valores de retorno à esquerda porque eu gosto de seguir a convenção de nomenclatura 'converter-de' (destino-de-origem) em oposição a 'converter-para' -destino) convenção. (O que é mais um acidente do que uma convenção, na verdade, no sentido de que, muito provavelmente, ninguém pensou nisso, porque, se tivessem pensado nisso, teriam chegado à convenção de "converter-se". )

Eu li sobre isso em Joel Spolksy - Fazendo o código errado parecer errado , é um artigo muito longo, que eu recomendo ler na íntegra, mas se você quiser ir direto para o caso em questão, procure por 'TypeFromType', mas para obter o TL; DR, a ideia é que myint = intFromStr( mystr ) é muito melhor que myint = strToInt( mystr ) , porque no primeiro caso os nomes dos tipos estão próximos dos valores associados, então você pode ver facilmente que o 'int' corresponde ao 'int' e 'str' combina com o 'str'.

Então, por extensão, tenho a tendência de ordenar as coisas da maneira como elas aparecem no código.

    
por 20.03.2015 / 15:30
fonte
18

Por que não Command ? Dado que ele não pega dados e não retorna nenhum dado, mas assumindo que chamá-lo causa algum efeito (de outra forma seria sem sentido na verdade), eu imagino que é mais ou menos a única coisa que pode fazer - disparar uma ação, fazer algo acontecer. p>

Falando nisso, há também um delegado Action genérico no .NET. Ao contrário do Consumer do Java, ele pode levar de 0 a 16 argumentos; Em outras palavras, a versão mais simples não leva nenhum - consulte MSDN .

E como o nome não implica em algo para "consumir", também parece ser uma boa escolha de nomes.

    
por 20.03.2015 / 12:02
fonte