2012/1/9 Nicolas Garcin <nicolas.etienne.gar...@gmail.com>

> Hello,
>
> I'm new to functional programming and Clojure and I'm trying to
> translate a simple java program into Clojure. My program must build
> from 2 input lists (stored in a vector) 2 output lists (also stored in
> a vector) which have same number of elements as input lists for both
> output lists. The elements' values of the output lists will be the
> result of a very simple arithmetical calculation based on input lists'
> elements.
> Since my java program iterates on lists, I wanted to use a 'higher
> order function' in the Clojure version of the program (like the 'map'
> function). But I didn't manage to write the equivalent program in
> Clojure.
> Could someone please help me?
> Below is the java program that I'd like to translate.
> Thanks a lot,
>
> Regards,
> Nicolas
>

I've started sketchy below, but the matching function would really be
happier if it had one or two comments. Usually it's a lot easier to
implement clojure code from algoritmic ideas rather than existing java code
since they are quite different. For instance I would change the object to a
hash map {:name :value} and NOT change the input vector, the actions taken
would actually return a new nested vector.

I guess you could make a much better algoritm in the matching function
using reduce or some other higher order function. Also, null is nil which
is mostly the same but less prone to break, which could probably remove a
few of the if-statements as well.

Sorry for sketchy answer, but hopefully it's a start. The solutions to the
problem would be quite different than the java version, and the clojure
version will be a somewhat more compact. Rich Hickey have made some really
really good introductions to Clojure where he touches many of concepts you
could have good use of in the code below named "Clojure for Java
Programmes" pt 1 and 2
http://blip.tv/clojure/clojure-for-java-programmers-1-of-2-989128
http://blip.tv/clojure/clojure-for-java-programmers-2-of-2-989262

Hopefully this will get you started!

/Linus

>
> // first file (these are the elements of my lists):
> public class Pos {
>
>    public String name;
>    public int value;
>
>    public Pos(String newName, int newValue) {
>        name = newName;
>        value = newValue;
>    }
>
>    @Override
>    public String toString() {
>        return "Name: " + name + ", Value: " + value + "\n";
>    }
> }
>
A pos could be described as {:name "IBM" :value 150}.

(defn pos-str [pos]
   (str "Name: " (:name pos) ", Value: " (:value pos) "\n"))


> // second file that contains the method I'd like to translate using a
> higher order function (method called "match"):
>
> import java.util.ArrayList;
> import java.util.List;
> import java.util.Vector;
>
> public class Matching {
>
>    public static void main(String[] args) throws Exception {
>        List<Pos> options = new ArrayList<Pos>(5);
>        Pos option1 = new Pos("IBM", -50);
>        Pos option2 = new Pos("ACCOR", -30);
>        Pos option3 = new Pos("IBM", -10);
>        Pos option4 = new Pos("APPLE", -20);
>        Pos option5 = new Pos("AIRFRANCE", -20);
>        options.add(option1);
>        options.add(option2);
>        options.add(option3);
>        options.add(option4);
>        options.add(option5);


>        List<Pos> actions = new ArrayList<Pos>(4);
>        Pos action1 = new Pos("IBM", 55);
>        Pos action2 = new Pos("ACCOR", 40);
>        Pos action3 = new Pos("AIRFRANCE", 10);
>        Pos action4 = new Pos("LUFTHANSA", 100);
>        actions.add(action1);
>        actions.add(action2);
>        actions.add(action3);
>        actions.add(action4);


>        Vector<List<Pos>> input = new Vector<List<Pos>>(2);
>        input.set(0, options);
>        input.set(1, actions);
>
(ns matching.thing)
(def options [{:name "IBM" :value -50} {...} ...])
(def actions [{:name "IBM" :value 55} {...} ...])
(def input [options actions]) ;;or just write everything in one declaration

>
>        System.out.println("Options: " + options);
>        System.out.println("Actions: " + actions);
>        Vector<List<Pos>> res = Matching.match(input);
>        System.out.println("Options: " + res.get(0));
>        System.out.println("Actions: " + res.get(1));
>
(println "Options: " options)
...
(println "Matched: " (match options))
;;since you have immutability you get a new vector, no changing of the old
above, so you have to catch the result somehow


>    }
>
> ;;The code below is a can of worms for someone who don't know what the
algoritm is supposed to do


>    public static Vector<List<Pos>> match(Vector<List<Pos>>
> optionsAndActions) {
>
;;if null return null (would probably not be needed to catch when using nil)

>

       if (optionsAndActions == null) {
>            return optionsAndActions;
>        }
>
;;if one or zero elements they're already matched, return it as a whole

>        if (optionsAndActions.size() < 2) {
>            return optionsAndActions;
>        }
>

;;this code is quite opaque to me:

>
>        Vector<List<Pos>> modifiedOptionsAndActions = new
> Vector<List<Pos>>(2);
>        if (optionsAndActions.get(1) == null) {
>            modifiedOptionsAndActions.add(0, new
> ArrayList<Pos>(optionsAndActions.get(0)));
>            return modifiedOptionsAndActions;
>        } else if (optionsAndActions.get(0) == null) {
>            modifiedOptionsAndActions.add(1, new
> ArrayList<Pos>(optionsAndActions.get(1)));
>            return modifiedOptionsAndActions;
>        }
>        ArrayList<Pos> modifiedOptions = new
> ArrayList<Pos>(optionsAndActions.get(0));
>        ArrayList<Pos> modifiedActions = new
> ArrayList<Pos>(optionsAndActions.get(1));
>        modifiedOptionsAndActions.add(0, modifiedOptions);
>        modifiedOptionsAndActions.add(1, modifiedActions);
>
>
(defn match [[options actions]] ;;check out *destruction*, very clever
functionality
;;go through both options and actions and do something to them
;;this throws back the answer as an "action vector" of sorts
(cond or condp for all the if statements above

the last one becomes something like this:

(for [option modified-options action modified-actions]
   (if (= (:name option) (:name option))
      (let [sum (+ (:value action) (:value option))]
         [{:name (:name option) (Math/max 0 sum)} {:name (:name option)
(Math/min 0 sum)}])))




>        for (Pos option : modifiedOptions) {
>            for (Pos action : modifiedActions) {
>
>                if (option.name.equals(action.name)) {
>                    int tempActionValue = Math.max(0, action.value +
> option.value);
>                    int tempOptionValue = Math.min(0, action.value +
> option.value);
>                    action.value = tempActionValue;
>                    option.value = tempOptionValue;
>                }
>            }
>        }
>        return modifiedOptionsAndActions;
>    }
> }
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to