Question about functions in clojure.string/replace

Hi all, I’m new here.

I’m working through an exercise in The Clojure Workshop, and the goal is to create encoding functions that can take a string and convert each of the characters to a number. The instruction is to use clojure.string/replace in the exercise.

Here are my functions:

(defn encode-letter
      "Encode individual characters to an int"
      [s]
      (let [code (Math/pow (int (first (char-array s))) 2)]
        (str "#" (int code))))

(defn encode-phrase
  [s]
  (clojure.string/replace s #"\w" encode-letter))

When playing with these, I noticed that encode-phrase will work correctly like this as well:

(defn encode-phrase
      [s]
      (clojure.string/replace s #"\w" (fn [s] (encode-letter s))))

But not like this:

(defn encode-phrase
      [s]
      (clojure.string/replace s #"\w" (encode-letter s)))

In the latter case, the output ends up just being a repeat of the first character of the string. I’m struggling to understand why - would someone mind explaining?

Thank you!

Hello!

As far as I can tell from reading your code, in the latter case you call (encode-letter) once, with the whole string (s) as input.

I see - so I guess in the latter case the (encode-letter s) form is being run first and evaluated once, and then its output is replaced for each match.

In the case of the anonymous function approach, I’m guessing we’re passing each match (letter) to the anonymous function, changing the value of s in each case. Is that just the nature of anonymous function in this case?

Thanks for the response!

Yes, that’s what a function does (anonymous or not). A non-anonymous function is just an anonymous function that is bound to a name, but they are the same thing. defn = fn + def.

Thanks - I think I understand what’s happening now.