commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matt Benson <gudnabr...@gmail.com>
Subject Re: [functor] Change default arity of Function, Predicate and Procedure
Date Fri, 15 Feb 2013 17:16:03 GMT
On Fri, Feb 15, 2013 at 11:12 AM, Bruno P. Kinoshita <kinow@apache.org>wrote:

> Hi Matt,
>
> Thanks for the pointer, I forgot it had already been asked here.
>
> >Do we want to do this?
>
>
> Indeed that wouldn't be very pleasant for the users of [functor] API.
>
>
> But my idea was to have the interfaces in the api module extending
> Function, and let users write their own implementation, without the need
> for abstract classes... but maybe I'm missing something.
>
> I was thinking in:
>
> // Unary predicate
> public interface Predicate<T> extends Function<T, Boolean> {
>
> }
>
> Predicate<Integer> isLessThanTwo = new Predicate<Integer>() {
>
>   public boolean evaluate(Integer obj) {
>     return obj != null && obj < 2;
>   }
> };
>
>
Wouldn't that technically have to be:

public Boolean evaluate(Integer obj) { ...

?

Then the user has to either rely on autoboxing or use the object.  While it
might be nice to have the *option* to use our functors interchangeably, it
feel nice to me that the "specialized" functor interfaces use primitive or
void return types.

Matt


> Instead of test(), we would have to change to evaluate() :-/
>
> It's hard to find a good compromise for this. And Guava, FunctionalJava
> and Java 8 have no super interface for Function/Procedure/Predicate (names
> differ in each API). And our original super interface has different
> meanings accross functional programming languages :)
>
> Bruno P. Kinoshita
> http://kinoshita.eti.br
> http://tupilabs.com
>
>
> >________________________________
> > From: Matt Benson <gudnabrsam@gmail.com>
> >To: Commons Developers List <dev@commons.apache.org>; Bruno P. Kinoshita
> <kinow@apache.org>
> >Sent: Friday, February 15, 2013 2:25 PM
> >Subject: Re: [functor] Change default arity of Function, Predicate and
> Procedure
> >
> >Hi Bruno,
> >  This idea was talked about some time ago; Emmanuel Bourg had asked:
> >
> >why Predicate isn't an extension of Function<Boolean> ?
> >
> >My answer is at
> >http://wiki.apache.org/commons/Sanity%20Check%20of%20APIs%2C%20etc. .
> >
> >Now, thinking about it more, I feel more amenable to the idea of
> everything
> >inheriting from a single interface, but the fact remains that something
> has
> >to be sacrificed to do this.  I suppose the least painful approach would
> be
> >to implement abstract predicate/procedure classes for each supported
> arity;
> >these could implement {Arity}Function in terms of the abstract method e.g.
> >
> >public abstract class AbstractUnaryPredicate<A> implements
> >UnaryPredicate<A> {
> >  public final Boolean evaluate(A argument) {
> >    return Boolean.valueOf(test(argument));
> >  }
> >
> >  public abstract boolean test(A argument);
> >
> >}
> >
> >Do we want to do this?
> >
> >Matt
> >
> >
> >On Fri, Feb 15, 2013 at 4:11 AM, Bruno P. Kinoshita <kinow@apache.org
> >wrote:
> >
> >> Hi all,
> >>
> >> This thread started after I received feedback about [functor] from a FP
> >> programmer with knowledge in Haskell. Among his observations, was that
> >> Functors in Haskell have a different meaning  and using Functors as
> >> function objects can mislead programmers from Haskell, scalaz and other
> >> functional programming languages.
> >>
> >> However, in C++ a Functor has a meaning similar to [functor] Functor
> (pun
> >> inteded :-).
> >>
> >> In the beginning I liked the idea to replace it by the Arity interface,
> >> but after Benedikt's comments, and thinking from a FP programmer coming
> >> from Haskell, or even from other non pure FP languages like Python or
> Perl,
> >> I think it may cause some confusion too. So between Functor and Arity I
> >> would now prefer Functor.
> >>
> >> But there's a third option, that I want to experiment in my GitHub repo
> >> too. Use the Function interface as the superinterface in [functor]. This
> >> was suggested to me by the same guy that noticed the use of Functors
> with
> >> different meaning. I invited him to join us here in the mailing list, so
> >> hopefully he will chime in later.
> >>
> >> Basically, we would have:
> >>
> >> public interface Function<A, B>
> >>
> >> public interface Predicate<A> extends Function<A, Boolean>
> >>
> >> public interface Procedure<A> extends Function<A, Void>
> >>
> >> I have the feeling this could be useful with function currying and
> >> function folding. I'll experiment with while playing with the adapter
> and
> >> composite packages. But I think maybe the Function interface could be
> >> indeed used as the superinterface, replacing the Functor concept in
> >> [functor].
> >>
> >> What do you guys think?
> >>
> >> Thank you in advance!
> >>
> >> ps: in Java 8, the @FunctionalInterface does not guarantee the arity of
> >> classes, but raises compile time errors if you define an invalid
> functional
> >> interface (like one interface with two abstract public methods). This
> >> applies to [functor] interfaces, any subclasses of Functor can be
> annotated
> >> with @FunctionalInterface and used with lambdas :)
> >>
> >> Bruno P. Kinoshita
> >> http://kinoshita.eti.br
> >> http://tupilabs.com
> >>
> >>
> >> >________________________________
> >> > From: Benedikt Ritter <beneritter@gmail.com>
> >> >To: Commons Developers List <dev@commons.apache.org>
> >> >Sent: Friday, February 15, 2013 6:54 AM
> >> >Subject: Re: [functor] Change default arity of Function, Predicate and
> >> Procedure
> >> >
> >> >2013/2/14 Oliver Heger <oliver.heger@oliver-heger.de>
> >> >
> >> >> Am 14.02.2013 16:51, schrieb Matt Benson:
> >> >>
> >> >>  I would say that certainly one would often want to create an API
> like
> >> >>> you've described.  What I am reluctant not to support is:
> >> >>>
> >> >>> class Foo {
> >> >>>    static void add(Argumented<Binary<? extends CharSequence,
?
> extends
> >> >>> CharSequence>> functor);
> >> >>> }
> >> >>>
> >> >>> Foo.add(new BinaryFunction<String, String, String>() {});
> >> >>> Foo.add(new BinaryProcedure<String, StringBuffer>() {});
> >> >>> Foo.add(new BinaryPredicate<String, StringBuilder>() {});
> >> >>>
> >> >>> The arguments are alike in their "argumentedness" while having
> >> different
> >> >>> functional interfaces.  Convince me this can never be useful, and
we
> >> can
> >> >>> drop the whole thing ;P
> >> >>>
> >> >>> Matt
> >> >>>
> >> >>
> >> >> Scala seems to use a similar approach: There are traits (a trait is
> >> >> something like a more advanced interface in Java) like Function1,
> >> >> Function2, ... with type parameters for the argument types and the
> >> result
> >> >> type.
> >> >>
> >> >> The nice thing in Scala is that its syntax allows you to write
> function
> >> >> literals in a pretty comprehensive form. The compiler maps this
> >> >> automatically to the corresponding FunctionX trait.
> >> >>
> >> >> Oliver
> >> >
> >> >
> >> >I'd say, let's try Matts proposal out and see how it feels. WDYT?
> >> >
> >> >Benedikt
> >> >
> >> >
> >> >>
> >> >>
> >> >>
> >> >>>
> >> >>> On Thu, Feb 14, 2013 at 8:55 AM, Jörg Schaible
> >> >>> <Joerg.Schaible@scalaris.com>**wrote:
> >> >>>
> >> >>>  Hi Matt,
> >> >>>>
> >> >>>> Matt Benson wrote:
> >> >>>>
> >> >>>>  Once again, an enum wouldn't readily be able to contribute
to your
> >> >>>>> functor's being able to participate in some method by type
> signature;
> >> >>>>> i.e., I want to support the use case of:
> >> >>>>>
> >> >>>>> add(Argumented<Binary> somethingThatTakesTwoArguments**);
> >> >>>>>
> >> >>>>> Maybe this isn't a worthwhile goal, but so far I don't
see
> anything
> >> else
> >> >>>>> that accomplishes this.
> >> >>>>>
> >> >>>>
> >> >>>> In any case, I wonder if we really want to support type safety
for
> the
> >> >>>> argument *types* themselves.
> >> >>>>
> >> >>>> [snip]
> >> >>>>
> >> >>>>
> >> >>>>>>>>> interface Arity {
> >> >>>>>>>>> }
> >> >>>>>>>>>
> >> >>>>>>>>> interface Argumented<A extends Arity>
{
> >> >>>>>>>>> }
> >> >>>>>>>>>
> >> >>>>>>>>> interface Unary<A> extends Arity
{
> >> >>>>>>>>> }
> >> >>>>>>>>>
> >> >>>>>>>>> interface UnaryFunction<A, T> extends
Argumented<Unary<A>> {
> >> >>>>>>>>> }
> >> >>>>>>>>>
> >> >>>>>>>>>
> >> >>>>>>>>>  This is more complicated then having the
functors extend
> Arity,
> >> but
> >> >>>>>>>>
> >> >>>>>>> it
> >> >>>>
> >> >>>>> makes better use of inheritance from an OO POV I think.
> >> >>>>>>>>
> >> >>>>>>>> Just to make sure I understand correctly: If
I had an
> >> UnaryFunction
> >> >>>>>>>> that take a Boolean argument and return an
Integer I would
> model
> >> this
> >> >>>>>>>> as: class MyFunction implements UnaryFunction<Boolean,
> Integer>,
> >> >>>>>>>> right?
> >> >>>>>>>>
> >> >>>>>>>
> >> >>>>   class Foo {
> >> >>>>   static CharSequence add(UnaryFunction<? extends CharSequence,
?
> >> extends
> >> >>>> CharSequence> f);
> >> >>>>   }
> >> >>>>
> >> >>>>   Foo.add(new UnaryFunction<String, String>(){});
> >> >>>>   Foo.add(new UnaryFunction<StringBuilder, String>(){});
> >> >>>>   Foo.add(new UnaryFunction<StringBuilder, StringBuilder>(){});
> >> >>>>
> >> >>>>
> >> >>>> This could get really nasty to use.
> >> >>>>
> >> >>>> - Jörg
> >> >>>>
> >> >>>>
> >> >>>> ------------------------------**------------------------------**
> >> >>>> ---------
> >> >>>> To unsubscribe, e-mail: dev-unsubscribe@commons.**apache.org<
> >> dev-unsubscribe@commons.apache.org>
> >> >>>> For additional commands, e-mail: dev-help@commons.apache.org
> >> >>>>
> >> >>>>
> >> >>>>
> >> >>>
> >> >>
> >> >>
> >>
> ------------------------------**------------------------------**---------
> >> >> To unsubscribe, e-mail: dev-unsubscribe@commons.**apache.org<
> >> dev-unsubscribe@commons.apache.org>
> >> >> For additional commands, e-mail: dev-help@commons.apache.org
> >> >>
> >> >>
> >> >
> >> >
> >> >
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> >> For additional commands, e-mail: dev-help@commons.apache.org
> >>
> >>
> >
> >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message