Pawan Kumar
Pawan Kumar

Reputation: 21

multiple functions with same name in clojure

(defn hi[](+ 5 6))  
(hi)  
(defn hi[](+ 6 7))  
(hi) 

Hi, i'm new to clojure . as above writen code i wrote two functions with same name. can we have same name for multiple functions in clojure. if yes does it conflict within same namespaces?

Upvotes: 2

Views: 1284

Answers (2)

Thumbnail
Thumbnail

Reputation: 13473

I wrote two functions with same name.

Yes and No:

  • You wrote two function definitions with the same name.
  • The second definition overwrote the first.
  • The functions never shared the name.

Can we have same name for multiple functions in clojure?

Not in the same namespace. A second def or defn for a symbol erases the first.

  • There is only one symbol with a given name in a namespace.
  • A symbol refers to only one var at a time.
  • The def form ties a symbol to the var it refers to.
  • The fn form creates a function.
  • The defn macro is a wrapper round the def and fn forms, causing the named symbol to refer to a var holding the function.
  • Symbols with the same name in different namespaces do not conflict: they are different symbols.

If yes does it conflict within the same namespace?

Yes.

But ...

One function can have several arities - argument counts. This applies to functions referred to by symbols through vars and in other contexts.


Function definition is a side-effect of evaluating a defn. The best explanation I know of how lisps evaluate function definitions is Chapter 2 of Paul Graham's On Lisp.

Upvotes: 1

Mark Karpov
Mark Karpov

Reputation: 7599

You cannot have several functions with the same name in the same namespace. If you define function foo and then redefine it again, newer version will replace the older.

It's not quite clear what you're trying to achieve, but Clojure has quite a few ways to have several implementations under one name.

Arity Dispatch

You can dispatch functions on arity:

(defn foo
  ([x] :version-one)
  ([x y] :version-two)
  ([x y & more] :version-tree))

Different arities of the same function can call one another, and this is somewhat equivalent to having several functions with the same name.

Multimethods

You can dispatch using multimethods. They allow you to define a function that will be called on arguments and its result will be used for dispatching.

(defmulti foo odd?)

(defmethod foo true [x]
  (format "look, ma, %d is odd!" x))

(defmethod foo false [x]
  (format "look, ma, %d is even!" x))

Protocols

This technique is similar to polymorphism in other languages. You can dispatch on argument type. Here is example:

(defprotocol foo
  (my-fnc [x] "description..."))

(extend-protocol foo
  Number
  (my-fnc [x] :number-version)
  String
  (my-fnc [x] :string-version))

Multimethods are most powerful tool, you can emulate protocols with them this way:

(defmulti foo class)

Upvotes: 10

Related Questions