"Practically speaking, you should use DEFVAR to define variables that will contain data you'd want to keep even if you made a change to the source code that uses the variable. For instance, suppose the two variables defined previously are part of an application for controlling a widget factory. It's appropriate to define the *count* variable with DEFVAR because the number of widgets made so far isn't invalidated just because you make some changes to the widget-making code."

I don't get it: I write some app, and the code for a widget factory. Let's suppose I write a function:

The function returns a new widget, but it also counts, how many times it was called. I get it.

Now, let's suppose that I have found a bug. I have to stop my app, fix the bug, compile my app again and run it. There are two possibilities: my app either is able to read (from some configuration file) the number of times the make-a-widget function was called, or it isn't. In the first case:

Yes, this one is a bit odd and I have never seen a distinction like this in another language.

For small, transient programs, where you shutdown the running program and completely restart, there is no big difference. Remember that Lisp has often been used to create long-running programs that may not terminate for years. In these cases, debugging is done while the program runs. We're not just talking Lisp Machines here; you can do this today with SBCL and SLIME/SWANK. As a part of that debugging, you'll sometimes want to reload a portion of that program as you update it to fix bugs. If you execute a DEFVAR a second time, it will recognize that the variable has already been created and initialized and will not reinitialize it. DEFPARAMETER will reinitialize in that case, with extreme prejudice.

So, if you are working with Lisp as if it's C, with very separate compile, load, run, shutdown, debug cycle, then there is not a big difference since every time you execute either form it will be for the first time. If you're working with long-running programs where you are doing a lot of debug inside the Lisp image, you can generate the right behavior by choosing the right form.

The example of when the difference matters which I ran into a few times are configuration variables, which have some default values, but which you might want to change from the REPL when developing/testing the program. Since in CL, as findinglisp has written, you can recompile code without restarting entire environment, using DEFVAR means that configuration setting will "stick" even if you reload a file containing them.

I tend to use defparameter more often than defvar, precisely to take advantage of the distinction.

The value of the distinction comes from the interactive nature of Lisp; if it were edit-compile-run in the manner of C or Perl (minus the "compile" part), there'd be no difference between the two.However, if you load a system and interact with it, then edit and reload it, defvar will leave the variable's value alone while defparameter will override it with the new value.

Actually, thinking about this has suggested a slight refinement to the way I've written a couple of bits of code. What I mostly work on is a web application, an online store (or two). When I'm working on the development machine, there's little damage to be done by b0rking the configuration variables that define the database connection: I just curse my own stupidity, fix the definitions and carry on. When I log into the production machine, on the other hand, I generally do it to upgrade the application, which I do by reloading the relevant system(s) in the currently running image. This is nice and convenient, as it means there's no downtime while I restart the app server. However, it behooves me to be very careful about changes to the config files. I might just have to come up with a better strategy for loading the configuration, so that it's more cautious about overriding existing values.

Then again, I only just wrapped my head around some implications of OOP, so a major redesign of the foundation code is coming up anyway, where I get to figure out serialisation strategies. That's one of the things I love about the language: I'm on a perpetual learning curve, but rather than memorising yet more APIs, I'm learning entire classes of techniques and technologies.

I'm a Lisp newbie. I do realize I'm asking lame questions, but I haven't had any touch with Lisp before. Programming is my hobby, my passion, and now also my profession. I started to study Lisp, because I came to conclusion that I just can't afford not using this language. I was about to switch from Java to Scala (Java lacks FP features), but I realized that Lisp is a (the?) language I can extend however I like...

Now, I'm reading "Practical Common Lisp". Although I don't find this lecture perfect (I'm going also to read "Successful Common Lisp" and "On Lisp"), and many Lisp concepts are hard to understand, I'm starting to use this language. Lisp is not my first programming language, but I hope it to be the last one

So please excuse me asking obvious questions, but the Lisp concepts are really "foreign" for me.

findinglisp wrote:Remember that Lisp has often been used to create long-running programs that may not terminate for years. In these cases, debugging is done while the program runs.

Now I get it. Although I'm not interested in programs which run for years (but months sounds much more interesting...), I can see the point. Lisp is quite different from any other tool I know (Java, Python, C, etc.); as far as I understand it, Lisp programs can be debugged and fixed while running.

Ramarren wrote:The example of when the difference matters which I ran into a few times are configuration variables, which have some default values, but which you might want to change from the REPL when developing/testing the program.

It sounds very interesting...

(A small OT: greetings from Silesia! I wasn't expected to meet so many people from Poland on this forum )

JamesF wrote:What I mostly work on is a web application, an online store (or two). When I'm working on the development machine, there's little damage to be done by b0rking the configuration variables that define the database connection: I just curse my own stupidity, fix the definitions and carry on. When I log into the production machine, on the other hand, I generally do it to upgrade the application, which I do by reloading the relevant system(s) in the currently running image. This is nice and convenient, as it means there's no downtime while I restart the app server.

And this idea just rocks!

Well, I'm not interested in web apps (for now; I might be in a couple of months, though!), but I'm very interested in scientifical software and server-client apps. The ability to debug/update software without stopping it is worth any effort.