This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

Problem properly using defvar/defparameter/defconstant

4 posts · 2812 views

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:
(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

What's with this version:
(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:
(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

When in doubt, use late binding. (By which I mean “use symbols.”)
(defparameter *functions* `((label1 . function1) (label2 . other-function)))
Since symbols are funcallable, this will solve your problem.

Re: Problem properly using defvar/defparameter/defconstant

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.