Hi all, If there are no objections, I'll start working on this issue (FUNCTOR-24 [1]) and will commit the changes throughout the next days.
Let me know if you have any thoughts on this, please :) Thanks! [1] https://issues.apache.org/jira/browse/FUNCTOR-24 Bruno P. Kinoshita http://kinoshita.eti.br http://tupilabs.com --- Em sex, 15/2/13, Bruno P. Kinoshita <ki...@apache.org> escreveu: > De: Bruno P. Kinoshita <ki...@apache.org> > Assunto: Re: [functor] Change default arity of Function, Predicate and > Procedure > Para: "Commons Developers List" <dev@commons.apache.org>, > "gudnabr...@gmail.com" <gudnabr...@gmail.com> > Data: Sexta-feira, 15 de Fevereiro de 2013, 15:28 > > Wouldn't that technically have > to be: > > > > public Boolean evaluate(Integer obj) { ... > > > > ? > > You're right indeed. > > > > 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. > > You're right again. Java 8 Predicate interface has a boolean > test(T t) method, with no autoboxing needed, but it shares > only the @FunctionalInterface annotation with Function or > Consumer. > > I think we just have to find a good name to the > superinterface then, or stick with Functor. > > > Bruno P. Kinoshita > http://kinoshita.eti.br > http://tupilabs.com > > > ----- Original Message ----- > > From: Matt Benson <gudnabr...@gmail.com> > > To: Bruno P. Kinoshita <ki...@apache.org> > > Cc: Commons Developers List <dev@commons.apache.org> > > Sent: Friday, February 15, 2013 3:16 PM > > Subject: Re: [functor] Change default arity of > Function, Predicate and Procedure > > > > 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 > >> >> > >> >> > >> > > >> > > >> > > >> > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: 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