Qual è il nome di una funzione che non accetta argomenti e non restituisce nulla? [chiuso]

58

Nel pacchetto java.util.function di Java 8 abbiamo:

  • Funzione : accetta un argomento, produce un risultato.
  • Consumatore : accetta un argomento, non produce nulla.
  • Fornitore : non accetta argomenti, produce un risultato.
  • ... : altri casi che gestiscono le primitive, 2 argomenti, ecc.

Ma devo gestire il caso " non accetta argomenti, non produce niente ".

Non c'è nulla per questo in java.util.functionnal .

Quindi la domanda è:

Qual è il nome di " una funzione che non accetta argomenti e non restituisce nulla "?

In Java 8, la sua definizione sarebbe:

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

Executor esiste già e ha un altro scopo: " Un oggetto che esegue attività eseguibili sottoposte ". La firma non corrisponde ( execute(Runnable):void ) e non è nemmeno un'interfaccia funzionale .

Eseguibile esiste, ma è strongmente collegato al threading contesto:

  • Il pacchetto è java.lang , non java.util.function .
  • Gli stati javadoc: " L'interfaccia Runnable dovrebbe essere implementata da qualsiasi classe le cui istanze devono essere eseguite da un thread ".
  • Il nome "Runnable" suggerisce un codice in esecuzione all'interno di un thread.
posta superbob 20.03.2015 - 11:56
fonte

3 risposte

61

La scelta di Java di farlo in quel modo con un nome separato per ogni ragione era stupida. Non vale esattamente la pena di emulare. Tuttavia, se devi per motivi di coerenza, o se stai scrivendo codice di libreria molto generico, i suggerimenti di Konrad sono buoni. Potrei lanciare Procedure nell'anello.

L'uso di un paradigma pseudo-funzionale non significa che i normali principi di denominazione dovrebbero uscire dalla finestra. Le interfacce dovrebbero quasi sempre essere intitolate a ciò che fanno , non dopo qualche idea sintattica generica. Se le funzioni sono inserite in una pila di annullamenti, devono essere denominate UndoFunction . Se vengono chiamati dagli eventi della GUI, devono essere denominati GUIEventHandler . Gli amici non lasciano che gli amici perpetuino le convenzioni sbagliate sui nomi.

    
risposta data 20.03.2015 - 14:03
fonte
27

Nel mondo java, è chiamato Runnable . Nel mondo C #, si chiama Action .

Ma c'è un nome migliore che si adatta bene a una visione più ampia delle cose.

La visione più ampia delle cose viene dopo, quando decidi che oltre all'interfaccia funzionale priva di parametri devi anche avere interfacce funzionali simili che accettano uno, due o più argomenti o che restituiscono un valore. Quando ciò accade, vorrai che i nomi di tutte quelle entità siano isomorfe e corrispondenti l'uno con l'altro.

Quindi, in Java, ho il mio insieme di interfacce funzionali che chiamo Procedure s, definito come segue:

public interface Procedure
{
    void invoke();
}

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

... (ottieni l'immagine.)

E ho anche un insieme simile di interfacce chiamate Function s, definite in modo simile, con il primo parametro generico che è il tipo di ritorno:

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

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

Quindi, il mio punto qui è che Procedure è un nome molto buono perché si adatta perfettamente a una visione più ampia delle cose. Se in un secondo momento decidi di avere interfacce funzionali simili con metodi che accettano argomenti o restituiscono un valore, ti imbatterai in questo.

NOTA: fondamentalmente sono d'accordo con l'affermazione di Karl Bielefeldt che "i normali principi di denominazione dovrebbero [non] uscire dalla finestra "e che" Le interfacce dovrebbero quasi sempre essere intitolate a quello che fanno, non dopo un'idea generica sintattica ". Ma nota che anche lui ammette "quasi sempre". A volte c'è bisogno di procedure e funzioni (essenzialmente anonime), ed è quello che l'OP sta chiedendo, ed è quello che sto rispondendo.

Modifica 2017-11-10:

Potresti chiedere perché Function1<R,T1> anziché Function1<T1,R> ? Potrebbe andare in entrambi i modi, ma ho una preferenza per i valori di ritorno a sinistra perché mi piace seguire la convenzione di denominazione 'convert-from' (destinazione-da-sorgente) in opposizione al 'convert-to' (source-to -destinazione) convenzione. (Che è più un incidente che una convenzione, in realtà, nel senso che molto probabilmente nessuno ci ha mai pensato, perché se gli avessero dato qualche pensiero sarebbero arrivati alla convention "convert-da". )

Ho letto di questo in Joel Spolksy - Rendere il codice sbagliato apparire sbagliato , è un articolo molto lungo, che consiglio di leggere nella sua interezza, ma se vuoi saltare direttamente al caso, cerca 'TypeFromType', ma per darti il TL; DR, l'idea è che myint = intFromStr( mystr ) è molto meglio di myint = strToInt( mystr ) , perché nel primo caso i nomi dei tipi sono vicini ai valori associati, quindi puoi facilmente vedere che "int" corrisponde a "int" e "str" corrisponde con lo "str".

Quindi, per estensione, tendo a ordinare le cose nel modo in cui appariranno nel codice.

    
risposta data 20.03.2015 - 15:30
fonte
18

Perché non Command ? Dato che non prende dati e non restituisce dati, ma supponendo che chiamarli causi qualche effetto (altrimenti sarebbe davvero inutile), immagino che sia più o meno l'unica cosa che può fare: lanciare un'azione, far accadere qualcosa.

A proposito, c'è anche un delegato generico Action in .NET. A differenza di Consumer di Java, può richiedere da 0 a 16 argomenti; in altre parole, la versione più semplice di esso non ne accetta: vedere MSDN .

E dal momento che il nome non implica che ci sia qualcosa da "consumare", sembra anche una buona scelta per il nome.

    
risposta data 20.03.2015 - 12:02
fonte

Leggi altre domande sui tag