• Re: Stupid beginner CL question

    From B. Pym@21:1/5 to Wade Scholine on Sat Jul 12 23:12:48 2025
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Wade Scholine on Sun Jul 13 01:11:27 2025
    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. It’s similar to the __setitem__ concept
    in Python (except that works with regular assignment).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Wade Scholine on Sun Jul 13 01:09:00 2025
    Wade Scholine <[email protected]> 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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Monnier@21:1/5 to All on Sun Jul 13 11:36:49 2025
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lars Brinkhoff@21:1/5 to Stefan Monnier on Sun Jul 13 16:29:32 2025
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeff Barnett@21:1/5 to All on Wed Jul 16 00:06:37 2025
    T24gNy8xNS8yMDI1IDM6MTMgUE0sIHRwZXBsdCB3cm90ZToNCj4gV2FkZSBTY2hvbGluZSA8 d3NjaG9saW5lQGdtYWlsLmNvbT4gd3JpdGVzOg0KPiANCj4+IEkgaGF2ZSBkYWJibGVkIHdp dGggbWFueSBmbGF2b3JzIG9mIExJU1Agb3ZlciB0aGUgZGVjYWRlcyBidXQgbmV2ZXINCj4+ IGdvdHRlbiBteSBmZWV0IHdldCB3aXRoIENMIHVudGlsIGp1c3QgdmVyeSByZWNlbnRseS4g SSdtIHVzaW5nIHRoZQ0KPj4gbGF0ZXN0IGFuZCBncmVhdGVzdCBTdGVlbCBCYW5rIENMIHdp dGggZXZlcnl0aGluZyBzZXQgdXAgYXMgaXQgY2FtZSBvdXQNCj4+IG9mIHRoZSBib3gsIGFu ZCBhbSBwdXp6bGVkIGJ5IHRoZSBmYWN0IHRoYXQgSSBhcHBhcmVudGx5IGhhdmUgdG8NCj4+ DQo+PiAgICAoZGVmdmFyIGZvbykNCj4+DQo+PiBiZWZvcmUgSSBhbSBhbGxvd2VkIHRvIChz ZXRxIGZvbyBzb21ldGhpbmcpLiBFdmVuIG1vc3Qgb2YgdGhlIENMDQo+PiB0dXRvcmlhbCBz dHVmZiBkb2VzIG5vdCByZXF1aXJlIGFsbCBpZGVudGlmaWVycyB0byBiZSBkZWNsYXJlZCB1 cCBmcm9udA0KPj4gbGlrZSB0aGF0Lg0KPj4NCj4+IERvIEkgaGF2ZSBzb21lIGtpbmQgb2Yg c3VwZXItcGVkYW50aWMgb3B0aW9uIHR1cm5lZCBvbiB0aGF0IEkgZG9uJ3Qga25vdw0KPj4g YWJvdXQ/DQo+Pg0KPiANCj4gTGlzcCBkb2VzIG5vdCByZXF1aXJlIHRoYXQgeW91IGNyZWF0 ZSB0aGUgZGVmaW5pdGlvbi4gIEl0IGlzDQo+IGlzc3VpbmcgYSB3YXJuaW5nIHNvIHRoYXQg eW91IGFyZSBub3RpZmllZCB0aGF0IHlvdSBoYXZlDQo+IChwb3NzaWJseSBlcnJvbmVvdXNs eSkgc2V0IGEgdmFyaWFibGUgdGhhdCB5b3UgaGF2ZSBub3QNCj4gZGVjbGFyZWQuICBUaGlz IGlzIGhlbHBmdWwgaWYgeW91LCBzYXksIG1pc3NwZWxsIHRoZSBuYW1lIG9mDQo+IGEgdmFy aWFibGUgaW4gYSDigJhzZXRx4oCZIGV4cHJlc3Npb24gaW4gc29tZSBmdW5jdGlvbi4NCj4g DQo+IERlc3BpdGUgdGhlIHdhcm5pbmcsIOKAmHNldHHigJkgaGFzIHNldCB0aGUgdmFyaWFi bGUgdG8gdGhlDQo+IHZhbHVlIHRoYXQgeW91IHNwZWNpZmllZCwgd2hpY2ggeW91IGNhbiBj b25maXJtIGJ5DQo+IGV2YWx1YXRpbmcgaXQgYXQgdGhlIFJFUEwgcHJvbXB0Og0KPiANCj4g KiAoc2V0cSB3YWRlICJzb21lIHN0cmluZyIpDQo+IDsgaW46IFNFVFEgV0FERQ0KPiA7ICAg ICAoU0VUUSBXQURFICJzb21lIHN0cmluZyIpDQo+IDsNCj4gOyBjYXVnaHQgV0FSTklORzoN Cj4gOyAgIHVuZGVmaW5lZCB2YXJpYWJsZTogQ09NTU9OLUxJU1AtVVNFUjo6V0FERQ0KPiA7 DQo+IDsgY29tcGlsYXRpb24gdW5pdCBmaW5pc2hlZA0KPiA7ICAgVW5kZWZpbmVkIHZhcmlh YmxlOg0KPiA7ICAgICBXQURFDQo+IDsgICBjYXVnaHQgMSBXQVJOSU5HIGNvbmRpdGlvbg0K PiAic29tZSBzdHJpbmciDQo+ICogd2FkZQ0KPiAic29tZSBzdHJpbmciDQo+IA0KPiBTbywg eW91IGNhbiBpZ25vcmUgdGhlIHdhcm5pbmcsIG9yIHlvdSBjYW4gYmVnaW4gYWRkaW5nDQo+ IGRlY2xhcmF0aW9ucy4NCj4gDQo+IFlvdSBzaG91bGQgY29uc2lkZXIgdXNpbmcg4oCYZGVm cGFyYW1ldGVy4oCZIGluc3RlYWQgb2Yg4oCYZGVmdmFy4oCZDQo+IGlmIHlvdSB3YW50IHRv IGNoYW5nZSB0aGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlOg0KPiANCj4gICAgIuKAmGRlZnBh cmFtZXRlcuKAmSBhbmQg4oCYZGVmdmFy4oCZIGVzdGFibGlzaCBOQU1FIGFzIGEgZHluYW1p YyB2YXJpYWJsZS4NCj4gDQo+ICAgICDigJhkZWZwYXJhbWV0ZXLigJkgdW5jb25kaXRpb25h bGx5IGFzc2lnbnMgdGhlIElOSVRJQUwtVkFMVUUNCj4gICAgIHRvIHRoZSBkeW5hbWljIHZh cmlhYmxlIG5hbWVkIE5BTUUuICDigJhkZWZ2YXLigJksIGJ5DQo+ICAgICBjb250cmFzdCwg YXNzaWducyBJTklUSUFMLVZBTFVFIChpZiBzdXBwbGllZCkgdG8gdGhlDQo+ICAgICBkeW5h bWljIHZhcmlhYmxlIG5hbWVkIE5BTUUgb25seSBpZiBOQU1FIGlzIG5vdCBhbHJlYWR5DQo+ ICAgICBib3VuZC4iDQoNCkkgdGhpbmsgeW91IG1pZ2h0IGhhdmUgZGVmcGFyYW1ldGVyIGNv bmZ1c2VkIHdpdGggZGVmY29uc3RhbnQgKG9yIA0KZGVmY29uc3QgaW4gc29tZSBpbXBsZW1l bnRhdGlvbnMuIEkgYmVsaWV2ZSB0aGF0IGRlZnZhciBpcyB1c2VkIHdoZW4gdGhlIA0KbmFt ZSBjYW4gYmUgYXNzaWduZWQgb3IgYm91bmQgb3IgYm90aC4gTmFtZXMgaW50cm9kdWNlZCBi eSBkZWZwYXJhbWV0ZXIgDQpjYW4gaGF2ZSB0aGUgdmFsdWVzIGNoYW5nZWQgZ2xvYmFsbHkg YnV0IGFyZSBub3QgZXhwZWN0ZWQgdG8gYmUgcmVib3VuZCANCi0gdGhpbmsgb2YgdGhlbSBh cyBjb25zdGFudHMgZm9yIG9uZSBvciBhIGZldyBydW5zIG9mIHlvdXIgcHJvZ3JhbS4gDQpU aG9zZSBpbnRyb2R1Y2VkIGJ5IGRlZmNvbnN0KGFudCkgYXJlIGFzc3VtZWQgdG8gbm90IGJl IHJlYm91bmQgb3IgDQphc3NpZ25lZDsgaW4gZmFjdCwgYSBjb21waWxlciBtYXkgYnVyeSBy ZWZlcmVuY2VzIHRvIHRoYXQgY29uc3RhbnQgdmFsdWUgDQppbiBjb21waWxlZCBjb2RlIHdo aWNoIHdvdWxkIG1ha2UgdGhlbSByYXRoZXIgaW1wZXJ2aW91cyB0byBhbnkgY2hhbmdlIA0K b3IgYXBwYXJlbnQgdmFsdWUuDQo+PiBBbHNvLCBmcm9tIHRoZSBzYW1wbGUgc3R1ZmYgSSBh bSBzZWVpbmcsIGl0IGFwcGVhcnMgdGhhdA0KPj4gc2V0cSBpcyBvdXQgb2Ygc3R5bGUgZm9y IENMLCBhbmQgcGVvcGxlIHVzZSBzZXRmIGluc3RlYWQ/DQo+PiBJcyB0aGVyZSBhIHBvaW50 ZXIgdG8gYSBoaXN0b3J5IG9mIHRoZSB2YXJpb3VzIHNldCBmb3Jtcw0KPj4gYW5kIHdoYXQg dGhleSdyZSBmb3I/DQo+IA0KPiDigJhzZXRx4oCZIGlzIG1vcmUgbGltaXRlZCBpbiB3aGF0 IGtpbmQgb2YgYXNzaWdubWVudCBpdCBjYW4NCj4gcGVyZm9ybToNCj4gDQo+ICAgICAi4oCY KHNldHEgdmFyMSBmb3JtMSB2YXIyIGZvcm0yIC4uLinigJkgaXMgdGhlIHNpbXBsZQ0KPiAg ICAgIHZhcmlhYmxlIGFzc2lnbm1lbnQgc3RhdGVtZW50IG9mIExpc3AuICBGaXJzdCBGT1JN MSBpcw0KPiAgICAgIGV2YWx1YXRlZCBhbmQgdGhlIHJlc3VsdCBpcyBzdG9yZWQgaW4gdGhl IHZhcmlhYmxlIFZBUjEsDQo+ICAgICAgdGhlbiBGT1JNMiBpcyBldmFsdWF0ZWQgYW5kIHRo ZSByZXN1bHQgc3RvcmVkIGluIFZBUjIsDQo+ICAgICAgYW5kIHNvIGZvcnRoLiAg4oCYc2V0 ceKAmSBtYXkgYmUgdXNlZCBmb3IgYXNzaWdubWVudCBvZiBib3RoDQo+ICAgICAgbGV4aWNh bCBhbmQgZHluYW1pYyB2YXJpYWJsZXMuIg0KPiANCj4gSWYgeW91IGNvbnRpbnVlIHdpdGgg Q29tbW9uIExpc3AsIGV2ZW50dWFsbHkgeW91IHdpbGwgbGVhcm4NCj4gYWJvdXQgImdlbmVy YWxpemVkIHZhcmlhYmxlcyIgb3IgImdlbmVyYWxpemVkIHJlZmVyZW5jZXMiLA0KPiB3aGlj aCBjYW4gYmUgdXNlZCBib3RoIGZvciByZWFkaW5nIGZyb20gYW5kIHdyaXRpbmcgdG8gYQ0K PiBsb2NhdGlvbi4gIOKAmHNldGbigJkgaXMgdXNlZCBmb3Igd3JpdGluZyB0byB0aGVzZSBn ZW5lcmFsaXplZA0KPiB2YXJpYWJsZXMsIGJ1dCBjYW4gYmUgdXNlZCB3aGVyZSDigJhzZXRx 4oCZIGlzIHVzZWQuICAoTGlrZWx5IGZvcg0KPiBzaW1wbGljaXR5LCBtYW55IExpc3AgcHJv Z3JhbW1lcnMgaGF2ZSBkZWNpZGVkIHRoYXQgaXQgaXMNCj4gIm1vZGVybiB1c2FnZSIgdG8g YWx3YXlzIHVzZSDigJhzZXRm4oCZLiktLSANCkplZmYgQmFybmV0dA0KDQoNCg==

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Madhu@21:1/5 to All on Thu Jul 17 20:19:30 2025
    * tpeplt <[email protected]> :
    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 ‘defvar’ not change my variable?" (The
    documentation for ‘defvar’ 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.


    ‘defparameter’ 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 ‘setf’ will change either, a new user who is
    playing with various expressions can be confused when, after
    changing a ‘defvar’ 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 ‘defvar’/‘defparameter’:
    [snip]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Monnier@21:1/5 to All on Thu Jul 17 19:41:29 2025
    It’s worth bearing in mind what the Common Lisp
    documentation on ‘defparameter’/‘defvar’ says in its
    example:

    "The choice of whether to use ‘defparameter’ or ‘defvar’
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Madhu@21:1/5 to All on Fri Jul 18 07:56:22 2025
    * Stefan Monnier <[email protected]> :
    Wrote on Thu, 17 Jul 2025 19:41:29 -0400:

    It’s worth bearing in mind what the Common Lisp
    documentation on ‘defparameter’/‘defvar’ says in its
    example:

    "The choice of whether to use ‘defparameter’ or ‘defvar’
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Monnier@21:1/5 to All on Thu Jul 17 22:42:37 2025
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeff Barnett@21:1/5 to All on Thu Jul 17 23:28:36 2025
    T24gNy8xNy8yMDI1IDU6NDEgUE0sIFN0ZWZhbiBNb25uaWVyIHdyb3RlOg0KPj4gSXTigJlz IHdvcnRoIGJlYXJpbmcgaW4gbWluZCB3aGF0IHRoZSBDb21tb24gTGlzcA0KPj4gZG9jdW1l bnRhdGlvbiBvbiDigJhkZWZwYXJhbWV0ZXLigJkv4oCYZGVmdmFy4oCZIHNheXMgaW4gaXRz DQo+PiBleGFtcGxlOg0KPj4NCj4+ICAgICAiVGhlIGNob2ljZSBvZiB3aGV0aGVyIHRvIHVz ZSDigJhkZWZwYXJhbWV0ZXLigJkgb3Ig4oCYZGVmdmFy4oCZDQo+PiAgICAgIGhhcyB2aXNp YmxlIGNvbnNlcXVlbmNlcyB0byBwcm9ncmFtcywgYnV0IGlzDQo+PiAgICAgIG5ldmVydGhl bGVzcyBvZnRlbiBtYWRlIGZvciBzdWJqZWN0aXZlIHJlYXNvbnMuIg0KPiANCj4gWWVhLCBJ TUUgdGhlIGltcG9ydGFudCBwb2ludCBpcyB0aGF0IGluIGEgZ2l2ZW4gcHJvZ3JhbSB0aGVy ZSBzaG91bGQgYmUNCj4gZXhhY3RseSAxIGBkZWZ2YXJgIG9yIGBkZWZwYXJhbXRlcmAgb3Ig YGRlZmNvbnN0YW50YCBwZXINCj4gZ2xvYmFsIHZhcmlhYmxlLiAgVGhhdCAqdGhlKiBkZWZp bml0aW9uIG9mIHRoZSB2YXJpYWJsZS4NCj4gV2l0aCBhbiBleGNlcHRpb24gZm9yIGAoZGVm dmFyIFZBUilgIHdoaWNoIGFyZSBub3QgKmRlZmluaXRpb25zKiBidXQNCj4ganVzdCBkZWNs YXJhdGlvbnMgdGhhdCB0aGUgdmFyIHNob3VsZCBiZSBkZWZpbmVkIGVsc2V3aGVyZS4NCkJl dHRlciB0ZXJtaW5vbG9neSBpcyAidGhlIHZhcmlhYmxlIHdpbGwgYmUgYm91bmQgZWxzZXdo ZXJlIi4gSSB0aGluayANCnRoYXQgZGVmaW5pbmcgYW5kIGJpbmRpbmcgYXJlIGRpZmZlcmVu dCB0aGluZ3MuIEFsb25nIHRoZXNlIGxpbmVzLCBJIA0Kd2lzaGVkIHRoYXQgQ0wgaGFkIG1h ZGUgaXQgZWFzaWVyIHRvIHNheSBzb21ldGhpbmcgbGlrZXINCg0KICAgIChkZWZ2YXIgPG5h bWU+IDxuby12YWx1ZT4gPGRvYy1zdHJpbmc+KQ0KDQpJIHdvdWxkIGxpa2UgdG8gYmUgYWJs ZSB0byBkZWNsYXJlIGEgbmFtZSB0byBiZSB0cmVhdGVkIGFzIHNwZWNpYWwgQU5EIA0KaW5j bHVkZSBhIGRvY3VtZW50YXRpb24gc3RyaW5nIHdpdGhvdXQgc3RhbmRpbmcgb24gbXkgaGVh ZCBvciBjcmVhdGluZyBhIA0KdG9wLWxldmVsIGJpbmRpbmcuIChTb21ldGltZXMgSSBvbmx5 IHdhbnQgYSBzcGVjaWFsIHRvIGJlIHJlZmVyZW5jZWQgDQp3aGVuIEknbSBpbiB0aGUgKGR5 bmFtaWMpIHNjb3BlIG9mIGl0cyBiaW5kaW5nOyBJIHdhbnQgb3RoZXIgcmVmZXJlbmNlcyAN CnRvIHNpZ25hbCBhbiBlcnJvciwgaS5lLiwgSSB3YW50IGxhbmd1YWdlIGNvbnZlbnRpb25z IHRvIGhlbHAgZW5mb3JjZSBhIA0KdXNhZ2UgY2F0ZWdvcnkgdGhhdCBJJ3ZlIGZvdW5kIHF1 aXRlIGhlbHBmdWwgcGFydGljdWxhcmx5IHdpdGggbXVsdGlwbGUgDQpjb29wZXJhdGluZyBw cm9ibGVtLXNvbHZpbmcgdGhyZWFkcy4pDQotLSANCkplZmYgQmFybmV0dA0KDQo=

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Madhu@21:1/5 to All on Fri Jul 18 15:58:37 2025
    * Jeff Barnett <105cm25$1sc6h$[email protected]> :
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)