2

I am pretty new with Clojure. I have one Java method including a boolean variable and I want to rewrite this method to use it with the same functional in Clojure as well. But I couldn't find how to set the boolean value true and false in run-time in Clojure.

The following snippet basically emphasize only the boolean part, It is difficult to think for me to write this in a functional way.

int calculate(...){
  int y = 0;
  boolean flag = false;
  foreach(...){
     if(!flag){
        y = 1;
        flag = true;
     }
     else{
        y = -1;
        flag = false;
     }
  }
  return y;
} 

Here is the my first attempt in Clojure:

(defn calculate [...]
    ( ??flag?? -> I do not know which macro I should use over here
      (doseq [x ...]
        (if (false? flag) (do 1 (set the flag true)) 
           (do -1 (set the flag false)))))

How can I implement the same concept in Clojure?

3
  • Conceptually, it might be cleaner to use a helper function and a recursive function - (defn calculate [y flag] ..) Commented Jun 11, 2014 at 23:40
  • this program makes no sense...you loop over the elements of collection, flipping the value of y -- is "flag" meant to stand for some function of each element in the collection ? If not, just return 1 or -1 depending on whether the collection has an odd or even number of elements Commented Jun 12, 2014 at 5:08
  • 3
    You ask "How can I implement the same concept in Clojure?". Why do you wish to do so? Pointwise translation of Java into Clojure, even where possible, is generally futile. And until your Java program makes sense, it is hard to see how to render its function in idiomatic Clojure. If you want to tackle well-defined small problems in Clojure, take a look at 4Clojure. If you want to compare Clojure solutions with those in Java and other languages, Rosetta Code is a good source. I have found both very helpful. All the best! Commented Jun 12, 2014 at 6:02

2 Answers 2

7

For the Java code you have, it looks like the simplest way to translate it into Clojure would be to skip all the iterating and just return the final value:

(defn calculate [coll]
  (odd? (count coll)))

If you want something more elaborate I guess you could do something like

(defn calc [coll flag]
  (if (empty? coll)
    flag
    (recur (rest coll) (not flag))))

and call it with

(defn calculate [coll]
  (calc coll false))     

This kind of recursion isn't the most idiomatic style, and it's kind of crazy for this problem, but it demonstrates how instead of mutating variables you write an expression that when evaluated produces the value passed into the next iteration (see the recur call in the example above).

It would be better style to rewrite this like

(defn calculate
  ([coll flag]
    (if (empty? coll)
      flag
      (recur (rest coll) (not flag))))
  ([coll]
    (calculate coll false)))

so there's only one function name to deal with. (I left the other way in thinking it would likely be clearer to read for somebody new to Clojure.)

I second the comment suggesting you look at 4clojure. It's a good way to get practice, and once you have a solution you can learn from what other users did.

Sign up to request clarification or add additional context in comments.

Comments

2

Use loop/recur to emulate iterative statements in Clojure:

(defn calculate [...]
  (loop [...
         y    0
         flag false]
    ...
    (if (false? flag)
      (recur ...  1 true)   ;; "loop with x = ..., y = 1 and flag = true"
      (recur ... -1 false)) ;; "loop with x = ..., y = -1 and flag = false"
    ... )

EDIT: let me elaborate. What I understand from your question is that you have trouble translating mutability-based (Java) code into Clojure. This is natural. Clojure is big on immutability.

One way to implement mutability in a Clojure program is to use reference types, in particular atoms. Your piece of code could be written this way in Clojure:

(defn calculate [...]
  (let [y    (atom 0)
        flag (atom false)]
    (doseq [x ...]
      (if (false? @flag)
        (do (reset! y 1)
            (reset! flag true))
        (do (reset! y -1)
            (reset! flag false))))
    (... return some function of y and flag ...)))

It works. But heavy use of atoms and side-effects is not idiomatic in Clojure; useful at times, yes, but not necessary and cumbersome compared to functional, idiomatic Clojure.

A better way to model mutability in the context of iteration is to translate it in terms of recursion, like what I did with loop/recur above.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.