73

In Java 8's java.util.function package, we have:

  • Function: Takes one argument, produces one result.
  • Consumer: Takes one argument, produces nothing.
  • Supplier: Takes no argument, produces one result.
  • ...: Other cases handling primitives, 2 arguments, etc...

But I need to handle the "takes no argument, produces nothing" case.

There is nothing for this in java.util.functionnal.

So, the question is:

What is the name of 'a function that takes no argument and returns nothing'?

In Java 8, its definition would be:

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

Executor already exists and has another purpose : "An object that executes submitted Runnable tasks". The signature doesn't match (execute(Runnable):void) and is not even a functional interface.

Runnable exists, but it is strongly linked to the threading context:

  • The package is java.lang, not java.util.function.
  • The javadoc states : "The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread".
  • The name "Runnable" suggest some running code inside a thread.

closed as primarily opinion-based by gnat, user40980, Bart van Ingen Schenau, GlenH7, Kilian Foth Mar 23 '15 at 14:39

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 27
    "But there is nothing for "Takes no argument, produces nothing."" - Runnable? – user11153 Mar 20 '15 at 13:24
  • 10
    I think that the javadoc for Runnable is outdated at this point, because a Runnable is also used by other classes than Thread(Executor for example). – SpaceTrucker Mar 20 '15 at 14:18
  • 13
    @superbob That doesn't mean that Runnables can only be .run() by Threads. In fact they're very commonly used for exactly the purpose described in the question – blgt Mar 20 '15 at 14:20
  • 4
    @superbob That was it's initial purpose, but since Java 8 it was "retrofitted" as functional interface. So this is why you found nothing in java.util.function package. – user11153 Mar 20 '15 at 14:21
  • 5
    Semi-Snark: ImpureFuntion because it surely relies only on side effects, otherwise it is a no-op. (en.wikipedia.org/wiki/Pure_function#Impure_functions) More Seriosuly: Imperative (do something), which would at least match the semantics of void execute(); – Kristian H Mar 20 '15 at 16:06
68

Java's choice to do it that way with a separate name for every arity was stupid. It's not exactly worth emulating. However, if you must for the sake of consistency, or if you're writing very generic library code, Konrad's suggestions are good. I might throw Procedure into the ring.

Using a pseudo-functional paradigm doesn't mean normal naming principles should go out the window. Interfaces should almost always be named after what they do, not after some generic syntactic idea. If the functions are placed into an undo stack, they should be named UndoFunction. If they are called from GUI events, they should be named GUIEventHandler. Friends don't let friends perpetuate bad naming conventions.

  • Procedure is fine too. For the context, I'm developing a generic library that needs to handle this kind of "structure". – superbob Mar 20 '15 at 13:16
  • 17
    I like Procedure from my pascal days. A Procedure has side effects, a Function does not. Since you don't return a value, the only thing it could do is have a side effect. – Spencer Rathbun Mar 20 '15 at 15:41
  • I might be inclined to use ProcedureRIR<T1,T2> for void proc(T1, int, T2), and likewise for other types--probably creating most of them on demand rather than trying to cram in every possible combination of types. – supercat Mar 20 '15 at 19:39
  • 1
    Indeed, real functional programming generally don't encourage Hungarian style naming. This is more the mentality of the oo paradigm rather than functional. – slebetman Mar 21 '15 at 1:03
  • 3
    If the functions are placed into an undo stack, they should be named UndoFunction. There's a difference between naming the function and giving it a different type though. In functional style you wouldn't create an UndoFuncton type because now you can't pass it to flip, curry, compose, filter, map, etc. In my opinion that is the real reason Java's decision to give functions with different arities different names is stupid. Of course, if you're going to use side effects, call it whatever; you already threw composition out the window and you're arguably not using functions either. – Doval Mar 21 '15 at 16:57
31

In the java world, it is called Runnable. In the C# world, it is called Action.

But, there is a better name which nicely fits within a larger view of things.

The larger view of things comes later, when you decide that besides your parameterless void functional interface you also need to have similar functional interfaces that accept one, two, or more arguments, or that return a value. When that happens, you will want the names of all those entities to be isomorphic and correspondent with each other.

So, in Java, I have my own set of functional interfaces that I call Procedures, defined as follows:

public interface Procedure
{
    void invoke();
}

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

... (you get the picture.)

And I also have a similar set of interfaces called Functions, defined in a similar way, with the first generic parameter being the return type:

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

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

So, my point here is that Procedure is a very good name because it nicely fits within a larger view of things. If you later decide to have similar functional interfaces with methods that accept arguments or return a value, you will run into this.

NOTE: I basically do agree with Karl Bielefeldt's assertion that "normal naming principles should [not] go out the window" and that "Interfaces should almost always be named after what they do, not after some generic syntactic idea." But note that even he allows for "almost always". Sometimes there is a need for (essentially anonymous) procedures and functions, and that's what the OP is asking, and that's what I am answering.

Amendment 2017-11-10:

You might ask, why Function1<R,T1> instead of Function1<T1,R>? It could go either way, but I have a preference for return values on the left because I like to follow the 'convert-from' (destination-from-source) naming convention as opposed to the 'convert-to' (source-to-destination) convention. (Which is more of an accident than a convention, really, in the sense that most probably, nobody ever gave it any thought, because if they had given it any thought at all they would have arrived at the 'convert-from' convention.)

I read about this in Joel Spolksy - Making Wrong Code Look Wrong, it is a very long article, which I recommend reading in its entirety, but if you want to jump straight to the case at hand, search for 'TypeFromType', but to give you the TL;DR, the idea is that myint = intFromStr( mystr ) is much better than myint = strToInt( mystr ), because in the first case the names of the types are close to the associated values, so you can easily see that the 'int' matches with the 'int' and the 'str' matches with the 'str'.

So, by extension, I tend to order things in the way they are going to appear in code.

  • 1
    This solution is really good, it seems even more bulletproof than java's own Supplier, Consumer, BiFunction, ..., because it lays everything down to two concepts only. It reminds me of @Karl Bielefeldt answer about "Java's choice to do it that way with a separate name for every arity [that] was stupid". The only "downside" being that it doesn't handle primitive types and their combinations (fun stuff like DoubleToLongFunction, ToLongBiFunction, ...). But primitives is another concern ... – superbob Mar 20 '15 at 15:20
  • Yes. Basically, once you start replacing generics with primitives, this means that you really care about performance, so it is okay if you deviate from the convention presented here and use highly customized names for a highly custom performance improvement. – Mike Nakis Mar 20 '15 at 15:32
  • 1
    If I could accept a 2nd answer, I would choose yours thanks to the Procedure N, Function N suggestions. I still upvoted it. – superbob Mar 21 '15 at 12:19
  • Why is it not Function1<T1, R>? – ErikE Nov 20 '17 at 1:06
  • @ErikE that's a very good question, and I amended my post to answer it. – Mike Nakis Nov 20 '17 at 11:10
18

Why not Command? Given that it takes no data and returns no data, but assuming that calling it causes some effect (otherwise it would be rather pointless really), I imagine that's roughly the only thing it can do - fire an action, make something happen.

Speaking of which, there's also a generic Action delegate in .NET. Unlike Java's Consumer it can take from 0 to 16 arguments; in other words, the simpliest version of it takes none - see MSDN.

And since the name doesn't imply there's anything to "consume", it also seems like a good name choice.

  • 1
    Command is good. It can be confused with the Command pattern but it might be the solution. – superbob Mar 20 '15 at 13:01
  • 7
    I do like Action more than Command. A command sounds more like something that is received and evaluated, while an action is executed for its side effects. – Bergi Mar 20 '15 at 13:47
  • 7
    Umm... how can it not be a Command pattern? You have built exactly the Command entity! It even has traditionally-named execute() method. 0_o' – hijarian Mar 20 '15 at 14:47
  • 1
    Dislike suggestion of Action, as that is a common (and good) Swing interface. Command is reasonable. – user949300 Mar 20 '15 at 16:30
  • @user949300 but it depends on the context - Java is a big world you see, I'm an Android developer (now) and I have no J2EE-related idiosyncrasies ;) I agree, of course, that chosen naming convention shouldn't clash with the one your framework uses. – Konrad Morawski Mar 20 '15 at 20:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.