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:12:10 GMT
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;
  }
};


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