commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bruno P. Kinoshita" <ki...@apache.org>
Subject Re: [functor] Change default arity of Function, Predicate and Procedure
Date Fri, 15 Feb 2013 17:28:48 GMT
> 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 <gudnabrsam@gmail.com>
> To: Bruno P. Kinoshita <kinow@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 
> <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
>>  >>
>>  >>
>>  >
>>  >
>>  >
>> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message