• Stupid beginner CL question

    From Wade Scholine@wscholine@gmail.com to comp.lang.lisp on Sat Jul 12 15:19:03 2025
    From Newsgroup: comp.lang.lisp


    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?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From B. Pym@Nobody447095@here-nor-there.org to comp.lang.lisp on Sat Jul 12 23:12:48 2025
    From Newsgroup: comp.lang.lisp

    Wade Scholine wrote:


    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?

    I'm not a CL guru, but the reason is that you are supposed to create
    a variable (using let or defvar, etc.) before you set it.
    It's basically the same way in Scheme:

    gosh> (set! u 8)
    *** ERROR: symbol not defined: #<identifier user#u.1267600>
    gosh> (define u 0)
    u
    gosh> (set! u 8)
    8

    Of course, you can
    (defvar foo something)

    I think that you should consider using Scheme instead of CL.

    Here's what the experts say about CL:

    "an unwieldy, overweight beast"
    "intellectual overload"
    "did kill Lisp"
    "A monstrosity"
    "ignores the basics of language design"
    "killed Lisp"
    "sucks"
    "an aberration"
    "the WORST thing that could possibly happen to LISP"
    "incomprehensible"
    "a nightmare"
    "not commercially viable"
    "no future"
    "a significantly ugly language"
    "hacks"
    "unfortunate"
    "a disaster"
    "bad"


    In context:


    Guy L. Steele, Jr., July 1989:

    I think we may usefully compare the approximate number of pages
    in the defining standard or draft standard for several
    programming languages:

    Common Lisp 1000 or more
    COBOL 810
    ATLAS 790
    Fortran 77 430
    PL/I 420
    BASIC 360
    ADA 340
    Fortran 8x 300
    C 220
    Pascal 120
    DIBOL 90
    Scheme 50


    -----

    Brooks and Gabriel 1984, "A Critique of Common Lisp":

    Every decision of the committee can be locally rationalized
    as the right thing. We believe that the sum of these
    decisions, however, has produced something greater than its
    parts; an unwieldy, overweight beast, with significant costs
    (especially on other than micro-codable personal Lisp
    engines) in compiler size and speed, in runtime performance,
    in programmer overhead needed to produce efficient programs,
    and in intellectual overload for a programmer wishing to be
    a proficient COMMON LISP programmer.

    -----

    Bernard Lang:

    Common Lisp did kill Lisp. Period. (just languages take a
    long time dying ...) It is to Lisp what C++ is to C. A
    monstrosity that totally ignores the basics of language
    design, simplicity and orthogonality to begin with.

    -----

    Gilles Kahn:

    To this day I have not forgotten that Common Lisp killed
    Lisp, and forced us to abandon a perfectly good system,
    LeLisp.

    -----

    Paul Graham (who wrote 2 books about Lisp), May 2001:

    A hacker's language is terse and hackable. Common Lisp is not.

    The good news is, it's not Lisp that sucks, but Common Lisp.

    Historically, Lisp has been good at letting hackers have their
    way. The political correctness of Common Lisp is an aberration.
    Early Lisps let you get your hands on everything.

    A really good language should be both clean and dirty:
    cleanly designed, with a small core of well understood and
    highly orthogonal operators, but dirty in the sense that it
    lets hackers have their way with it. C is like this. So were
    the early Lisps. A real hacker's language will always have a
    slightly raffish character.

    Organic growth seems to yield better technology and richer
    founders than the big bang method. If you look at the
    dominant technologies today, you'll find that most of them
    grew organically. This pattern doesn't only apply to
    companies. You see it in sponsored research too. Multics and
    Common Lisp were big-bang projects, and Unix and MacLisp
    were organic growth projects.

    -----

    Dick Gabriel:

    Common LISP just was never designed to be a commercially
    viable LISP. It was intended to serve as a compromise between
    the manufacturers of LISP machines and other vendors of LISP
    products. Never did we think of it as an industrial strength
    system... So, to the extent that ANSI's ongoing efforts to
    standardize on Common LISP exercise some influence over how LISP
    is accepted in the world at large, I anticipate a disaster.

    -----

    Jeffrey M. Jacobs:

    I think CL is the WORST thing that could possibly happen to LISP.
    In fact, I consider it a language different from "true" LISP.

    *****

    Common LISP is the PL/I of Lisps. Too big and too
    incomprehensible, with no examination of the real world of
    software engineering.

    ... The CL effort resembles a bunch of spoiled children,
    each insisting "include my feature or I'll pull out, and
    then we'll all go down the tubes". Everybody had vested
    interests, both financial and emotional.

    CL is a nightmare; it has effectively killed LISP
    development in this country. It is not commercially viable
    and has virtually no future outside of the traditional academic/defense/research arena.

    -----

    Dick Gabriel:

    Common Lisp is a significantly ugly language. If Guy and I
    had been locked in a room, you can bet it wouldn't have
    turned out like that.

    -----

    Paul Graham:

    Do you really think people in 1000 years want to be
    constrained by hacks that got put into the foundations of
    Common Lisp because a lot of code at Symbolics depended on
    it in 1988?


    -----

    Daniel Weinreb, 24 Feb 2003:

    Having separate "value cells" and "function cells" (to use
    the "street language" way of saying it) was one of the most
    unfortunate issues. We did not want to break pre-existing
    programs that had a global variable named "foo" and a global
    function named "foo" that were distinct. We at Symbolics
    were forced to insist on this, in the face of everyone's
    knowing that it was not what we would have done absent
    compatibility constraints. It's hard for me to remember all
    the specific things like this, but if we had had fewer
    compatibility issues, I think it would have come out looking
    more like Scheme in general.

    -----

    Daniel Weinreb, 28 Feb 2003:

    Lisp2 means that all kinds of language primitives have to
    exist in two versions, or be parameterizable as to whether
    they are talking about the value cell or function cell. It
    makes the language bigger, and that's bad in and of itself.



    What about the LOOP macro, upon which most users of CL are
    completely dependent?

    Paul Graham:

    I consider Loop one of the worst flaws in CL, and an example
    to be borne in mind by both macro writers and language designers.


    [In "ANSI Common Lisp", Graham makes the following comments:]

    The loop macro was originally designed to help inexperienced
    Lisp users write iterative code. Instead of writing Lisp code,
    you express your program in a form meant to resemble English,
    and this is then translated into Lisp. Unfortunately, loop is
    more like English than its designers ever intended: you can
    use it in simple cases without quite understanding how it
    works, but to understand it in the abstract is almost
    impossible.
    ....
    the ANSI standard does not really give a formal specification
    of its behavior.
    ....
    The first thing one notices about the loop macro is that it
    has syntax. A loop expression contains not subexpressions but
    clauses. The clauses are not delimited by parentheses;
    instead, each kind has a distinct syntax. In that, loop
    resembles traditional Algol-like languages. But the other
    distinctive feature of loop, which makes it as unlike Algol as
    Lisp, is that the order in which things happen is only
    loosely related to the order in which the clauses occur.
    ....
    For such reasons, the use of loop cannot be recommended.


    Dan Weinreb, one of the designers of Common Lisp:

    ... the problem with LOOP was that it turned out to be hard to
    predict what it would do, when you started using a lot of
    different facets of LOOP all together. This is a serious problem
    since the whole idea of LOOP was to let you use many facets
    together; if you're not doing that, LOOP is overkill.


    Barry Margolin:

    My recommendation is based on seeing many question in the past
    of the form "What happens if you use both XXX and YYY in the
    same LOOP?" The unfortunate fact is that when we were writing
    the standard we didn't have time to nail down all the possible
    interactions between different LOOP features, so many of these
    are not well specified. And even if we did get it right in
    the standard, it's likely to be difficult to find them and I
    wouldn't trust that all implementors got it right (many of
    those questions were probably from implementors, trying to
    figure out what they were supposed to do). And even if they
    all got it right, someone reading your code may not be able to
    figure it out.

    So, with all those potential problems, my feeling is that if
    you have to ask, it's probably better to use something other
    than LOOP.


    Barry Margolin:

    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.

    But it is! Because any use of LOOP has the potential to be
    unreadable, the reader must read it carefully to verify that
    it's just one of the cases that doesn't require careful
    reading!


    Barry Margolin (1997-01-08)

    There are a few things that can be done extremely conveniently
    with LOOP, and I will usually use LOOP in those cases. In
    particular, the COLLECTING feature is one of the most
    convenient.

    The Generators and Collectors macros described in Appendix B
    of CLtL2 also provide this convenience and are much more
    Lisp-like. It's too bad they weren't around when LOOP was
    gaining popularity, and I think they're a better way to go.
    But LOOP is what I got used to, and its popularity is why it
    got elevated into the ANSI standard.


    Barry Margolin: (05 Apr 2002 20:57:48 GMT)

    This seems like a big change just to clean up the way LOOP is described.
    And LOOP will still be a wart, because it will be the only language feature that uses "per-macro keywords". Providing this interface and giving a name
    to them would encourage other macro designers to do something similar, and
    we don't want more things like LOOP.


    John Foderaro:

    I'm not trying to join a debate on loop. I just wanted to present
    the other side of [the issue so that] the intelligent people can
    then weigh the arguments on both sides.

    I'm not suggesting that loop can be fixed either by adding
    parenthesis or coming up with ways of indenting it to make it
    understandable. It's a lost cause.

    ...

    Another great example from kmp:

    === from kmp

    For example, you might think
    (loop with i = (random 100) for x from 1 to 10 do (print (list i x)))
    and
    (loop for i = (random 100) for x from 1 to 10 do (print (list i x)))
    meant the same in English, [but they don't do the same thing in loop]

    === end kmp

    loop lulls you into thinking that you understand the program since
    you understand English. Make no mistake about it, loop is its
    own language. If you use it you condemn everyone who reads the
    code to also learn the loop language.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence D'Oliveiro@ldo@nz.invalid to comp.lang.lisp on Sun Jul 13 01:11:27 2025
    From Newsgroup: comp.lang.lisp

    On Sat, 12 Jul 2025 15:19:03 -0400, Wade Scholine wrote:

    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?

    setf is a generalization of setq. setq only works on simple variable
    names. setf allows more complex objects to define what it means to perform assignment to selected components. ItrCOs similar to the __setitem__ concept in Python (except that works with regular assignment).
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Paul Rubin@no.email@nospam.invalid to comp.lang.lisp on Sun Jul 13 01:09:00 2025
    From Newsgroup: comp.lang.lisp

    Wade Scholine <wscholine@gmail.com> writes:
    Do I have some kind of super-pedantic option turned on that I don't know about?

    (setf foo 3) in sbcl works for me but gives a warning message, not an
    error.

    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.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Stefan Monnier@monnier@iro.umontreal.ca to comp.lang.lisp on Sun Jul 13 11:36:49 2025
    From Newsgroup: comp.lang.lisp

    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.

    Yeah: `setq` is a special form to mutate a variable, whereas `setf` is
    a macro that can mutate any "place" (array-element, variable, you name
    it).

    `setf` is extensible and complex, so making it into a special-form
    is undesirable. But `setf` can't work without having lower-level
    primitives like `setq`.

    In Scheme, you can *re*define a `setq` special form as a macro (which
    expands to uses of the original special form definition), but I don't
    know how to do that portably in Common Lisp. There are lots of
    solutions in practice, of course, but the historical path taken leaves
    its marks.


    Stefan
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lars Brinkhoff@lars.spam@nocrew.org to comp.lang.lisp on Sun Jul 13 16:29:32 2025
    From Newsgroup: comp.lang.lisp

    Stefan Monnier wrote:
    Paul Rubin:
    setf is a clever macro that can update a bunch of different types of
    mutable objects, rather than just symbol values.
    Yeah: `setq` is a special form to mutate a variable, whereas `setf` is
    a macro that can mutate any "place"

    But remember:
    "If any var refers to a binding made by symbol-macrolet, then that var
    is treated as if setf (not setq) had been used."

    https://www.lispworks.com/documentation/HyperSpec/Body/s_setq.htm
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From tpeplt@tpeplt@gmail.com to comp.lang.lisp on Tue Jul 15 17:13:26 2025
    From Newsgroup: comp.lang.lisp

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

    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?

    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.)
    --
    The lyf so short, the craft so long to lerne.
    - Geoffrey Chaucer, The Parliament of Birds.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Jeff Barnett@jbb@notatt.com to comp.lang.lisp on Wed Jul 16 00:06:37 2025
    From Newsgroup: comp.lang.lisp

    On 7/15/2025 3:13 PM, tpeplt wrote:
    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."

    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.
    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?

    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.)--
    Jeff Barnett


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From tpeplt@tpeplt@gmail.com to comp.lang.lisp on Wed Jul 16 18:55:17 2025
    From Newsgroup: comp.lang.lisp

    Jeff Barnett <jbb@notatt.com> writes:

    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.

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

    https://www.lispworks.com/documentation/HyperSpec/Body/m_defpar.htm#defparameter

    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.

    SBCL will signal a condition when a (defconstant ...) is
    assigned a new value and then allow the constant to be
    changed. It will signal a compile-time error if rCysetfrCO
    attempts to change a rCydefconstantrCO.
    --
    The lyf so short, the craft so long to lerne.
    - Geoffrey Chaucer, The Parliament of Birds.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Madhu@enometh@meer.net to comp.lang.lisp on Thu Jul 17 20:19:30 2025
    From Newsgroup: comp.lang.lisp

    * tpeplt <87cy9zu4oa.fsf@gmail.com> :
    Wrote on Wed, 16 Jul 2025 18:55:17 -0400:

    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.)

    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)

    * (defparameter var2 (list 1 2 3))
    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:
    [snip]

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From tpeplt@tpeplt@gmail.com to comp.lang.lisp on Thu Jul 17 19:33:41 2025
    From Newsgroup: comp.lang.lisp

    Madhu <enometh@meer.net> writes:

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


    You might be right that that is the correct approach, or
    not. If you have several years of teaching Common Lisp to
    classes and trying different approaches (I donrCOt), then I
    will defer to your experience. If not, then it is a matter
    of opinion and that cannot be a substitute for measuring
    what works better and resolves confusion by teaching
    students. Of course, even teaching Common Lisp is different
    from this situation where someone is self-teaching, without
    all of the feedback that a classroom could provide.

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

    I hope that the original poster has been able to read and
    understand some of the previous responses and get past their
    problems with using Common Lisp up to this point.
    --
    The lyf so short, the craft so long to lerne.
    - Geoffrey Chaucer, The Parliament of Birds.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Stefan Monnier@monnier@iro.umontreal.ca to comp.lang.lisp on Thu Jul 17 19:41:29 2025
    From Newsgroup: comp.lang.lisp

    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.


    Stefan
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Madhu@enometh@meer.net to comp.lang.lisp on Fri Jul 18 07:56:22 2025
    From Newsgroup: comp.lang.lisp

    * Stefan Monnier <jwvfreugzfr.fsf-monnier+comp.lang.lisp@gnu.org> :
    Wrote on Thu, 17 Jul 2025 19:41:29 -0400:

    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.

    But this is also misleading and purposed to creating confusion in the
    reader which will then be manipulated by some "functional agenda"

    There are only 2 operators in question. defparameter and defvar. the
    semantics are defined clearly, instead of accepting the semantics you
    are reading your prejudices into the semantics and inclining your
    students and followers to the same [unwarranted] prejudices.

    defparameter used a second time will mutate the binding as a side
    effect. it is not just a declaration as you want to make it to be.

    (defvar var) the first time is an important idiom to declare a special
    variable withoot a binding.

    calling it a second time after the variable has been bound does not mean anything. same as calling (defvar var val) after var has been assigned.

    without pointing out the right way to use these functions i.e. to mutate
    the bindings with setq and setf.

    so while you started off with the right idea that defvar and
    defparameter should occur only once, you are still misleading your
    students into saying these declarations can appear at other places. This
    is not common lisp and this sort of propganda is calculated to produce
    disgust at common lisp in new users, it's overboard coming from a
    respected person like you but the functional schemers behind the agenda
    then rub their hands in glee.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Stefan Monnier@monnier@iro.umontreal.ca to comp.lang.lisp on Thu Jul 17 22:42:37 2025
    From Newsgroup: comp.lang.lisp

    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"
    [...]

    I must be blinded by some "functional agenda" because I have no idea
    what you're trying to say.


    Stefan
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Jeff Barnett@jbb@notatt.com to comp.lang.lisp on Thu Jul 17 23:28:36 2025
    From Newsgroup: comp.lang.lisp

    On 7/17/2025 5:41 PM, Stefan Monnier wrote:
    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.
    Better terminology is "the variable will be bound elsewhere". I think
    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.)
    --
    Jeff Barnett

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Madhu@enometh@meer.net to comp.lang.lisp on Fri Jul 18 15:58:37 2025
    From Newsgroup: comp.lang.lisp


    * Jeff Barnett <105cm25$1sc6h$3@dont-email.me> :
    Wrote on Thu, 17 Jul 2025 23:28:36 -0600:

    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.

    It's a 2 line macro away if once you decide how to represent <no-value>.
    and decide what to do if <name> exists and has properties or
    documetation attached. or 3 lines.

    1. optionally MAKUNBOUND name, 2. proclaim it special with an empty defvar
    and 3. (setf (documentation <name> 'variable>) doc)

    The hard problem is to represent <no-value> and to decide what to do
    with an existing 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.)

    I too find this useful. The implementation looks clumsy at first, but
    the assembler bits at dealing with dynamic scope and bindings are there,
    i think.

    languages provide syntactic sugar for set idioms lack the tools of
    throwing (and catching) a dynamic type error or dynamic unbound error,
    and even count those as negative design.
    --- Synchronet 3.21a-Linux NewsLink 1.2