defvar, defparameter

Discussion of Common Lisp
Post Reply
TPJ
Posts: 11
Joined: Tue Nov 25, 2008 6:37 am
Location: Gliwice, Poland

defvar, defparameter

Post by TPJ » Wed Nov 26, 2008 7:03 am

From "Practical Common Lisp", chapter 6 "Variables":

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

Code: Select all

(defun make-a-widget ...<some stuff here>...)
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:

Code: Select all

(defvar *counter* my-read-value)
In the second case:

Code: Select all

(defvar *counter* 0)
In both cases DEFVAR will refer to an unbound variable, so the default value will be used.

So, what's the point?

findinglisp
Posts: 447
Joined: Sat Jun 28, 2008 7:49 am
Location: Austin, TX
Contact:

Re: defvar, defparameter

Post by findinglisp » Wed Nov 26, 2008 9:04 am

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. :D

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.
Cheers, Dave
Slowly but surely the world is finding Lisp. http://www.findinglisp.com/blog/

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: defvar, defparameter

Post by ramarren » Wed Nov 26, 2008 9:17 am

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.

JamesF
Posts: 98
Joined: Thu Jul 10, 2008 7:14 pm

Re: defvar, defparameter

Post by JamesF » Wed Nov 26, 2008 4:28 pm

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.

TPJ
Posts: 11
Joined: Tue Nov 25, 2008 6:37 am
Location: Gliwice, Poland

Re: defvar, defparameter

Post by TPJ » Thu Nov 27, 2008 12:04 pm

Well, thank you all for your answers.

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.

Post Reply