What does a Consumer consume?
zhong.j.yu at gmail.com
Thu Apr 11 09:58:09 PDT 2013
On Thu, Apr 11, 2013 at 8:02 AM, Brian Goetz <brian.goetz at oracle.com> wrote:
> I sympathize with your concerns -- naming is hard and subjective, and
> fraught with lots of pre-existing baggage -- but this is not on the
> table to be reopened. We simply cannot reopen every decision every time
> one of the ten million Java developers discovers it for the first time,
> decides they don't like it, and assumes there couldn't possibly have
> been adequate consideration the first n-1 times it was brought up.
> For the record, there's two ways to think about the function shaped
> value -> void body
> One is focusing on the side-effects inherent in the body (which there
> must be, otherwise there'd be no point of having this this function at
> all). The other is focusing on its role in a larger system -- it *takes
> a value* and does something with it. While the boundary between the two
> perspectives is fuzzy and one can't live without the other, the former
> is mostly the view from the writer of the lambda (I'm going to get a
> value and TAKE AN ACTION), and the latter is mostly the view from the
> consumer of the lambda (I'm going to PASS THIS VALUE TO THE OTHER GUY
> and he'll probably do something with it).
>From the latter perspective, how is "Consumer" better than "Procedure"?
"Consumer" might be more fitting in some use cases, where there's an
ownership of the object and it is transferred to the receiver. But is that
really the more common case?
> For some functional interface types, like Predicate, the "obvious" name
> worked great from both perspectives. There was no real debate about
> Predicate, because there was very little to not like about it from any
> For this shape, there was no name that worked great from both
> perspectives; some names highlight one perspective, other names
> highlight the other (and to make it worse, many candidates had various
> kinds of baggage that made them less attractive in some situations.)
> The preference is highly subjective, and therefore there was (and
> apparently will be forever more) endless debate. Remember, though,
> there is a not a right answer; for everyone who hates Block or Consumer
> or ValueReceiver, there is someone who hates Procedure or Action for
> analogous reasons.
> In the end, because the place these names are going to appear more than
> anywhere else is in APIs, that gave weight to the latter perspective.
We should give more weight to the readers of APIs, right? They will likely
assign more meaning to the word "consumer" than just "being a receiver".
it sounds like "thenAccept()" can only be invoked once, because the future
result will be "consumed". I think it'll be less misleading if the API reads
The term "consumer" has been widely used in the industry with a strong
connotation, and there are probably lots of existing Java classes with
"Consumer" in their names with that connotation. A "j.u.f.Consumer" with a
different connotation is going to be quite confusing.
> On 4/11/2013 6:22 AM, Thomas Münz wrote:
> > Hi
> > Thanks for the answer. That's a funny find.
> > Sadly, I fail to see the relation to the provided arguments.
> > I'm sorry if there have been too much over-specific suggestions like
> "Block", "Receiver" or "Consumer" all over the place in the past for such a
> much more general concept :-(.
> > All I see currently see is the name "Consumer", which is way too
> specific for the general concept of a generic void logic for the reasons
> provided before.
> > Regards,
> > Thomas
> > Original Message
> > Re: What does a Consumer consume? (11-Apr-2013 11:09)
> > From: David Holmes
> > To:Thomas Münz
> > Cc:lambda-dev at openjdk.java.net
> > On 11/04/2013 6:19 PM, Thomas Münz wrote:
> >> Bike shedding alert :)
> >> While I think Java 8 is pretty optimal from what I saw so far (I know
> it can't be perfect considering Java history), there's one particular thing
> that worries me so much that I feed compelled to bother you with it.
> >> Please bear with me.
> >> I strongly appeal to rename the type Consumer to a more approriate
> name, like maybe Procedure.
> > See the following
> > "Let's please rename Block to Receiver before it's too late"
> > "Hopefully the last message on Block"
> > David
> > -----
> >> Rationale follows:
> >> A consumer is an entity that consumes another entity, meaning removes
> it from its context. Best example is a collection that is used for
> inter-thread communication: the producer/supplier thread puts a new item in
> the queue and the consumer thread removes the item from the queue, hence
> _consumes_ it.
> >> Consuming generally implies that the entity it is applied to is
> _consumed_, made gone, removed. Also see the meaning of consumer in the
> economy: consumers (we) take and buy stuff, remove things from their shelf
> and then use/digest/etc. them until they're gone.
> >> But this core meaning of the term is absolutely not the case with the
> functional type that currently carries this name. It's just a procedure,
> not a consumer.
> >> It MAY be used to consume entities from a collection (which depends on
> the method called, not the passed function instance), but it may and will
> be used many times more to just iterate them and apply a logic to them in
> general busines logic.
> >> I must say was very happy to see that the old,
> compiler-specific-oriented name "Block" has been given up (already wanted
> to post about it, but the problem solved itself, thankfully).
> >> But only to be replaced by an apparently concurrency-specific-oriented
> name like "Consumer".
> >> But why not just take the general functional way of thinking to find a
> name for a general functional element in the first place?
> >> Can('t?) you imagine the hundreds of questions from beginners and not
> so talented developer colleagues like "If I apply the consumer to the
> collection, is the collection empty afterwards?"? ... and the hundreds of
> times we will sigh, start explaining "No, you see, this is just a ..." and
> think "why oh why did they give it that name?" and then start to explain
> time and time again?
> >> This won't be a sign of missing understanding of the asker, but it's a
> sign for confusing naming in the official API.
> >> Also, a very good indicator that Consumer is an unlucky choice can be
> found in its own JavaDoc:
> >> "An operation which accepts a single input argument and returns no
> >> If you instantly have to switch to another term to even begin to
> explain it, then why did you chose the unfitting term in the first place?
> Why not then call it "Operation" right away? Or as "Operation" might be
> ambiguous, something even more fitting, like said "Procedure".
> >> And again: where is the reference to the name, to the process of
> consuming in the java doc? It's missing for a good reason: because nothing
> is consumed in the first place.
> >> I have function types in my own (sry: next generation start-over)
> collection framework that I use very successfully for years now, namely:
> >> Predicate with boolean apply(E)
> >> Function with O apply(I)
> >> Procedure with void apply(E)
> >> (Plus a couple of others like Aggregator extends Procedure which for me
> is a much more elegant, flexible and efficient concept than a reducer, but
> that doesn't matter here much).
> >> Those are very thoroughly thought through names, based on the following
> >> 1.) Procedure correlates very good with the other type Function when it
> comes to building the mental conception of different functional types.
> >> They are both very similar, but Function returns something, Procedure
> does not. Like "brothers". Very intuitive, very straight forward. At first
> I named it "Operation" (like mentioned above), but because of this point,
> procedure appeared to be much more fitting.
> >> 2.) All the functional types have a unifiedly named method "apply". A
> function is applied to an entity. A predicate can apply to an entity
> (honestly: who says "the predicate tests the entity" in common speaking? I
> think 90% say "if the predicate applies to the entity, then...")
> >> As a side node: colliding method names are irrelevant because in
> practice you never come accross a case where a concrete implementation has
> to implement a procedure and a predicate or so. Such cases are done by
> internal separated delegates anyway, not by directly implementing multiple
> >> Me personally (however much that is worth), I will happily delete my
> proprietary "Function" and refactor everything to use the standard one the
> moment Java 8 goes live. I'm all for standard conformity if it's at least
> "okay" to use it.
> >> I'm currently struggling with myself to accept the standard Predicate
> with it sub-optimal "test()" as well for sake of standard conformity, but I
> think I'll get there in the end.
> >> But I cannot in good conscious replace an intuitive, easy
> understandable "Procedure" in my private and professional work with a
> confusion-prone "Consumer" and explain my customers and colleagues endless
> times that it doesn't really do what it implies but instead is just an
> ordinary procedure/operation/routine. The reaction of anyone having even a
> little reservation about functional programming will instantly be "Aha,
> this doesn't sound very thought-out, I knew it, functional programming is
> crap, go away".
> >> I'd rather stick to my proprietary Procedure type and tell them to
> better not use the standard mechanism from the JDK because it does more
> harm than good. Sadly, I do this a lot and I hate to do it every time.
> Maybe this time, I hope I can prevent it ...
> >> Alternatives fitting the concept instead of Procedure might be
> "Routine" or even more abstract "Logic" or "Action", but really, please
> consider that in practice, on a daily business logic designing level
> instead of a language design working bench, "Consumer" is the second worst
> and confusing choice right behind "Block". Why not pick a term from the
> upper end of fitting terms instead of the lower end and save everyone
> several tons of hazzle in the coming years?
> >> Thank you for your attention.
> >> Regards and thanks very much for the 99% pretty optimal rest :-). Can't
> wait to see it go live.
> > To: david.holmes at oracle.com
> > Cc: lambda-dev at openjdk.java.net
More information about the lambda-dev