Jason Basanese
Jason Basanese

Reputation: 710

How to write a function that defines another function with given name

Here is my clojure code:

(defn salutation-adder-maker                                                                                   
  ([salutation call]                                                                                     
   (def call (salutation-adder-maker salutation)))                                                             
  ([salutation]                                                                                          
   #(str % salutation))                        
)                                                                                                        
(salutation-adder-maker "-Thanks!" salutation1)                                                              
(salutation1 "Help me!")

The bottom two lines of code give an error unable to resolve symbol salutation1. The function compiles fine, but this is because it defines the function as call. Thus the following code works:

(call "Help me!")

It spits out

Help me-Thanks!

Rather than the function salutation1 having that functionality. How can I change the code so that salutation1 does the same thing as call is currently doing?

I want to be able to pass two arguments:

For example:

(salutation-adder-maker "-Have a good day!" day_salutation)
(day_salutation "I will talk to you later")=>"I will talk to you later-Have a good day!"

Upvotes: 1

Views: 91

Answers (1)

Valentin Waeselynck
Valentin Waeselynck

Reputation: 6051

Your code seems to assume def works like a function. In spite of the syntax, it's very different, in particular the symbol you use as the first argument of def must be resolved at compile-time, not run-time. As a consequence, to build on top of def, you will tend to use a macro, not a function. This is problematic, because while the 2-args arity requires a macro, the 1-arg arity would be best served by a function.

Let me suggest to split the work into a function and a macro:

(defn salutation-maker [salutation]
  #(str % salutation))

(defmacro defsalutation [name salutation]
  `(def ~name (salutation-maker ~salutation)))

Upvotes: 6

Related Questions