On Fri, Feb 15, 2013 at 11:12 AM, Bruno P. Kinoshita <ki...@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 <gudnabr...@gmail.com> > >To: Commons Developers List <dev@commons.apache.org>; Bruno P. Kinoshita > <ki...@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 <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 > >> > >> > > > > > > >