Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`def` vs `declare` for forward declaration

Tags:

Clojure, has a declare macro that allows you to forward-declare functions or variables. It seems to function exactly as def: Both (declare x) and (def x) create #<Unbound Unbound: #'user/x>

When should (declare x) be used instead of (def x)?

like image 956
Zaz Avatar asked Nov 22 '15 14:11

Zaz


People also ask

Should I use forward declaration or include?

As the name itself implies, forward declaration is just a Declaration and not a definition. So, you will declare saying the compiler that it is a class and I just declaring it here and will provide you the definition when am gonna use it. So, normally you forward declare in the Header file and #include in the .

When can you use forward declaration?

You will usually want to use forward declaration in a classes header file when you want to use the other type (class) as a member of the class. You can not use the forward-declared classes methods in the header file because C++ does not know the definition of that class at that point yet.

Why should I use forward declarations?

A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier. In the case of functions, this allows us to tell the compiler about the existence of a function before we define the function's body.

What is forwarding declaration?

forward declaration (countable and uncountable, plural forward declarations) (programming) The declaration of an identifier before it is given a complete definition, so that the compiler can know its data type and memory size.


2 Answers

Both declare and def do create an unbound var, but there are 3 advantages to using declare:

  1. You can create multiple vars in one statement, e.g. (declare x y z)
  2. The vars are tagged with the additional metadata {:declared true}
  3. Using the word declare is arguably more clear and idiomatic

(source declare):

(defmacro declare   "defs the supplied var names with no bindings, useful for making forward declarations."   {:added "1.0"}   [& names] `(do ~@(map #(list 'def (vary-meta % assoc :declared true)) names))) 
like image 134
Zaz Avatar answered Oct 10 '22 19:10

Zaz


The documentation gives the answer:

=> (doc declare) ------------------------- clojure.core/declare ([& names]) Macro   defs the supplied var names with no bindings, useful for making forward declarations. 

Looking at the implementation, it's clear that declare is defined in terms of def and provides a little bit of syntax sugar. So functionally, they're pretty much the same.

The advantage of declare is to show intent for a later reader. (declare x y z) means I intended to make a forward declaration of those symbols, because the macro is useful for making forward declarations.

(def x) (def y) (def z) means I'm interning these symbols, but you don't know if I meant to give them definitions and forgot to or whether I'm making forward declarations, or maybe something else subtle.

So, (declare x) should be preferred over (def x) when you're making a forward declaration, to show mercy on future readers of your code.

like image 38
munk Avatar answered Oct 10 '22 19:10

munk