Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 23 |
Nodes: | 6 (0 / 6) |
Uptime: | 52:44:04 |
Calls: | 583 |
Files: | 1,139 |
D/L today: |
179 files (27,921K bytes) |
Messages: | 111,617 |
I have dabbled with many flavors of LISP over the decades but never
gotten my feet wet with CL until just very recently. I'm using the
latest and greatest Steel Bank CL with everything set up as it came out
of the box, and am puzzled by the fact that I apparently have to
(defvar foo)
before I am allowed to (setq foo something). Even most of the CL
tutorial stuff does not require all identifiers to be declared up front
like that.
Do I have some kind of super-pedantic option turned on that I don't know about?
Also, from the sample stuff I am seeing, it appears that setq is out of
style for CL, and people use setf instead? Is there a pointer to a
history of the various set forms and what they're for?
3. Loop is very powerful, granted, and many people are trying to
argue that "you can do so much with loop that it's unreadable."
This is not an argument.
Also, from the sample stuff I am seeing, it appears that setq is out of
style for CL, and people use setf instead? Is there a pointer to a
history of the various set forms and what they're for?
Do I have some kind of super-pedantic option turned on that I don't know about?
Also, from the sample stuff I am seeing, it appears that setq is out of
style for CL, and people use setf instead? Is there a pointer to a
history of the various set forms and what they're for?
Also, from the sample stuff I am seeing, it appears that setq is out of
style for CL, and people use setf instead? Is there a pointer to a
history of the various set forms and what they're for?
I don't know offhand of a history document, but setf is a clever macro
that can update a bunch of different types of mutable objects, rather
than just symbol values.
Paul Rubin:
setf is a clever macro that can update a bunch of different types ofYeah: `setq` is a special form to mutate a variable, whereas `setf` is
mutable objects, rather than just symbol values.
a macro that can mutate any "place"
I have dabbled with many flavors of LISP over the decades but never
gotten my feet wet with CL until just very recently. I'm using the
latest and greatest Steel Bank CL with everything set up as it came out
of the box, and am puzzled by the fact that I apparently have to
(defvar foo)
before I am allowed to (setq foo something). Even most of the CL
tutorial stuff does not require all identifiers to be declared up front
like that.
Do I have some kind of super-pedantic option turned on that I don't know about?
Also, from the sample stuff I am seeing, it appears that
setq is out of style for CL, and people use setf instead?
Is there a pointer to a history of the various set forms
and what they're for?
Wade Scholine <wscholine@gmail.com> writes:
I have dabbled with many flavors of LISP over the decades but never
gotten my feet wet with CL until just very recently. I'm using the
latest and greatest Steel Bank CL with everything set up as it came out
of the box, and am puzzled by the fact that I apparently have to
(defvar foo)
before I am allowed to (setq foo something). Even most of the CL
tutorial stuff does not require all identifiers to be declared up front
like that.
Do I have some kind of super-pedantic option turned on that I don't know
about?
Lisp does not require that you create the definition. It is
issuing a warning so that you are notified that you have
(possibly erroneously) set a variable that you have not
declared. This is helpful if you, say, misspell the name of
a variable in a rCysetqrCO expression in some function.
Despite the warning, rCysetqrCO has set the variable to the
value that you specified, which you can confirm by
evaluating it at the REPL prompt:
* (setq wade "some string")
; in: SETQ WADE
; (SETQ WADE "some string")
;
; caught WARNING:
; undefined variable: COMMON-LISP-USER::WADE
;
; compilation unit finished
; Undefined variable:
; WADE
; caught 1 WARNING condition
"some string"
* wade
"some string"
So, you can ignore the warning, or you can begin adding
declarations.
You should consider using rCydefparameterrCO instead of rCydefvarrCO
if you want to change the value of the variable:
"rCydefparameterrCO and rCydefvarrCO establish NAME as a dynamic variable.
rCydefparameterrCO unconditionally assigns the INITIAL-VALUE
to the dynamic variable named NAME. rCydefvarrCO, by
contrast, assigns INITIAL-VALUE (if supplied) to the
dynamic variable named NAME only if NAME is not already
bound."
Jeff BarnettAlso, from the sample stuff I am seeing, it appears that
setq is out of style for CL, and people use setf instead?
Is there a pointer to a history of the various set forms
and what they're for?
rCysetqrCO is more limited in what kind of assignment it can
perform:
"rCy(setq var1 form1 var2 form2 ...)rCO is the simple
variable assignment statement of Lisp. First FORM1 is
evaluated and the result is stored in the variable VAR1,
then FORM2 is evaluated and the result stored in VAR2,
and so forth. rCysetqrCO may be used for assignment of both
lexical and dynamic variables."
If you continue with Common Lisp, eventually you will learn
about "generalized variables" or "generalized references",
which can be used both for reading from and writing to a
location. rCysetfrCO is used for writing to these generalized
variables, but can be used where rCysetqrCO is used. (Likely for
simplicity, many Lisp programmers have decided that it is
"modern usage" to always use rCysetfrCO.)--
You should consider using rCydefparameterrCO instead of rCydefvarrCO
if you want to change the value of the variable:
"rCydefparameterrCO and rCydefvarrCO establish NAME as a dynamic
variable.
rCydefparameterrCO unconditionally assigns the INITIAL-VALUE
to the dynamic variable named NAME. rCydefvarrCO, by
contrast, assigns INITIAL-VALUE (if supplied) to the
dynamic variable named NAME only if NAME is not already
bound."
I think you might have defparameter confused with defconstant (or
defconst in some implementations. I believe that defvar is used when
the name can be assigned or bound or both. Names introduced by
defparameter can have the values changed globally but are not expected
to be rebound - think of them as constants for one or a few runs of
your program.
Those introduced by defconst(ant) are assumed to not be
rebound or assigned; in fact, a compiler may bury
references to that constant value in compiled code which
would make them rather impervious to any change or
apparent value.
My intent was to help the new user avoid the confusion from
the following:
* (defvar var1 (list 1 2 3))
var1
* var1
(1 2 3)
* (defvar var1 (list 'a 'b 'c))
var1
* var1
(1 2 3)
"What?! Why did rCydefvarrCO not change my variable?" (The
documentation for rCydefvarrCO explains why, but it can be
missed by a new user.)
rCydefparameterrCO does not have this behavior and the new user
wants simplicity at this stage.
* (defparameter var2 (list 1 2 3))[snip]
var2
* var2
(1 2 3)
* (defparameter var2 (list 'a 'b 'c))
var2
* var2
(a b c)
So, although rCysetfrCO will change either, a new user who is
playing with various expressions can be confused when, after
changing a rCydefvarrCO expression (and assumes that it has been
changed) finds that the variable they reassigned does not
have the new value.
Eventually, a new user should read the example provided for rCydefvarrCO/rCydefparameterrCO:
"What?! Why did rCydefvarrCO not change my variable?" (The
documentation for rCydefvarrCO explains why, but it can be
missed by a new user.)
The intention is commended, but IMO this is the wrong way to go about it didactically. You should explain defvar does what it does, and then
explain after the variable has been "declared [special]" the way to
change the binding of the variable is through SETQ. Since you are
mutating the binding of a variable (a symbol) you should use SETQ to
signal that point. There is no need to use SETF here since the variable
is not a "generalised reference". (c.f. English Usage and why English distinguishes between "A" and "AN" )
Then the astute new user will cotton on to this and will find it
ridiculous to even imagine that defvar could be used to change a
variable.
rCydefparameterrCO does not have this behavior and the new user
wants simplicity at this stage.
No, this only complicates the situation for the new user. If
Defparameter's sematics are explained clearly the astute new user would
not even think of using defparameter to change the binding of a variable declared and bound through defparameter. He would just use SETQ, (of if
less astute, SETF)
ItrCOs worth bearing in mind what the Common Lisp
documentation on rCydefparameterrCO/rCydefvarrCO says in its
example:
"The choice of whether to use rCydefparameterrCO or rCydefvarrCO
has visible consequences to programs, but is
nevertheless often made for subjective reasons."
ItrCOs worth bearing in mind what the Common Lisp
documentation on rCydefparameterrCO/rCydefvarrCO says in its
example:
"The choice of whether to use rCydefparameterrCO or rCydefvarrCO
has visible consequences to programs, but is
nevertheless often made for subjective reasons."
Yea, IME the important point is that in a given program there should be exactly 1 `defvar` or `defparamter` or `defconstant` per
global variable. That *the* definition of the variable.
With an exception for `(defvar VAR)` which are not *definitions* but
just declarations that the var should be defined elsewhere.
[...]Yea, IME the important point is that in a given program there should be
exactly 1 `defvar` or `defparamter` or `defconstant` per
global variable. That *the* definition of the variable.
With an exception for `(defvar VAR)` which are not *definitions* but
just declarations that the var should be defined elsewhere.
But this is also misleading and purposed to creating confusion in the
reader which will then be manipulated by some "functional agenda"
Better terminology is "the variable will be bound elsewhere". I thinkItrCOs worth bearing in mind what the Common Lisp
documentation on rCydefparameterrCO/rCydefvarrCO says in its
example:
"The choice of whether to use rCydefparameterrCO or rCydefvarrCO
has visible consequences to programs, but is
nevertheless often made for subjective reasons."
Yea, IME the important point is that in a given program there should be exactly 1 `defvar` or `defparamter` or `defconstant` per
global variable. That *the* definition of the variable.
With an exception for `(defvar VAR)` which are not *definitions* but
just declarations that the var should be defined elsewhere.
that defining and binding are different things. Along these lines, I
wished that CL had made it easier to say something liker
(defvar <name> <no-value> <doc-string>)
I would like to be able to declare a name to be treated as special AND include a documentation string without standing on my head or creating
a top-level binding.
(Sometimes I only want a special to be referenced
when I'm in the (dynamic) scope of its binding; I want other
references to signal an error, i.e., I want language conventions to
help enforce a usage category that I've found quite helpful
particularly with multiple cooperating problem-solving threads.)