¿Cuál es el nombre de una función que no toma argumentos y no devuelve nada? [cerrado]

58

En el paquete java.util.function de Java 8, tenemos:

  • Función : toma un argumento, produce un resultado.
  • Consumidor : toma un argumento, no produce nada.
  • Proveedor : no toma argumentos, produce un resultado.
  • ... : otros casos que manejan primitivas, 2 argumentos, etc ...

Pero necesito manejar el caso " sin argumentos, no produce nada ".

No hay nada para esto en java.util.functionnal .

Entonces, la pregunta es:

¿Cuál es el nombre de ' una función que no toma argumentos y no devuelve nada '?

En Java 8, su definición sería:

@FunctionalInterface
public interface InsertANameHere {
    void execute();
}

Executor ya existe y tiene otro propósito: " Un objeto que ejecuta las tareas Runnable enviadas ". La firma no coincide ( execute(Runnable):void ) y ni siquiera es una interfaz funcional .

Runnable existe, pero está fuertemente vinculado al subproceso contexto:

  • El paquete es java.lang , no java.util.function .
  • El javadoc declara: " La interfaz Runnable debe ser implementada por cualquier clase cuyas instancias estén destinadas a ser ejecutadas por un subproceso ".
  • El nombre "Ejecutable" sugiere algún código en ejecución dentro de un hilo.
pregunta superbob 20.03.2015 - 11:56

3 respuestas

61

La elección de Java de hacerlo de esa manera con un nombre separado para cada aridad fue estúpida. No es exactamente digno de emular. Sin embargo, si debes por coherencia, o si estás escribiendo un código de biblioteca muy genérico, las sugerencias de Konrad son buenas. Podría lanzar Procedure en el anillo.

El uso de un paradigma pseudo-funcional no significa que los principios de nomenclatura normales deben salir por la ventana. Las interfaces casi siempre deben tener el nombre de lo que hacen , no después de alguna idea sintáctica genérica. Si las funciones se colocan en una pila de deshacer, deben llamarse UndoFunction . Si se llaman desde eventos GUI, deberían llamarse GUIEventHandler . Los amigos no permiten que los amigos perpetúen las malas convenciones de nomenclatura.

    
respondido por el Karl Bielefeldt 20.03.2015 - 14:03
27

En el mundo java, se llama Runnable . En el mundo C #, se llama Action .

Pero, hay un nombre mejor que encaja perfectamente en una visión más amplia de las cosas.

La vista más amplia de las cosas viene más adelante, cuando decide que, además de su interfaz funcional sin parámetros y sin parámetros, también necesita tener interfaces funcionales similares que acepten uno, dos o más argumentos, o que devuelvan un valor. Cuando eso suceda, querrá que los nombres de todas esas entidades sean isomorfos y se correspondan entre sí.

Entonces, en Java, tengo mi propio conjunto de interfaces funcionales que llamo Procedure s, definido de la siguiente manera:

public interface Procedure
{
    void invoke();
}

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

... (obtienes la imagen)

Y también tengo un conjunto similar de interfaces llamado Function s, definido de manera similar, con el primer parámetro genérico que es el tipo de retorno:

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

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

Por lo tanto, mi punto aquí es que Procedure es un nombre muy bueno porque encaja muy bien con una visión más amplia de las cosas. Si luego decide tener interfaces funcionales similares con métodos que aceptan argumentos o devuelven un valor, se encontrará con esto.

NOTA : Básicamente, estoy de acuerdo con la afirmación de Karl Bielefeldt de que "los principios de nomenclatura normales deben [no] salga por la ventana "y que" las interfaces casi siempre deben tener el nombre de lo que hacen, no de alguna idea sintáctica genérica ". Pero tenga en cuenta que incluso él permite "casi siempre". A veces hay una necesidad de procedimientos y funciones (esencialmente anónimas), y eso es lo que pregunta el OP, y eso es lo que estoy respondiendo.

Enmienda 2017-11-10:

Puede preguntar, ¿por qué Function1<R,T1> en lugar de Function1<T1,R> ? Podría ir en cualquier dirección, pero tengo una preferencia por los valores de retorno de la izquierda porque me gusta seguir la convención de nomenclatura "convertir desde" (destino desde origen) en lugar de "convertir a" (origen a) -destino) convención. (Lo que es más un accidente que una convención, en realidad, en el sentido de que lo más probable es que nadie haya pensado en ello, porque si lo hubieran pensado, hubieran llegado a la convención de 'conversión' ''. )

Leí sobre esto en Joel Spolksy - Hacer que el código incorrecto parezca incorrecto , es un artículo muy largo, que recomiendo leer en su totalidad, pero si quieres ir directamente al caso en cuestión, busca 'TypeFromType', pero para darte el TL; DR, la idea es ese myint = intFromStr( mystr ) es mucho mejor que myint = strToInt( mystr ) , porque en el primer caso los nombres de los tipos están cerca de los valores asociados, por lo que puede ver fácilmente que 'int' coincide con la 'int' y la 'str' coincide con el 'str'.

Entonces, por extensión, tiendo a ordenar las cosas de la forma en que aparecerán en el código.

    
respondido por el Mike Nakis 20.03.2015 - 15:30
18

¿Por qué no Command ? Dado que no toma datos y no devuelve datos, pero suponiendo que llamarla produce algún efecto (de lo contrario, sería bastante inútil), me imagino que eso es aproximadamente lo único que puede hacer: disparar una acción, hacer que suceda algo. p>

Hablando de eso, también hay un delegado genérico Action en .NET. A diferencia de Consumer de Java, puede tomar de 0 a 16 argumentos; en otras palabras, la versión más sencilla no requiere ninguna: consulte MSDN .

Y como el nombre no implica que haya algo para "consumir", también parece ser una buena opción de nombre.

    
respondido por el Konrad Morawski 20.03.2015 - 12:02

Lea otras preguntas en las etiquetas