111

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.function.

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.
Nicolapps
  • 103
  • 5
superbob
  • 1,282
  • 2
  • 8
  • 11
  • http://meta.programmers.stackexchange.com/questions/6582/on-the-troubles-of-naming-and-terminology – gnat Mar 20 '15 at 11:37
  • That is not a function. – Den Mar 20 '15 at 12:24
  • 2
    Why is this not a function ? [FunctionalInterface](http://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html) doesn't forbid it (and it compiles and run fine). Mathematically speaking it is called an empty function for the empty set [Empty function](http://en.wikipedia.org/wiki/Empty_function). – superbob Mar 20 '15 at 12:53
  • 34
    *"But there is nothing for "Takes no argument, produces nothing.""* - [Runnable](http://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html)? – user11153 Mar 20 '15 at 13:24
  • 1
    I +1'd your comment even if _"The Runnable interface should be implemented by any class whose instances are intended to be **executed by a thread**"_ which is not my case. – superbob Mar 20 '15 at 14:08
  • 11
    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
  • 14
    @superbob That doesn't mean that `Runnable`s can only be `.run()` by `Thread`s. In fact they're very commonly used for exactly the purpose described in the question – blgt Mar 20 '15 at 14:20
  • 6
    @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
  • @user11153, I'm considering using Runnable, I will edit my question to mention this – superbob Mar 20 '15 at 14:23
  • 5
    Semi-Snark: ImpureFuntion because it surely relies only on side effects, otherwise it is a no-op. (https://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
  • 1
    Well, what I learned in my intro to programming course (on tests) is that it should be called `mystery` to tell any future reader that they have no possible hope of understanding it. Isn't this just a procedure/behavior though? – Snakes and Coffee Mar 21 '15 at 08:11
  • RxJava has an `Action0` interface (among many other functional reactive programming niceties) that could be used for this purpose. Of course it's not worth to add a big library for this purpose, but if you are already using RxJava, the `Action0` name makes less confusion about threading. – Javad Apr 30 '16 at 23:28
  • 2
    Ugh! Those JavaDocs are **missing the main point:** Those names have to do with the _roles_ of the methods within a pipeline: to transform a value, to produce a value, or to consume a value. They are not names for method arity. E.g. not every method that takes one argument and produces nothing acts as a "Consumer." There is no role in a pipeline for a method that takes no argument and returns nothing. There are such roles elsewhere, e.g. within a task queue. – Jerry101 Mar 11 '17 at 02:55
  • 1
    FWIW Java 11 standard library uses a `Runnable` for this purpose in at least one place: [`Optional::ifPresentOrElse​(Consumer super T> action, Runnable emptyAction)`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Optional.html#ifPresentOrElse(java.util.function.Consumer,java.lang.Runnable)) (Which admittedly also made me think at first if it would run on a different thread) – aksh1618 Jun 01 '20 at 15:24
  • You could use `Consumer` as your type. You can instantiate one with `unused -> someVoidAction()`, and always pass `null` in place of `unused`. – AlexJ136 Dec 06 '20 at 23:00
  • *"A function that takes no argument and returns nothing"*? I'd like to suggest the term *whitespace*. I've turned to using the word "method" to generically describe a named block of instructions, which may or may not take any arguments or return any values. Categorising methods as suppliers and consumers etc. is almost certain to lead to woe, because either you have to accept that the niladic function with no return values is of no computational effect at all, or you have to acknowledge the existence of "side effects" which invalidates the categories of "supplier" and "consumer". (1/2) – Steve May 29 '21 at 12:26
  • 1
    Because you can easily have suppliers and consumers with "side effects" too (i.e. access to context in a way that doesn't correspond with, and can't be explained by, the functional paradigm), as well as those without such effects (i.e. "pure" functions). So there's at least 8 categories, based on whether they are pure or contextual, and whether they supply, consume, transform, or have no inline effect, and that's before attempting to categorise the contextual effects in a similar manner as the inline effects. (2/2) – Steve May 29 '21 at 12:26

3 Answers3

77

Java's choice to do it that way with a separate name for every arity was 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.

Karl Bielefeldt
  • 146,727
  • 38
  • 279
  • 479
  • `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
  • 21
    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` 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 01:03
  • 5
    `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
  • Generic function names make sense in Java 8 with lambdas. Let's say I come across the method `getUsername(Consumer onUsername)`. I immediately know the signature of the argument, and the name of the argument tells me what it does. If it were called `getUsername(UsernameCallback callback)`, I would know what it does, but I would have to look up the signature of `UsernameCallback`. And since lambdas are unnamed anyway, my code will be the same either way, so the former is better in my view. – McMath Oct 03 '18 at 19:08
  • 1
    Names like `Consumer` are better than `UsernameCallback`, but still not as good as specifying a simple signature like `String => Unit`. – Karl Bielefeldt Oct 03 '18 at 22:23
46

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.

Mike Nakis
  • 32,003
  • 7
  • 76
  • 111
  • 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`? – ErikE Nov 20 '17 at 01:06
  • @ErikE that's a very good question, and I amended my post to answer it. – Mike Nakis Nov 20 '17 at 11:10
  • Mike, I am familiar with that article and have named things so for years, too—makes so much sense. Despite that, I think it best to follow the convention established by both Java and C# of putting the return value type argument last in generics... the risk of confusing developers is higher when there’s a clearly established convention being broken. While we can all be sad they didn’t do it the other way, I recommend all readers to consider very carefully if breaking the convention is good for your code base. – ErikE Nov 20 '17 at 11:58
  • @ErikE yes, sure, there are reasons for not doing it my way, that's why I wrote "it can go either way". Personally, I am a bit weary of the philosophical question of whether "convention" is another word for "progress-stopper" in certain areas. – Mike Nakis Nov 20 '17 at 12:40
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.

Konrad Morawski
  • 9,721
  • 4
  • 37
  • 58
  • 1
    `Command` is good. It can be confused with the [Command pattern](http://en.wikipedia.org/wiki/Command_pattern) but it might be the solution. – superbob Mar 20 '15 at 13:01
  • 8
    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