Page 1 of 1

Problem properly using defvar/defparameter/defconstant

Posted: Fri Jun 08, 2012 6:32 pm
by MicroVirus
Dear Lispers,

I'm having problems 'properly' using defparameter (or defvar or defconstant) in my code. Occasionally I find myself trying to code something like:

Code: Select all

(defparameter *functions* `((label1 . ,#'function1) (label2 ,#'other-function)))

(defun function1 (something)
 ...)

(defun other-function ()
 ...)
And when I load the entire file to start editing it, I get the error that function1 is not fboundp, which I suppose it isn't at the time the defparameter is executed. I'm now left wondering, what is 'proper style' for common lisp in this situation?
How and where do I initialise the *functions* variable in my file such that it is properly assigned after the file has been loaded?
I'm also still really unclear on the way lisp load and compile and eval-when works. I read the Gigamonkeys Common Lisp Book's chapter about it three times, and I checked the CLHS, but it still isn't making much sense to me :( Probably if I correctly understood this I could solve the problem above myself. If anyone has some good reading on this, I'd love to know about it.

Any advice/tips/tricks on this would be greatly appreciated :)

Best Regards,

Richard

Re: Problem properly using defvar/defparameter/defconstant

Posted: Sat Jun 09, 2012 4:30 am
by edgar-rft
What's with this version:

Code: Select all

(defun function1 (something) ...)

(defun other-function () ...)

(defparameter *functions* `((label1 . ,#'function1) (label2 ,#'other-function)))
Or if you want to define the special variable at the top of the file:

Code: Select all

(defparameter *functions* nil
  "Documentation...")

(defun function1 (something) ...)

(defun other-function () ...)

(setf *functions* `((label1 . ,#'function1) (label2 ,#'other-function)))
EVAL-WHEN only makes a difference if you compile the file. The main difference is that if you LOAD a file then the file is read and evaluated expression by expression, while many compilers first READ the entire file (all expressions) and only then COMPILE the entire file. In such a situation it may happen that you must wrap the DEFUNs from above into an EVAL-WHEN, so they are evaluated at READ time, because only then the functions are known by the COMPILEr and can be assigned to the *FUNCTIONS* variable. But the exact behaviour depends on the compiler.

The gory details are documented in the CLHS Chapter 3 Evaluation and Compilation, i.e. 3.2.3 File Compilation.

It's generally a good strategy to first define a function or a top-level variable before using them in any other forms. This way you will have no problems if you try to load or compile your code with different Common Lisp implementations.

- edgar

Re: Problem properly using defvar/defparameter/defconstant

Posted: Sun Jun 10, 2012 3:32 am
by Kompottkin
When in doubt, use late binding. (By which I mean “use symbols.”)

Code: Select all

(defparameter *functions* `((label1 . function1) (label2 . other-function)))
Since symbols are funcallable, this will solve your problem.

Re: Problem properly using defvar/defparameter/defconstant

Posted: Mon Jun 18, 2012 5:07 am
by MicroVirus
Thanks for the responses! I played around with it a bit and I think I'll be using the late binding suggestion, which seems most elegant to me.