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 <ki...@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 <benerit...@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.he...@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.schai...@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-unsubscr...@commons.apache.org> > >>>> For additional commands, e-mail: dev-h...@commons.apache.org > >>>> > >>>> > >>>> > >>> > >> > >> > ------------------------------**------------------------------**--------- > >> To unsubscribe, e-mail: dev-unsubscribe@commons.**apache.org< > dev-unsubscr...@commons.apache.org> > >> For additional commands, e-mail: dev-h...@commons.apache.org > >> > >> > > > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org > >