Discussions

News: FunctionalJ - a library for Functional Programming in Java

  1. FunctionalJ is an open source library for Functional Programming in Java.

    Java is a popular language, and is mainly Object-Oriented. OO is good; however, when you learn a Functional Programming language such as Haskell, you learn some nice FP patterns. Converting to Haskell is not necessarily easy (or possible, in the confines of the workplace). With FunctionalJ, you continue using Java and its OO features, but you can also use FP patterns where appropriate. Of course, this also means that you do not have to learn a whole new programming language.

    The first thing that FunctionalJ does is allow developers to easily refer to a Java method or constructor as an object. For example, consider this simple example where the method to be invoked, Math.min or Math.max, is based on some condition.

    > Integer a = ...; // some value
    > Integer b = ...; // some other value

    > // Based on someCondition, we want the min or max of a and b
    > String name = someCondition ? "min" : "max";

    Using the standard Java reflection mechanism is somewhat code-heavy:

    > Class[] parameterTypes = {int.class, int.class};
    > Method method = Math.class.getMethod(name, parameterTypes);
    > Object[] parameters = {a, b};
    > Integer result = (Integer) method.invoke(null, parameters);

    Not to mention that you have to catch and deal with, or rethrow, IllegalAccessException, IllegalArgumentException, and InvocationTargetException.

    Now to get the above result using FunctionalJ:

    > Function f = new StaticFunction(Math.class, name);
    > Integer result = (Integer) f.addParameters(a, b).call();

    The only exception that FunctionalJ throws is FunctionException, which extends RuntimeException so that you do not have to deal with it if you don't want to.

    FunctionalJ builds on this feature to provide the developer with partial function application (also known as currying), higher-order functions, mapping, filtering, folding, scanning, and more, without having to modifying your original Java methods.

    Here is an example of filtering. Consider a list of objects of type SomeClass, which has an isValid() method that returns a boolean value. You would like a list of only those objects for which isValid() returns true.

    Instead of:

    > List result = new ArrayList();
    > for (Iterator iter = originalList.iterator(); iter.hasNext();) {
    > SomeClass next = (SomeClass) iter.next();
    > if (next.isValid()) {
    > result.add(next);
    > }
    > }
    > return result;

    With FunctionalJ, you could write:

    > Function f = new InstanceFunction(SomeClass.class, "isValid");
    > List result = Functions.filter(f, originalList);

    As I mentioned earlier, FunctionalJ also allows partial function application. This means that you can supply a parameter to a function which expects several parameters, and you will obtain a new function object with that parameter already applied, reducing the expected number of parameters by one. This enables you to construct new functions on the fly without writing new methods. For example, a function which returns a positive int value, by returning the provided int value unchanged if it is positive, or 0 if it is negative, could be defined as:

    > Function positive = new StaticFunction(Math.class, "min").addParameter(new Integer(0));

    Mapping could be used to obtain a list of positive ints from a list of positive and negative ints:

    > List positiveAndNegative = ...;
    > List positiveOnly = Functions.map(positive, positiveAndNegative);

    These are just some simple examples to get you started.

    I wrote FunctionalJ because I wanted to use the Functional Programming patterns used in languages such as Haskell, in Java code, without having to subclass the library's classes nor have to implement special interfaces. In that respect, FunctionalJ is "non-invasive"; you can refer to the constructors and methods of existing classes without having to modify them. FunctionalJ then allows you to harness the power of FP paradigms such as mapping and folding, replacing certain types of error-prone procedural code by cleaner, simpler functional code.

    FunctionalJ is simple to install: just add the functionalj.jar file to your Java CLASSPATH. No other dependencies.

    Please see the FunctionalJ web site to download, view the Javadocs, and for more information.

    Thank you for trying FunctionalJ and for sending me your feedback, questions, comments, suggestions, and any feature requests you may have.

    Frederic Daoud (javelotinfo at users dot sourceforge dot net)

    Threaded Messages (184)

  2. What about typing?[ Go to top ]

    What about typing? As far as I can see there is no typing at all. In this case there is no much worth in using this library because filter, map, fold(l|r) can be easiliy created in java. For example:

    <S,T> List<S> map(Function<T, S> func, List<T> list) {
      List<S> result = new ArrayList<S>();
      for (T t : list) result.add(func.eval(t));
      return result;
    }
  3. What about typing?[ Go to top ]

    Exactly: generics are ideal for function typing.

    Very interesting by the way. Does the documentation contain any information on what these functional patterns look like?
  4. Re: What about typing?[ Go to top ]

    I wanted to first release a version of FunctionalJ that does not require JDK 1.5 (J2SE 5.0), because not everyone has converted to it already. I do plan to provide a 1.5-compatible release that includes typing.

    However, either way, you still need a library that provides you with filter, map, fold(l|r). In your example, Konstantin, you still need the Function class to be defined; it does not come standard with the JDK. Furthermore, with the mecanism I've implemented in FunctionalJ, partial function application becomes possible. Thus the Function<T,S> in your example accepts a parameter of type T and returns a result of type S. With FunctionalJ, this function could actually refer to any of the following (all of which return a result of type S):

    - a static method that accepts a single parameter of type T
    - an instance method that accepts a single parameter of type T
    - a constructor that accepts a single parameter of type T
    - any of the above that accepts several parameters, all but the last one of which has been specified, with the last one being of type T
    - an instance method that accepts no parameters, but to be invoked on objects of type T
    - an instance method that accepts one or more parameters, all of which have been specified, to be invoked on objects of type T.

    It's not particularily difficult to implement this, but I wanted to package it up in a reusable library and build upon it according to developers' experiences and feature requests.

    As for functional patterns, Joost, the "Quick start" section contains some examples. I'll be adding more examples and a "patterns" section to the web site in the next few days.

    Thank you for your feedback..!

    Frederic Daoud
  5. Evangelization[ Go to top ]

    I agree that you'll still need a library.

    I guess you'll have to do some evangelization Frédéric: most documentation that comes with functional languages focuses on implementing AI-like problems like the 9 queens problem.
    The only documentation that described how to do functional programming in 'the real world' was David Mertz' Text Processing in Python
    I for one would need some extra pointers to apply functional programming to the space that Java is usually applied to.
  6. Evangelization[ Go to top ]

    Joost,

    Thank you for your reply.

    I agree with you that many texts on functional programming languages present very theoretical/mathematical problems, making it difficult to see how to apply the concepts to everyday real-world scenarios.

    Your request for more examples is quite pertinent; I will add a "Patterns" section to the FunctionalJ web site to give you common scenarios. These will often be of the form "instead of this, you could use this", which I think will help you see how you could use FP concepts.

    I'll make sure to notify you when this is available - within the next couple of days.

    Thanks again for your interest.

    Frederic Daoud
  7. Most documentation that comes with functional languages focuses on implementing AI-like problems like the 9 queens problem.

    I could have used something like this for my last project.

    One real world example I have is having the ability to apply a set of functions against a collection of objects.

    For instance I had an engine that took in a large list of objects. I needed to queue up and perform many filter, sum, type queries against this list and store the individual results for later use. This is akin to a SQL query where the collection is the table and the set of query functions are were individual SELECT statements.

    The query functions were of the sort:

    "Give me the subset of items in the collection where property X < 50"

    OR

    "Give me the sum of property Y times property Z for all items in the collection of type T".

    The benefit of this approach was that the query functions were logically named and separated for easy maintenance. There was also a performance gain since the collection of items only had to be iterated once. During the iteration each list item was applied to the set of query functions, which would store their results individually.
     
    Thinking of each "query" as a business rule I suppose I could have used a rules engine but that seemed like overkill for an algorithm where
      1) the "queries" didn't change dynamically
      2) the algorithm was very linear (do this, then this, then this...)
      3) the "queries" were going to be applied against the data set exactly once
      4) the data set was read-only

    Using a common functional library may have been better than building our own project-specific pattern to achieve the above.

    My main question is if you can define an entire block to be a function, not just one command?

    Function myFunction = new Function(anObject) {
      // do several things against the given object.
    }

    I'd need something like

    // possibly using variargs
    Functions.apply(originalList, f1, f2, f3...);
    String result = f1.result();
    List result = f2.result();

    or

    Functions.apply(originalList, functionSet);
    foreach (f in functionSet) {
      System.out.println(f.toString());
    }

    If I was using Groovy I guess I'd be using Closures to get this kind of functionality.
  8. Hi George,
       
    Here are some possible solutions to the scenarios you provided:
       
    "Give me the subset of items in the collection where property X < 50"

    If you have a method isPropertyXLessThan50() that returns boolean:

    > Function f = new InstanceFunction(SomeClass.class, "isPropertyXLessThan50");
    > List result = Functions.map(f, originalList);

    If you have a more generic method, isPropertyXLessThan(int value) that returns boolean:

    > Function f = new InstanceFunction(SomeClass.class, "isPropertyXLessThan").addParameter(new Integer(50));
    > List result = Functions.map(f, originalList);
    "Give me the sum of property Y times property Z for all items in the collection of type T".

    > Function getY = new InstanceFunction(T.class, "propertyY");
    > Function getZ = new InstanceFunction(T.class, "propertyZ");
    >
    > List ys = Functions.map(getY, collectionOfT);
    > List zs = Functions.map(getZ, collectionOfT);
    >
    > List results = Tuples.zipWith(Operators.add, ys, zs);

    Here zipWith takes a function of two parameters and two lists, and returns the results of calling the function with one parameter from each list, in turn (two-by-two). There is some convenience work done here too; if the lists happen to be of unequal length, the length of the smaller list is used.

    If you wanted the final sum, you could use:

    > int sum = Functions.sum(results);
    My main question is if you can define an entire block to be a function, not just one command?

    Function myFunction = new Function(anObject) {
    &nbsp;&nbsp;// do several things against the given object.
    }

    Yes, in fact you could simply define this as a plain Java method:

    > public ResultType doManyThings(Object parameter1, String parameter2, int parameter3) {
    > &nbsp;&nbsp;// do several things against the given objects.
    > &nbsp;&nbsp;return result;
    > }

    Then, to refer to this method as a Function:

    > Function f = new InstanceFunction(T.class, "doManyThings");
    foreach (f in functionSet) {&nbsp;&nbsp;System.out.println(f.toString());}

    This would be:

    > Function f = new StaticFunction(PrintStream.class, "println", System.out);
    > Function g = new InstanceFunction(FunctionSetType.class, "toString");
    > Functions.map(new ComposedFunction(f,g), functionSet);

    Thus for each object in the list, first toString() is called, then the result is passed on to the println() method of System.out.

    Let me know what you think..

    Hope this helps,

    Frederic Daoud
  9. I think I see where FunctionalJ's limitations may be in regard to my issue.

    Your library's benefit seems to be to make it easier to reflectively call methods that already exist on an object. I want something that makes it easy and concise to create new functions against an object (or list of objects) and store the result independent of the object. They would use that object's methods to perform the function's task.

    I use reflection a lot to make code more concise and avoid duplication of similar functionality. I end up with some sort of ReflectionUtil but maybe an API like FunctionalJ is more appropriate.

    I guess what I really want is a reasonable way to do closures in Java.

    Others, please don't tell me to just use language X or even scripting language X' that runs on the JVM. Many times it isn't my call or I don't want to add more APIs on top of a project. I agree with the FunctionalJ's author that there are some good design patterns that, while a bit clumsy looking, still are useful to use in Java.
  10. Hi George,

    I really want to understand exactly what you're trying to do, to see if there is a reasonable solution.

    Please correct me if I'm mistaken. You have, say, a list of objects of type SomeClass. However, you do not want to add methods to the SomeClass class. Rather, you want to create functions that operate on objects of type SomeClass, using those methods already defined on SomeClass, and perhaps performing other computations before returning a result.

    Am I to understand that you do not want to define these methods somewhere else either? Such as:

    public class SomeUtil {
      public Result operateOn(SomeClass parameter1) {
        // perform computations based on the SomeClass object
        return result;
      }
    }

    Then:

    Function f = new StaticFunction(SomeUtil.class, "operateOn");
    List results = Functions.map(f, listOfSomeClass);

    Also, if you have an existing method and you want to apply certain parameters to it, and use the last one open to be supplied, you can in this fashion easily define a function in terms of that existing method. Examples:

    Function max100 = new StaticFunction(Math.class, "max").addParameter(new Integer(100));

    Function splitByComma = new InstanceFunction(String.class, "split").addParameter(",");

    And so on.

    Please let me know more about what you are trying to achieve.

    Thanks George for your feedback,

    Frederic
  11. One real world example I have is having the ability to apply a set of functions against a collection of objects.For instance I had an engine that took in a large list of objects. I needed to queue up and perform many filter, sum, type queries against this list and store the individual results for later use.

    Have you looked at the Strategy Pattern?
  12. Have you looked at the Strategy Pattern?

    Which is an OO analogue for some applications of higher order functions (for the sake of my health I did not make any statements about the quality of this analogue) :)
  13. Have you looked at the Strategy Pattern?
    Which is an OO analogue for some applications of higher order functions (for the sake of my health I did not make any statements about the quality of this analogue) :)

    Are you suggesting it would not be a solution to the issue in the post I was replying to?

    Can you give an example where it doesn't suffice?
  14. question[ Go to top ]

    I asked on another thread at this site for an example of a problem that could not be solved (at least not cleanly) in OO but could be done in a functional language. I never got one (to my knowledge.) Perhaps someone on this thread could give one.
  15. question[ Go to top ]

    I asked on another thread at this site for an example of a problem that could not be solved (at least not cleanly) in OO but could be done in a functional language. I never got one (to my knowledge.) Perhaps someone on this thread could give one.

    One historical topic which functional languages seem to be very good at is compilers and interpreters. Another good example is the one where processing XML with XSLT is considerably simpler than with Java.
  16. question[ Go to top ]

    I asked on another thread at this site for an example of a problem that could not be solved (at least not cleanly) in OO but could be done in a functional language. I never got one (to my knowledge.) Perhaps someone on this thread could give one.
    One historical topic which functional languages seem to be very good at is compilers and interpreters. Another good example is the one where processing XML with XSLT is considerably simpler than with Java.

    That seems to be a very spurious example. It's kind of like saying that a race car is better for racing that a general purpose car. XSLT is a language specifically designed for processing XML. Are you saying that all functional languages are better a XML processing that OO languages?

    I just want to point tha my intention is not to defend OO or to attack functional programming. I am just not experienced with functional languages. I'm reading a lot of stuff and I see the advantages here and there but I haven't hit a point where I've thought, "wow, that's really better for that problem".

    I seems to me that a lot of arguments for functional languages set up straw men in OO. I have this impression that functional progamming is all typing and no thinking. I don't think that's likely to be the case it's just the impression I get because that's how the OO 'problem' is presented in the examples I see.
  17. question[ Go to top ]

    One historical topic which functional languages seem to be very good at is compilers and interpreters. Another good example is the one where processing XML with XSLT is considerably simpler than with Java.
    That seems to be a very spurious example. It's kind of like saying that a race car is better for racing that a general purpose car. XSLT is a language specifically designed for processing XML. Are you saying that all functional languages are better a XML processing that OO languages?

    Yeah, since all reasonable functional languages support similar data-centric abstractions which are used in XSLT. E.g. XML Schema can be (and is) directly translated to Haskell types and then you can construct, match and recurse on this types as on native ones. The whole reason it works is since functional languages are inherently data-centric.
  18. question[ Go to top ]

    One historical topic which functional languages seem to be very good at is compilers and interpreters. Another good example is the one where processing XML with XSLT is considerably simpler than with Java.
    That seems to be a very spurious example. It's kind of like saying that a race car is better for racing that a general purpose car. XSLT is a language specifically designed for processing XML. Are you saying that all functional languages are better a XML processing that OO languages?
    Yeah, since all reasonable functional languages support similar data-centric abstractions which are used in XSLT. E.g. XML Schema can be (and is) directly translated to Haskell types and then you can construct, match and recurse on this types as on native ones. The whole reason it works is since functional languages are inherently data-centric.

    I can see that I think. One more question. If Java treated functions as Objects, would it qualify as a functional lanaguage or is there more to it?
  19. question[ Go to top ]

    I can see that I think. One more question. If Java treated functions as Objects, would it qualify as a functional lanaguage or is there more to it?

    No. The whole trouble with functional languages, is that their name is a bit of a misnomer. Though ability to pass functions around is definitely important algebraic types (or there dynamic equivalent) is considered almost as important. Algebraic types allow to structure and combine functions, not unlike the OO concepts, but in a data-centric way (I swear, if I have to write "data-centric" once more I'll catch on fire :).

    So even if Java would be able to pass around functions (like C# does already) it would be a step in that direction, but not enough to call it functional. Pizza was a project to add functional features to Java. So far 1 out of 3 is in :)
  20. question[ Go to top ]

    I can see that I think. One more question. If Java treated functions as Objects, would it qualify as a functional lanaguage or is there more to it?
    No. The whole trouble with functional languages, is that their name is a bit of a misnomer. Though ability to pass functions around is definitely important algebraic types (or there dynamic equivalent) is considered almost as important. Algebraic types allow to structure and combine functions, not unlike the OO concepts, but in a data-centric way (I swear, if I have to write "data-centric" once more I'll catch on fire :).So even if Java would be able to pass around functions (like C# does already) it would be a step in that direction, but not enough to call it functional. Pizza was a project to add functional features to Java. So far 1 out of 3 is in :)

    What's the third? Function pointers, algebraic types, ?

    I can see real benefit in treating functions as Objects. It would allow for mixins and I do feel funny creating an Object so that I can pass a method around, especially when that Object has no state. So that could be a nice feature that wouldn' go too far from the 'Java way'. I don't know of the other features though.
  21. question[ Go to top ]

    I can see that I think. One more question. If Java treated functions as Objects, would it qualify as a functional lanaguage or is there more to it?
    No. The whole trouble with functional languages, is that their name is a bit of a misnomer. Though ability to pass functions around is definitely important algebraic types (or there dynamic equivalent) is considered almost as important. Algebraic types allow to structure and combine functions, not unlike the OO concepts, but in a data-centric way (I swear, if I have to write "data-centric" once more I'll catch on fire :).So even if Java would be able to pass around functions (like C# does already) it would be a step in that direction, but not enough to call it functional. Pizza was a project to add functional features to Java. So far 1 out of 3 is in :)
    What's the third? Function pointers, algebraic types, ?I can see real benefit in treating functions as Objects. It would allow for mixins and I do feel funny creating an Object so that I can pass a method around, especially when that Object has no state. So that could be a nice feature that wouldn' go too far from the 'Java way'. I don't know of the other features though.

    If you are ok with imitating the functionnal approach with objects, it's your right. But don't think functionnal programming is just about treating functions as objects. Take a look at currying and high order for instance :
    http://en.wikipedia.org/wiki/Functional_programming

    You seem to define functional programming as using "Functor" (by the way, I was wrong closure is different from functor). My experience in functional programming was in ML and I can say it was really powerful some types of problems.
    Sorry, but I have to work for the moment so I have no time to write some other exemples but my advice is just try it before judging it, you could be surprised.
  22. question[ Go to top ]

    You seem to define functional programming as using "Functor" (by the way, I was wrong closure is different from functor).

    I don't know why you got the impression I was defining anything. I merely pointed out what I think would be a useful addition to Java: the ability to treat methods as Objects.
  23. question[ Go to top ]

    You seem to define functional programming as using "Functor" (by the way, I was wrong closure is different from functor).
    I don't know why you got the impression I was defining anything. I merely pointed out what I think would be a useful addition to Java: the ability to treat methods as Objects.

    I was not just refering to this quote but to your posts in general. A lot of people do this mistake when looking at first at functional languages. I told you a lot of reasons why I like functionnal programming for some kind of problems but you don't agree with me. Fine then! My point is just if you haven't tried functional programming, wich I don't know, it may be hard to understand its usefulness.
  24. question[ Go to top ]

    You seem to define functional programming as using "Functor" (by the way, I was wrong closure is different from functor).
    I don't know why you got the impression I was defining anything. I merely pointed out what I think would be a useful addition to Java: the ability to treat methods as Objects.
    I was not just refering to this quote but to your posts in general. A lot of people do this mistake when looking at first at functional languages. I told you a lot of reasons why I like functionnal programming for some kind of problems but you don't agree with me. Fine then! My point is just if you haven't tried functional programming, wich I don't know, it may be hard to understand its usefulness.

    What logical system are you using that saying "this feature would be useful" implies others are not?
  25. question[ Go to top ]

    You seem to define functional programming as using "Functor" (by the way, I was wrong closure is different from functor).
    I don't know why you got the impression I was defining anything. I merely pointed out what I think would be a useful addition to Java: the ability to treat methods as Objects.
    I was not just refering to this quote but to your posts in general. A lot of people do this mistake when looking at first at functional languages. I told you a lot of reasons why I like functionnal programming for some kind of problems but you don't agree with me. Fine then! My point is just if you haven't tried functional programming, wich I don't know, it may be hard to understand its usefulness.
    What logical system are you using that saying "this feature would be useful" implies others are not?

    I don't think we are still discussing with answers like this. Plus, maybe it's me, but you don't look like someone who want to understand our point of view, since most of the time you dismiss our arguments without even having considering it.

    I stated several times I don't want my objets to implements those kind of interfaces and I don't want to create class which only goal is to implements those interfaces. This implementation is already available in the Apache commons-collections, so I could already do it before. Like I said, I prefer to use a dynamic typing approach here. I'm not a 100% static typing approach believer and I'm neither 100% dynamic typic approach believer. For the moment, I try to use a hybrid approach. I may be wrong but I have no other arguments excepts the one I already pointed out here. And my arguments don't take in account the performance factor since I haven't tested the library yet, so a static approach might be better if the dynamic approach causes bad performances.
  26. question[ Go to top ]

    What logical system are you using that saying "this feature would be useful" implies others are not?
    I don't think we are still discussing with answers like this. Plus, maybe it's me, but you don't look like someone who want to understand our point of view, since most of the time you dismiss our arguments without even having considering it.</blocquote>

    How it looks to me is that when I address your points, you get defensive. You could respond to what I have said. Instead you keep repeating the same thing.
    I stated several times I don't want my objets to implements those kind of interfaces</blocquote>

    And I pointed out that wasn't necessary each time. But you kept repeating it. This is an example of the above.
    and I don't want to create class which only goal is to implements those Interfaces.

    First time I've seen this from you. That's fine. I just think the cost of using reflection is too great.
    This implementation is already available in the Apache commons-collections, so I could already do it before. Like I said, I prefer to use a dynamic typing approach here. I'm not a 100% static typing approach believer and I'm neither 100% dynamic typic approach believer. For the moment, I try to use a hybrid approach. I may be wrong but I have no other arguments excepts the one I already pointed out here. And my arguments don't take in account the performance factor since I haven't tested the library yet, so a static approach might be better if the dynamic approach causes bad performances.

    I've ignored the peformance aspect on purpose. But I can pretty much guarantee you that reflection will be slower than using the interface approach. I'm fairly certain that JIT cannot optimize reflection, at least not as well as it can optimize normal polymorphic calls.

    I don't really understand your problem. I specifically state that I've learned something from this discussion and that my opinion has changed. Specifically that function pointers should have been included in Java. And then you tell me I'm not considering your arguments. Maybe you should re-read these posts and ask yourself who is really not considering the other's perspective.
  27. question[ Go to top ]

    What logical system are you using that saying "this feature would be useful" implies others are not?
    I don't think we are still discussing with answers like this. Plus, maybe it's me, but you don't look like someone who want to understand our point of view, since most of the time you dismiss our arguments without even having considering it.</blocquote>
    How it looks to me is that when I address your points, you get defensive. You could respond to what I have said. Instead you keep repeating the same thing.
    I stated several times I don't want my objets to implements those kind of interfaces</blocquote>
    And I pointed out that wasn't necessary each time. But you kept repeating it. This is an example of the above.
    and I don't want to create class which only goal is to implements those Interfaces.
    First time I've seen this from you. That's fine. I just think the cost of using reflection is too great.
    This implementation is already available in the Apache commons-collections, so I could already do it before. Like I said, I prefer to use a dynamic typing approach here. I'm not a 100% static typing approach believer and I'm neither 100% dynamic typic approach believer. For the moment, I try to use a hybrid approach. I may be wrong but I have no other arguments excepts the one I already pointed out here. And my arguments don't take in account the performance factor since I haven't tested the library yet, so a static approach might be better if the dynamic approach causes bad performances.
    I've ignored the peformance aspect on purpose. But I can pretty much guarantee you that reflection will be slower than using the interface approach. I'm fairly certain that JIT cannot optimize reflection, at least not as well as it can optimize normal polymorphic calls.I don't really understand your problem. I specifically state that I've learned something from this discussion and that my opinion has changed. Specifically that function pointers should have been included in Java. And then you tell me I'm not considering your arguments. Maybe you should re-read these posts and ask yourself who is really not considering the other's perspective.

    I think we just didn't understand each other and it has probably a bit to do with the fact english isn't my native language. I can understand it pretty well when it is an informative text but sometimes I forget some expressions may sound rude in french but they aren't in english. No offense then and I am sorry if I sounded offending :)
  28. Re: Alexandre[ Go to top ]

    I think we just didn't understand each other and it has probably a bit to do with the fact english isn't my native language.

    Alexandre, feel free to email me in French if you prefer at javelotinfo at users dot sourceforge dot net (I don't think it would be appropriate to post in French here.)

    Of course if I'm wrong and French is not your native language, then just ignore me :)

    Frederic
  29. dolphin[ Go to top ]

    Graham Hamilton mentioned at Javapolis that method reference à la C# are a feature slated for J2SE 7 Dolphin if I remember correctly.
    C# has method references and generics in 2.0 I think. So maybe somebody has explored that solution in that space.
  30. question[ Go to top ]

    If you are ok with imitating the functionnal approach with objects, it's your right. But don't think functionnal programming is just about treating functions as objects. Take a look at currying and high order for instance :http://en.wikipedia.org/wiki/Functional_programming You seem to define functional programming as using "Functor" (by the way, I was wrong closure is different from functor).

    Currying is just a way of writing everything as higher order functions, which are nothing more than "treating functions as objects", or rather as put in FP "treating functions as first-class citizens". And "functor" has different meaning in FP and OO contexts.
  31. question[ Go to top ]

    If you are ok with imitating the functionnal approach with objects, it's your right. But don't think functionnal programming is just about treating functions as objects. Take a look at currying and high order for instance :http://en.wikipedia.org/wiki/Functional_programming You seem to define functional programming as using "Functor" (by the way, I was wrong closure is different from functor).
    Currying is just a way of writing everything as higher order functions, which are nothing more than "treating functions as objects", or rather as put in FP "treating functions as first-class citizens". And "functor" has different meaning in FP and OO contexts.

    You are right but if I remember correctly my ML class, there was another advantage. Currying allows a partial evaluation of a function, ie the function doesn't need all the arguments to be evaluated. So basically it allows you to build new functions. I think there is more then treating functions as object here but I could be wrong. I am far from being a functional programming expert, I just think it is useful sometimes.
  32. question[ Go to top ]

    Pizza was a project to add functional features to Java. So far 1 out of 3 is in :)
    What's the third? Function pointers, algebraic types?


    Why the parametric bounded polymorphism also known as Java Generics :) Though the syntax came from C++ templates, the abstraction came from the functional languages, where it's been used for some time (ML being the oldest popular language using it).
    I can see real benefit in treating functions as Objects. It would allow for mixins and I do feel funny creating an Object so that I can pass a method around, especially when that Object has no state. So that could be a nice feature that wouldn' go too far from the 'Java way'. I don't know of the other features though.

    Well, that's why I given you a link to Pizza, where they had some nice motivational examples for other features.

    BTW another useful feature coming from FP is type inference, e.g. writing
    list = new ArrayList();
    and having the actual type inferred for you while retaining statical typing (yet again available in .NET). Funny thing is that Microsoft hired a lot of functional researchers and now the features start turning up in their languages (the DLinq extension was actually modelled after monads).
  33. Type Inference[ Go to top ]

    I whole-heartedly hope type inference will end up in Java, especially now with the ugly pointed brackets. We need type inference!
  34. Type inference pitfalls[ Go to top ]

    BTW another useful feature coming from FP is type inference, e.g. writinglist = new ArrayList();and having the actual type inferred for you while retaining statical typing
    Actually, this is a pretty bad example of type inference because in this case, the type inferred will be wrong (or let's say, poor): ArrayList whereas it should be List (the interface).

    Other than that, I fully agree that type inference is sorely needed in Java, as are method pointers.

    --
    Cedric
  35. Type inference pitfalls[ Go to top ]

    Actually, this is a pretty bad example of type inference because in this case, the type inferred will be wrong (or let's say, poor): ArrayList whereas it should be List (the interface).Other than that, I fully agree that type inference is sorely needed in Java, as are method pointers.-- Cedric

    Actually you have no idea what will be the actual type inferred, as type inference takes usage into account as much as type inference takes usage into account as well. You could have an inference strategy that we always try to infer the most general type possible, which would in this case produce just as likely a List.

    What's more, the pattern of "always program to the interface" does not make too much sence for local variables (which are the most likely candidates for type inference in Java) and you will anyway have to specify method interfaces and fields fully, since Java does not have a "closed-world" principal. So actually this example is as good as any :)
  36. Re: question[ Go to top ]

    I asked on another thread at this site for an example of a problem that could not be solved (at least not cleanly) in OO but could be done in a functional language. I never got one (to my knowledge.) Perhaps someone on this thread could give one.

    Hi James,

    I agree with you that an OO language such as Java can solve a good number of problems. In fact, in my first post I mentioned that OO and Java are Good, which is why I want to continue using them.

    That said, sometimes in my work I find myself writing blocks of code, thinking, in a functional language, I would use this, and it would be nicer. Mind you, these are small blocks of code, but still. For example, I want to know if at least one object of a list meets a certain condition:

    boolean result = false;
    for (Iterator iter = list.iterator(); iter.hasNext();) {
        SomeClass next = (SomeClass) iter.next();
        if (next.meetsSomeCondition()) {
            result = true;
            break;
        }
    }
    // use result...

    Now there's nothing wrong with the above code, but personally I much prefer this:

    Function f = new InstanceFunction(SomeClass.class, "meetsSomeCondition");
    boolean result = Functions.any(f, list);
    // use result...

    It's for solving these simple-but-frequent types of problems that I like having a small functional library like FunctionalJ available. This doesn't mean that I'm suddenly coding everything in a functional way; most of my code still uses the strengths of OO. However, there are always pieces of procedural code which I find cleaner when written in a functional manner.

    So, like a lot of open source projects, it started out as an itch I wanted to scratch, I looked for an existing project that meets my wishes, couldn't find one, so I wrote my own. I used it for a while, and when I thought it could be of some use to others, I cleaned it all up, structured things properly, wrote more complete Javadocs, and released it. I'm simply hoping others will find it useful, and I'm also eager to receive feedback and improve the library according to users' requests.

    James, I do understand your point though. You can definitely solve these problems with pure OO. However, sometimes it's nice to have another tool in your toolbox, and when you need it, it's there for you and sometimes it's just a better fit. I also agree that if you haven't done FP, or have and didn't like it, you don't find it particularily useful to apply FP principles in an OO language. But for those who do, it's a nice-to-have.

    By the way, I also like being able to invoke a method using reflection (because the name of the method is determined only at runtime, for example), with more concise code than just using the standard reflection mechanism. Again, it's not like this occurs every day, but when it does, I like having a simpler way to achieve the result.

    Best regards,

    Frederic
  37. Re: question[ Go to top ]

    boolean result = false;
    for (Iterator iter = list.iterator(); iter.hasNext();) {
        SomeClass next = (SomeClass) iter.next();
        if (next.meetsSomeCondition()) {
            result = true;
            break;
        }
    }
    // use result...

    Now there's nothing wrong with the above code, but personally I much prefer this:

    Function f = new InstanceFunction(SomeClass.class, "meetsSomeCondition");
    boolean result = Functions.any(f, list);
    // use result...

    OK, this is exactly what I am talking about. The first example is not an OO solution. You won't convince anyone who is comfortable with OO with examples like the above.

    Here's one OO solution:

    interface Condition
    {
        boolean evaluate(Object o);
    }

    ...

    class SetFunctions{
    static boolean any(Iterable iterable, Condition condition)
    {
        for (Object o : iterable) {
            if (condition(o)) return true;
        }

        return false;
    }
    }
    ...

    {
        // check if list contains a String
        SetFunctions.any(list, new Condition {
            boolean evaluate(Object o) {
                return o instanceof String;
            }
        });
    }

    Of course, this is more verbose than a language that allows me to pass the function directly. But that's not enough to convince me that is worth it. The advantage of this over using reflection is that I don't need to declare a method.
  38. Re: question[ Go to top ]

    Here's one OO solution:interface Condition{&nbsp;&nbsp;&nbsp;&nbsp;boolean evaluate(Object o);}...class SetFunctions{static boolean any(Iterable iterable, Condition condition){&nbsp;&nbsp;&nbsp;&nbsp;for (Object o : iterable) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (condition(o)) return true; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;return false;}}...{&nbsp;&nbsp;&nbsp;&nbsp;// check if list contains a String&nbsp;&nbsp;&nbsp;&nbsp;SetFunctions.any(list, new Condition {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean evaluate(Object o) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return o instanceof String;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;});}Of course, this is more verbose than a language that allows me to pass the function directly. But that's not enough to convince me that is worth it. The advantage of this over using reflection is that I don't need to declare a method.

    It's also more verbose than the more natural procedural solution it replaces. Would you really write all that the first time you found the need for the "evaluate" mapping function?
  39. Re: question[ Go to top ]

    Ugh. It sucks that "Quote Original Message" just doesn't do the natural thing. You say this system is written in Java? Java must suck...
  40. Well done[ Go to top ]

    This is qutie neat.

    I like it.

    With Java 5 you can statically import Functions into your code, thus you can to things like:

    map(f, blah) which will look a lot more functional then a static method on Functions. Kind of like a poor mans extension to the language !

    Nicely done. I could see myself getting carried away with this !
  41. Re: question[ Go to top ]

    It's also more verbose than the more natural procedural solution it replaces. Would you really write all that the first time you found the need for the "evaluate" mapping function?

    No. But this topic is not about that. If you like you can read the posts that lead to mine.
  42. Re: question[ Go to top ]

    It's also more verbose than the more natural procedural solution it replaces. Would you really write all that the first time you found the need for the "evaluate" mapping function?
    No. But this topic is not about that. If you like you can read the posts that lead to mine.

    I always try to keep my objects clean of such interfaces (Comparable), especially business objects. The code becomes bloated and not totally focused on business logic, so it is harder to read and understand. How many kind of interfaces like that would you have to implement?

    I think the functional approach is better here. Of course, it is possible to do it in OO because Java is a Turing complete language (good old "computer sciences theory" class :)). java.util.Collections mimic functionnal programming in a couple of method. For example, the Comparator interface is a specific instance of what is called a "closure" (or functor I think) in functionnal programming. In fact, Apache have a general "functor" interface in commons collections for those who want to keep things OO oriented. In Java, you can see the "Command" pattern there. In my mind, patterns are basically a way to bring the other languages advantages in OOP. For example, in Smalltalk you don't need factories. In functionnal programming, you don't need iterator or commands. Well that's another subject.

    For my part, I would rather use a functionnal approach for mass treatments on collections. Faster and easier to developp in my mind :) Feel free to do it your way but don't critizice functionnal paradigm unless you have experimented it. It's quite powerful but you have to try it to be convinced. Static languages can be sometimes cubersome, I don't like having to implement interfaces for utility services. I keep it to express my domain model.

    I think mixing all kind of paradigms is quite powerful AOP + OOP + functionnal can reduce the complexity of your code greatly.

    Nice work! I'll give a look to this!

    By the way, I think relationnal programming languages like Prolog (quite similar to functionnal from what I remember) are the best at interpreting grammars-based language like xslt.
  43. Re: question[ Go to top ]

    Whoops look like I have the wrong name. Damn memory! Prolog is a logic programming language like Lisp and a relationnal language (don't know where I took that). Anyway, I still think they are the best at interpreting grammar languages :)
  44. Logic programming?[ Go to top ]

    Whoops look like I have the wrong name. Damn memory! Prolog is a logic programming language like Lisp and a relationnal language (don't know where I took that). Anyway, I still think they are the best at interpreting grammar languages :)

    Lisp is not a logic programming language. It's a (non-pure) functional language. Of course, since it's a highly evolvable language, it's easy to do logic programming in it, too (I believe there are logic libraries for it), but nevertheless it's not really a logic language.
  45. Logic programming?[ Go to top ]

    Whoops look like I have the wrong name. Damn memory! Prolog is a logic programming language like Lisp and a relationnal language (don't know where I took that). Anyway, I still think they are the best at interpreting grammar languages :)
    Lisp is not a logic programming language. It's a (non-pure) functional language. Of course, since it's a highly evolvable language, it's easy to do logic programming in it, too (I believe there are logic libraries for it), but nevertheless it's not really a logic language.

    Thank didn't know that, I just remember my AI teacher saying Lisp was the equivalent of Prolog. Probably, just a subset of it.
  46. Logic programming?[ Go to top ]

    Thank didn't know that, I just remember my AI teacher saying Lisp was the equivalent of Prolog. Probably, just a subset of it.

    Not even a subset. Lisp and prolog are completely different languages.

    But your teacher was right, lisp and prolog are both turing-complete so they are equivalent in that sense. Howver, that doesn't mean they are similar at all.
  47. Logic programming?[ Go to top ]

    Thank didn't know that, I just remember my AI teacher saying Lisp was the equivalent of Prolog. Probably, just a subset of it.
    Not even a subset. Lisp and prolog are completely different languages.But your teacher was right, lisp and prolog are both turing-complete so they are equivalent in that sense. Howver, that doesn't mean they are similar at all.

    Ok thank I have never used Lisp so I don't know but on wikipedia http://en.wikipedia.org/wiki/Prolog they say Prolog was created to compete Lisp, so maybe it is from there the confusion comes.
  48. Re: question[ Go to top ]

    It's also more verbose than the more natural procedural solution it replaces. Would you really write all that the first time you found the need for the "evaluate" mapping function?
    No. But this topic is not about that. If you like you can read the posts that lead to mine.
    I always try to keep my objects clean of such interfaces (Comparable), especially business objects.

    Look at the example again. The class that usese the any function doesn't implement the interface. Again, you are arguing from a (seemingly) ignorant position on OO.
    ...[snip]...
    Feel free to do it your way but don't critizice functionnal paradigm unless you have experimented it.

    I already said I am not criticizing functional paradigms. I am questioning faking it in Java using reflection.
  49. Re: question[ Go to top ]

    I would rather use a functionnal approach for mass treatments on collections. Faster and easier to developp in my mind :)

    Just curious, why is it faster than the technique that I just demonstrated? Is it because you have less typing? If so, I find that to be the weakest reason to use a specific approach.
  50. Re: question[ Go to top ]

    I would rather use a functionnal approach for mass treatments on collections. Faster and easier to developp in my mind :)
    Just curious, why is it faster than the technique that I just demonstrated? Is it because you have less typing? If so, I find that to be the weakest reason to use a specific approach.

    Because you don't need to developp custom interfaces. I don't think you need interfaces there, they are cumbersomes and they don't make your code cleaner but more complex. I don't like using interfaces when they are not meaningful.
    Comparable or Sortable or those kind of things doesn't fit on any business objects in my mind. Why would an objet be Comparable and not the other one.

    Another thing you can't program cleanly using your approach is implements a complex algorithm that call your custom interfaces. Let me explain. Imagine you had to implement several sort algorithms but with a similar API. Your API would have to rely on your custom interface. Not a problem? Ok, now say you write a function that go throught the collections and check SOME elements based on an custom algorithm. The goal of the algorithm is to find the first element validating a certain boolean condition. You think no problem, my objets just have to implement an interface similar to java.util.Comparable. Ok work for the basic cases but what happen if you want to mix two tests (for instance veryfing if the value > 0 and value % 3 = 0), wich happen very frequently in math algorithms. Using your approach you would have to developp a new object whose purpose is only to aggregate the two method in one. That's very ugly code in my opinion, I don't want fake objetcs... That's where functionnal programming shines.

    From there it's all depend if you want to support dynamic typing or static typing. If you prefer static typing, you can use the interfaces in Apache commons-collections (it works like the Comparator interface in Java). If you prefer dynamic typing wich I do for this case, you use libraries like FunctionnalJ.

    Hope I made it clear enough since english isn't my native language.
  51. Re: question[ Go to top ]

    Ok work for the basic cases but what happen if you want to mix two tests (for instance veryfing if the value > 0 and value % 3 = 0), wich happen very frequently in math algorithms. Using your approach you would have to developp a new object whose purpose is only to aggregate the two method in one.
    No, you just implement an interface a little more general than Comparable:

    interface Filter {
      public boolean accept();
    }
     That's very ugly code in my opinion
    Ugly is subjective, so I won't debate that.

    Objectively, this approach has the merit to be statically typed (no reflection, no strings to name the methods, an approach that is going to fail badly in the face of refactoring).
     I don't want fake objetcs... That's where functionnal programming shines.
    You seem to be implying that functional programming shines because it provides "real" objects?

    That's quite a startling claim and certainly not how I would describe the strengths of functional programming. Go tell that to a Haskell hardcore programmer and he'll look at you in a very funny way :-)

    Don't get me wrong, Alexandre: I think you did a good job with this library, but I also think that applying functional programming to Java is a hopelessly flawed approach that creates programs that are much more error-prone than if they were written leveraging Java constructs such as interface and static typing.

    --
    Cedric
  52. Re: question[ Go to top ]

    Ugly is subjective, so I won't debate that.Objectively, this approach has the merit to be statically typed (no reflection, no strings to name the methods, an approach that is going to fail badly in the face of refactoring).

    This is an excellent point and one I've had personal experience with. When I need to implement changes to code, my IDE allows me to select a method and find all references to that method in the entire code base. Because we have many applications running off the same code base, this is extremely critical. Anytime there is reflection in the code (and there is some in ours) it throws a huge monkey wrench in the works. I now have to manually look though the code to see what methods are being called through reflection. This is a huge time-killer. And I haven't even gotten to making any changes yet.

    Another big problem with this is that reflection allows arbtitrary strings as input. The methods being called may not even appear in code. We have code that calls through reflection where the class and method are retrieved from a external data source. It took me a good day to figure out tha the code didn't actually do anything. However, point the code at a different data source and it might. How can I test that effectively?
  53. Re: question[ Go to top ]

    Ok work for the basic cases but what happen if you want to mix two tests (for instance veryfing if the value > 0 and value % 3 = 0), wich happen very frequently in math algorithms. Using your approach you would have to developp a new object whose purpose is only to aggregate the two method in one.
    No, you just implement an interface a little more general than Comparable:interface Filter {&nbsp;&nbsp;public boolean accept();}
    &nbsp;That's very ugly code in my opinion
    Ugly is subjective, so I won't debate that.Objectively, this approach has the merit to be statically typed (no reflection, no strings to name the methods, an approach that is going to fail badly in the face of refactoring).
    &nbsp;I don't want fake objetcs... That's where functionnal programming shines.
    You seem to be implying that functional programming shines because it provides "real" objects?That's quite a startling claim and certainly not how I would describe the strengths of functional programming. Go tell that to a Haskell hardcore programmer and he'll look at you in a very funny way :-)Don't get me wrong, Alexandre: I think you did a good job with this library, but I also think that applying functional programming to Java is a hopelessly flawed approach that creates programs that are much more error-prone than if they were written leveraging Java constructs such as interface and static typing.-- Cedric

    First, I'm not the author of the library :)

    I agree that ugly code is subjective but I think it's a quality having your business objects focusing on business data and behavior. Easier to read, reuse and maintain. It's one of the reason Spring and Hibernate have become so popular, by getting ride of utility interfaces.

    Anyway, I'm not implying functionnal programming shines because it provides "real objects". I was probably not clear in my post. I was just saying that for implementing volatile business rules for instance it is better to use some form of functional programming approach (or maybe some rule-based programming for bigger problems).

    But it seems the debate here is about implementing the functional approach with static typing or dynamic typing. I prefer dynamic typing in this case but some prefer static typing.
  54. Re: question[ Go to top ]

    Ok work for the basic cases but what happen if you want to mix two tests (for instance veryfing if the value > 0 and value % 3 = 0), wich happen very frequently in math algorithms. Using your approach you would have to developp a new object whose purpose is only to aggregate the two method in one.
    No, you just implement an interface a little more general than Comparable:interface Filter {&amp;nbsp;&amp;nbsp;public boolean accept();}
    &amp;nbsp;That's very ugly code in my opinion
    Ugly is subjective, so I won't debate that.Objectively, this approach has the merit to be statically typed (no reflection, no strings to name the methods, an approach that is going to fail badly in the face of refactoring).
    &amp;nbsp;I don't want fake objetcs... That's where functionnal programming shines.
    You seem to be implying that functional programming shines because it provides "real" objects?That's quite a startling claim and certainly not how I would describe the strengths of functional programming. Go tell that to a Haskell hardcore programmer and he'll look at you in a very funny way :-)Don't get me wrong, Alexandre: I think you did a good job with this library, but I also think that applying functional programming to Java is a hopelessly flawed approach that creates programs that are much more error-prone than if they were written leveraging Java constructs such as interface and static typing.-- Cedric
    First, I'm not the author of the library :)I agree that ugly code is subjective but I think it's a quality having your business objects focusing on business data and behavior. Easier to read, reuse and maintain. It's one of the reason Spring and Hibernate have become so popular, by getting ride of utility interfaces.Anyway, I'm not implying functionnal programming shines because it provides "real objects". I was probably not clear in my post. I was just saying that for implementing volatile business rules for instance it is better to use some form of functional programming approach (or maybe some rule-based programming for bigger problems). But it seems the debate here is about implementing the functional approach with static typing or dynamic typing. I prefer dynamic typing in this case but some prefer static typing.

    One last argument. Remenber the *old* EJB 2.1? Remember what is one of the biggest complaint about this technolgy? I think it was about having to implement some interfaces not related to your business services or business objects.

    I think a lot of people have learned their lesson from EJB 1 and 2. So my reasoning is the same about using a dynamic typing functional approach based upon reflection.
  55. Re: question[ Go to top ]

    One last argument. Remenber the *old* EJB 2.1? Remember what is one of the biggest complaint about this technolgy? I think it was about having to implement some interfaces not related to your business services or business objects. I think a lot of people have learned their lesson from EJB 1 and 2. So my reasoning is the same about using a dynamic typing functional approach based upon reflection.

    This goes back to my point that function pointers or functors are what Java lacks. I've seen little argument for any of the other functional features.

    I'd prefer that this was done with a compiled feature instead of through reflection. I can't think of any reason why they shouldn't be included. It's like the Java language was created and the creators said, "no funcion pointers" and then later said "we need function pointers" and instead of just implementing them as a language feature, they wrote a hacked up library.
  56. Re: question[ Go to top ]

    One last argument. Remenber the *old* EJB 2.1? Remember what is one of the biggest complaint about this technolgy? I think it was about having to implement some interfaces not related to your business services or business objects. I think a lot of people have learned their lesson from EJB 1 and 2. So my reasoning is the same about using a dynamic typing functional approach based upon reflection.
    This goes back to my point that function pointers or functors are what Java lacks. I've seen little argument for any of the other functional features.I'd prefer that this was done with a compiled feature instead of through reflection. I can't think of any reason why they shouldn't be included. It's like the Java language was created and the creators said, "no funcion pointers" and then later said "we need function pointers" and instead of just implementing them as a language feature, they wrote a hacked up library.

    Your point is not quite clear in my opinion, you were debating about providing an interface instead of using reflection to implement functional programming.

    Then you say your point was Java doesn't support function pointers. Why it doesn't? I don't know, maybe there are some implications we haven't taught. We all agree functions pointers supported natively will be the best solution, but we were arguing about how to implement with the current language features.

    My argument was I don't like having to implement interfaces that has nothing to do with the concerns of the layer where the object is located. Business objects should implement business object interfaces, input controller should implement input controller interfaces. I don't want my objets to implements some Condition or AndCondition interfaces. Last year, I will have said the interface solution was the best but now having used Spring and Hibernate and experimenting how they simplify the development using reflective approachs, I am trying to use a hybrid approach. Of course, this a tradeoff and I will have to be careful when refactoring but I consider it's worth it if it allows your objets to stay *clean* and simple. You probably think the opposite and that's fine, it's still work, you prefer having consistency across all your objects.
    So like someone said before let's agree we disagree.
  57. Re: question[ Go to top ]

    My argument was I don't like having to implement interfaces that has nothing to do with the concerns of the layer where the object is located. Business objects should implement business object interfaces, input controller should implement input controller interfaces. I don't want my objets to implements some Condition or AndCondition interfaces.
    Personal preference, I suppose.

    I, for one, really like objects that implement many interfaces because they give me a lot of information on their capabilities and these multiple interfaces make testing these objects so much easier.

    When I pass such objects around, I can dramatically restrict the types exposed in my API to the exact interface I need instead having to use a monster object that will be very hard to isolate or inject when the time comes to understand or test that code.

    --
    Cedric
  58. Re: question[ Go to top ]

    I, for one, really like objects that implement many interfaces because they give me a lot of information on their capabilities and these multiple interfaces make testing these objects so much easier.

    Yeah, I feel that one more feature I'm sorely missing in Java is compound types (see Scala compound types), as some methods would require more than one interface, but there is no _good_ way to require it in the contract.
  59. Re: question[ Go to top ]

    Yeah, I feel that one more feature I'm sorely missing in Java is compound types (see Scala compound types), as some methods would require more than one interface, but there is no _good_ way to require it in the contract.
    Speaking of which, I fail to see the difference between this and multiple inheritance of implementation, as defined in C++.

    Am I missing something?

    --
    Cedric
  60. Re: question[ Go to top ]

    Am I missing something?-- Cedric

    I guess you are. Cedric. The compound type is like saying "object o implements both InterfaceA and InterfaceB, but I do not know its class name".


    In Java or C++, one has to find out the one single class or sub-interface that extends/implements these two interfaces.

    While with compound type, we can simply say (syntax borrowed from ML)

    f(InterfaceA*InterfaceB o){
      InterfaceA ia = o;
      InterfaceB ib = o;
    }



    That said, I don't consider this feature that much useful. And it apparently introduces quite some complexity to the language, which I don't know if it's worthy.
  61. Re: question[ Go to top ]

    guess you are. Cedric. The compound type is like saying "object o implements both InterfaceA and InterfaceB, but I do not know its class name".
    That's not my understanding. Compound types are concrete classes, not interfaces.

    The only difference I can think of between compound types / mix-ins and multiple inheritance of implementation is that with the latter, you usually embed an instance of the class you derive from.

    --
    Cedric
  62. Re: question[ Go to top ]

    guess you are. Cedric. The compound type is like saying "object o implements both InterfaceA and InterfaceB, but I do not know its class name".
    That's not my understanding. Compound types are concrete classes, not interfaces.The only difference I can think of between compound types / mix-ins and multiple inheritance of implementation is that with the latter, you usually embed an instance of the class you derive from.-- Cedric
    Google "compound type" and "scala", you'll see your understanding is wrong.

    Compound type has nothing to do with mixin or milti-inheritance. It's about how you define method signatures, not about how you mix-in or inherit.
  63. Re: question[ Go to top ]

    Google "compound type" and "scala", you'll see your understanding is wrong.Compound type has nothing to do with mixin or milti-inheritance. It's about how you define method signatures, not about how you mix-in or inherit.
    Well, I went straight to the source, and it definitely seems to confirm my understanding:

    trait Cloneable with java.lang.Cloneable {
      override def clone(): Cloneable = { super.clone(); this }
    }

    Compound types include the implementation of these types, so they are similar to mix-ins and multiple inheritance of implementation.

    --
    Cedric
  64. Re: question[ Go to top ]

    Google "compound type" and "scala", you'll see your understanding is wrong.Compound type has nothing to do with mixin or milti-inheritance. It's about how you define method signatures, not about how you mix-in or inherit.
    Well, I went straight to the source, and it definitely seems to confirm my understanding:trait Cloneable with java.lang.Cloneable {&nbsp;&nbsp;override def clone(): Cloneable = { super.clone(); this }}Compound types include the implementation of these types, so they are similar to mix-ins and multiple inheritance of implementation.-- Cedric
    Looks like they made a bad document that's at least confusing to some people. :-)
  65. Re: question[ Go to top ]

    Compound types include the implementation of these types, so they are similar to mix-ins and multiple inheritance of implementation.-- Cedric
    Looks like they made a bad document that's at least confusing to some people. :-)

    Nope, you just seen the wrong example:
    def cloneAndReset(obj: Cloneable with Resetable): Cloneable = {
      ...
    }

    This is the compound types, not the "trait"s, which really do combine multiple inheritence with interfaces with mixins :)
  66. Re: question[ Go to top ]

    This goes back to my point that function pointers or functors are what Java lacks. I've seen little argument for any of the other functional features.I'd prefer that this was done with a compiled feature instead of through reflection. I can't think of any reason why they shouldn't be included. It's like the Java language was created and the creators said, "no funcion pointers" and then later said "we need function pointers" and instead of just implementing them as a language feature, they wrote a hacked up library.
    Your point is not quite clear in my opinion, you were debating about providing an interface instead of using reflection to implement functional programming.

    No I was saying that it makes more sense to solve these problems in an OO way in Java, not that interfaces should be used to do functional programming.
    Then you say your point was Java doesn't support function pointers. Why it doesn't? I don't know, maybe there are some implications we haven't taught. We all agree functions pointers supported natively will be the best solution, but we were arguing about how to implement with the current language features.

    The Java language only supports using Objects and interfaces to simulate function pointers. Reflection is mainly there for dynamic instantiation and execution.
    My argument was I don't like having to implement interfaces that has nothing to do with the concerns of the layer where the object is located. Business objects should implement business object interfaces, input controller should implement input controller interfaces. I don't want my objets to implements some Condition or AndCondition interfaces.

    I agree and they don't have to, as I demonstrated.
    Last year, I will have said the interface solution was the best but now having used Spring and Hibernate and experimenting how they simplify the development using reflective approachs, I am trying to use a hybrid approach. Of course, this a tradeoff and I will have to be careful when refactoring but I consider it's worth it if it allows your objets to stay *clean* and simple. You probably think the opposite and that's fine, it's still work, you prefer having consistency across all your objects.So like someone said before let's agree we disagree.

    I don't know why you are so ready to stop the discussion. I also don't understand why you have such a combatative tone. I am asking for help to understand why I should care about functional programming. I've actually been swayed by your arguments and others' arguments.

    I was thinking about your example of Spring and I realized it is not really simulating function pointers but really simualating a dynamic language. It does lend credence to the RoR apostles arguments. Personally I haven't had a chance to use Spring, though we are looking at it. One thing I don't like is the use of the JavaBeans paradigm. Why not just let people specify the method name in the configuration file? JavaBeans are just stupid IMO. In any event I'm not sure the problem with EJB was that it used interfaces but that the interfaces were so poorly designed. That's another discussion, though.
  67. Re: question[ Go to top ]

    Alexandre, I'm a bit curious about why you think that you have to implement the Function class?

    Functional constructs is better as a glue to compose different pieces together.

    When designing your business logic, one certainly doesn't have to implement the Function interface/class, I would say.
  68. Re: question[ Go to top ]

    Alexandre, I'm a bit curious about why you think that you have to implement the Function class?Functional constructs is better as a glue to compose different pieces together.When designing your business logic, one certainly doesn't have to implement the Function interface/class, I would say.

    I think you didn't understand what I wrote or maybe I didn't get you point. Anyway, I'm all for the Function class. I agree with the way the author uses it. What I was disagreeing with what James proposed previously, ie using reflective programming to specify the function is a bad thing, you shoud use valid OO concepts to implement it. I have nothing against the Function class but I don't want to have to implement some custom interfaces. Apache already provides this kind of OO functional programming, I prefer the approach FunctionalJ takes but I could be wrong of course.

    Some people think reflective API is a dirty hack, maybe it is. But having used SmallTalk in the past, I can see why Java needs it. For those who don't know, SmallTalk is based upon a 4 levels OO model (t he true theorical model) where Java is based upon a 3 levels OO model to keep the consistency with C++. However, it does have some "back door" to provide 4 levels functionalities, ie the static keyword and the reflective API. With SmallTalk, you don't need these things, you just use a Meta-Class, I think it makes more sense but the 4 levels model is harder to understand and that's why I think SmallTalk never enjoyed a big popularity from the mass. Well sorry for the long philosophical talk but I just wanted to add my 2 cent :)
  69. Re: question[ Go to top ]

    I kinda agree that reflection is something to be careful about. performance, type safety are concerns.

    I also disagree with you that a custom interface is a big deal. What's the difference between these two?


    1)
    Function f = new InstanceFunction(this, "mylogic");

    2)
    Function f = new LamdaFunction(){
      public Object lamda(Object obj){
        return mylogic(obj);
      }
    };

    I see them no fundamental diff. The first uses reflection and is slower. The 2nd uses anonymous class and is more verbose. Other than that, there's no difference. You have to depend on the Functional library either way. And your biz object doesn't have to implement any funny interface either way.
  70. Re: question[ Go to top ]

    I kinda agree that reflection is something to be careful about. performance, type safety are concerns.I also disagree with you that a custom interface is a big deal. What's the difference between these two?1)Function f = new InstanceFunction(this, "mylogic");2)Function f = new LamdaFunction(){&nbsp;&nbsp;public Object lamda(Object obj){&nbsp;&nbsp;&nbsp;&nbsp;return mylogic(obj);&nbsp;&nbsp;}};I see them no fundamental diff. The first uses reflection and is slower. The 2nd uses anonymous class and is more verbose. Other than that, there's no difference. You have to depend on the Functional library either way. And your biz object doesn't have to implement any funny interface either way.

    Yeah, I said earlier I agree with the anonymous class approach. I didn't think about it at first because I always try to avoid them as much as possible but sometimes they are quite useful :)
  71. Re: question[ Go to top ]

    I'm the contrary. :-)

    Always tried to avoid reflection unless necessary.

    Hate annonymous class syntax too but I'd pay a few more lines of code for faster performance, better static type safety, clearer logic, easier debugging, easier refactoring, easier "find reference in Eclipse" etc.
  72. Re: question[ Go to top ]

    Ben,

    Sorry that I haven't had the chance to answer your previous posts yet, I just wanted to add a small comment here:
    What's the difference between these two?

    1)
    Function f = new InstanceFunction(this, "mylogic");

    2)

    Function f = new LamdaFunction(){
      public Object lamda(Object obj) {
        return mylogic(obj);
      }
    };

    If you are targetting JDK < 1.5, as I am, and one of your goals is to simplify code, there is even more verbosity involved. Consider a mylogic method like this:

    public Object mylogic(String p_string, int p_int, List p_list);

    Then you have:

    1)
    Function f = new InstanceFunction(this, "mylogic");

    2)

    Function f = new LamdaFunction(){
      public Object lamda(Object[] obj) {
        return mylogic((String) obj[0], ((Integer) obj[1]).intValue(), (List) obj[2]);
      }
    };

    Things get more messy in 2), but 1) remains the same.

    I do agree that reflection has its inconveniences. I'm considering providing both alternatives and give people the choice of which pros are more important to them (or which cons are less important).

    Frederic
  73. Re: question[ Go to top ]

    In java 5, I'd provide a few variants of Lamda interfaces, Lamda1, Lamda2, through Lamda5 maybe.

    Then I can say:

    Function f = new Lamda3<String,Integer,List>(){
      public Object lamda(String s1, Integer i2, List l3) {
        return mylogic(s1, i2, l3);
      }
    };

    I think it's even better.
  74. Re: question[ Go to top ]

    Sorry, I think I misunderstood your point.

    Yes, Pre java 5 will incur a lot of casting in the lamda abstraction. And it's ugly.

    Things can be ugly to an unacceptable level in case of the mutli-dispatch example I gave.

    I can see the benefit of using reflection in such case, especially if the code is not meant to be a general library or framework where performance is the key.

    That's why JFunctional provides reflection support as well as lamda abstraction.
  75. Re: question[ Go to top ]

    I would rather use a functionnal approach for mass treatments on collections. Faster and easier to developp in my mind :)
    Just curious, why is it faster than the technique that I just demonstrated? Is it because you have less typing? If so, I find that to be the weakest reason to use a specific approach.
    Because you don't need to developp custom interfaces.

    The assumption is that the library would provide the interfaces as FunctionalJ provides the helper classes. Apples to apples.
    I don't think you need interfaces there, they are cumbersomes and they don't make your code cleaner but more complex. I don't like using interfaces when they are not meaningful. Comparable or Sortable or those kind of things doesn't fit on any business objects in my mind. Why would an objet be Comparable and not the other one.

    Huh? What other one? Comparable Objects really should be symetric. With Generics, you can actually enforce this so some degree.
    Another thing you can't program cleanly using your approach is implements a complex algorithm that call your custom interfaces. Let me explain. Imagine you had to implement several sort algorithms but with a similar API. Your API would have to rely on your custom interface. Not a problem? Ok, now say you write a function that go throught the collections and check SOME elements based on an custom algorithm. The goal of the algorithm is to find the first element validating a certain boolean condition. You think no problem, my objets just have to implement an interface similar to java.util.Comparable. Ok work for the basic cases but what happen if you want to mix two tests (for instance veryfing if the value > 0 and value % 3 = 0), wich happen very frequently in math algorithms. Using your approach you would have to developp a new object whose purpose is only to aggregate the two method in one.

    Comparable isn't really applicable to the situation you are describing. If you want to use differing comparisons use Comparators. The situation above is a boolean condition so Comparator isn't Applicable. Using the Condition interface I created above:

    abstract class MultiCondition<T> implements Condition<T>
    {
        final List<Condition<T>> conditions;
        
        public void add(Condition<T> c)
        {
            conditions.add(c);
        }

        abstract public boolean evaluate(T t);
    }

    class AndCondition<T> extends MultiCondition<T>
    {
        AndCondition(final List<Condition<? super T>> conditions)
        {
            super(conditions);
        }

        public boolean evaluate(T t)
        {
            for (Condition<T> c : conditions) {
                if (!c.evaluate(t)) return false;
            }

            return true;
        }
    }

    //many other classes
    {
        Condition<Integer> conditions = new AndCondition<Integer>();

        conditions.add(new Condition<Integer>() {
            public boolean evaluate(Integer i)
            {
               return i > 0;
            }
        });

        conditions.add(new Condition<Integer>() {
            public boolean evaluate(Integer i)
            {
               return i % 3 == 0;
            }
        });

        conditions.evaluate(6);
    }

    This took me a couple minutes to type out and I'd never need to do it again. It seems to me the OO is a perfectly fine too for this kind of thing,
  76. Re: question[ Go to top ]

    It's also more verbose than the more natural procedural solution it replaces. Would you really write all that the first time you found the need for the "evaluate" mapping function?
    No. But this topic is not about that. If you like you can read the posts that lead to mine.

    It is about that. The question is, the first time (and quite possibly only time) you need to do that particular mapping function, how do you do it? Do you create a new interface and implementation and do it the OO way? Do you do it the procedural way? Or the functional way? We all know what you can do in one language you can do in another - the point is, which way would you rather do it?
  77. Re: question[ Go to top ]

    It's also more verbose than the more natural procedural solution it replaces. Would you really write all that the first time you found the need for the "evaluate" mapping function?
    No. But this topic is not about that. If you like you can read the posts that lead to mine.
    It is about that.

    No. It's about using functional paradigms in a language that does not support them natively. It's not about pOO vs. procedural styles.
    The question is, the first time (and quite possibly only time) you need to do that particular mapping function, how do you do it? Do you create a new interface and implementation and do it the OO way? Do you do it the procedural way? Or the functional way? We all know what you can do in one language you can do in another - the point is, which way would you rather do it?

    You seem to be missing the fact that my code was a complete soltuion while the functional solution I was responding to required an import of a library that did the works. The point was if you are going to supply a library to do these things in Java, why would you do it using reflection instead of using OO?
  78. Re: question[ Go to top ]

    You seem to be missing the fact that my code was a complete soltuion while the functional solution I was responding to required an import of a library that did the works. The point was if you are going to supply a library to do these things in Java, why would you do it using reflection instead of using OO?

    Because the library using reflection is already written and adding third-party jars to my project is a very simple thing to do. The OO version doesn't seem to be written, nor could it be, I think, because every interface you might come up with would only handle what it handles. With reflection, I have the dynamicism to do whatever I happen to want to do on the fly.

    Though I agree with your point about the value of static typing and being able to find references using my IDE. I simply could not program anything sizable in python or Ruby for that very reason, but I do think there's a 90-10 rule where about 10% of the time, it's more practical to have access to a fully dynamic solution.
  79. Re: question[ Go to top ]

    You seem to be missing the fact that my code was a complete soltuion while the functional solution I was responding to required an import of a library that did the works. The point was if you are going to supply a library to do these things in Java, why would you do it using reflection instead of using OO?
    Because the library using reflection is already written and adding third-party jars to my project is a very simple thing to do.

    That really neither here nor there because I was asking why this library was written using reflection. If it had been written using OO it would already be written in OO.
    The OO version doesn't seem to be written, nor could it be, I think, because every interface you might come up with would only handle what it handles. With reflection, I have the dynamicism to do whatever I happen to want to do on the fly.

    You have to write code that accepts these 'Function pointers' do you not? I don't see how that's really different from providing an interface instead.
    Though I agree with your point about the value of static typing and being able to find references using my IDE. I simply could not program anything sizable in python or Ruby for that very reason, but I do think there's a 90-10 rule where about 10% of the time, it's more practical to have access to a fully dynamic solution.

    One thing that a senior member of my department mentioned was using dynamic languages inside Java code. We realy already do this with XSLT. I think there are Ruby interpreters in Java, for example. So you can build the 'firm' parts of the application or API in Java and then use a dynamic language to do the more flexible portions. It's not really a new idea, like I said, many people (including myself) do this now with XSLT.
  80. Re: question[ Go to top ]

    You have to write code that accepts these 'Function pointers' do you not? I don't see how that's really different from providing an interface instead.

    Usually, the methods already exist and you just want to refer to them dynamically. Rarely do I end up writing a new method just to empower a function pointer.
    One thing that a senior member of my department mentioned was using dynamic languages inside Java code. We realy already do this with XSLT. I think there are Ruby interpreters in Java, for example. So you can build the 'firm' parts of the application or API in Java and then use a dynamic language to do the more flexible portions. It's not really a new idea, like I said, many people (including myself) do this now with XSLT.

    As someone else pointed out, it's clumsy as hell embedding these other languages. You're not really embedding them, after all - you write a new file with some scripting and then load it using some java mechanism, and tracking down errors because a problem as you usually don't get a nice stack trace. With the reflection API, you do still get a decent stack trace.
  81. Re: question[ Go to top ]

    You have to write code that accepts these 'Function pointers' do you not? I don't see how that's really different from providing an interface instead.
    Usually, the methods already exist and you just want to refer to them dynamically. Rarely do I end up writing a new method just to empower a function pointer.

    I don't see how that's possible if you are importing a new library to do this in Java. Clarivoyant code?
    One thing that a senior member of my department mentioned was using dynamic languages inside Java code. We realy already do this with XSLT. I think there are Ruby interpreters in Java, for example. So you can build the 'firm' parts of the application or API in Java and then use a dynamic language to do the more flexible portions. It's not really a new idea, like I said, many people (including myself) do this now with XSLT.
    As someone else pointed out, it's clumsy as hell embedding these other languages.

    Clumsy? That implies to me that the dynamic language is clumsy. Running an interpreter in Java isn't fundamentally different that running an interpreter in any other context.
    You're not really embedding them, after all - you write a new file with some scripting and then load it using some java mechanism, and tracking down errors because a problem as you usually don't get a nice stack trace. With the reflection API, you do still get a decent stack trace.

    Are you suggesting that you would use this library to replace XSLT in Java? That sounds pretty ridiculous.
  82. Re: question[ Go to top ]

    You have to write code that accepts these 'Function pointers' do you not? I don't see how that's really different from providing an interface instead.
    Usually, the methods already exist and you just want to refer to them dynamically. Rarely do I end up writing a new method just to empower a function pointer.
    I don't see how that's possible if you are importing a new library to do this in Java. Clarivoyant code?

    Well, as Mike mentioned, simply by using reflection. Then you can refer to your already existing methods without defining or implementing any particular interfaces, and the library does not need to be "clairvoyant". In fact, that's the idea - having something that works without having to try to foresee every possible scenario.
  83. Re: question[ Go to top ]

    You have to write code that accepts these 'Function pointers' do you not? I don't see how that's really different from providing an interface instead.
    Usually, the methods already exist and you just want to refer to them dynamically. Rarely do I end up writing a new method just to empower a function pointer.
    I don't see how that's possible if you are importing a new library to do this in Java. Clarivoyant code?
    Well, as Mike mentioned, simply by using reflection. Then you can refer to your already existing methods without defining or implementing any particular interfaces, and the library does not need to be "clairvoyant". In fact, that's the idea - having something that works without having to try to foresee every possible scenario.

    Really? Show me how you pass the 'function pointer' to a pre-existing method such that that pre-existing method evaluates the function and uses the result.
  84. Re: question[ Go to top ]

    You have to write code that accepts these 'Function pointers' do you not? I don't see how that's really different from providing an interface instead.
    Usually, the methods already exist and you just want to refer to them dynamically. Rarely do I end up writing a new method just to empower a function pointer.
    I don't see how that's possible if you are importing a new library to do this in Java. Clarivoyant code?
    Well, as Mike mentioned, simply by using reflection. Then you can refer to your already existing methods without defining or implementing any particular interfaces, and the library does not need to be "clairvoyant". In fact, that's the idea - having something that works without having to try to foresee every possible scenario.
    Really? Show me how you pass the 'function pointer' to a pre-existing method such that that pre-existing method evaluates the function and uses the result.

    James,

    I think we have a misunderstanding. It's probably my fault for jumping in the middle of the discussion.

    You are saying that the pre-existing method must accept a function pointer, use it, and evaluate the result.

    I'm saying that if you want to create a function object that refers to an existing method, and use it for some purpose, such as mapping, filtering, etc., you do not need to modify the original method, make it implement some interface, etc. You can just create a Function object that targets the method by name. This is where reflection is used to find the method. Then, you can use the Function object as you wish.

    I apologize if this is not what you were talking about.

    Best regards-
    Frederic
  85. Re: question[ Go to top ]

    You have to write code that accepts these 'Function pointers' do you not? I don't see how that's really different from providing an interface instead.
    Usually, the methods already exist and you just want to refer to them dynamically. Rarely do I end up writing a new method just to empower a function pointer.
    I don't see how that's possible if you are importing a new library to do this in Java. Clarivoyant code?
    Well, as Mike mentioned, simply by using reflection. Then you can refer to your already existing methods without defining or implementing any particular interfaces, and the library does not need to be "clairvoyant". In fact, that's the idea - having something that works without having to try to foresee every possible scenario.
    Really? Show me how you pass the 'function pointer' to a pre-existing method such that that pre-existing method evaluates the function and uses the result.
    James,I think we have a misunderstanding. It's probably my fault for jumping in the middle of the discussion.You are saying that the pre-existing method must accept a function pointer, use it, and evaluate the result.I'm saying that if you want to create a function object that refers to an existing method, and use it for some purpose, such as mapping, filtering, etc., you do not need to modify the original method, make it implement some interface, etc.

    Mike wrote:
    The OO version doesn't seem to be written, nor could it be, I think, because every interface you might come up with would only handle what it handles. With reflection, I have the dynamicism to do whatever I happen to want to do on the fly.

    The point I am making is that your map, filter, etc. methods that take your Functions.filter method didn't write itself, nor is it part the standard JDK. In order to use the Function class, you must write code. Just like when one wants to create a filter method that takes an interface. Moreover, if you had written this library to us interfaces instead of reflection, I wouldn't need to write an interface to use it, it would be provided.

    In other words, "because the reflective library exists" is not a valid answer to the question "why was the library written with reflection?"
  86. Re: question[ Go to top ]

    The point I am making is that your map, filter, etc. methods that take your Functions.filter method didn't write itself, nor is it part the standard JDK. In order to use the Function class, you must write code. Just like when one wants to create a filter method that takes an interface. Moreover, if you had written this library to us interfaces instead of reflection, I wouldn't need to write an interface to use it, it would be provided.

    Yes, but you, as a client user of the library, would still have to wrap your existing method in an implementation of that interface in order to use map, filter, etc. With reflection, you just create an object that refers to that method.
    In other words, "because the reflective library exists" is not a valid answer to the question "why was the library written with reflection?"

    I agree. Instead, the valid answer is that I prefer to have a library that uses reflection in order to be generic, rather than have one with interfaces which not only requires a different interface for each type of scenario (and if I need a scenario that you didn't think of, I'm out of luck or I have to write my own), but also requires me to wrap my existing methods to implement those interfaces.

    I'm all for OO, interfaces, inheritance, polymorphism, etc., but in certain particular cases I find it ill-suited and too verbose. So we just have different preferences; I won't try to convince you to agree to mine, don't try to convince me to agree to yours. In certain cases I'd rather write 2 lines of code that use a functional style of programming. If you'd rather write 15 lines of code instead because it's more important that they remain OO, I can respect that.
  87. Re: question[ Go to top ]

    The point I am making is that your map, filter, etc. methods that take your Functions.filter method didn't write itself, nor is it part the standard JDK. In order to use the Function class, you must write code. Just like when one wants to create a filter method that takes an interface. Moreover, if you had written this library to us interfaces instead of reflection, I wouldn't need to write an interface to use it, it would be provided.
    Yes, but you, as a client user of the library, would still have to wrap your existing method in an implementation of that interface in order to use map, filter, etc. With reflection, you just create an object that refers to that method.

    All you need to do is declare an instance of the interface and fill in the method implementation as I have already shown. I don't see anything fundamentally different between this and doing it with reflection except that the interface is supported by the language.
    In other words, "because the reflective library exists" is not a valid answer to the question "why was the library written with reflection?"
    I agree. Instead, the valid answer is that I prefer to have a library that uses reflection in order to be generic, rather than have one with interfaces which not only requires a different interface for each type of scenario
    That's false. You don't need a different interface for every scenario as demostrated by the accept or condition interfaces above. You need one for every distinct return type and input set. Really you should provide one for each meaningful distinction.

    The othe thing about this that is misleading is that it implies that I can pass any method to any method that takes one of your Function instances. This is not the case. You still have distinct interfaces, they just aren't declared. I don't see this as an advantage.
    (and if I need a scenario that you didn't think of, I'm out of luck or I have to write my own), but also requires me to wrap my existing methods to implement those interfaces.

    Writing a simple interface is not hard. This is why your argument is not convincing.

    You still have to wrap them in your Function instances anyway.
    I'm all for OO, interfaces, inheritance, polymorphism, etc., but in certain particular cases I find it ill-suited and too verbose. So we just have different preferences; I won't try to convince you to agree to mine, don't try to convince me to agree to yours. In certain cases I'd rather write 2 lines of code that use a functional style of programming. If you'd rather write 15 lines of code instead because it's more important that they remain OO, I can respect that.

    Saving a few lines of code has never been a priority. It's definitely not worth the loss of self-documentation and automated code analysis/refactoring.

    I don't understand why people will use Java but never actually use it the way it's intended. If you want to use a function language use a functional language.

    This library is an improved way to do reflection, no doubt. But I don't want reflection.
  88. Re: question[ Go to top ]

    I don't understand why people will use Java but never actually use it the way it's intended. If you want to use a function language use a functional language.

    I've already mentioned that I'm still all for OO and that most of my Java code is OO. I just like having the option of using a little bit of FP once in a while, in my Java code. That's all. I'm not looking to drop OO completely and switch to an FP language.
    This library is an improved way to do reflection, no doubt. But I don't want reflection.

    That's your right, absolutely. You see a project. You don't want to use it. So don't use it, and move on. No problem.

    Let's agree to disagree. :)

    Frederic
  89. Re: question[ Go to top ]

    That's false. You don't need a different interface for every scenario as demostrated by the accept or condition interfaces above. You need one for every distinct return type and input set. Really you should provide one for each meaningful distinction.

    I think you are coming at this from the opposite direction as me. You see the "map" and "filter" methods and seem to think they are nothing special and aren't much of an argument for using function pointers. I agree. It is the function pointers themselves that are interesting, and for the things I do with them, no "accept" or "condition" interfaces suffice. I'll give you an example.

    In JMeter, I made a tablemodel class that makes rows out of objects. Any type of object. For the class to answer the question "what's in this column?", it uses a function pointer. For the class to set a value in a column, it uses another function pointer. By creating the class with these function pointers, it can serve as model for nearly any type of custom object, and adding or getting the data from the model is as easy as working with a Collection. The methods needed to get and write data already exists on the object, so no further work is necessary.

    I'm not sure I could have done this in a purely OO style without needing the objects to implement some interface or needing a lot of anonymous inner classes. Both such solutions would have been far less elegant, IMO.
  90. JGA has a similar class[ Go to top ]

    ...In JMeter, I made a tablemodel class that makes rows out of objects. Any type of object. For the class to answer the question "what's in this column?", it uses a function pointer. For the class to set a value in a column, it uses another function pointer. By creating the class with these function pointers, it can serve as model for nearly any type of custom object, and adding or getting the data from the model is as easy as working with a Collection. The methods needed to get and write data already exists on the object, so no further work is necessary. I'm not sure I could have done this in a purely OO style without needing the objects to implement some interface or needing a lot of anonymous inner classes. Both such solutions would have been far less elegant, IMO.

    JGA has a similar class -- GenericTableModel. What works out particularly nicely is that using richer set of functors allows your columns to include computations that are not necessarily limited to those provided by the class that makes up your rows.
  91. JGA has a similar class[ Go to top ]

    I'll have to look at JGA, it sounds good, though I did make my own function class to be maximally convenient to use, so I'll be loathe to give it up :-)
  92. Re: question[ Go to top ]

    In JMeter, I made a tablemodel class that makes rows out of objects. Any type of object. For the class to answer the question "what's in this column?", it uses a function pointer. For the class to set a value in a column, it uses another function pointer. By creating the class with these function pointers, it can serve as model for nearly any type of custom object, and adding or getting the data from the model is as easy as working with a Collection.

    If I understand your solution correctly, you are passing two function pointers to the TableModel when you create the TableModel column, right? The table model then calls these methods against the Object in the column to do gets and sets.

    Let me be clear, passing a language supported function pointer to the method is the best solution IMO. But that doesn't exist in Java. Here's an OO solution:

    interface GetAndSet // bad name, I know
    {
        Object getValue(Object tableElement);

        void setValue(Object tableElement, Object value);
    }

    Then lets say you have a Column class:

    Column
    {
       //...

       Column(GetAndSet gands)
       {
           //...
    }

    //...
    {
        new Column(new GetAndSet(){
            Object getValue(Object tableElement)
            {
                return ((StringBuffer) tableElement).toString();
            }

            void setValue(Object tableElement, Object value)
            {
                ((StringBuffer) tableElement).clear();
                ((StringBuffer) tableElement).append(value);
            }
        });
    }

    With Generics, this becomes:

    interface GetAndSet<T> // bad name, I know
    {
        Object getValue(T tableElement);

        void setValue(T tableElement, Object value);
    }

    Then lets say you have a Column class:

    Column<T>
    {
       //...

       Column(GetAndSet<T> gands)
       {
           //...
    }

    //...
    {
        new Column<StringBuffer>(new GetAndSet<StringBuffer>(){
            Object getValue(StringBuffer tableElement)
            {
                return tableElement.toString();
            }

            void setValue(StringBuffer tableElement, Object value)
            {
                tableElement.clear();
                tableElement.append(value);
            }
        });
    }

    The point isn't that your solution is bad (it isn't) it's just that it seems that a lot of these arguments are assuming a false premise: that there is no elegant OO solution. I feel that I can learn a lot in this discussion but if people making their arguments from false premises, I will keep pointing them out.
  93. Comments on the data model[ Go to top ]

    James:

    I'd really like to get you to take a look at JGA and tell me what you think, because I think it demonstrates a lot of the points you're trying to make. For example, the GenericTableModel has basically the same structure you've sketched out here, but fully fleshed out.

    It's possible to use JGA functors as a base for extension via anonymous classes, and it's possible to use the reflection functors in JGA in much the same way that Frederic has demonstrated in FunctionalJ. The basis of JGA, though, is a set of primitive functor objects that can be freely mixed and matched to build up composite objects that represent java expressions. What's different in JGA from Mango, Apache Commons Functor, JGL, STL, etc., is that JGA supports methods much like Frederic's for combining the various primitives, and an expression language parser for things that are too complicated for event that.

    Dave
  94. Re: question[ Go to top ]

    The point isn't that your solution is bad (it isn't) it's just that it seems that a lot of these arguments are assuming a false premise: that there is no elegant OO solution. I feel that I can learn a lot in this discussion but if people making their arguments from false premises, I will keep pointing them out.

    You might have missed my last line of my post where I specifically mention my desire to avoid writing lots of anonymous inner classes. My table model takes two collections of function pointers, not just one for a setter and one for a getter, so that would mean writing a lot of those anonymous inners - yech.
  95. Re: question[ Go to top ]

    The point isn't that your solution is bad (it isn't) it's just that it seems that a lot of these arguments are assuming a false premise: that there is no elegant OO solution. I feel that I can learn a lot in this discussion but if people making their arguments from false premises, I will keep pointing them out.
    You might have missed my last line of my post where I specifically mention my desire to avoid writing lots of anonymous inner classes. My table model takes two collections of function pointers, not just one for a setter and one for a getter, so that would mean writing a lot of those anonymous inners - yech.

    OK but to say that there is no elegant OO way to do it isn't really correct. I mean 'elegant' is a subjective term but creating an anonymous instance isn't fundamentally different from creating a Function object with reflection.
  96. Re: question[ Go to top ]

    I mean 'elegant' is a subjective term but creating an anonymous instance isn't fundamentally different from creating a Function object with reflection.

    I suppose I could have said "requires 10 times more code", but that wouldn't have been as elegant.
  97. Re: question[ Go to top ]

    I mean 'elegant' is a subjective term but creating an anonymous instance isn't fundamentally different from creating a Function object with reflection.
    I suppose I could have said "requires 10 times more code", but that wouldn't have been as elegant.

    Elegant and short are orthogonal concepts.
  98. Re: question[ Go to top ]

    Really? Show me how you pass the 'function pointer' to a pre-existing method such that that pre-existing method evaluates the function and uses the result.

    Adapter, my friend.

    This is what I did in "JFunctional":

    Pre-existent code:

    public interface Map{
      Object map(Object obj);
    }
    public SomeClass{
      public obj someAlgorithm(Map m, Object obj){
        return m.map(obj);
      }
    }



    Code that passes Function to pre-existent code:

    Function someFunction = ...;
    SomeClass someObj = ...;
    someObj.someAlgorithm(
      (Map)Fun.nofun(Map.class, someFunction), obj);



    One can manually create the adapter using anonymous class as well.
  99. Re: question[ Go to top ]

    Really? Show me how you pass the 'function pointer' to a pre-existing method such that that pre-existing method evaluates the function and uses the result.
    Adapter, my friend.

    I don't think that really addresses the point. The pre-existing callee isn't evaluating the function. It doesn't accomplish anything we can't do without the functor.
  100. Re: question[ Go to top ]

    The pre-existing callee isn't evaluating the function.
    It is. Indirectly.
    It doesn't accomplish anything we can't do without the functor.
    Yeh. Nothing in the functor lib that we literally can't do. It's just a different paradigm.
  101. Re: question[ Go to top ]

    Let's talk about a trickier problem: pattern-match.

    In Haskell, we typically compare two binary trees like this:

    data Tree = Leaf Int | BinNode Tree Tree
    compare (Leaf a) (Leaf b)
      | a < b = -1
      | a > b = 1
      | otherwise = 0
    compare(Leaf _) (BinNode _ _) = -1
    compare(BinNode _ _) (Leaf _) = 1
    compare(BinNode l1 r1) (BinNode l2 r2) = let x = compare l1 l2 in
      if x == 0 then compare l2 r2 else x
    compare _ _ = raise "no match"


    Think about how you can implement it in Java:
    int compare(Tree t1, Tree t2);

    Like this?

    compare(Tree t1, Tree t2){
      if(t1 instanceof Leaf && t2 instanceof Leaf){
        final Leaf l1 = (Leaf)t1;
        final Leaf l2 = (Leaf)t2;
        final int x = l1.getValue() - l2.getValue();
        if(x<0)return -1;
        else if(x>0)return 1;
        else return 0;
      }
      else if(t1 instanceof Leaf && t2 instanceof BinNode){
        return -1;
      }
      else if(t1 instanceof BinNode && t2 instanceof Leaf){
        return 1;
      }
      else if(t1 instanceof BinNode && t2 instanceof BinNode){
        final BinNode l1 = (BinNode)t1;
        final BinNode l2 = (BinNode)t2;
        final int x = compare(l1.getLeft(), l2.getLeft());
        if(x==0) return compare(l1.getRight(), l2.getRight());
        else return x;
      }
      else{throw new IllegalStateException("sorry no match");}
    }

    Yuk!


    It is easy in the functional library:

      public static final class TreeCompare{
        public int compare(Leaf a, Leaf b){
          final int r = a.getValue() - b.getValue();
          if(r<0) return -1;
          else if(r>0) return 1;
          else return 0;
        }
        public int compare(BinNode a, BinNode b){
          final int lr = compareTree(a.getLeft(), b.getLeft());
          if(lr == 0) return compareTree(a.getRight(), b.getRight());
          else return lr;
        }
        public int compare(Leaf a, BinNode b){
          return -1;
        }
        public int compare(BinNode a, Leaf b){
          return 1;
        }
        public int compare(Tree a, Tree b){
          throw new IllegalStateException("no pattern");
        }
      }
      private static Function comp = Fun.fun(new TreeCompare(), "compare");
      private static int compareTree(Tree a, Tree b){
        final Function result = comp.f(a,b);
        assertTrue(result.isValue());
        return ((Integer)result.getValue()).intValue();
      }
  102. Re: question[ Go to top ]

    Let's talk about a trickier problem: pattern-match.In Haskell, we typically compare two binary trees like this:... Think about how you can implement it in Java:...

    I don't know if you actually think this is how it would be done in Java or if you are purposely posting bad Java code to make the functional code look better.

    class Tree implements Comparable
    {
        public static int compare(Tree t1, Tree t2)
        {
            return t1.compareTo(t2);
        }

        abstract int compareTo(Object o);
    }

    class Leaf extends Tree
    {
        int value;

        int compareTo(Object o)
        {
            Tree tree = (Tree) o;
            if (o instanceof Leaf) return compareTo((Leaf) o);
            else if (o instanceof BinNode) return -1;
            else throw new RuntimeException();
        }

        int compareTo(Leaf other)
        {
            return value - other.value;
        }
    }

    class BinNode extends Tree
    {
        Tree left;
        Tree right;

        int compareTo(Object o)
        {
            Tree tree = (Tree) o;
            if (o instanceof BinNode) return compareTo((BinNode) o);
            else if (o instanceof Leaf) return 1;
            else throw new RuntimeException();
        }

        int compareTo(BinNode other)
        {
            int compare = left.compareTo(other.left);
            return compare == 0 ? right.compareTo(other.right) : compare;
        }
    }
  103. Re: question[ Go to top ]

    I don't know if you actually think this is how it would be done in Java or if you are purposely posting bad Java code to make the functional code look better.
    Ok, let's see your "good" Java code. :-)

    1. In order to write some comparator code, you opt to change the source code of Leaf and BinNode who have nothing to do with this custom "compare" function.

    2. If tomorrow I want to write a new "compareRightSubTreeFirst" method that consider right subtree more significant than the left tree, what will you do? Introduce a new RightSignificantComparator interface and change the source code of Leaf and BinNode to implement them?

    3. A piece of cohesive "comparison logic" are seperated into several classes.


    Sometimes I have no idea what people consider as "good code". It just differs so dramatically between different brains.
  104. Re: question[ Go to top ]

    I don't know if you actually think this is how it would be done in Java or if you are purposely posting bad Java code to make the functional code look better.
    Ok, let's see your "good" Java code. :-)1. In order to write some comparator code, you opt to change the source code of Leaf and BinNode who have nothing to do with this custom "compare" function.2. If tomorrow I want to write a new "compareRightSubTreeFirst" method that consider right subtree more significant than the left tree, what will you do? Introduce a new RightSignificantComparator interface and change the source code of Leaf and BinNode to implement them?3. A piece of cohesive "comparison logic" are seperated into several classes. Sometimes I have no idea what people consider as "good code". It just differs so dramatically between different brains.

    That's was exactly the concerns I was expressing earlier or trying to with my frenglish :)
  105. Re: question[ Go to top ]

    I don't know if you actually think this is how it would be done in Java or if you are purposely posting bad Java code to make the functional code look better.
    Ok, let's see your "good" Java code. :-)1. In order to write some comparator code, you opt to change the source code of Leaf and BinNode who have nothing to do with this custom "compare" function.2. If tomorrow I want to write a new "compareRightSubTreeFirst" method that consider right subtree more significant than the left tree, what will you do? Introduce a new RightSignificantComparator interface and change the source code of Leaf and BinNode to implement them?3. A piece of cohesive "comparison logic" are seperated into several classes. Sometimes I have no idea what people consider as "good code". It just differs so dramatically between different brains.
    That's was exactly the concerns I was expressing earlier or trying to with my frenglish :)

    Really? I can't understand why someone who appears to use Java would write it. It demonstrates a lack of familiarity with the core libraries.

    This is my problem with a lot of the arguments in this thread. Maybe it's just that the OO approach is foreign to developers who are familiar with functional programming and for this reason they have trouble using OO effectively. I'm not trying to be insulting but think of it this way: if I wrote some really amatuerish functional code and then said: "look how bad this is! You should do it with OO" and then presented a standard OO solution. Would you be likely to accept that argument?

    I have no doubt that functional programming has advantages in solving many problems. I have no doubt that Java could use some features from functional languages. But strawman arguments are not valid. Even if one doesn't realize it's a strawman argument.
  106. Re: question[ Go to top ]

    I don't know if you actually think this is how it would be done in Java or if you are purposely posting bad Java code to make the functional code look better.
    Ok, let's see your "good" Java code. :-)1. In order to write some comparator code, you opt to change the source code of Leaf and BinNode who have nothing to do with this custom "compare" function.2. If tomorrow I want to write a new "compareRightSubTreeFirst" method that consider right subtree more significant than the left tree, what will you do? Introduce a new RightSignificantComparator interface and change the source code of Leaf and BinNode to implement them?3. A piece of cohesive "comparison logic" are seperated into several classes. Sometimes I have no idea what people consider as "good code". It just differs so dramatically between different brains.
    That's was exactly the concerns I was expressing earlier or trying to with my frenglish :)
    Really? I can't understand why someone who appears to use Java would write it. It demonstrates a lack of familiarity with the core libraries.This is my problem with a lot of the arguments in this thread. Maybe it's just that the OO approach is foreign to developers who are familiar with functional programming and for this reason they have trouble using OO effectively. I'm not trying to be insulting but think of it this way: if I wrote some really amatuerish functional code and then said: "look how bad this is! You should do it with OO" and then presented a standard OO solution. Would you be likely to accept that argument?I have no doubt that functional programming has advantages in solving many problems. I have no doubt that Java could use some features from functional languages. But strawman arguments are not valid. Even if one doesn't realize it's a strawman argument.

    It's not the point. Your premise is we should use OO constructs everywhere and some people like me disagree with that. So it's not we don't get OO, I understand your solution, I have implemented comparator and those kind of simple "command" objects in the past and I still do but not in every cases like I was before. I think it is rather an heavy solution sometimes just complexing my code. You prefer consistency across your model fine, static typing OO is perfect for that but like I stated earlier I prefer simplicity sometimes. OO is not just about consistency, Smalltalk is a complety dynamic OO language. Of course you probably know that but it's an old debate here going on, dynamic typing vs static typing. We are not going to resolve this here :)

    Having taken a look at Ruby and SmallTalk, using Spring and Hibernate, I have learned some lessons from their approach.
    In fact, Hibernate and Spring use a lot of reflective programming, you can't check your configuration respect your OO model before running the application. But they are still very good and very simple. In my opinion, a lot of times we overestimated the consistency value wich result among other thing in reducing the simplicity of the code.

    I try to capture the concerns I care in my OO structure so a developper can really catch quickly the design of the app. Of course, my application can broke more easily but Ruby, Python or Smalltalk folk would typically answers they can catch the bugs the compiler would have catched just by using unit testing. I don't want to generalize this to every case but I think it makes sense in the simples cases when you don't need to capture the algorithm since it is used just one time.

    I agree about using anonymous classes instead of reflective programming but I wouldn't create a comparator for a single business rule for instance. If it is repeated lot of times, I will consider creating the class and adding it to my util package.
  107. Re: question[ Go to top ]

    I don't know if you actually think this is how it would be done in Java or if you are purposely posting bad Java code to make the functional code look better.
    Ok, let's see your "good" Java code. :-)1. In order to write some comparator code, you opt to change the source code of Leaf and BinNode who have nothing to do with this custom "compare" function.2. If tomorrow I want to write a new "compareRightSubTreeFirst" method that consider right subtree more significant than the left tree, what will you do? Introduce a new RightSignificantComparator interface and change the source code of Leaf and BinNode to implement them?3. A piece of cohesive "comparison logic" are seperated into several classes. Sometimes I have no idea what people consider as "good code". It just differs so dramatically between different brains.
    That's was exactly the concerns I was expressing earlier or trying to with my frenglish :)
    Really? I can't understand why someone who appears to use Java would write it. It demonstrates a lack of familiarity with the core libraries.This is my problem with a lot of the arguments in this thread. Maybe it's just that the OO approach is foreign to developers who are familiar with functional programming and for this reason they have trouble using OO effectively. I'm not trying to be insulting but think of it this way: if I wrote some really amatuerish functional code and then said: "look how bad this is! You should do it with OO" and then presented a standard OO solution. Would you be likely to accept that argument?I have no doubt that functional programming has advantages in solving many problems. I have no doubt that Java could use some features from functional languages. But strawman arguments are not valid. Even if one doesn't realize it's a strawman argument.
    It's not the point.

    It's my point. I'm not diagreeing with the premise of most of these arguments. I am disagreeing with the way the argument is being presented. It's like a 'before' picture and an 'after' picture. In the before the person is frowning, hair all messed up. In the after picture the person is smiling with makeup and a nice new haircut.

    Lets compare apples to apples.
  108. Re: question[ Go to top ]

    Here's a better way to do the Comparator in Java BTW:

    class TreeComparator implements Comparator<Tree>
    {
        protected TreeCompare() {}

        public int compare(Tree a, Tree b) {
            return create(a).compareTo(create(b));
        }

        protected TreeCompare create(Tree tree) {
            if (tree instanceof Leaf) return new LeafCompare(tree);
            else if (tree instanceof BinValue) return new BinValueCompare(tree);
            else thrown new RuntimeException();
        }

        protected int compareTo(TreeCompare tree) {
            if (tree instanceof LeafCompare) return compareTo((LeafCompare) tree);
            else if (tree instanceof BinNodeCompare) return compareTo((BinNodeCompare) tree);
            else thrown new RuntimeException();
        }

        protected abstract int compareTo(LeafCompare leafCompare);

        protected abstract int compareTo(BinNodeCompare leafCompare);

        protected class LeafCompare extends TreeCompare {
            Leaf leaf;

            LeafCompare(Tree tree) {
                this.leaf = (Leaf) tree;
            }

            public int compareTo(LeafCompare leafCompare) {
                return leaf.value - leafCompare.leaf.value;
            }

            public int compareTo(BinNodeCompare leafCompare) {
                return -1;
            }
        }

        protected class BinNodeCompare extends TreeCompare {
            BinNode node;

            LeafCompare(Tree tree) {
                this.node = (BinNode) tree;
            }

            public int compareTo(LeafCompare leafCompare) {
                return 1;
            }

            public int compareTo(BinNodeCompare leafCompare) {
                int compare = create(node.left).compareTo(create(leafCompare.node.left));
                return compare == 0
                    ? create(node.right).compareTo(create(leafCompare.node.right))
                    : compare;
            }
        }
    }
  109. Re: question[ Go to top ]

    Here's a better way to do the Comparator in Java BTW:
    snip

    So that's what you call "better"? Forgive me I can't agree.

    You've shown your lack-of-expertise in OO field, James, I can't avoid this impression.

    First, you failed to see an apparent design principle (low coupling, high cohesion) and gave an amateurish OO soltuion. It was really a good example of bad OO design. :-)

    Then, you gave several "Yuk" code that does "instanceof" and downcast everywhere and just claim "this is better".

    You can have your opinion, let's disagree.
  110. Re: question[ Go to top ]

    Here's a better way to do the Comparator in Java BTW:snip
    So that's what you call "better"? Forgive me I can't agree.You've shown your lack-of-expertise in OO field, James, I can't avoid this impression.

    I really don't think you are qualified to make that asseemnt. Sorry. You've outright rejected the main tenet of OO, (that Objects have state and behavior) in favor of a procural approach. Whether you think the proecural approach is better or not, it's not OO.
    First, you failed to see an apparent design principle (low coupling, high cohesion)

    This assesment again is coming from your misunderstanding. The reuse of classes in the way your statments imply is one of the biggest mistakes people make about OO.
    and gave an amateurish OO soltuion.

    Again, I don't think you can make that assesment. The fact that all your are doing is 'throwing my words' back at me is that you are emotional about this discussion. I prefer to debate in a rational manner.
    It was really a good example of bad OO design. :-)

    Putting ':)' after attacks makes them seem very passive aggressive.
    Then, you gave several "Yuk" code that does "instanceof" and downcast everywhere

    Here are other ways to do it. I was attempting to make the code not unsimilar to your original.

    </bockquote> and just claim "this is better". You can have your opinion, let's disagree.
    The orignal code was not only not OO, it was not good procedural code. It was one big method filled with code diarrhea. THe second example I gave was equivalent to yours, just cleaned up such that pieces of the algorithm could be modified without editing the original. Can I suppose you did not pick up on that? The third example is equivalent to the first but doesn't 'couple' the Leaf and BinNode classes, per your 'requirement'.
  111. Re: question[ Go to top ]

    I don't know if you actually think this is how it would be done in Java or if you are purposely posting bad Java code to make the functional code look better.
    Ok, let's see your "good" Java code. :-)1. In order to write some comparator code, you opt to change the source code of Leaf and BinNode who have nothing to do with this custom "compare" function.

    Oh this is a fun game. You give an example, I offer a rewrite and you tell me it doesn't meet your unspecified requirements.

    I assumed that this was the natural order of Trees. It's not a Comparator. A Comparator example is given below.
    2. If tomorrow I want to write a new "compareRightSubTreeFirst" method that consider right subtree more significant than the left tree, what will you do? Introduce a new RightSignificantComparator interface and change the source code of Leaf and BinNode to implement them?

    Write a Comparator. Below.
    3. A piece of cohesive "comparison logic" are seperated into several classes. Sometimes I have no idea what people consider as "good code". It just differs so dramatically between different brains.

    Right. These classes have nothing to do with each other. There's no relationship at all.

    class TreeComparator implements Comparator<Tree>
    {
        public int compare(Tree a, Tree b)
        {
            if (a instanceof Leaf) {
                Leaf leafA = (Leaf) a;

                if (b instanceof Leaf) return compare(leafA, (Leaf) b);
                else if (a instanceof BinNode) return compare(leafA, (BinNode) b);
            } else if (a instanceof BinNode) {
                BinNode nodeA = (BinNode) a;

                if (b instanceof BinNode) return compare(nodeA, (BinNode) b);
                else if (a instanceof Leaf) return -compare(nodeA, (Leaf) b);
            }

            throw new RuntimeException();
        }

        protected int compare(Leaf a, Tree b)
        {
            return -1;
        }

        protected int compare(Leaf a, Leaf b)
        {
            return a.value - b.value;
        }

        protected int compare(BinNode a, BinNode b)
        {
            int compare = compare(a.left, b.left);
            return compare == 0 ? compare(a.right, b.right) : compare;
        }
    }

    class RightFirstTreeComparator extends TreeComparator // your name
    {
        protected int compare(BinNode a, BinNode b)
        {
            int compare = compare(a.right, b.right);
            return compare == 0 ? compare(a.left, b.left) : compare;
        }
    }
  112. Re: question[ Go to top ]

    Oh this is a fun game. You give an example, I offer a rewrite and you tell me it doesn't meet your unspecified requirements.
    You are right if "low coupling", "avoid bad smell" is considered as "unspecified requirement". :-)


    class TreeComparator implements Comparator<Tree>{&nbsp;&nbsp;&nbsp;&nbsp;public int compare(Tree a, Tree b)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (a instanceof Leaf) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Leaf leafA = (Leaf) a;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (b instanceof Leaf) return compare(leafA, (Leaf) b);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (a instanceof BinNode) return compare(leafA, (BinNode) b);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else if (a instanceof BinNode) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinNode nodeA = (BinNode) a;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (b instanceof BinNode) return compare(nodeA, (BinNode) b);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (a instanceof Leaf) return -compare(nodeA, (Leaf) b);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new RuntimeException();&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;protected int compare(Leaf a, Tree b)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;protected int compare(Leaf a, Leaf b)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return a.value - b.value;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;protected int compare(BinNode a, BinNode b)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int compare = compare(a.left, b.left);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return compare == 0 ? compare(a.right, b.right) : compare;&nbsp;&nbsp;&nbsp;&nbsp;}}class RightFirstTreeComparator extends TreeComparator // your name{&nbsp;&nbsp;&nbsp;&nbsp;protected int compare(BinNode a, BinNode b)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int compare = compare(a.right, b.right);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return compare == 0 ? compare(a.left, b.left) : compare;&nbsp;&nbsp;&nbsp;&nbsp;}}

    Oh. I thought you were trying to provide a "better" Java solution than my "purposely bad Java code" can compete with the functional version. Am I wrong? Or, maybe you are claiming that this is _the_ "better version"?
  113. Re: question[ Go to top ]

    Oh. I thought you were trying to provide a "better" Java solution than my "purposely bad Java code" can compete with the functional version. Am I wrong? Or, maybe you are claiming that this is _the_ "better version"?

    Yes. It's better than your code. That you don't see why only demostrates my point.
  114. Re: question[ Go to top ]

    James. Did I mention that your claimed "good" java code introduces coupling between Leaf and BinNode that are otherwise independent of each other? And I for sure didn't say "don't introduce unnecessary coupling", which you may consider as "unspecified requirement".

    But I'm glad to see that you apparently took my advice and your "better" version is going in the right direction. The "compare" algorithm forces no intrusion into Leaf, Tree and BinNode this time.


    It's just that your "instanceof" and downcasts now look the same "Yuk" as my "purposely bad java code".


    And, let me be even tricier. Now there's an algorithm that operates on three Tree objects. Based on BinNode and Leaf, it takes different logic.

    It's like:

    int compute(Leaf a, Leaf b, Leaf c){...}
    int compute(BinNode a, BinNode b, BinNode c){...}
    int compute(Leaf a, Leaf b, Tree c){...}
    int compute(BinNode a, Tree b, BinNode c){...}
    int compute(Leaf a, Tree b, Leaf c){...}
    int compute(BinNode a, BinNode b, Tree c){...}



    Now show us your professional OO code that does it nicely.
  115. Re: question[ Go to top ]

    It's just that your "instanceof" and downcasts now look the same "Yuk" as my "purposely bad java code".

    Yes. The point of your code was lost in the poor execution. It is unfortunate that Java doesn't support double-dispatch.
    And, let me be even tricier. Now there's an algorithm that operates on three Tree objects. Based on BinNode and Leaf, it takes different logic.It's like:int compute(Leaf a, Leaf b, Leaf c){...}int compute(BinNode a, BinNode b, BinNode c){...}int compute(Leaf a, Leaf b, Tree c){...}int compute(BinNode a, Tree b, BinNode c){...}int compute(Leaf a, Tree b, Leaf c){...}int compute(BinNode a, BinNode b, Tree c){...}Now show us your professional OO code that does it nicely.

    If you demonstrate the expected behavior. You can even do it in a functional style. I probably should do some work now. I agree that Java doesn't handle this kind of situation, though I think the example is contrived. I think that's a weird way to construct a tree. Normally all nodes have values in my experience. In any event the problem isn't with OO, it's with Java. OO languages can support double dispatch. The only reasons I can think of for why Java doesn't to decrease the language complexity and to improve runtime performance.
  116. Re: question[ Go to top ]

    James. Did I mention that your claimed "good" java code introduces coupling between Leaf and BinNode that are otherwise independent of each other?

    BTW they are not independent of each other. Draw a class diagram of the Tree classes.
  117. Re: question[ Go to top ]

    James. Did I mention that your claimed "good" java code introduces coupling between Leaf and BinNode that are otherwise independent of each other?

    I was thinking about this more. This is where your understanding of OO is failing you.

    The concept of an Object in OO is that it carries state and behavior. Different behavior implies a different class.

    The point is that the 'problem' you see is resulting from the rejection of this concept. I'm not saying that the OO way is better just that you can't claim the OO way fails if you are unwilling to embrace it's paradigm.

    It's kind of like saying that planes don't fly because you think pulling back on the stick should cause the plane to go down.
  118. Re: question[ Go to top ]

      public static final class TreeCompare{
        public int compare(Leaf a, Leaf b){
          final int r = a.getValue() - b.getValue();
          if(r<0) return -1;
          else if(r>0) return 1;
          else return 0;
        }
        public int compare(BinNode a, BinNode b){
          final int lr = compareTree(a.getLeft(), b.getLeft());
          if(lr == 0) return compareTree(a.getRight(), b.getRight());
          else return lr;
        }
        public int compare(Leaf a, BinNode b){
          return -1;
        }
        public int compare(BinNode a, Leaf b){
          return 1;
        }
        public int compare(Tree a, Tree b){
          throw new IllegalStateException("no pattern");
        }
      }
      private static Function comp = Fun.fun(new TreeCompare(), "compare");
      private static int compareTree(Tree a, Tree b){
        final Function result = comp.f(a,b);
        assertTrue(result.isValue());
        return ((Integer)result.getValue()).intValue();
      }

    Maybe I need to explain more.

    First of all, the Tree, BinNode and Leaf hierarchy is not a valid OO structure from what I can tell. There is nothing acheived by declaring a Tree class that (apparently) has no behaviors. Perhaps you would like to show me the Tree type in your design.

    Ignoring that for a moment. What happens to your code if create a new Tree subclass:

    class Node extends Tree
    {
        Node left;
        Node right;
        int value;
    }

    Your compare does not work. It must be modified to work for my new Tree implementation.

    If you define the Tree class as comparable, this is not the case. Any code that tries to compare two trees will work with my new implementation. If someone doesn't have access to modify your compare method, they are stuck. They must use the classes you have defined.

    You say that you don't couple the classes but you do. You've coupled them a a far worse place at a level that should be generic to Trees, you only support specific structues.
  119. Re: question[ Go to top ]

    Again. James. Let's disagree.

    We've shown our solutions and views. There's no point trying to convince each other.

    I wasn't trying to offend you. It was just my impression. Objectively, anybody could be wrong. My impression doesn't officially make you whatever I feel you are.

    You are entitled to call anything good OO design and anybody who disagree as "OO amateur". And I'll give no comment from now on. How's that sound?
  120. Re: question[ Go to top ]

    Again. James. Let's disagree.

    Why? Are you unable to address my points?
    We've shown our solutions and views. There's no point trying to convince each other. I wasn't trying to offend you. It was just my impression. Objectively, anybody could be wrong. My impression doesn't officially make you whatever I feel you are.You are entitled to call anything good OO design and anybody who disagree as "OO amateur". And I'll give no comment from now on. How's that sound?

    If you can explain why my OO solution is bad or point me to a reputable source that describes it as such. I'll consider it. All done so far is lash out at me. 'Yuk' is not a powerful way to describe something.
  121. Re: question[ Go to top ]

    Again. James. Let's disagree.

    Let me explain. I spent this time posting on this thread (which is considerable) because I find that I learn a lot from it. I also hope that others gain something from me too. But this doesn't happen without discussion. Just saying let's agree to disagree is of no value to me.

    The other thing that this implies is that I am discussing this wilth you because I see value in your opinion. I'm sorry if I come off like a hard-on sometimes. I get annoyed at work and it bleeds through my posts.

    You example of Java code wasn't terrible. It just wasn't a good example of the OO way of approaching the issue. Your complaints about how the OO code couples two classes ae valid. Let's talk about that. I think there are ways around it and that this is a downside among other upsides. But say it's not a valid solution. It's a very standard solution that works in practice.

    To steal the normal duck-typing proponent's answer, the reason the coupling isn't a problem is that the need decouple these types of classes just doesn't come up that often and if it does, there are ways to deal with it.
  122. Re: question[ Go to top ]

    Alright, James. Let's sit back and talk.

    First of all, the multi-dispatch example, represents a piece of ad-hoc algorithm that's cohesive. Any attempt to break this integral algorithm down into seperate modules, or introduce intrusion to the Tree/Leaf/BinNode classes will be labeled "bad practice".

    Secondly, this algorithm works on binary relationships between different subtypes of Tree. None of the individual subtypes should have dependency on this algorithm, but this algorithm will have to depend on the subtypes and somehow manage their relationships. it's unnatural then to try to fit such binary/ternary relationship into an individual LeafXXX class or BinNodeXXX class.


    Just as the Comparator interface in Java. It describes a piece of comparison behavior that doesn't belong to the lhs operand, nor the rhs operand. One should not try to cram such logic into the comparatees, in the name of OO, data+behavior or whatever.

    Now let's look at your solutions.

    The first one commits the crime by cramming un-related logic (or behavior) into the entities. It will look more obvious if we have 10 such algorithms, or if we have none when designing Tree classes, of if we simply don't have ownership of the Tree class source code.


    It also introduces unnecessary coupling between BinNode and Leaf, as you already see.

    Then you gave a better solution by moving this algorithm outside of Tree classes. The latest code tried to utilize OO polymorphism to get the job done in a more "OO fashion".

    Imho, your latest OO code works, but it commits the "OO in order to OO" sin. Code wise, it winds up longer and harder to understand than the straight-forward "if/else if" version. Complexity is intorduced for no good reason. Several classes and subclasses are created just to follow the simple algorithm description. If the algorithm changes, you'll have to change the class relationship. If one more subtype of Tree is introduced, your class diagram will go through a dramatic change. Now if we imagine 10 such algorithms, how many classes are you gonna end up with?

    In contrast, the straight-forward "if/elseif" version has the virtue of easier to understand, easier to change, no class explosion, and ugly. :-)


    The functional pattern match facility helps to eliminate all the ugliness. I'd not claim this as a merit of functional though. In fact it is not. Many dynamically typed language can do this I believe. But, hey, who cares? The code looks nicer anyway.

    Honestly, if I'm really handling such requirement, I'd go with the "if-else if" version first. Ugly as it is, it's simple. The pattern match ability of the functional library is cool, but is an additional library dependency and the runtime reflection overhead worth it? The answer may not be always yes.
  123. Re: question[ Go to top ]

    BTW, if you want the best OO solution for implementing functional programming, implement the visitor pattern. But I do think it's using a hammer to squash a fly (or whatever is the insect in english, I never remember) when you just need to perfom some meaningless treatment on a collection.

    One last thing I would like to mention James is from your posts it's seem like you think the biggest OO strength is the type safety OO give you, that everything will compile well. BTW do you use unit testing? I think it's indeed important but I think capturing the model structure is from far the most important thing. This way new developpers can jump really quick in the code. That's why I am so careful about introducing meaningless abstraction like AndCondition. My Spring and Hibernate experiences have taught me a lesson : before anything else my code has to be simple and meaningful to someone who look at it for the first time. Even if you put your Condition classes in utility packages, your code end up bloated by this rather weird classes. I might be wrong but it is my vision for the moment. I really prefer the anonymous class approach and combining the strength of functionnal programming, OOP and AOP. I have no other argument then that so buy my opinion, keep yours or don't care about my post since you were arguing with Ben, but it looks like we have the same vision for this problem.
  124. Re: question[ Go to top ]

    BTW, if you want the best OO solution for implementing functional programming, implement the visitor pattern.

    That's how you simulate double dispatch in Java, yes.
    One last thing I would like to mention James is from your posts it's seem like you think the biggest OO strength is the type safety OO give you, that everything will compile well.

    What gave you that impression? It's completely wrong. I think that's the least important reason to use static types. The reason I like static typing is that it's self-documenting and makes it easy to determine what dependencies exist in code.
    BTW do you use unit testing? I think it's indeed important but I think capturing the model structure is from far the most important thing. This way new developpers can jump really quick in the code.

    Of course I use unit testing. Who doesn't?
    That's why I am so careful about introducing meaningless abstraction like AndCondition.

    I have never needed such a class in 'real' code. But it isn't meaningless in the context of logical expressions.
    My Spring and Hibernate experiences have taught me a lesson : before anything else my code has to be simple and meaningful to someone who look at it for the first time. Even if you put your Condition classes in utility packages, your code end up bloated by this rather weird classes.

    Kind of like classes that use Functions? (Sorry couldn't resist.) It was an example for this thread only. A response to a implicit challenge if you look back.
    I might be wrong but it is my vision for the moment. I really prefer the anonymous class approach and combining the strength of functionnal programming, OOP and AOP. I have no other argument then that so buy my opinion, keep yours or don't care about my post since you were arguing with Ben, but it looks like we have the same vision for this problem.

    I think there are a lot of improvements that could be made to Java. Loosening the type system would be a huge thing and then we could look at some others. But until that happens, I'm not going to try to twist Java into something it's not. I have to mentor other developers. I can't bring in oddball theories from left field and expect them to understand. If the language doesn't support it, I don't do it.

    The Spring thing is a good example for reflection. I'll conceed that. My only answer to that is that Spring is a framework and is very well thought-out and tested. It's more of an argument for dynamic languages than function programming too.
  125. Re: question[ Go to top ]

    One last thing I would like to mention James is from your posts it's seem like you think the biggest OO strength is the type safety OO give you, that everything will compile well.
    What gave you that impression? It's completely wrong. I think that's the least important reason to use static types. The reason I like static typing is that it's self-documenting and makes it easy to determine what dependencies exist in code.

    More on this. Personally, I think that a lot of arguments against static typing attack this supposed 'key reason' for using static typing primarily because it's the easiest to tear apart. It isn't really the reason most developer who use static typing like static typing.

    An easy demonstration of why this is the case as well as the real benefit of static typing can be demonstrated by the addition of generics to Java.

    Before generics, the often used Collections framework required using casting Objects to a more specific type for most uses of the Collections. This meant that the types were not checked until runtime and the idea that static typing provided some sort of compile time correctness was at least partially flawed, if not totally flawed. Why, because Java program still worked. Java is one of the most popular languages, how could it be that this was the reason for it's success if it didn't really even do that?

    Along comes generics. Now we remove a large majority of the casts that were needed prior to 1.5. But wait, the programs already worked, why do we even need this? You might think that I don't think generics are a valuable addition to the language thing because of the above. You would be wrong. I do think they are a valuable addition (although I have issues with the implementation) because they dramatically improve the expressiveness of the language. For example, if I have a method getUsers that returns a List, I can't tell what that list contains just by looking at the method declaration. It might contain Strings, instances of a User class or some other type that I'll have to dig through the documentation or experiment with the code in order to determine. I'll also have to put casts in my code anytime I want to retrieve items from the List. However, if it returns List<User> I know exactly what's in there. No explicit casts. But mostly, the structure of the program is much easier to understand. Looking at the JavaDocs for a 1.5 API gives me some much more information at a glance than what I could get before.

    The thing about the Java typing system that I don't like is that you have to explicitly implement the interface. This results in the anonymous inner class verboseness. It would be nice if there were an easier and less verbose way to implicitly implement the interface. Kind of the reverse of duck-typing.
  126. Re: question[ Go to top ]

    [snipped various points I agree with]
    The thing about the Java typing system that I don't like is that you have to explicitly implement the interface. This results in the anonymous inner class verboseness. It would be nice if there were an easier and less verbose way to implicitly implement the interface. Kind of the reverse of duck-typing.
    Not sure I follow... care to give more details on what you are thinking?

    --
    Cedric
  127. Re: question[ Go to top ]

    [snipped various points I agree with]
    The thing about the Java typing system that I don't like is that you have to explicitly implement the interface. This results in the anonymous inner class verboseness. It would be nice if there were an easier and less verbose way to implicitly implement the interface. Kind of the reverse of duck-typing.
    Not sure I follow... care to give more details on what you are thinking?-- Cedric

    It's kind of fuzzy and admittedly not carefully considered but I've got a few hand-waving ideas. I don't claim to have invented any of them BTW.

    The first (and core idea) would be that if you pass a type to a method that requires a specific interface, if all the methods required by that interface are there, the compiler will treat the type as if it implements the interface. Not too useful on it's own...

    The next thing would be a syntax change to allow methods behave simlar to classes. 'method' would be a key word (perhaps). Instances of methods would behave like methods do now, but could be referenced. This gives us method pointers. There would be a relationship between methods with the same (or compatible) return types and parameters (this could get really tricky and I haven't considered it too much but the current overloading logic the compiler should work for most of it.) I could then declare a method like this (syntax not crucial):

    List filter(List list, method boolean(Object));

    Then we can create local methods, we can also create mixins from Objects like this:

    interface Foo
    {
        int count();

        boolean validate(Object o);
    }
    //...

    class Whatever
    {
        List<String> strings = new ArrayList<String>();

        method isValid boolean(Object o) {return o instanceof String;}

        void bar()
        {
            callMethodWithFoo(
                {count = list.size; validate = isValid;}
            );
        }
    }

    I'm sure a lot of people wouldn't care for this. I'm not married to the syntax (or the idea, really). I guess my argument for it would be that we keep the information of the type with a much less verbose syntax. The verboseness of the current way of dong things, I think discourages people from using closure like approaches. A lot of Java classes implement interfaces that they have no business implementing. For example, the Map interface returns a keySet. A lot of developers would try to make Map implement Set instead. Another example is how many classes extend JFrame and how many of those implement 5 listener interfaces. Making a syntax specifically for this kind of approach would steer people towards cleaner designs.
  128. Re: question[ Go to top ]

    On the above, while this would change the syntax greatly, I think it could be done in a way that would be completely compatible with the current implementation of Java. the compiler could generate intefaces, classes and casts to do this. So basically, this kind of feature could be done with syntactical sugar and without a fundamental rewrite of Java.
  129. Re: question[ Go to top ]

    It occured to me that this:

    callMethodWithFoo(new Foo(){count = list.size; validate = isValid;});

    is pretty trivial so infering the type isn't that important I guess.
  130. Re: question[ Go to top ]

    Alright, James. Let's sit back and talk.First of all, the multi-dispatch example, represents a piece of ad-hoc algorithm that's cohesive. Any attempt to break this integral algorithm down into seperate modules, or introduce intrusion to the Tree/Leaf/BinNode classes will be labeled "bad practice".

    You aren't giving any reason here. I could call your code bad practice. It doesn't get us anywhere.
    Secondly, this algorithm works on binary relationships between different subtypes of Tree. None of the individual subtypes should have dependency on this algorithm, but this algorithm will have to depend on the subtypes and somehow manage their relationships.

    So the algorithm is coupled to the types themselves.
    it's unnatural then to try to fit such binary/ternary relationship into an individual LeafXXX class or BinNodeXXX class.

    On the contrary, OO principles state that you should do exactly that. Encapsulate the functionality inside a class.
    Just as the Comparator interface in Java. It describes a piece of comparison behavior that doesn't belong to the lhs operand, nor the rhs operand.

    Comparator is the exception, not the rule. Most classes that have valid comparisons implement the Comparable class. Look at the JDK if you don't believe me. Comparators are for situations that are out of the norm or for comparing things that don't have a natural ordering.

    <blockaquote>One should not try to cram such logic into the comparatees, in the name of OO, data+behavior or whatever.
    Again you are just telling me things. What is your reasoning? What evidence do you have to support this?
    Now let's look at your solutions.The first one commits the crime by cramming un-related logic (or behavior) into the entities. It will look more obvious if we have 10 such algorithms, or if we have none when designing Tree classes, of if we simply don't have ownership of the Tree class source code.

    This is where I think you are absolutely wrong. The point of interfaces is that one should not need to know about the concrete implementation to use them. In this case: comapre the trees. Your functional solution violates this. One cannot compare two trees unless one knows how they are built. If there are 10 different tree structures, you need 10 different comparators. With my solution I can create code that compares trees that works regardless of the underlying tree implementation.
    It also introduces unnecessary coupling between BinNode and Leaf, as you already see.

    I find it highly dubious that the BinNode class and Leaf classes are very useful apart from each other. If they are, there's no reason why base implementations can;t be created that are reusable across different solutions while still maintaining encapsulation. I probably wouldn't even make these two classes public. They would be package level classes. Any code that uses the tree should be able to do everything through the Tree interface.
    Then you gave a better solution by moving this algorithm outside of Tree classes. The latest code tried to utilize OO polymorphism to get the job done in a more "OO fashion".Imho, your latest OO code works, but it commits the "OO in order to OO" sin. Code wise, it winds up longer and harder to understand than the straight-forward "if/else if" version.

    The first version is the best, it took me a while to come back to me senses.
    Now if we imagine 10 such algorithms, how many classes are you gonna end up with?In contrast, the straight-forward "if/elseif" version has the virtue of easier to understand, easier to change, no class explosion, and ugly. :-)

    That's the point of OO, you shouldn't need to change the implementation. And with the if else solution, you need a new comparator for every tree structure. My version could have a tertiary tree and callers wouldn't ever need to know.
    The functional pattern match facility helps to eliminate all the ugliness. I'd not claim this as a merit of functional though. In fact it is not. Many dynamically typed language can do this I believe. But, hey, who cares?

    It's not functional. It's merely double-dispatch.
    The code looks nicer anyway.Honestly, if I'm really handling such requirement, I'd go with the "if-else if" version first.

    That's fine if it's a one shot problem but it's not a way to design things for extension.
  131. Re: question[ Go to top ]

    The pre-existing callee isn't evaluating the function.
    It is. Indirectly.

    It is? You mean the functor is evaluated after during the execution of the called method? This is not an arbitrary distinction. As I understand it, lazy execution is an important feature of function passing.
    It doesn't accomplish anything we can't do without the functor.
    Yeh. Nothing in the functor lib that we literally can't do. It's just a different paradigm.

    I mean, there's about this that makes it preferrable over using intefaces. This was the context of the post your replied to.
  132. Re: question[ Go to top ]

    It is? You mean the functor is evaluated after during the execution of the called method? This is not an arbitrary distinction. As I understand it, lazy execution is an important feature of function passing.
    I'm afraid I don't know what you mean now. A Function object, until "call()" is invoked, is a piece of lazily evaluated closure, isn't it?
  133. Re: question[ Go to top ]

    It is? You mean the functor is evaluated after during the execution of the called method? This is not an arbitrary distinction. As I understand it, lazy execution is an important feature of function passing.
    I'm afraid I don't know what you mean now. A Function object, until "call()" is invoked, is a piece of lazily evaluated closure, isn't it?

    Is the functor evaluated before or after the call to the pre-existing code you have wrapped an adaptor around? I don't know how to state it any more clearly.
  134. Re: question[ Go to top ]

    It is? You mean the functor is evaluated after during the execution of the called method? This is not an arbitrary distinction. As I understand it, lazy execution is an important feature of function passing.
    I'm afraid I don't know what you mean now. A Function object, until "call()" is invoked, is a piece of lazily evaluated closure, isn't it?
    Is the functor evaluated before or after the call to the pre-existing code you have wrapped an adaptor around? I don't know how to state it any more clearly.

    When you say "functor is evaluated", what do you mean by that?

    Java is a strict language where every parameter is passed by-value. But Function itself encapsulates a piece of code that will be evaluated by the callee.

    Guess some example will do better job than english here. Would you please?
  135. Are you suggesting it would not be a solution to the issue in the post I was replying to?Can you give an example where it doesn't suffice?

    A-a-and we're back at the Turing-complete argument. Every reasonable language can do more-or-less every solvable problem. The whole reason for existence of many languages is that some are better for solving some classes of problems than other. You can also transform XML with Java, it has the capacity, it just looks clumsy.

    Another question is whether it is meaningful to transfer concepts from other languages, but it really is a matter of personal preference and seems to work for some people. Such is the case that functional approach can be transferred to non-functional languages with limited success and some of us take advantage of that, while also knowing and respecting the OO concepts and patterns which are totally appropriate for different classes of problems.
  136. One real world example I have is having the ability to apply a set of functions against a collection of objects.For instance I had an engine that took in a large list of objects. I needed to queue up and perform many filter, sum, type queries against this list and store the individual results for later use.
    Have you looked at the Strategy Pattern?

    The design I delivered seems close to the Strategy Pattern.

    I basically had an interface (Operation) with a single method (apply(T object)) and a set of abstract classes (SumOperation, SelectOperation, etc).

    I filled a Map with instances of Operation that I wanted to apply against my data set, which is a List of transactions.

    The loop was basically:
    foreach (Transaction t in transactionList) {
      foreach Operation in operationMap.values() {
        o.apply(t);
      }
    }

    Then I could get the individual query results as needed from my map.

    SelectOperation o = operationMap.get("SelectXTransactions");
    List<Transaction> list = o.getResult();

    or

    SumOperation o = operationMap.get("SumByXYZ");
    double sum = o.getResult();

    It worked out great since each Operation instance was a separated out business rule. Performance was fine since I only had to traverse the list once.

    I was interested in this topic because I thought that maybe something like FunctionalJ would have removed the need to come up with my Operation design. My prototype used Groovy and closures, which are nice but I didn't want to heap a whole new language onto my client when I could do it in Java. It was thinking in closures that inspired my design, which as it turns out already had a pattern name.

    The point I think is to learn different ways of programming: SQL, OO, Functional, Script, Regular Expressions, since it will open you to new ideas even if you are stuck using one language.
  137. Hi George

    Sounds like you might like the JoSQL project. It
    allows SELECT-like restriction/projection over java
    objects - similar to your real-world example.

    Have fun.

    - Gary
    ___________________________________________________________
  138. Hi GeorgeSounds like you might like the JoSQL project. Itallows SELECT-like restriction/projection over javaobjects - similar to your real-world example.

    I swear I must have looked at this project since I remember doing Google searches like "query against collection java" etc.

    I may have shied away because of not wanting to bring in something too out of the ordinary to my client. Their development team was still polishing their Java skills so I didn't want to get that far outside of plain java.

    I'll keep it in mind as something to try out soon though. Thanks.
  139. George:

    I think it's a reasonable possibility that you're skimming the longest posts lightly. I thought I'd call to your attention that in my long post to Frederic above, I included examples of how to use jga to address the two problems you posted in Message #196502

    Dave
  140. George:I think it's a reasonable possibility that you're skimming the longest posts lightly. I thought I'd call to your attention that in my long post to Frederic above, I included examples of how to use jga to address the two problems you posted in Message #196502 Dave


    Yes, skimming today - can't read too much at the client site. I also wanted to quickly respond to those who took a stab at helping me to make sure they knew it was appreciated.

    I just read your post and it does give me an idea for how JCA primatives could be built up to create the functions I would have needed. You are correct in that the functions I seek are basically queries (that I named Operations - see my more recent post) against getters that exist on my collection items. Some of the logic in my Operation instances got kind of hairy (lots of ifs, etc) just using java so I'm not sure how easily it would have been to build them up using JCA - though it would be worth a try for academic reasons.

    Well maybe easily isn't the right word. Maybe it would be easy to build them up step by step but I'm not sure how the final code block would look and how hard it would be to maintain - and to teach my junior programmers.

    I'll definatly keep JCA and FunctionalJ bookmarked though - I do find cross-polination of langauge concepts fun and sometimes useful.
  141. A few patterns (reply to Joost)[ Go to top ]

    Hi again Joost,

    I've added a Patterns section to the FunctionalJ web site with a few usage examples.

    I've also added a link to the FunctionalJ forum on SourceForge, which I encourage people to use for more discussion concerning FunctionalJ. Feel free to post questions, suggestions for improvement, comments, etc.

    Thanks for your interest and cooperation!

    Frederic
  142. Looks really promising[ Go to top ]

    Frederic,

    This stuff looks really cool! I'll be really interested when you get a JDK 1.5 genericized version with some type safety.

    Really exciting!
  143. Re: Looks really promising[ Go to top ]

    Jason,

    Thank you for your comment! I really appreciate it. I'll keep you posted on a JDK 1.5 version.

    PS if I may say, congratulations on WebWork :)

    Frederic Daoud
  144. Re: Looks really promising[ Go to top ]

    Frederic, first congrats (been thinking of the same thing once; coming from OCaml background), can you keep me posted as well on the JDK5.0 version (btw: how do you keep one posted from TSS thread)?

    Rgds, Ales
  145. Frederic:

    It seems to me from a cursory look at your site that there's nothing in FunctionalJ that JGA hasn't already been doing for a couple of years, minus trivial naming discrepencies. JGA already supports both generic and pre-generic compilers, as well.

    I'd be curious to know if you were aware of JGA, and if so, what you found to be missing

    Dave Hall
    http://jroller.com/page/dhall
    http://jga.sf.net/
  146. Dave,

    Thank you for your reply. To be honest, I was not aware of JGA, although I did do an extensive search for existing Java libraries for functional programming before starting work on FunctionalJ.

    Having briefly looked over JGA, it seems that it is much more JDK-1.5 ready than FunctionalJ is at this point. However, to answer your question about what I would find to be missing: my main insatisfaction with such a library, which seems to resemble the Apache Commons Functor library, is that each type of algorithm, or scenario in terms of a function, is represented by a specific class. Thus to use the library, you have to find the specific class that meets what you are trying to do.

    I'm interested in discussing with you in an open manner. Could you please demonstrate how to code the following scenarios with JGA? I'll provide the FunctionalJ code. I'd like to determine if perhaps I was wrong in the type of code that needs to be written to obtain those results. Please keep in mind that my first goal was to be compatible with all versions of the JDK, not just 1.5, so assume we are using JDK 1.4. (I've already conceded that for JDK 1.5 I haven't released yet.)

    Let's say you have a List of Strings, and you want a List of those, in uppercase:

    > List originalList = ...; // list of String objects
    > Function f = new InstanceFunction(String.class, "toUpperCase");
    > List allUpperCase = Functions.map(f, originalList);

    Similarily, to call a static method on a list of objects and obtain the results, such as getting the String representation of a list of Objects using String.valueOf():

    > List originalList = ...; // list of any Objects, even nulls
    > Function f = new StaticFunction(String.class, "valueOf");
    > List strings = Functions.map(f, originalList);

    A final example is one where you have an object of SomeClass with some state, and you have a list of objects. You want to call someMethod(Object) with each of those objects in turn, and obtain a list of results:

    > SomeClass object = ...; // object with a state
    > List objects = ...; // list of objects to be passed as a parameter to object.someMethod(Object), each in turn
    > Function f = new InstanceFunction(SomeClass.class, "someMethod", object);
    > List results = Functions.map(f, objects);

    What I'm trying to demonstrate is that here the mapping mechanism can accept just about any type of Function object, as long as there is one parameter missing, which will be each object of the original list, in turn. Thus, this could be:

    - a constructor that accepts one parameter
    - a constructor that accepts N parameters, N-1 of which have been specified
    - a static method that accepts one parameter
    - a static method that accepts N parameters, N-1 of which have been specified
    - an instance method that accepts no parameters
    - an instance method that accepts one parameter, for which the object on which to invoke the method has been specified
    - an instance method that accepts N parameters, for which the object on which to invoke the method and N-1 parameters have been specified.

    The addParameter/addParameters methods are used on the Functon object to obtain a new Function object for which the parameter(s) have been specified (this is partial function application).

    I find that the fact that all of this is achieved without having to use different subclasses for different algorithms/number of parameters/etc. greatly simplifies the library, and allows for refering to constructors and methods of existing Java code without any modifications to that code.

    Dave, I'm of course very interested to hear your thoughts about these issues.

    Thanks,

    Frederic Daoud
  147. Great API[ Go to top ]

    Hey Frederic -

    What if Function was an interface rather than an Abstract class? It seems awkward that all Functions need have a common base class when they're mostly unrelated. Perhaps something like this:
    interface Function<A,B> {
        public B invoke(A subject, Object... args);
    }

    I really like the ideas in FunctionalJ and JGA. In the Glazed Lists project, we apply similar functions dynamically as a List changes, to perform live sorting and filtering in Swing UIs.
  148. Re: Great API[ Go to top ]

    Hi Jesse,
    What if Function was an interface rather than an Abstract class? It seems awkward that all Functions need have a common base class when they're mostly unrelated. Perhaps something like this:interface Function<A,B> {&nbsp;&nbsp;&nbsp;&nbsp;public B invoke(A subject, Object... args);}

    Actually, that's the beauty of it. Let's make something clear right now: you do not need to extend the Function class, nor any of its subclasses, nor do you need to implement any special interfaces! You write your Java methods as usual, each in the class where it belongs. It does not need to be "FunctionalJ-aware". Then, when you want to target a method in order to perform some kind of computation for which functional programming would be useful, you create a Function object that refers to your method.

    Just as in my "toUpperCase" example:
    List originalList = ...; // list of String objects
    Function f = new InstanceFunction(String.class, "toUpperCase");
    List allUpperCase = Functions.map(f, originalList);

    Here the toUpperCase() method of the java.lang.String class is used as a Function, but the original method has not been modified, does not implement a special call() method, etc. This is why I refer to FunctionalJ as being "non-invasive".

    Please let me know if this answers your question satisfactorily (hmm if that's a word..;)
    I really like the ideas in FunctionalJ and JGA. In the Glazed Lists project, we apply similar functions dynamically as a List changes, to perform live sorting and filtering in Swing UIs.

    Thanks for indicating Glazed Lists; the ideas there also seem interesting!

    Frederic
  149. cool![ Go to top ]

    Hi Frederic, cool library, it really appeals to me.

    I've been learning JParsec, a java implementation of the Haskell parser combinator library (Parsec), and I could really get rid of a lot of necessary cruft (like anonymous subclassing in order to simulate currying).

    One question I have is whether there's a best-practice to ensure compile time safety regarding method renaming.

    Thanks,
    Ron
  150. Re: cool![ Go to top ]

    Hi Ron,

    Thanks for your encouragement.

    I did look into JParsec when looking for projects that deal with functional programming in Java, but, like you, I found that it was too code-heavy to achieve the results I was looking for.
    One question I have is whether there's a best-practice to ensure compile time safety regarding method renaming.

    Good question. Indeed, if you use a Function object that refers to a method, and then you change the name of that method, you will not know at compile-time that you must also change the name where you create your Function object. This is because the name of the method is passed as a String to the Function constructor.

    If you think about it, it has to do with the nature of the problem: here we are providing a means for calling a method, the name of which could be determined dynamically at runtime. Thus it is normal that the validity of that method name cannot be ensured at compile time.

    I believe that some IDEs such as Eclipse to provide a way to search Strings in your code to match the name of the method which you are changing during refactoring; of course, a simple grep would also do the trick. This applies to cases where the name of the method is fixed, such as "doSomething". Obviously, if the name of the method is "get" + someVariable + "Value", even a text search won't find it.

    What do you think?

    Thanks for your feedback.

    Frederic
  151. Re: cool![ Go to top ]

    Thanks for taking the time to write that response.
    here we are providing a means for calling a method, the name of which could be determined dynamically at runtime. Thus it is normal that the validity of that method name cannot be ensured at compile time.

    I hear you. I guess my angst here comes from how XYZ.class is a language level feature but not XYZ.main([Ljava/lang/String;)V.method is not.

    What's funny is when you look at the bytecode for XYZ.class, it's just calling Class.forName, reinforcing your point.

    Thanks,
    Ron
  152. Re: cool![ Go to top ]

    I wanted to make a point about performance.

    If I were going to guess between anonymous subclassing and reflective method invocation, I would expect that reflective method invocation (provided the class & method were cached) would win.

    After I profile my parser I may try converting some of the bottlenecks to the functionalj style for comparison, but I bet there will be a marked improvement.
  153. anonymous classes[ Go to top ]

    Only my opinion, but, although I did not like the syntax at first, with time I fell deeply in love with anonymous inner classes. I think they are a wonderful feature of the Java language and at least partially fill the void left by not having function pointers.

    Anyway, looks like a neat idea and will need to take a closer look.

    Don Morgan, Founder
    http://www.DeveloperAdvantage.com
    Audio Training for Software Developers
  154. anonymous classes[ Go to top ]

    Only my opinion, but, although I did not like the syntax at first, with time I fell deeply in love with anonymous inner classes. I think they are a wonderful feature of the Java language and at least partially fill the void left by not having function pointers.Anyway, looks like a neat idea and will need to take a closer look. Don Morgan, Founderhttp://www.DeveloperAdvantage.comAudio Training for Software Developers

    Yeah anonymous inner classes (or just anonymous method) would be a good idea here too instead of using interfaces.
  155. is it so new?[ Go to top ]

    I had published this kind of stuff over a year ago on myjavatools.com - together with an article how to use it, etc.

    Check it out, it has more than just apply() and filter().

    -Vlad Patryshev.
  156. Re: is it so new?[ Go to top ]

    Vlad,

    I had a look, and again, it looks like you have to create a subclass of Function with an apply() method in order to use Java methods in a functional way - something that I'm avoiding in FunctionalJ, to make it easy to use existing methods without any special modifications.

    Note that FunctionalJ also includes more than just mapping and filtering; those were just some examples.

    Frederic
  157. Performance[ Go to top ]

    Frederic,

    Do you have any performance data about your library? I am assuming that you are using Java Reflection that is noticed to be a bottleneck in some cases.

    Regards,

    Alexandre Masson
  158. Re: Performance[ Go to top ]

    Hi Alexandre,

    I do not have any performance data yet, but you are correct to assume that I am using reflection, and that it follows that the performance would not be as good as when using direct method calls.

    I am evaluating some options for improving performance, and also for adding a different way than reflection for creating a Function object, for the situations where performance is key.

    Thanks for your interest,
    Best regards,
    Frederic
  159. I fail to see the benefit here. You can do functional programming per se in Java -- just use anonymous classes as closures and you get a syntax which is almost as clumsy as this reflection wrapping style.

    The main benefit of the functional language is the data-centric approach -- that is why functional languages without algebraic types (or their dynamic analogues) are so rare to come by (in fact there is pretty much functional languages without higher order functions and, God forbid, currying).

    The second benefit of a functional language is it's conciseness, which allows to express a sum of squares of all the elements in a list as
    sumOfSquares = (foldr (+) 0) . map (^2)

    Eventhough all the "functional" features can be defined in Java (and even abstracted in a framework/toolkit, see this for references) I sincerely don't understand the reason to bother with that. You won't get algebraic types and you won't get the conciseness.

    This is especially funny with languages like Scala on the horizon, which runs on JVM and is compatible with the Java classes. Just use it if you want to go functional, while retaining Java compatibility.
  160. Jevgeni,
    I fail to see the benefit here. You can do functional programming per se in Java -- just use anonymous classes as closures and you get a syntax which is almost as clumsy as this reflection wrapping style.

    As I mentioned earlier, FunctionalJ provides a way of using functional programming patterns without having to write special anonymous classes.
    The main benefit of the functional language is...

    I agree with you 100% that functional languages have nice advantages. However, this is not the point. If you read my initial entry, you saw that I mentioned that when you learn a functional programming language such as Haskell, you learn about all of those nice advantages that you mention. However, in my case, and this is probably the case for many other people, using Haskell in the workplace is not an option. Thus my goal is to provide a few of those nice things that come from FP, while continuing to code in Java.
    see this for references)

    This also involves writing subclasses or anonymous classes, which I find too code-heavy.
    I sincerely don't understand the reason to bother with that. You won't get algebraic types and you won't get the conciseness. This is especially funny with languages like Scala on the horizon, which runs on JVM and is compatible with the Java classes. Just use it if you want to go functional, while retaining Java compatibility.

    You are correct; however, one could argue that if you switch to Haskell, you won't get OO and you won't get all the nice web app frameworks that are available and you won't reuse all the Java expertise that is out there and you won't...etc.

    If you're lucky enough to be using a functional programming language in your workplace, with all of its advantages, then of course there is no use for adding FP capabilities to an OO language if you can use "the real thing" instead.

    As for Scala, this involves learning Yet Another Programming Language. I did not want to require that either.

    Frederic
  161. As I mentioned earlier, FunctionalJ provides a way of using functional programming patterns without having to write special anonymous classes.

    My whole point was that functional patterns can not be captured well in Java. I'm not arguing for or against functional languages, neither am I arguing against using functional programming style or "patterns" in Java. In fact I'm a big proponent of functional design style in some particular cases. The point I was making is that there is no point in capturing that in a framework, as it just does not look any better, than just thinking functionally.

    And please do not mention the monstrosity that is Haskell so much -- I programmed enough in it and I never want to see another language without a debugger, a profiler and with inpredictable runtime behaviour. One can capture all these patterns just as well without purity or lazyness, as is done in O'Caml.
    This also involves writing subclasses or anonymous classes, which I find too code-heavy.

    It's almost as verbose as your solution, I don't see the difference from this altitude.
    I sincerely don't understand the reason to bother with that. You won't get algebraic types and you won't get the conciseness. This is especially funny with languages like Scala on the horizon, which runs on JVM and is compatible with the Java classes. Just use it if you want to go functional, while retaining Java compatibility.
    You are correct; however, one could argue that if you switch to Haskell, you won't get OO and you won't get all the nice web app frameworks that are available and you won't reuse all the Java expertise that is out there and you won't...etc. (snip) As for Scala, this involves learning Yet Another Programming Language. I did not want to require that either.Frederic

    All right, first of all I haven't mentioned Haskell once, so why would you imply I'm suggesting to learn it? Secondly Scala supports all of the fancy Web Frameworks, OO patterns and other candy stuff. Lastly Scala has a syntax dangerously near to Java or Groovy and should be relatively simple to learn for a Java programmer.
  162. The point I was making is that there is no point in capturing that in a framework, as it just does not look any better, than just thinking functionally.

    OK, so we disagree here. When I'm thinking functionally, and want to write a block of code that is more of a functional style than a procedural style, I find it much easier and more concise to do so with a library than without.
    All right, first of all I haven't mentioned Haskell once, so why would you imply I'm suggesting to learn it?

    I did not mean to imply that. I'm sorry if it sounded like I did. It just happens that Haskell is the functional programming language from which I learned these FP patterns. You seem to feel strongly against it, and that's fine, I'm not here to debate that. I won't pretend I have enough experience with different functional languages to start contrasting them.
    Lastly Scala has a syntax dangerously near to Java or Groovy and should be relatively simple to learn for a Java programmer.

    OK, but in my case you do not need to learn *any* new language. In that respect, Scala and FunctionalJ can happily co-exist, since both have their pros and cons and the developer can choose which one more closely meets their requirements. Isn't that the point of open source and having different solutions from which to choose? If one solution doesn't suit your needs, move on to a different one..

    Frederic
  163. The point I was making is that there is no point in capturing that in a framework, as it just does not look any better, than just thinking functionally.
    OK, so we disagree here. When I'm thinking functionally, and want to write a block of code that is more of a functional style than a procedural style, I find it much easier and more concise to do so with a library than without.

    All right, let's agree to disagree :) Now if somebody would bring pattern matching into Java I'd be happy. So far XML will just have to do...
  164. All right, let's agree to disagree :)

    I was going to say exactly that, but I was afraid you'd make fun of me..! Hehe. Well, I definitely agree to agree to disagree. :)
    Now if somebody would bring pattern matching into Java I'd be happy. So far XML will just have to do...

    Wow, that was on my wishlist too, but I couldn't come up with anything. If somebody presents a solution to that, I'm sure we'll all be quite impressed!

    Jevgeni, if I may ask, what are your favorite FP languages?

    Thanks and happy coding.
    Frederic
  165. Wow, that was on my wishlist too, but I couldn't come up with anything. If somebody presents a solution to that, I'm sure we'll all be quite impressed!

    JXPath is the best choice so far, though I still find it too clumsy for usage in most cases. We try to do stuff in XML and get the full XSLT to go.
    Jevgeni, if I may ask, what are your favorite FP languages?Thanks and happy coding.Frederic

    Nevah, the secret will go with me to the grave ;) In reality I don't program much in FP, I just have the sad neccesity to get acquinted with them for research needs. So far I'd say that O'Caml was the most practical and Erlang was the sexiest (in its own weird way). Scala also deserves a mention, but more as a JVM-compatible option than thanks to its other features. BTW if you like Haskell you might like Clean even more -- it has more or less Haskell syntax, but has a bonus of not being written by a consorcium of researchers. Haskell itself is a fine researh platform, which for some weird reason is positioned as a general-purpose high level language.
  166. Nevah, the secret will go with me to the grave ;)

    *lol*
    In reality I don't program much in FP, I just have the sad neccesity to get acquinted with them for research needs. So far I'd say that O'Caml was the most practical and Erlang was the sexiest (in its own weird way). Scala also deserves a mention, but more as a JVM-compatible option than thanks to its other features. BTW if you like Haskell you might like Clean even more -- it has more or less Haskell syntax, but has a bonus of not being written by a consorcium of researchers. Haskell itself is a fine researh platform, which for some weird reason is positioned as a general-purpose high level language.

    Very interesting.

    It's funny that you mention Clean, because I actually learned Clean before learning Haskell, and of course I noticed how similar they are. I'm not sure why I continued on with Haskell -- there were more tools, packages, libraries, etc. available? Or was it just higher-profile? To me it seemed more general-purpose, but from what you said, I may have been mistaken or mislead.

    I think I was also miffed that at the time, the Clean IDE was only available for Windows, and not Linux. But let's not go there.. like you said, don't want to start any kind of war :)
  167. Very interesting.It's funny that you mention Clean, because I actually learned Clean before learning Haskell, and of course I noticed how similar they are. I'm not sure why I continued on with Haskell -- there were more tools, packages, libraries, etc. available? Or was it just higher-profile? To me it seemed more general-purpose, but from what you said, I may have been mistaken or mislead.I think I was also miffed that at the time, the Clean IDE was only available for Windows, and not Linux. But let's not go there.. like you said, don't want to start any kind of war :)

    Haskell definitely has a bigger community, it just that it is in the hands of high-profile researchers, which are interested in trying out new things more than in making a stable powerful and simple language. Clean is a by-product of one guy, who has a bit more practical thinking. E.g. uniqueness typing is much more intuitive than monadic IO. Though purity still gets in the way sooner or later :) But yeah, one of it's minuses is that most of the people developing it use Windows, so not much support for other platforms.

    BTW GHC used to compile Haskell to JVM, and I think .NET target is still supported ;)
  168. The point I was making is that there is no point in capturing that in a framework, as it just does not look any better, than just thinking functionally.
    OK, so we disagree here. When I'm thinking functionally, and want to write a block of code that is more of a functional style than a procedural style, I find it much easier and more concise to do so with a library than without.

    What happened to OO? If we want to program in a functional way, why wouldn't we use a functional language. Why use a non-functional OO language to write functional code.

    The other question is why use reflection? It seems completely uneccesary. Again, what happened to OO?
  169. What happened to OO? If we want to program in a functional way, why wouldn't we use a functional language. Why use a non-functional OO language to write functional code.The other question is why use reflection? It seems completely uneccesary. Again, what happened to OO?

    Functional and OO do not exclude each other. They're just different approaches, which are good in different contexts. OO is great for GUI applications, but when you have a lot of algorithmics and data manipulation functional approach fits better (at least for me, God save from starting a functional v/s imperative war here). Therefore XML Schema, XPath and XSLT which basically form together a functional language with algebraic datatypes and pattern matching.

    Sometimes one also wants to apply functional approach where implementation language is not a choice, whereas the argument comes.
  170. What happened to OO? If we want to program in a functional way, why wouldn't we use a functional language. Why use a non-functional OO language to write functional code.The other question is why use reflection? It seems completely uneccesary. Again, what happened to OO?
    Functional and OO do not exclude each other.

    I never said they did. If you take care in reading I made special effort to qualify 'OO' with 'non-functional'.
    They're just different approaches, which are good in different contexts. OO is great for GUI applications, but when you have a lot of algorithmics and data manipulation functional approach fits better (at least for me, God save from starting a functional v/s imperative war here).

    This really has nothing to do with my question. First, the statement "When I'm thinking functionally, and want to write a block of code that is more of a functional style than a procedural style" presents what appears to be a false dilemma: that if it cannot be done functionally, it will have to be done procedurally. This is especially strange in the context of a non-functional OO language.
  171. Jakarta Commons Collections[ Go to top ]

    Good work. You may also want take a look at commons-collections in Apache's Jakarta, too. It comes with transformer, predicate, and closure interface. The corresponding utils classes provide some convinent method to create the objects. You may want to have those in the next version.
  172. Frederic:

    >> Having briefly looked over JGA, it seems that it is much more JDK-1.5 ready than FunctionalJ is
    at this point.

    JGA was implemented with generics in mind from the very beginning, going back to the early access
    generic compilers before the 1.5 beta was available. In those days, the compiler emitted a 1.4
    compatable class file, so I've always supported both generic and non-generic uses. However, being
    designed with generics in mind has costs as well as benefits -- where you can be more flexible with
    the types of arguments, JGA is designed to catch type mismatches as early as possible. That's
    probably more important to the STL-ish approach than it might be in your approach, although I
    suspect that your addParameters method(s) can't catch type mismatches at compile time. In your
    favor, though,(once you are using a 1.5 implementation with varargs) is that you'll have more
    flexibility with respect to the number of arguments you can support than I have.

    You appear to have more support for variable numbers of arguments than I can support, due to
    design limitations in java generics. I've suggested enhancements, but Sun does not seem
    receptive.

    >> However, to answer your question about what I would find to be missing: my main insatisfaction
    with such a library, which seems to resemble the Apache Commons Functor library, is that each type
    of algorithm, or scenario in terms of a function, is represented by a specific class. Thus to use
    the library, you have to find the specific class that meets what you are trying to do.

    That's true, but it's not the limitation that you seem to think. The existing functor
    implementations are all designed to support common operations: relational comparison, simple
    arithmetic, accessing fields and methods via reflection, etc.

    Your first (very trivial) example would be

      Integer a = ...; // some value
      Integer b = ...; // some other value
      BinaryFunctor bf = someCondition ? new Min.Comp() : new Max.Comp();
      Integer result = (Integer) bf.fn(a, b);


    However, if there isn't something that supports your specific operation, JGA makes it fairly easy to
    combine the primitives to support arbitrary operations. However, if you want to stick with a style
    that is reflection heavy, JGA has functors that will support you.

    Where George asked for:

    >> Give me the subset of items in the collection where property X < 50

    ... in JGA, there are a couple of ways to get that. Comparing a property of some object to
    a given threshhold is such a common operation that I felt it useful to implement a single
    class. For some class T with property X, you'd write

      UnaryFunctor propXlt50 = new CompareProperty(T.class, 'X', new Less.Comp(), 50);

    To find examples where property Y == 50, its even easier...
     
      UnaryFunctor propYeq50 = new CompareProperty(T.class, "Y", 50);

    You've seemed to imply that FunctionalJ requires that the user write a method
    'isPropertyXLessThan50()' in some class, somewhere, and call it reflectively.
    For simple operations, I think assembly from primitives is easier, but JGA has
    an alternative that scales up for much more complex operations.

    George's other request was

    >> Give me the sum of property Y times property Z for all items in the collection of type T.

    Assuming that Y and Z are integers, we'd write

      UnaryFunctor propY = new GetProperty(T.class, "Y");
      UnaryFunctor propZ = new GetProperty(T.class, "Z");
      UnaryFunctor multYZ = new Multiplies(Integer.class).compose(propY, propZ);

      List products = new ArrayList();
      Algorithms.transformCopy(collectionOfT, products, multYZ);
      return Algorithms.accumulate(Integer.class, products)

    {{ NOTE: JGA supports all Collection implementations, even those that don't come from Sun,
    so I can't presume that Sun's ArrayList is the best choice for the output list. Therefore,
    JGA requires that the user pass the collection he wishes to populate. However, this could
    be a little simple if JGA's various fooCopy methods returned the output list (rather than
    void), which (combined with static import) would reduce the last three lines to

      return accumulate(Integer.class, transformCopy(collectionOfT, new ArrayList(), addYZ));

     }}

    As it stands, it seems pretty similar in terms of actual code required of the user.

    To your examples:

    >>Let's say you have a List of Strings, and you want a List of those, in uppercase:

      List originalList = ...; // list of String objects
      UnaryFunction f = new InvokeNoArgMethod(String.class, "toUpperCase");
      List allUpperCase = new ArrayList();
      Algorithms.transformCopy(originalList, allUpperCase, f);


    >>Similarily, to call a static method on a list of objects and obtain the results, such as getting
      the String representation of a list of Objects using String.valueOf():

    This may be one where JGA is still a little rough around some edges, but that is in some measure due
    to JGA's trying to catch as much at compile time as possible.

      BinaryFunctor valueOf = new InvokeMethod(String.class, "valueOf", new Class[] { Object.class });
      UnaryFunctor f = valueOf.bind1st(null).compose(new ArrayUnary());
      List allUpperCase = new ArrayList();
      Algorithms.transformCopy(originalList, allUpperCase, f);


    I don't have a functor that is specific to static methods -- InvokeMethod and InvokeNoArgMethod
    both support static and instance methods. Idiomatically, when either is used with static methods,
    we'd simply bind the (first) arg to null. The result is a new functor that takes one less argument
    (much as you've described as 'partial function application').

    You're doing a better job of hiding the array of arguments being passed to the method than I do.
    Part of that is due to my desire to treat reflection as just another primitive -- the InvokeMethod
    functor is declared...

      public class InvokeMethod<T,R> extends BinaryFunctor<T,Object[],R>

     ... which means that the object array is part of the signature. The ArrayUnary functor takes a
    single argument, and returns an array of lenght 1 containing that element, so we can use that to
    convert the unary functor that expects an array into a unary functor that expects a scalar argument.

    However, earlier I alluded to an alternative in JGA that scales to support much more complicated
    expressions. I realized early that assembling compound functors doesn't scale, so I came up
    with an alternative:

      UnaryFunctor valueOf = UnaryFunctor.parse("String.valueOf(x)", Object.class, String.class);

    ... which generates pretty much the same functor that I derived above. For a unary functor,
    you pass the expression (pretty much any Java expression that could appear on the right
    side of an assignment), the type of the argument, and the return type.

    Your last example:

    >> A final example is one where you have an object of SomeClass with some state, and you have a list
       of objects. You want to call someMethod(Object) with each of those objects in turn, and obtain a
       list of results:

      SomeClass object = ...; // object with a state
      List objects = ...; // list of objects to be passed as a parameter to object.someMethod(Object), each in turn
      BinaryFunctor valueOf = new InvokeMethod(SomeClass.class, "someMethod", new Class[] { Object.class });
      UnaryFunctor f = valueOf.bind1st(object).compose(new ArrayUnary());
      List results = new ArrayList();
      Algorithms.transformCopy(objects, results, f);

    or using the alternative,

      BinaryFunctor someMethod = parse("x.someMethod(y)", SomeClass.class, Object.class, Object.class);
      UnaryFunctor f = someMethod.bind1st(object);

    >> What I'm trying to demonstrate is that here the mapping mechanism can accept just about any type of Function object, as long as there is one parameter missing, which will be each object of the original list, in turn. Thus, this could be:

    >> - a constructor that accepts one parameter
    >> - a constructor that accepts N parameters, N-1 of which have been specified
    >> - a static method that accepts one parameter
    >> - a static method that accepts N parameters, N-1 of which have been specified
    >> - an instance method that accepts no parameters
    >> - an instance method that accepts one parameter, for which the object on which to invoke the method has been specified
    >> - an instance method that accepts N parameters, for which the object on which to invoke the method and N-1 parameters have been specified.

    Of this list, JGA can't support the cases where N > 2, at least in the immediate future. I've had
    on my list of goals support for variable length functors, but I've come to the conclusion that it
    isn't possible with functor assembly using generics. However, with the parser that I have in place,
    I think that I can add a vararg functor at the root of the function hierarchy. The trade-off that
    I chose at the beginning, and am very hesitant to change, is sacrificing the compile-time type
    safety that comes with the generics.

    >> The addParameter/addParameters methods are used on the Functon object to obtain a new Function
       object for which the parameter(s) have been specified (this is partial function application).

    For the functions that JGA can support, the bind mechanisms provide essentially the same thing.

    >> I find that the fact that all of this is achieved without having to use different subclasses for
       different algorithms/number of parameters/etc. greatly simplifies the library, and allows for
       refering to constructors and methods of existing Java code without any modifications to that
       code.

    Going the other way, though -- you'll have real problems trying to bring this into Java 1.5.
    Generics won't support variable numbers of arguments the way that you're using them. I've suggested
    an extension to generics that allows for a variable number of generic parameters, which would allow
    for JGA to do variable length functions and retain type-safety. Sun doesn't appear willing to
    pursue the issue, so I may have to, under the research licens. It'd be interesting to see if
    a staticly typed functional language based on Java is possible -- I think it is.

    ======

    There've been a number of implementations in this area, and I think we've all scratched
    that particular itch. I've learned something from all of the libraries that came after
    JGA, and yours is no exception (there's a few things that I'll consider adjusting to
    better support the idioms that you seem to prefer). I've linked to all of the libraries
    that I've found that are playing in the same space (and when I get around to it, I'll
    link to yours as well). That page is http://jga.sf.net/links.shtml
  173. Among the many typos ...

    There've been a number of implementations in this area, and I think we've all scratched that particular itch in interesting and unique ways,
  174. I hate writing long messages without an Edit after publication

    Funny, last night I was complaining to my wife about having only this little text box to work with when posting and not seeing a "preview" of the message before it actually goes live. That would be a feature I think all TSS posters would appreciate.

    Dave, thanks very much for taking the time to reply. I want to first look over your explanations carefully before answering, because you discuss some interesting issues.

    Frederic
  175. I hate writing long messages without an Edit after publication
    Funny, last night I was complaining to my wife about having only this little text box to work with when posting and not seeing a "preview" of the message before it actually goes live. That would be a feature I think all TSS posters would appreciate.Dave, thanks very much for taking the time to reply. I want to first look over your explanations carefully before answering, because you discuss some interesting issues.Frederic

    Between that, the lack of usable threading, and the inability to cleary differentiate between text and code, I'm suprised this site has the level of discussion that it does.

    Dave
  176. I hate writing long messages without an Edit after publication
    Funny, last night I was complaining to my wife about having only this little text box to work with when posting and not seeing a "preview" of the message before it actually goes live. That would be a feature I think all TSS posters would appreciate.Dave, thanks very much for taking the time to reply. I want to first look over your explanations carefully before answering, because you discuss some interesting issues.Frederic

    I taught the same exact thing yesterday. I made a suggestion in the improvements forums about adding an edit button. I suggest you to add your votes!!
  177. Groovy or Jython[ Go to top ]

    No offense but this is like shooting a bird with a nuke, IMHO. Nice as a theoretical exercise, absolutely impractical.

    If you want agile code, for God's sake and love, just embed Groovy or Jython in your Java code and get over it. You will get what FunctionalJ gives and much more, just - in a much more organized and elegant manner.
  178. Groovy or Jython[ Go to top ]

    No offense but this is like shooting a bird with a nuke, IMHO. Nice as a theoretical exercise, absolutely impractical.If you want agile code, for God's sake and love, just embed Groovy or Jython in your Java code and get over it. You will get what FunctionalJ gives and much more, just - in a much more organized and elegant manner.

    My sentiment is similar. Also, Scala is functional and runs on a JVM and can use Java classes natively.
  179. Re: Groovy or Jython[ Go to top ]

    No offense taken. I agree with you that there are other ways of achieving this result, in a more natural way. The problem is that using Groovy or Jython or Scala or XYZ sometimes just isn't an option because of workplace constraints, server constraints, company constraints, available (human) resources, or any other reason. I don't want to debate the validity of those reasons; the fact is that sometimes, even if you disagree, those constraints are there and you can't do anything about them.

    So, for those situations where you have to stick to standard Java (and, in fact, Java < 1.5) and simple JAR files, FunctionalJ can be a nice-to-have.

    Frederic
  180. Groovy or Jython[ Go to top ]

    No offense but this is like shooting a bird with a nuke, IMHO. Nice as a theoretical exercise, absolutely impractical.If you want agile code, for God's sake and love, just embed Groovy or Jython in your Java code and get over it. You will get what FunctionalJ gives and much more, just - in a much more organized and elegant manner.

    As I have been struggling with embedding various scripting languages in Java recently, I have found this neither organised or elegant. At least if you code things in Java, then - no matter how ugly it may appear - you can actually easily trace and debug the code.

    If someone has a good suggestion of a scripting language which integrates cleanly with Java, has decent debugging tools, and where you don't end up sorting out bugs in the interpreter or implementation rather than your code, I would be interested. Until then, I'll welcome any new approach in pure Java, no matter how theoretical.
  181. Groovy or Jython[ Go to top ]

    Steve,

    I have no idea what you are talking about. I just recently had to embed Groovy in a JEE application (arguably trickier than just a vanilla Java app) and had it "talk" with the view layer.

    All of these took me about 30 minutes, including the view part.

    Honestly, if I did not know your from other posts I would seriously think that you are trolling. Now all I can say - I am very surprised and confused about what you mean.

    In my limitted experience embedding both Groovy and Jython in a Java application is extremely easy. If you could, please, explain what you mean.
  182. JFunctional and FunctionalJ[ Go to top ]

    Frederic,

    First of all, congratulations on this nice lib! I was once thinking Java developers all hate functional style programming. :-)

    I'm the author of JParsec, Yan Container (both utilizing functional combinatory logic in the core). So I'd claim I know functional style at least among average Java programmers.

    Same as you, I, about a year or 2 ago, tried to create my own higher order function library. You can see the relics of it on sourceforge jfun project. (Or, maybe as a suvenir, I should host it on codehaus. :-))

    And I did create a functional library. Pretty much use the same way you you did. To give a sense, creating a function is like:
    Fun.fun(obj, "someMethod");

    Calling or currying a function is like:
    "f.f(obj)" or "f.f(a,b)" or "f.apply(new Oject[]{a,b,c})" etc.

    Concerned about the performance and type safety of reflection, I went out of my way to provide a Lamda interface that allows programmer to create a Function using anonymous class that implements Lamda, Lamda2, etc.

    The library can also deal with method overloading. A nasty multi-dispatch problem can be expressed concisely in the jfuncitonal lib (so similar to functionalj!)
    So that:

    class Plus{
      public int compare(int i, int j){...}
      public int compare(Car c1, Car c2){...}
      public int compare(Animal a1, Animal a2){...}
    }
    int compare(Object o1, Object o2){
      return ((Integer)Fun.fun(new Plus(), "compare").f(o1, o2))
        .intValue();
    }

    This partially implements pattern match in a type-based manner.


    All went beautifully. I did not try to build a lot of algorithms like "filter" because I feel those don't belong to the core and can be easily added if wanted. But I did build a monad library that deals with all the common monad and monad transformers found in Haskell, even including continuation!

    And yet, I gave up publishing that library. With two reasons:

    1. performance. reflection is slow and a library meant to be used by various clients may better avoid using it in the core. While if we use Lamda anonymous class all the time, the syntax is ugly!
    2. More importantly. Debuggability of such functional lib is poor! Exceptions typically don't tell the exact location of the bug any more when functions are extensively combined (and that's what functional style mean to be). I as the author. even sometimes find it difficult to track down a bug.
    3. When trying to use it to build a parsec implementation, I found it much more intuitive and easier to debug and understand to totally throw away the Function lib and use a less functionalized, but more straight-forward Parser class.
    That made me wonder: where the heck is this lib useful at all?

    So I revert back to OO style and archived this jfunctional lib. Don't get me wrong, I still believe in the functinoal combinatory logic. I just gave up using a common functor library that's meant for _everything_. It's too general and too hard to use, with the current Java language. This is the reason why I don't buy apache commons functor.

    JParsec, Yan still use combinatory logic, still functional, but they each create their own combinators without trying to use a general functional library.

    And yes, I wanna concur with Yang's finding. JParsec code typically has a lot of anonymous classes which is ugly. But after several years messing around with functional in Java, I personally find it sometimes more practical to compromise than trying to overcome Java's limitations.

    And, worse comes to worse, one can always use a functor library to implement Map, Binder interfaces. For example, if we use your or my functor lib with JParsec, we can always say:

    parser.map(MapFunction.asMap(some_obj, "convert"));


    No big deal. The parsec library doesn't force you to use reflection, it doesn't force you to use anonymous class either. The choice is yours.


    Guess I'm talking too much. And just realized I missed two questions for you:

    1. how do you handle method overloading? In case of "new StaticFunction(Math.class, name)".
    2. Do you provide standard combinators such as const, flip, fst, snd, curry, uncurry, '.', '$' etc?

    Regards,

    Ben.
  183. JFunctional and FunctionalJ[ Go to top ]

    Had a little reading of the JavaDoc.

    I'd the say the API is neat.

    It doesn't provide advanced FP constructs such as monad, but, who cares.

    Lack of flip, '$', curry, uncurry is also fine because combining functions too much is hard to understand and maintain anyway.

    It's nice to have the foldl, foldr, scanl, scanr, zip, unzip, filter functions implemented, which my JFunctional didn't do. They are nothing hard to implement but quite practical.

    One key difference between my JFunctional and FunctionalJ, imho, is the use of reflection. FunctionalJ pretty much mandates reflection. While reflection is just one option in JFunctional.


    I just uploaded JFunctional to the internet:
    http://yan.codehaus.org/jfunctional/api/index.html

    Ignore those monad packages. They are useless. The core package and prelude package is almost everything.


    Ben.
  184. Bug[ Go to top ]

    I think you have a bug in your examples. Positive is the max (not min) of the number and 0.

    > Function positive = new StaticFunction(Math.class, "max").addParameter(new Integer(0));
  185. Hi, I recently wrote an article describing some tricks for readable functional programming in java: http://community.livejournal.com/jkff_en/341.html You might be interested to have a look at it. I argue that using its ideas, FunctionalJ can be made a lot more readable and, sometimes, even unneeded :)