From: cartercc
Subject: idiomatic Lisp style
Date: 
Message-ID: <2ac51fd3-f279-493b-94a5-62c190cae24a@33g2000yqm.googlegroups.com>
The following script averages a series of grades from console input. I
wrote it as if I would write a C program -- obviously not in idiomatic
Lisp. How would one rewrite this in idiomatic Lisp?

CC

(progn
           (setq total 0)
           (setq count 0)
           (setq avg 0)
           (loop
            (princ "Enter next grade, 'Q' to quit: ")
            (setq grade (read))
            (if (not (numberp grade)) (return (format t "~%Average is
~g~%" avg)))
            (setq total (+ total grade))
            (setq count (+ count 1))
            (setq avg (/ total count))
            (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
grade total count avg)))

From: Geoffrey Summerhayes
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <5af53bc1-cbb3-4cf5-8408-d3c4c35b5604@g38g2000yqd.googlegroups.com>
On Feb 11, 11:34 am, cartercc <········@gmail.com> wrote:
> The following script averages a series of grades from console input. I
> wrote it as if I would write a C program -- obviously not in idiomatic
> Lisp. How would one rewrite this in idiomatic Lisp?
>
> CC
>
> (progn
>            (setq total 0)
>            (setq count 0)
>            (setq avg 0)

google comp.lang.lisp with 'setq establish binding'

>            (loop
>             (princ "Enter next grade, 'Q' to quit: ")
>             (setq grade (read))
>             (if (not (numberp grade)) (return (format t "~%Average is
> ~g~%" avg)))
>             (setq total (+ total grade))
>             (setq count (+ count 1))
>             (setq avg (/ total count))
>             (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
> grade total count avg)))

LOOP packs more punch:

(loop for grade = (progn
                    (princ "Enter next grade, 'Q' to quit:")
                    (read))
      while (numberp grade)
      summing grade into total
      counting grade into count
      do (format *standard-output*
                 "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
                 grade total count (/ total count))
      finally (format *standard-output*
                      "~%Average is ~g~%"
                      (/ total count)))

--
Geoff
From: Marco Antoniotti
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <70e7ab28-8f92-4ceb-8594-3270ea1d6eb9@j35g2000yqh.googlegroups.com>
On Feb 11, 5:34 pm, cartercc <········@gmail.com> wrote:
> The following script averages a series of grades from console input. I
> wrote it as if I would write a C program -- obviously not in idiomatic
> Lisp. How would one rewrite this in idiomatic Lisp?
>
> CC
>
> (progn
>            (setq total 0)
>            (setq count 0)
>            (setq avg 0)
>            (loop
>             (princ "Enter next grade, 'Q' to quit: ")
>             (setq grade (read))
>             (if (not (numberp grade)) (return (format t "~%Average is
> ~g~%" avg)))
>             (setq total (+ total grade))
>             (setq count (+ count 1))
>             (setq avg (/ total count))
>             (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
> grade total count avg)))

Almost like Zach's with verbose loop.

(defun lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy ()
  (loop with total = 0.0
        with count = 0
        with avg   = 0.0
        initially (princ "Enter next grade, 'Q' to quit: ")
        for grade = (read *standard-input* nil t)
        while (numberp grade)
        sum grade into total
        count grade into count
        do (setf avg (/ total count))
        do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
                           Enter next grade, 'Q' to quit: "
                   grade total count avg)
        finally (format t "~&Average is ~G~%" avg)))

(compile 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)
(disassemble 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)


Cheers
--
Marco
From: Geoffrey Summerhayes
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <b6c4c56d-8baa-410e-87e4-8d6010ede866@s20g2000yqh.googlegroups.com>
On Feb 11, 12:37 pm, Marco Antoniotti <·······@gmail.com> wrote:
>
> Almost like Zach's with verbose loop.
>
> (defun lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy ()
>   (loop with total = 0.0
>         with count = 0
>         with avg   = 0.0
>         initially (princ "Enter next grade, 'Q' to quit: ")
>         for grade = (read *standard-input* nil t)
>         while (numberp grade)
>         sum grade into total
>         count grade into count
>         do (setf avg (/ total count))
>         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
>                            Enter next grade, 'Q' to quit: "
>                    grade total count avg)
>         finally (format t "~&Average is ~G~%" avg)))
>
> (compile 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)

LW 5.1.1

CL-USER 2 > (compile 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-
guy)

Error: Duplicate binding in LOOP: (COUNT TOTAL)
  1 (abort) Return to level 0.
  2 Return to top loop level 0.

--
Geoff
From: Marco Antoniotti
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <b43ea9fd-ef83-4f2f-b699-59e2312cd0a4@l16g2000yqo.googlegroups.com>
On Feb 11, 6:59 pm, Geoffrey Summerhayes <·······@gmail.com> wrote:
> On Feb 11, 12:37 pm, Marco Antoniotti <·······@gmail.com> wrote:
>
>
>
>
>
> > Almost like Zach's with verbose loop.
>
> > (defun lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy ()
> >   (loop with total = 0.0
> >         with count = 0
> >         with avg   = 0.0
> >         initially (princ "Enter next grade, 'Q' to quit: ")
> >         for grade = (read *standard-input* nil t)
> >         while (numberp grade)
> >         sum grade into total
> >         count grade into count
> >         do (setf avg (/ total count))
> >         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
> >                            Enter next grade, 'Q' to quit: "
> >                    grade total count avg)
> >         finally (format t "~&Average is ~G~%" avg)))
>
> > (compile 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)
>
> LW 5.1.1
>
> CL-USER 2 > (compile 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-
> guy)
>
> Error: Duplicate binding in LOOP: (COUNT TOTAL)
>   1 (abort) Return to level 0.
>   2 Return to top loop level 0.
>
> --
> Geoff

Oooops.  Never edit working code before posting....

(defun lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy ()
  (loop with avg   = 0.0
        initially (princ "Enter next grade, 'Q' to quit: ")
        for grade = (read *standard-input* nil t)
        while (numberp grade)
        sum grade into total
        count grade into count
        do (setf avg (/ total count))
        do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
                           Enter next grade, 'Q' to quit: "
                   grade total count avg)
        finally (format t "~&Average is ~G~%" avg)))

(compile 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)
(disassemble 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)

Cheers
--
Marco
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <772fc5c5-4d94-477d-b696-84bf6cbdfc10@k8g2000yqn.googlegroups.com>
On Feb 11, 1:12 pm, Marco Antoniotti <·······@gmail.com> wrote:
> Oooops.  Never edit working code before posting....
>
> (defun lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy ()
>   (loop with avg   = 0.0
>         initially (princ "Enter next grade, 'Q' to quit: ")
>         for grade = (read *standard-input* nil t)
>         while (numberp grade)
>         sum grade into total
>         count grade into count
>         do (setf avg (/ total count))
>         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
>                            Enter next grade, 'Q' to quit: "
>                    grade total count avg)
>         finally (format t "~&Average is ~G~%" avg)))
>
> (compile 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)
> (disassemble 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)
>
> Cheers
> --
> Marco

Ran your code. Couldn't understand all of it but am working on it -
appreciate your help in seeing idiomatic Lisp.

Output below. Apparently needs a priming read as it doesn't prompt the
user for the first input.

CC

--------------begin output---------------
CL-USER> (gr-anton)
99
Enter next grade, 'Q' to quit: Grade: 99, total: 99, count: 1,
average: 99.
Enter next grade, 'Q' to quit: 98
Grade: 98, total: 197, count: 2, average: 98.5
Enter next grade, 'Q' to quit: 97
Grade: 97, total: 294, count: 3, average: 98.
Enter next grade, 'Q' to quit: 96
Grade: 96, total: 390, count: 4, average: 97.5
Enter next grade, 'Q' to quit: 95
Grade: 95, total: 485, count: 5, average: 97.
Enter next grade, 'Q' to quit: q

Average is 97.
NIL
CL-USER>
-------------------end output---------------
From: Marco Antoniotti
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <82bedbae-cce0-4161-8edd-6ceb322e535a@q9g2000yqc.googlegroups.com>
On Feb 12, 2:47 pm, cartercc <········@gmail.com> wrote:
> On Feb 11, 1:12 pm, Marco Antoniotti <·······@gmail.com> wrote:
>
>
>
> > Oooops.  Never edit working code before posting....
>
> > (defun lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy ()
> >   (loop with avg   = 0.0
> >         initially (princ "Enter next grade, 'Q' to quit: ")
> >         for grade = (read *standard-input* nil t)
> >         while (numberp grade)
> >         sum grade into total
> >         count grade into count
> >         do (setf avg (/ total count))
> >         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
> >                            Enter next grade, 'Q' to quit: "
> >                    grade total count avg)
> >         finally (format t "~&Average is ~G~%" avg)))
>
> > (compile 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)
> > (disassemble 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)
>
> > Cheers
> > --
> > Marco
>
> Ran your code. Couldn't understand all of it but am working on it -
> appreciate your help in seeing idiomatic Lisp.
>
> Output below. Apparently needs a priming read as it doesn't prompt the
> user for the first input.
>
> CC
>
> --------------begin output---------------
> CL-USER> (gr-anton)
> 99
> Enter next grade, 'Q' to quit: Grade: 99, total: 99, count: 1,
> average: 99.
> Enter next grade, 'Q' to quit: 98
> Grade: 98, total: 197, count: 2, average: 98.5
> Enter next grade, 'Q' to quit: 97
> Grade: 97, total: 294, count: 3, average: 98.
> Enter next grade, 'Q' to quit: 96
> Grade: 96, total: 390, count: 4, average: 97.5
> Enter next grade, 'Q' to quit: 95
> Grade: 95, total: 485, count: 5, average: 97.
> Enter next grade, 'Q' to quit: q
>
> Average is 97.
> NIL
> CL-USER>
> -------------------end output---------------

That's because you are not using my function.  Mine is called
lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy.

Cheers
--
Marco
From: Slobodan Blazeski
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <6136ef2f-c440-4d39-81b4-e9d5a5946413@x9g2000yqk.googlegroups.com>
On Feb 12, 3:27 pm, Marco Antoniotti <·······@gmail.com> wrote:
> On Feb 12, 2:47 pm, cartercc <········@gmail.com> wrote:
>
>
>
>
>
> > On Feb 11, 1:12 pm, Marco Antoniotti <·······@gmail.com> wrote:
>
> > > Oooops.  Never edit working code before posting....
>
> > > (defun lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy ()
> > >   (loop with avg   = 0.0
> > >         initially (princ "Enter next grade, 'Q' to quit: ")
> > >         for grade = (read *standard-input* nil t)
> > >         while (numberp grade)
> > >         sum grade into total
> > >         count grade into count
> > >         do (setf avg (/ total count))
> > >         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
> > >                            Enter next grade, 'Q' to quit: "
> > >                    grade total count avg)
> > >         finally (format t "~&Average is ~G~%" avg)))
>
> > > (compile 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)
> > > (disassemble 'lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy)
>
> > > Cheers
> > > --
> > > Marco
>
> > Ran your code. Couldn't understand all of it but am working on it -
> > appreciate your help in seeing idiomatic Lisp.
>
> > Output below. Apparently needs a priming read as it doesn't prompt the
> > user for the first input.
>
> > CC
>
> > --------------begin output---------------
> > CL-USER> (gr-anton)
> > 99
> > Enter next grade, 'Q' to quit: Grade: 99, total: 99, count: 1,
> > average: 99.
> > Enter next grade, 'Q' to quit: 98
> > Grade: 98, total: 197, count: 2, average: 98.5
> > Enter next grade, 'Q' to quit: 97
> > Grade: 97, total: 294, count: 3, average: 98.
> > Enter next grade, 'Q' to quit: 96
> > Grade: 96, total: 390, count: 4, average: 97.5
> > Enter next grade, 'Q' to quit: 95
> > Grade: 95, total: 485, count: 5, average: 97.
> > Enter next grade, 'Q' to quit: q
>
> > Average is 97.
> > NIL
> > CL-USER>
> > -------------------end output---------------
>
> That's because you are not using my function.  Mine is called
> lets-use-cl-as-a-sldj-while-waiting-for-the-ruby-guy.
Another entry for my blog post. http://tourdelisp.blogspot.com/2008/03/real-lispers.html
Real Lispers use very-long-and-descriptive-hyphenated-names

thanks  Marco

bobi
>
> Cheers
> --
> Marco
From: Tobias C. Rittweiler
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <873aejik9m.fsf@freebits.de>
Slobodan Blazeski <·················@gmail.com> writes:

> Another entry for my blog post. http://tourdelisp.blogspot.com/2008/03/real-lispers.html
> Real Lispers use very-long-and-descriptive-hyphenated-names

Brucio, is that you?

  -T.
From: Slobodan Blazeski
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <c9f52bf3-eab5-4744-91e7-944982109da3@l39g2000yqn.googlegroups.com>
On Feb 12, 7:26 pm, "Tobias C. Rittweiler" <····@freebits.de.invalid>
wrote:
> Slobodan Blazeski <·················@gmail.com> writes:
> > Another entry for my blog post.http://tourdelisp.blogspot.com/2008/03/real-lispers.html
> > Real Lispers use very-long-and-descriptive-hyphenated-names
>
> Brucio, is that you?
Who's Brucio?

bobi
>
>   -T.
From: Slobodan Blazeski
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <75184b4d-807d-4646-9688-9baed39f3534@v39g2000yqm.googlegroups.com>
On Feb 12, 6:23 pm, cartercc <········@gmail.com> wrote:
> Yes, I didn't rename the recursive call. When I copied all the
> functions to one file, I had renamed it, but this must have come from
> my intermediate version. Anyway, the code works, and I think I like
> your version the best, mainly because it avoids the loop.

Thank you for your kind words, when you feel ready please consider
joining the club of extended loop haters, functional style bigots and
OO loathers. There is no entry fee but as per out first chairman
recommendation there is tax on every use of:
set setq setf psetf psetq incf decf push pop pushnew
rplaca rplacd rotatef shiftf remf remprop remhash


cheers
Bobi
From: Rob Warnock
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <XvadnTojd5Xd_QjUnZ2dnUVZ_qvinZ2d@speakeasy.net>
cartercc  <········@gmail.com> wrote:
+---------------
| Output below. Apparently needs a priming read as it doesn't prompt
| the user for the first input.
+---------------

It doesn't need a "priming READ"; it needs[1] a FORCE-OUTPUT after
the initial PRINC, and possibly after the main FORMAT as well.


-Rob

[1] Well, whether it *needs* it or not is implementation-dependent,
    but adding FORCE-OUTPUT will portably make it work.

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Alexander Lehmann
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <gmv2u4$4im$1@online.de>
Marco Antoniotti wrote:
>   (loop with total = 0.0
>         with count = 0
>         with avg   = 0.0
>         initially (princ "Enter next grade, 'Q' to quit: ")
>         for grade = (read *standard-input* nil t)
>         while (numberp grade)
>         sum grade into total
>         count grade into count
>         do (setf avg (/ total count))
>         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
>                            Enter next grade, 'Q' to quit: "
>                    grade total count avg)
>         finally (format t "~&Average is ~G~%" avg)))

Oh my... LOOP is such a beast ;-) I think I'll hang a printed copy of that on
the wall and do a daily prayer...
From: Phil Armitage
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <89184239-ca7c-451d-ac1f-1692a02a0584@v13g2000yqm.googlegroups.com>
On 11 Feb, 17:46, Alexander Lehmann <········@in.tum.de> wrote:
> Marco Antoniotti wrote:
> >   (loop with total = 0.0
> >         with count = 0
> >         with avg   = 0.0
> >         initially (princ "Enter next grade, 'Q' to quit: ")
> >         for grade = (read *standard-input* nil t)
> >         while (numberp grade)
> >         sum grade into total
> >         count grade into count
> >         do (setf avg (/ total count))
> >         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
> >                            Enter next grade, 'Q' to quit: "
> >                    grade total count avg)
> >         finally (format t "~&Average is ~G~%" avg)))
>
> Oh my... LOOP is such a beast ;-) I think I'll hang a printed copy of that on
> the wall and do a daily prayer...

It really is! The beauty of Marco's solution is that it reads like
prose so is nice and easy to see what it's doing. Not that I always
write loops like this but when you have the power of a looping DSL it
really is tempting :-)

--
Phil
http://phil.nullable.eu/
From: Marco Antoniotti
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <6a69db53-40a2-4c88-955c-722c579ca695@b16g2000yqb.googlegroups.com>
On Feb 11, 6:52 pm, Phil Armitage <···············@gmail.com> wrote:
> On 11 Feb, 17:46, Alexander Lehmann <········@in.tum.de> wrote:
>
>
>
> > Marco Antoniotti wrote:
> > >   (loop with total = 0.0
> > >         with count = 0
> > >         with avg   = 0.0
> > >         initially (princ "Enter next grade, 'Q' to quit: ")
> > >         for grade = (read *standard-input* nil t)
> > >         while (numberp grade)
> > >         sum grade into total
> > >         count grade into count
> > >         do (setf avg (/ total count))
> > >         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
> > >                            Enter next grade, 'Q' to quit: "
> > >                    grade total count avg)
> > >         finally (format t "~&Average is ~G~%" avg)))
>
> > Oh my... LOOP is such a beast ;-) I think I'll hang a printed copy of that on
> > the wall and do a daily prayer...
>
> It really is! The beauty of Marco's solution is that it reads like
> prose so is nice and easy to see what it's doing. Not that I always
> write loops like this but when you have the power of a looping DSL it
> really is tempting :-)

Some'd say it reads like COBOL :)

Cheers
--
Marco
From: Matthias Buelow
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <6vgn4vFjibulU1@mid.dfncis.de>
Phil Armitage wrote:

> easy to see what it's doing.

Is it? How far does the "while" extend, for example? Does it include the
two "do"s? It isn't even indented as to give any clue about that.

(IMHO, it's an abomination...)
From: Thomas A. Russ
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <ymir624h1wa.fsf@blackcat.isi.edu>
Matthias Buelow <···@incubus.de> writes:

> Phil Armitage wrote:
> 
> > easy to see what it's doing.
> 
> Is it? How far does the "while" extend, for example? Does it include
> the two "do"s? It isn't even indented as to give any clue about that.

"while" is easy, since it's a termination clause.  It includes
everything in the loop body except what is in the "finally" clause.  Now
if you wanted to talk about "when"....


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Barry Margolin
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <barmar-C6EBC0.18041711022009@mara100-84.onlink.net>
In article <··············@mid.dfncis.de>,
 Matthias Buelow <···@incubus.de> wrote:

> Phil Armitage wrote:
> 
> > easy to see what it's doing.
> 
> Is it? How far does the "while" extend, for example? Does it include the
> two "do"s? It isn't even indented as to give any clue about that.
> 
> (IMHO, it's an abomination...)

Use a good editor that knows how to indent it, and then the structure 
becomes pretty obvious.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Marco Antoniotti
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <aec3cd64-b907-499f-89c6-8c386b742fdd@x10g2000yqk.googlegroups.com>
On Feb 11, 8:27 pm, Matthias Buelow <····@incubus.de> wrote:
> Phil Armitage wrote:
> > easy to see what it's doing.
>
> Is it? How far does the "while" extend, for example? Does it include the
> two "do"s? It isn't even indented as to give any clue about that.

STrangely enough it is indented correctly.  WHILE is a 'termination'
clause.  I remember reading an article about the Loop 1/2 statement (I
think it may have been the "GOTO considered harmful"; show how old I
am).

> (IMHO, it's an abomination...)

Wow.  What'd you call the Ruby version then? :)

Cheers
--
Marco
From: Slobodan Blazeski
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <a2535a29-fe49-4976-97df-d8fe41068335@c12g2000yqj.googlegroups.com>
On Feb 11, 6:46 pm, Alexander Lehmann <········@in.tum.de> wrote:
> Marco Antoniotti wrote:
> >   (loop with total = 0.0
> >         with count = 0
> >         with avg   = 0.0
> >         initially (princ "Enter next grade, 'Q' to quit: ")
> >         for grade = (read *standard-input* nil t)
> >         while (numberp grade)
> >         sum grade into total
> >         count grade into count
> >         do (setf avg (/ total count))
> >         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
> >                            Enter next grade, 'Q' to quit: "
> >                    grade total count avg)
> >         finally (format t "~&Average is ~G~%" avg)))
>
> Oh my... LOOP is such a beast ;-) I think I'll hang a printed copy of that on
> the wall and do a daily prayer...

Our father in heaven hear my prayer
forgive me for creating unnecessary variables
and especially for mutating them
and grant me your pardon for every let and setf I wrote
and for ignoring the beauty of s-expression
and especially for using stinking loops
amen


But don't worry help is on the way

cheers
bobi
From: Alexander Lehmann
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <gn0d9j$7sm$1@online.de>
Slobodan Blazeski wrote:
>> Oh my... LOOP is such a beast ;-) I think I'll hang a printed copy of that on
>> the wall and do a daily prayer...
> 
> Our father in heaven hear my prayer
> forgive me for creating unnecessary variables
> and especially for mutating them
> and grant me your pardon for every let and setf I wrote
> and for ignoring the beauty of s-expression
> and especially for using stinking loops
> amen

Now I lay me down to sleep
I pray the LOOP my soul to keep
When in the morning light I wake
Teach me the path of LISP to take.

No offense :)
From: Slobodan Blazeski
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <ee2b43af-3e87-4bf4-9cc3-90a7d88400ff@x9g2000yqk.googlegroups.com>
On Feb 12, 6:49 am, Alexander Lehmann <········@in.tum.de> wrote:
> Slobodan Blazeski wrote:
> >> Oh my... LOOP is such a beast ;-) I think I'll hang a printed copy of that on
> >> the wall and do a daily prayer...
>
> > Our father in heaven hear my prayer
> > forgive me for creating unnecessary variables
> > and especially for mutating them
> > and grant me your pardon for every let and setf I wrote
> > and for ignoring the beauty of s-expression
> > and especially for using stinking loops
> > amen
>
> Now I lay me down to sleep
> I pray the LOOP my soul to keep
> When in the morning light I wake
> Teach me the path of LISP to take.
>
> No offense :)
LOL. Oh I need several full days of free time to integrate array
operators with built in looping into lisp and maybe tacit operator.
Then we won't have to rely on loop so much. In the mean time enjoy
steven apter code http://www.nsl.com/papers/kisntlisp.htm

cheers
bobi
From: ·········@yahoo.com
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <0d7883f6-561a-4fa5-9f20-4a199ec62ca3@t13g2000yqc.googlegroups.com>
On Feb 11, 10:34 am, cartercc <········@gmail.com> wrote:
> The following script averages a series of grades from console input. I
> wrote it as if I would write a C program -- obviously not in idiomatic
> Lisp. How would one rewrite this in idiomatic Lisp?
>
> CC
>
> (progn
>            (setq total 0)
>            (setq count 0)
>            (setq avg 0)
>            (loop
>             (princ "Enter next grade, 'Q' to quit: ")
>             (setq grade (read))
>             (if (not (numberp grade)) (return (format t "~%Average is
> ~g~%" avg)))
>             (setq total (+ total grade))
>             (setq count (+ count 1))
>             (setq avg (/ total count))
>             (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
> grade total count avg)))

This problem is quite pedestrian and boring.  Try to make them
more entertaining in the future.

Ruby:

total = count = 0
while (print "Enter next grade, 'Q' to quit: ") or true do
  break  if not (grade = gets.strip).match( /^\d/ )
  grade = grade.to_i
  total += grade
  count += 1
  printf "Grade: %d, total: %d, count: %d, average: %.2f\n",
    grade, total, count, total.to_f / count
end
puts "\nAverage is #{ total.to_f / count }"
From: Thomas A. Russ
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <ymiiqng22kp.fsf@blackcat.isi.edu>
cartercc <········@gmail.com> writes:

> The following script averages a series of grades from console input. I
> wrote it as if I would write a C program -- obviously not in idiomatic
> Lisp. How would one rewrite this in idiomatic Lisp?

;; OK.  First add a nice auxiliary function:

(defun prompt-for-number (prompt &optional (stream *terminal-io*))
   "Print prompt and return a number, or NIL if non-numeric input read."
   (princ prompt stream)
   (let ((entry (read stream nil nil)))
     (if (numberp entry)
         entry
         nil)))

;; Then write the loop function:

(defun get-grades ()
  "Repeatedly prompt for grades.  Compute and return the mean score."
  (loop with count = 0
        for grade = (prompt-for-number "Enter next grade, 'Q' to quit: ")
        while grade
        sum grade into grades
        do (incf count)
           (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
                     grade grades count (/ grades count))
        finally (format t "~%Average is ~g~%" (/ grades count))
                (return (/ grades count))))

;; Then call it

(get-grades)


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Zach Beane
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <m3skmksyn2.fsf@unnamed.xach.com>
cartercc <········@gmail.com> writes:

> The following script averages a series of grades from console input. I
> wrote it as if I would write a C program -- obviously not in idiomatic
> Lisp. How would one rewrite this in idiomatic Lisp?
>
> CC
>
> (progn
>            (setq total 0)
>            (setq count 0)
>            (setq avg 0)
>            (loop
>             (princ "Enter next grade, 'Q' to quit: ")
>             (setq grade (read))
>             (if (not (numberp grade)) (return (format t "~%Average is
> ~g~%" avg)))
>             (setq total (+ total grade))
>             (setq count (+ count 1))
>             (setq avg (/ total count))
>             (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
> grade total count avg)))

Here's a quick translation to Zach-idiom:

  (defun grade-averages ()
    (let ((total 0)
          (count 0)
          (*read-eval* nil))
      (loop
       (princ "Enter next grade, 'Q' to quit: ")
       (let ((grade (read)))
         (unless (numberp grade)
           (format t "~%Average is ~$~%" (/ total count))
           (return))
         (incf total grade)
         (incf count)
         (format t "Grade: ~A, total: ~A, count: ~A, average: ~$~%"
                 grade total count (/ total count))))))

Zach
From: David Golden
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <gmv3eb$675$1@aioe.org>
Zach Beane wrote:

>   (defun grade-averages ()
>     (let ((total 0)
>           (count 0)
>           (*read-eval* nil))


That reminds me - why don't people use &aux for values in such an outer
let of a defun? I vaguely know the facility exists but I almost never
see code using it (including my own since I learnt lisp from code that
almost never uses it...)  Is it just not well-liked due to being
arguably less regular, being lumped in with real arguments (though in
that respect highly similar to similar facilities in certain other
languages), or are there other problems with it? I realise it is a let*
rather than let but a lot of the time that wouldn't matter.
From: Zach Beane
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <m3ocx8st56.fsf@unnamed.xach.com>
David Golden <············@oceanfree.net> writes:

> Zach Beane wrote:
>
>>   (defun grade-averages ()
>>     (let ((total 0)
>>           (count 0)
>>           (*read-eval* nil))
>
>
> That reminds me - why don't people use &aux for values in such an outer
> let of a defun? I vaguely know the facility exists but I almost never
> see code using it (including my own since I learnt lisp from code that
> almost never uses it...)  Is it just not well-liked due to being
> arguably less regular, being lumped in with real arguments (though in
> that respect highly similar to similar facilities in certain other
> languages), or are there other problems with it? I realise it is a let*
> rather than let but a lot of the time that wouldn't matter.

I personally don't use it for a couple reasons. First, as you mention,
not a lot of recent code uses it, and I learned a lot of Lisp habits
from reading recent. Second, and this may be just a rationalization of
the first reason, I like to think of the lambda list as part of the
documentation of the public interface of a defun, and &aux exposes part
of the implementation instead.

Zach
From: David Golden
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <gmvecc$foa$1@aioe.org>
Zach Beane wrote:

> Second, and this may be just a rationalization of 
> the first reason, I like to think of the lambda list as part of the
> documentation of the public interface of a defun, and &aux exposes
> part of the implementation instead.
>

hmm. Perhaps it could serve a semi-useful role there in certain limited
circumstances as a heads-up of something surprising - function,
especially higher-order function, locally overriding a special
variable?

While one might wonder why a function is doing so in the first place,
at least it would stand out in slime-describe output.

;; contrived
(defun read-from-func (func &aux (*read-eval* nil))
   (read-from-string (funcall func)))
(read-from-func (lambda () "#.(pointless)"))

... Of course, it could also be mentioned in the docstring...
From: Kenneth Tilton
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <499340f7$0$10173$607ed4bc@cv.net>
David Golden wrote:
> Zach Beane wrote:
> 
>>   (defun grade-averages ()
>>     (let ((total 0)
>>           (count 0)
>>           (*read-eval* nil))
> 
> 
> That reminds me - why don't people use &aux for values in such an outer
> let of a defun? I vaguely know the facility exists but I almost never
> see code using it (including my own since I learnt lisp from code that
> almost never uses it...)  Is it just not well-liked due to being
> arguably less regular, being lumped in with real arguments (though in
> that respect highly similar to similar facilities in certain other
> languages), or are there other problems with it? I realise it is a let*
> rather than let but a lot of the time that wouldn't matter.
> 
> 

I use &aux if I just need one local.

kt
From: Kaz Kylheku
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <20090218070303.704@gmail.com>
On 2009-02-11, Kenneth Tilton <·········@gmail.com> wrote:
> I use &aux if I just need one local.

LOL!

I use &aux if I just need one /more/ local. 

If I need two more locals (or more), I pretend that I need just one more local,
and am not aware of the need for the others, which only occur to me after I
have added that one local. They occur to me gradually, one by one.
From: Kenneth Tilton
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <49938b51$0$10197$607ed4bc@cv.net>
Kaz Kylheku wrote:
> On 2009-02-11, Kenneth Tilton <·········@gmail.com> wrote:
>> I use &aux if I just need one local.
> 
> LOL!
> 
> I use &aux if I just need one /more/ local. 

How can you need more before you have needed any?

kzo
From: Mark Wooding
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <87eixu49b6.fsf.mdw@metalzone.distorted.org.uk>
Kaz Kylheku <········@gmail.com> writes:

> I use &aux if I just need one /more/ local. 

I think the only circumstances under which I use &AUX are in DEFSTRUCT
constructor lambda-lists.

-- [mdw]
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <84faf5a2-41c6-49e1-964e-0a9a279efc7f@f20g2000yqg.googlegroups.com>
On Feb 11, 11:53 am, Zach Beane <····@xach.com> wrote:
> cartercc <········@gmail.com> writes:
> > The following script averages a series of grades from console input. I
> > wrote it as if I would write a C program -- obviously not in idiomatic
> > Lisp. How would one rewrite this in idiomatic Lisp?
>
> > CC
>
> > (progn
> >            (setq total 0)
> >            (setq count 0)
> >            (setq avg 0)
> >            (loop
> >             (princ "Enter next grade, 'Q' to quit: ")
> >             (setq grade (read))
> >             (if (not (numberp grade)) (return (format t "~%Average is
> > ~g~%" avg)))
> >             (setq total (+ total grade))
> >             (setq count (+ count 1))
> >             (setq avg (/ total count))
> >             (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
> > grade total count avg)))
>
> Here's a quick translation to Zach-idiom:
>
>   (defun grade-averages ()
>     (let ((total 0)
>           (count 0)
>           (*read-eval* nil))
>       (loop
>        (princ "Enter next grade, 'Q' to quit: ")
>        (let ((grade (read)))
>          (unless (numberp grade)
>            (format t "~%Average is ~$~%" (/ total count))
>            (return))
>          (incf total grade)
>          (incf count)
>          (format t "Grade: ~A, total: ~A, count: ~A, average: ~$~%"
>                  grade total count (/ total count))))))
>
> Zach

I ran your code, output follows. Doesn't calculate the average. Is
this my mistake or yours?

CC

------------start output-------------
(gr-beane)
Enter next grade, 'Q' to quit: 99
Grade: 99, total: 99, count: 1, average: 99.00
Enter next grade, 'Q' to quit: 988
Grade: 988, total: 1087, count: 2, average: 543.50
Enter next grade, 'Q' to quit: 97
Grade: 97, total: 1184, count: 3, average: 394.67
Enter next grade, 'Q' to quit: 96
Grade: 96, total: 1280, count: 4, average: 320.00
Enter next grade, 'Q' to quit: 95
Grade: 95, total: 1375, count: 5, average: 275.00
Enter next grade, 'Q' to quit: q

Average is 275.00
NIL
CL-USER>
-----------------end output-----------------
From: Alexander Lehmann
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <gn1na6$cf4$1@online.de>
cartercc wrote:
> I ran your code, output follows. Doesn't calculate the average. Is
> this my mistake or yours?
> 
> CC
>
> ...
> Grade: 99, total: 99, count: 1, average: 99.00
> Enter next grade, 'Q' to quit: 988
> Grade: 988, total: 1087, count: 2, average: 543.50
        ^^^
> ...
> Average is 275.00

Seems correct from my point of view ;-)

-- Alexander
From: Slobodan Blazeski
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <287f601c-98a2-4096-bf9e-4f02e37ee5d7@w35g2000yqm.googlegroups.com>
cartercc wrote:
> The following script averages a series of grades from console input. I
> wrote it as if I would write a C program -- obviously not in idiomatic
> Lisp. How would one rewrite this in idiomatic Lisp?

(defun avg (&optional  (s 0) (n 0))
  (princ "Enter next grade, 'Q' to quit: ")
  (let ((g (read)))
     (if (numberp g)
        (progn
          (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
           g (+ g s) (1+ n) (/  (+ g s) (1+ n)))
          (avg (+ g s) (1+ n)))
       (format t "~%Average is ~g~%" (/ s n)))))

Sorry no time for golfing.

cheers
bobi
From: Pascal J. Bourguignon
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <87eiy4bsxl.fsf@galatea.local>
cartercc <········@gmail.com> writes:

> The following script averages a series of grades from console input. I
> wrote it as if I would write a C program -- 

What do you mean?  Didn't you write something like this in C?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void average_grades(double total,int count){
   char line[80];
   printf("Enter next grade, 'Q' to quit: ");
   fflush(stdout);
   if(fgets(line,sizeof(line)-1,stdin)){
      char* s=strtok(line," ");
      if(s[0]=='Q'){
         printf("\nAverage is %f\n",((count>0)?(total/count):0));
      }else{
         double x=atof(s);
         printf("\nGrade: %f, total: %f, count: %d, average: %f\n",
                  x,total+x,count+1,((total+x)/(count+1)));
         average_grades(total+x,count+1);
      }
   }else{
      average_grades(total,count);}}


int main(void){
  average_grades(0.0,0);
  return(0);
}



-- 
__Pascal Bourguignon__
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <e72c54c3-a1fb-465c-816a-26967c42120e@x38g2000yqj.googlegroups.com>
On Feb 11, 3:49 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> What do you mean?  Didn't you write something like this in C?

;-)  No, in fact. I would write something like this (untested):

int grade = 0, sum = 0, count = 0;
do {
  puts "Enter grade, -1 to quit";
  scanf ("%d", &grade);
  sum += grade;
  count++;
} while (grade > -1);
printf ("Average is %f\n", sum / count);

CC
From: ·········@yahoo.com
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <e1302601-68e1-4b9a-8e34-89d78281aa6f@i38g2000yqd.googlegroups.com>
On Feb 11, 3:24 pm, cartercc <········@gmail.com> wrote:
> On Feb 11, 3:49 pm, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>
> > What do you mean?  Didn't you write something like this in C?
>
> ;-)  No, in fact. I would write something like this (untested):
>
> int grade = 0, sum = 0, count = 0;
> do {
>   puts "Enter grade, -1 to quit";
>   scanf ("%d", &grade);
>   sum += grade;
>   count++;} while (grade > -1);
>
> printf ("Average is %f\n", sum / count);
>
> CC

That looks buggy. When the user enters -1 to quit,
you add -1 to the sum.
From: Pascal J. Bourguignon
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <7ciqnf94jw.fsf@pbourguignon.anevia.com>
cartercc <········@gmail.com> writes:

> On Feb 11, 3:49�pm, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> What do you mean? �Didn't you write something like this in C?
>
> ;-)  No, in fact. I would write something like this (untested):
>
> int grade = 0, sum = 0, count = 0;
> do {
>   puts "Enter grade, -1 to quit";
>   scanf ("%d", &grade);
>   sum += grade;
>   count++;
> } while (grade > -1);
> printf ("Average is %f\n", sum / count);

But this is full of state mutation!  How can you tell it's not buggy?

-- 
__Pascal Bourguignon__
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <8b03ebd9-fd97-4a08-bc73-382e1370dd3d@h5g2000yqh.googlegroups.com>
On Feb 12, 8:18 am, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> But this is full of state mutation!  How can you tell it's not buggy?

I didn't say it was good code, and in fact wax pointed out a logic
error. All I said was that I would (and have) written this exercise
like this.

At the risk of stirring up the natives, allow me this observation
concerning Lisp pedagogy. I've studied over a dozen languages so far,
learning about six well enough to use for real work. I'm a real big
fan of the Deitel series, owning the Deitel books in Java, Perl, C, C+
+, and Visual Basic. Comparing those books to the Lisp books I'm using
(Wilensky, Graham, Seibel), Deitel beats you to death with exercises
that only vary a little -- but the end result /IF YOU DO ALL THE
EXERCISES/ is that you develop some facility with the material. The
Lisp books do not take this approach, apparently thinking that the
learner will make up his own exercises. Seibel is the worst offender
in this (not a criticism particularly in view of his practical
chapters) by not providing ANY end-of-chapter exercises. By way of
contrast, the Schwartz book 'Learning Perl' not only contains
exercises but also the answers. (I'm not saying that this book is
necessarily that good of a text - just making a comparison.)

Personally, I would find it really helpful to have a series of go-slow
exercises, with the solutions, as an aid to learning. I'm trying to do
this on my own, but I really don't have the Lisp chops to do it, so
I'm pulling exercises from other sources that look like they relate to
a topic.

The above is merely an observation, not a personal attack on anyone or
an insult to the Lisp community, so please, no flames.

CC
From: Chris Riesbeck
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <6vjk6bFjkoqsU1@mid.individual.net>
cartercc wrote:
> 
> At the risk of stirring up the natives, allow me this observation
> concerning Lisp pedagogy. I've studied over a dozen languages so far,
> learning about six well enough to use for real work. I'm a real big
> fan of the Deitel series, owning the Deitel books in Java, Perl, C, C+
> +, and Visual Basic. Comparing those books to the Lisp books I'm using
> (Wilensky, Graham, Seibel), Deitel beats you to death with exercises
> that only vary a little -- but the end result /IF YOU DO ALL THE
> EXERCISES/ is that you develop some facility with the material. The
> Lisp books do not take this approach, apparently thinking that the
> learner will make up his own exercises. Seibel is the worst offender
> in this (not a criticism particularly in view of his practical
> chapters) by not providing ANY end-of-chapter exercises. By way of
> contrast, the Schwartz book 'Learning Perl' not only contains
> exercises but also the answers. (I'm not saying that this book is
> necessarily that good of a text - just making a comparison.)

When Peter was sending out drafts for comments, he asked if I'd use it 
in a course, and I said the lack of exercises was a serious problem.

Graham's not so bad on that score, though I augmented and modified for 
my purposes.

On the other hand, most textbook exercises are like gym exercises. They 
work on one or two muscles but they're not about how it all works 
together. They often encourage using the wrong tool for a job *as an 
exercise* which would be fine if students were told that in real code 
not to invent the wheel.
From: Pascal J. Bourguignon
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <7cy6wb7fzc.fsf@pbourguignon.anevia.com>
cartercc <········@gmail.com> writes:

> On Feb 12, 8:18�am, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> But this is full of state mutation! �How can you tell it's not buggy?
>
> I didn't say it was good code, and in fact wax pointed out a logic
> error. All I said was that I would (and have) written this exercise
> like this.
>
> At the risk of stirring up the natives, allow me this observation
> concerning Lisp pedagogy. I've studied over a dozen languages so far,
> learning about six well enough to use for real work. I'm a real big
> fan of the Deitel series, owning the Deitel books in Java, Perl, C, C+
> +, and Visual Basic. Comparing those books to the Lisp books I'm using
> (Wilensky, Graham, Seibel), Deitel beats you to death with exercises
> that only vary a little -- but the end result /IF YOU DO ALL THE
> EXERCISES/ is that you develop some facility with the material. The
> Lisp books do not take this approach, apparently thinking that the
> learner will make up his own exercises. Seibel is the worst offender
> in this (not a criticism particularly in view of his practical
> chapters) by not providing ANY end-of-chapter exercises. By way of
> contrast, the Schwartz book 'Learning Perl' not only contains
> exercises but also the answers. (I'm not saying that this book is
> necessarily that good of a text - just making a comparison.)
>
> Personally, I would find it really helpful to have a series of go-slow
> exercises, with the solutions, as an aid to learning. I'm trying to do
> this on my own, but I really don't have the Lisp chops to do it, so
> I'm pulling exercises from other sources that look like they relate to
> a topic.

Perhaps you should try:

    Common Lisp: A Gentle Introduction to Symbolic Computation
    David S. Touretzky
    http://www-cgi.cs.cmu.edu/afs/cs.cmu.edu/user/dst/www/LispBook/index.html
    http://www.cs.cmu.edu/~dst/LispBook/


> The above is merely an observation, not a personal attack on anyone or
> an insult to the Lisp community, so please, no flames.


Probably the lisp mind is self inquiring.  When I self taught my first
programming language, I had the reference manual. There were example
programs, but no "exercises" properly.  I wrote programs to exercise
each statement I learned, one by one.

Lisp REPL is so natural and essential to the lispers, that it comes
without saying that whenever you're presented with some lisp forms,
you will be exercising it at the REPL, trying variations, playing with
it.

-- 
__Pascal Bourguignon__
From: Bob Felts
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <1iv11t4.bylohmrycwm8N%wrf3@stablecross.com>
Pascal J. Bourguignon <···@informatimago.com> wrote:

> cartercc <········@gmail.com> writes:
> 
[...]

> >
> > Personally, I would find it really helpful to have a series of go-slow
> > exercises, with the solutions, as an aid to learning. I'm trying to do
> > this on my own, but I really don't have the Lisp chops to do it, so
> > I'm pulling exercises from other sources that look like they relate to
> > a topic.
> 
> Perhaps you should try:
> 
>     Common Lisp: A Gentle Introduction to Symbolic Computation
>     David S. Touretzky
>     http://www-cgi.cs.cmu.edu/afs/cs.cmu.edu/user/dst/www/LispBook/index.html
>     http://www.cs.cmu.edu/~dst/LispBook/
> 
> 

I'm using this book with my 16 yr. old daughter for this very reason.

There are also any number of web sites that have Lisp exercises.  One
example is:

http://www.cc.gatech.edu/computing/classes/cs2360/fall95/handouts/asgn3.
txt
From: ·········@yahoo.com
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <53bec60a-11df-4f0f-8ab9-a9d98e08b8f9@v13g2000yqm.googlegroups.com>
On Feb 11, 2:49 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> cartercc <········@gmail.com> writes:
> > The following script averages a series of grades from console input. I
> > wrote it as if I would write a C program --
>
> What do you mean?  Didn't you write something like this in C?
>
> #include <stdio.h>
> #include <string.h>
> #include <stdlib.h>
>
> void average_grades(double total,int count){
>    char line[80];
>    printf("Enter next grade, 'Q' to quit: ");
>    fflush(stdout);
>    if(fgets(line,sizeof(line)-1,stdin)){
>       char* s=strtok(line," ");
>       if(s[0]=='Q'){
>          printf("\nAverage is %f\n",((count>0)?(total/count):0));
>       }else{
>          double x=atof(s);
>          printf("\nGrade: %f, total: %f, count: %d, average: %f\n",
>                   x,total+x,count+1,((total+x)/(count+1)));
>          average_grades(total+x,count+1);
>       }
>    }else{
>       average_grades(total,count);}}
>
> int main(void){
>   average_grades(0.0,0);
>   return(0);
>
> }
>
> --
> __Pascal Bourguignon__

It's impolite, to put it mildly, to post non-lisp code in this forum.
From: Pascal J. Bourguignon
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <7ceiy394j2.fsf@pbourguignon.anevia.com>
·········@yahoo.com writes:

> On Feb 11, 2:49�pm, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> cartercc <········@gmail.com> writes:
>> > The following script averages a series of grades from console input. I
>> > wrote it as if I would write a C program --
>>
>> What do you mean? �Didn't you write something like this in C?
>>
>> #include <stdio.h>
>> #include <string.h>
>> #include <stdlib.h>
>>
>> void average_grades(double total,int count){
>> � �char line[80];
>> � �printf("Enter next grade, 'Q' to quit: ");
>> � �fflush(stdout);
>> � �if(fgets(line,sizeof(line)-1,stdin)){
>> � � � char* s=strtok(line," ");
>> � � � if(s[0]=='Q'){
>> � � � � �printf("\nAverage is %f\n",((count>0)?(total/count):0));
>> � � � }else{
>> � � � � �double x=atof(s);
>> � � � � �printf("\nGrade: %f, total: %f, count: %d, average: %f\n",
>> � � � � � � � � � x,total+x,count+1,((total+x)/(count+1)));
>> � � � � �average_grades(total+x,count+1);
>> � � � }
>> � �}else{
>> � � � average_grades(total,count);}}
>>
>> int main(void){
>> � average_grades(0.0,0);
>> � return(0);
>>
>> }
>>
>> --
>> __Pascal Bourguignon__
>
> It's impolite, to put it mildly, to post non-lisp code in this forum.

But contrarily to yours, this IS lisp code!

;-)
-- 
__Pascal Bourguignon__
From: Andrew Reilly
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <6vh5eeFk230kU1@mid.individual.net>
On Wed, 11 Feb 2009 08:34:20 -0800, cartercc wrote:

> The following script averages a series of grades from console input. I
> wrote it as if I would write a C program -- obviously not in idiomatic
> Lisp.

I'm going to leave the idiomatic lisp alone, because I don't consider 
myself worthy.  (Indeed I find it instructive that all of the responses 
have used loop, rather than functional/recursive style.)

But: that (OP's) code looked more like Fortran or Basic than C, to me.  
Certainly doesn't look like any of my C.  Wisely has it been said that 
it's possible to write fortran in any language.

I guess I just haven't seen a forced teletype dialog written into a 
program for a very long time.

Cheers,

-- 
Andrew
From: Slobodan Blazeski
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <2ac8af3c-6b02-4cf2-b589-4bb99cc26949@v19g2000yqn.googlegroups.com>
On Feb 12, 12:31 am, Andrew Reilly <···············@areilly.bpc-
users.org> wrote:
> On Wed, 11 Feb 2009 08:34:20 -0800, cartercc wrote:
> > The following script averages a series of grades from console input. I
> > wrote it as if I would write a C program -- obviously not in idiomatic
> > Lisp.
>
> I'm going to leave the idiomatic lisp alone, because I don't consider
> myself worthy.  (Indeed I find it instructive that all of the responses
> have used loop, rather than functional/recursive style.)
I beg you pardon. Where did I used loop in my solution?

bobi
From: Andrew Reilly
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <6vh7pgFk230kU2@mid.individual.net>
On Wed, 11 Feb 2009 16:02:53 -0800, Slobodan Blazeski wrote:

> On Feb 12, 12:31 am, Andrew Reilly <···············@areilly.bpc-
> users.org> wrote:
>> On Wed, 11 Feb 2009 08:34:20 -0800, cartercc wrote:
>> > The following script averages a series of grades from console input.
>> > I wrote it as if I would write a C program -- obviously not in
>> > idiomatic Lisp.
>>
>> I'm going to leave the idiomatic lisp alone, because I don't consider
>> myself worthy.  (Indeed I find it instructive that all of the responses
>> have used loop, rather than functional/recursive style.)
> I beg you pardon. Where did I used loop in my solution?

I'm afraid that I haven't seen your solution yet.
Must be something up with the pipes at the moment.

Cheers,

-- 
Andrew
From: Slobodan Blazeski
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <b72c801b-9b53-4c15-a83a-7d0a1eb76b9d@h20g2000yqn.googlegroups.com>
On Feb 12, 1:11 am, Andrew Reilly <···············@areilly.bpc-
users.org> wrote:
> On Wed, 11 Feb 2009 16:02:53 -0800, Slobodan Blazeski wrote:
> > On Feb 12, 12:31 am, Andrew Reilly <···············@areilly.bpc-
> > users.org> wrote:
> >> On Wed, 11 Feb 2009 08:34:20 -0800, cartercc wrote:
> >> > The following script averages a series of grades from console input.
> >> > I wrote it as if I would write a C program -- obviously not in
> >> > idiomatic Lisp.
>
> >> I'm going to leave the idiomatic lisp alone, because I don't consider
> >> myself worthy.  (Indeed I find it instructive that all of the responses
> >> have used loop, rather than functional/recursive style.)
> > I beg you pardon. Where did I used loop in my solution?
>
> I'm afraid that I haven't seen your solution yet.
> Must be something up with the pipes at the moment.
>
> Cheers,
>
> --
> Andrew
Try this
(defun avg (&optional  (s 0) (n 0))
  (princ "Enter next grade, 'Q' to quit: ")
  (let ((g (read)))
     (if (numberp g)
        (progn
          (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
           g (+ g s) (1+ n) (/  (+ g s) (1+ n)))
          (avg (+ g s) (1+ n)))
       (format t "~%Average is ~g~%" (/ s n)))))

cheers
bobi
From: John Thingstad
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <op.uo7puiiqut4oq5@pandora.alfanett.no>
P� Wed, 11 Feb 2009 17:34:20 +0100, skrev cartercc <········@gmail.com>:

> The following script averages a series of grades from console input. I
> wrote it as if I would write a C program -- obviously not in idiomatic
> Lisp. How would one rewrite this in idiomatic Lisp?
>
> CC
>
> (progn
>            (setq total 0)
>            (setq count 0)
>            (setq avg 0)
>            (loop
>             (princ "Enter next grade, 'Q' to quit: ")
>             (setq grade (read))
>             (if (not (numberp grade)) (return (format t "~%Average is
> ~g~%" avg)))
>             (setq total (+ total grade))
>             (setq count (+ count 1))
>             (setq avg (/ total count))
>             (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
> grade total count avg)))

The decomposition to me seems off as this function is doing several things.

First I would have a mathematical function average. (No need to keep the  
reader guessing by calling it avg.)
Seconly you have a prompt-value function that takes a prompt and a  
terminator as arguments.
This would return a value of the type or nil if the string is terminator,  
reprompt if it is not a value.
Third I would have a function find-average-grade that actually collects  
the values and prints the average.

(defun average (list)
   (/ (reduce #'+ list) (length list)))

(defun prompt-value (prompt terminator)
   (write-string prompt)
   (let* ((line (read-line))
          (value (read-from-string line)))
     (cond
      ((string= line terminator) nil)
      ((numberp value) value)
      (t (write-string "Not a Value!")
         (terpri)
         (prompt-value prompt terminator)))))

(defun find-average-grade ()
   "Prompt for a sequence of grades terminated by Q and return the average  
of thos values."
   (format t "~2%Average grade is: ~F~&"
           (average
            (loop for value = (prompt-value "grade > " "Q")
                  while value collect value)))
   (values))

--------------
John Thingstad
From: John Thingstad
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <op.uo7qlilwut4oq5@pandora.alfanett.no>
P� Thu, 12 Feb 2009 01:19:20 +0100, skrev John Thingstad  
<·······@online.no>:

>
> First I would have a mathematical function average. (No need to keep the  
> reader guessing by calling it avg.)
> Seconly you have a prompt-value function that takes a prompt and a  
> terminator as arguments.
> This would return a value of the type or nil if the string is  
> terminator, reprompt if it is not a value.
> Third I would have a function find-average-grade that actually collects  
> the values and prints the average.
> ...

Acually the idiomatic way would be to just use the REPL (Read Eval print  
Loop) for something this simple so I would probaly just write average.
If I change it to (defun average (&rest list) ...) I can just write fes.
> (average 1 2 3 4 5)
3

--------------
John Thingstad
From: Thomas A. Russ
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <ymimycsh1ow.fsf@blackcat.isi.edu>
"John Thingstad" <·······@online.no> writes:

> Acually the idiomatic way would be to just use the REPL (Read Eval print
> Loop) for something this simple so I would probaly just write average.
> If I change it to (defun average (&rest list) ...) I can just write fes.
> > (average 1 2 3 4 5)
> 3

Hear, hear!
This really is the most idiomatic solution to this particular problem.

Thanks, John.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Rob Warnock
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <Oa-dnfLKhJOe4w7UnZ2dnUVZ_j6dnZ2d@speakeasy.net>
John Thingstad <·······@online.no> wrote:
+---------------
| Acually the idiomatic way would be to just use the REPL (Read Eval print  
| Loop) for something this simple so I would probaly just write average.
| If I change it to (defun average (&rest list) ...) I can just write fes.
| > (average 1 2 3 4 5)
| 3
+---------------

Heh! Funny you should mention that! I actually found myself using
that enough that I put a (DEFUN AVERAGE ...) into my init file.
And since I have "=" aliased to a script that runs CL with the
rest-of-line fed to EVAL, I can say this at the Unix command line:  ;-}

    $ = average 72 65 91 82.0
    77.5
    $

[Yes, since it's CL you need that annoying ".0" to avoid getting
"155/2" as a result. (*sigh*)]

-Rob

p.s. The script even handles one level of REPL history anaphora!  ;-}  ;-}

    $ = + \* 10
    87.5
    $ 

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <053efe74-fd68-40e9-9220-8cbc8130a10a@j1g2000yqi.googlegroups.com>
On Feb 11, 7:19 pm, "John Thingstad" <·······@online.no> wrote:
> På Wed, 11 Feb 2009 17:34:20 +0100, skrev cartercc <········@gmail.com>:
>
>
>
> > The following script averages a series of grades from console input. I
> > wrote it as if I would write a C program -- obviously not in idiomatic
> > Lisp. How would one rewrite this in idiomatic Lisp?
>
> > CC
>
> > (progn
> >            (setq total 0)
> >            (setq count 0)
> >            (setq avg 0)
> >            (loop
> >             (princ "Enter next grade, 'Q' to quit: ")
> >             (setq grade (read))
> >             (if (not (numberp grade)) (return (format t "~%Average is
> > ~g~%" avg)))
> >             (setq total (+ total grade))
> >             (setq count (+ count 1))
> >             (setq avg (/ total count))
> >             (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
> > grade total count avg)))
>
> The decomposition to me seems off as this function is doing several things.
>
> First I would have a mathematical function average. (No need to keep the  
> reader guessing by calling it avg.)
> Seconly you have a prompt-value function that takes a prompt and a  
> terminator as arguments.
> This would return a value of the type or nil if the string is terminator,  
> reprompt if it is not a value.
> Third I would have a function find-average-grade that actually collects  
> the values and prints the average.
>
> (defun average (list)
>    (/ (reduce #'+ list) (length list)))
>
> (defun prompt-value (prompt terminator)
>    (write-string prompt)
>    (let* ((line (read-line))
>           (value (read-from-string line)))
>      (cond
>       ((string= line terminator) nil)
>       ((numberp value) value)
>       (t (write-string "Not a Value!")
>          (terpri)
>          (prompt-value prompt terminator)))))
>
> (defun find-average-grade ()
>    "Prompt for a sequence of grades terminated by Q and return the average  
> of thos values."
>    (format t "~2%Average grade is: ~F~&"
>            (average
>             (loop for value = (prompt-value "grade > " "Q")
>                   while value collect value)))
>    (values))
>
> --------------
> John Thingstad

Ran your code. Output below. Does not allow the user to terminate to
calculate the average.

CC

-------------output below-----------------
CL-USER> (gr-thing)
grade > 99
grade > 98
grade > 97
grade > 96
grade > 95
grade > q
Not a Value!
grade > 0
grade > -1
grade >
---------------end output--------------
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <2cb82e94-38e8-41a8-8397-fec79dab2da4@m42g2000yqb.googlegroups.com>
On Feb 12, 9:14 am, cartercc <········@gmail.com> wrote:
> On Feb 11, 7:19 pm, "John Thingstad" <·······@online.no> wrote:

MY APOLOGY!!! I didn't enter an uppercase 'Q'. Code works perfectly.
Thank you.

(Now all I have to do is understand it.)

CC
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <3edda981-dbe3-40d6-a991-20eacde64d7d@x10g2000yqk.googlegroups.com>
On Feb 11, 11:34 am, cartercc <········@gmail.com> wrote:
> The following script averages a series of grades from console input. I
> wrote it as if I would write a C program -- obviously not in idiomatic
> Lisp. How would one rewrite this in idiomatic Lisp?

Thanks to all. Here is a clean copy of the scripts so far submitted,
warts and all.

;;;---------------------Charles Carter---------------------
(defun gr-carter ()
  (progn
    (setq total 0)
    (setq count 0)
    (setq avg 0)
    (loop
     (princ "Enter next grade, 'Q' to quit: ")
     (setq grade (read))
     (if (not (numberp grade)) (return (format t "~%Average is ~g~%"
avg)))
     (setq total (+ total grade))
     (setq count (+ count 1))
     (setq avg (/ total count))
     (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"grade
total count avg))))

;;;-------------------Zach Beane----------------------------
;;; doesn't calcuate the average
(defun gr-beane ()
    (let ((total 0)
          (count 0)
          (*read-eval* nil))
      (loop
       (princ "Enter next grade, 'Q' to quit: ")
       (let ((grade (read)))
         (unless (numberp grade)
           (format t "~%Average is ~$~%" (/ total count))
           (return))
         (incf total grade)
         (incf count)
         (format t "Grade: ~A, total: ~A, count: ~A, average: ~$~%"
                 grade total count (/ total count))))))

;;;-------------------Geoffrey Summerhill-----------------
(defun gr-summer ()
  (loop for grade = (progn
                    (princ "Enter next grade, 'Q' to quit: ")
                    (read))
      while (numberp grade)
      summing grade into total
      counting grade into count
      do (format *standard-output*
                 "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
                 grade total count (/ total count))
      finally (format *standard-output*
                      "~%Average is ~g~%"
                      (/ total count))))

;;;------------------Marco Antoniotti--------------------
;;; doesn't prompt for input on the first instance
(defun gr-anton ()
   (loop with avg   = 0.0
        initially (princ "Enter next grade, 'Q' to quit: ")
        for grade = (read *standard-input* nil t)
        while (numberp grade)
        sum grade into total
        count grade into count
        do (setf avg (/ total count))
        do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
                           Enter next grade, 'Q' to quit: "
                   grade total count avg)
        finally (format t "~&Average is ~G~%" avg)))

;;;-------------------Thomas Russ------------------
;; OK.  First add a nice auxiliary function:

(defun prompt-for-number (prompt &optional (stream *terminal-io*))
   "Print prompt and return a number, or NIL if non-numeric input
read."
   (princ prompt stream)
   (let ((entry (read stream nil nil)))
     (if (numberp entry)
         entry
         nil)))

;; Then write the loop function:

(defun gr-russ ()
  "Repeatedly prompt for grades.  Compute and return the mean score."
  (loop with count = 0
        for grade = (prompt-for-number "Enter next grade, 'Q' to quit:
")
        while grade
        sum grade into grades
        do (incf count)
           (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
                     grade grades count (/ grades count))
        finally (format t "~%Average is ~g~%" (/ grades count))
                (return (/ grades count))))

;;;-----------------Slobodan Blazeski---------------------------------
(defun gr-blaze (&optional  (s 0) (n 0))
  (princ "Enter next grade, 'Q' to quit: ")
  (let ((g (read)))
     (if (numberp g)
        (progn
          (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
           g (+ g s) (1+ n) (/  (+ g s) (1+ n)))
          (avg (+ g s) (1+ n)))
       (format t "~%Average is ~g~%" (/ s n)))))

;;;-----------------John Thingstad----------------
(defun average (list)
   (/ (reduce #'+ list) (length list)))

(defun prompt-value (prompt terminator)
   (write-string prompt)
   (let* ((line (read-line))
          (value (read-from-string line)))
     (cond
      ((string= line terminator) nil)
      ((numberp value) value)
      (t (write-string "Not a Value!")
         (terpri)
         (prompt-value prompt terminator)))))

(defun gr-thing ()
   "Prompt for a sequence of grades terminated by Q and return the
average
of thos values."
   (format t "~2%Average grade is: ~F~&"
           (average
            (loop for value = (prompt-value "grade > " "Q")
                  while value collect value)))
   (values))
From: Marco Antoniotti
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <1dfb5f0a-727d-4dbf-a165-ac2f2207bcb0@i38g2000yqd.googlegroups.com>
On Feb 12, 3:24 pm, cartercc <········@gmail.com> wrote:
> On Feb 11, 11:34 am, cartercc <········@gmail.com> wrote:
>
> > The following script averages a series of grades from console input. I
> > wrote it as if I would write a C program -- obviously not in idiomatic
> > Lisp. How would one rewrite this in idiomatic Lisp?
>
> Thanks to all. Here is a clean copy of the scripts so far submitted,
> warts and all.
>
>
> ;;;------------------Marco Antoniotti--------------------
> ;;; doesn't prompt for input on the first instance
> (defun gr-anton ()
>    (loop with avg   = 0.0
>         initially (princ "Enter next grade, 'Q' to quit: ")
>         for grade = (read *standard-input* nil t)
>         while (numberp grade)
>         sum grade into total
>         count grade into count
>         do (setf avg (/ total count))
>         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
>                            Enter next grade, 'Q' to quit: "
>                    grade total count avg)
>         finally (format t "~&Average is ~G~%" avg)))
>

Nope.  It prints just fine.  Check the INITIALLY clause.

Cheers
--
Marco
From: Geoffrey Summerhayes
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <35e09ac8-4adf-42bd-b674-ad9133559994@h20g2000yqn.googlegroups.com>
On Feb 12, 9:35 am, Marco Antoniotti <·······@gmail.com> wrote:
>
> Nope.  It prints just fine.  Check the INITIALLY clause.
>

Ah well, at least he got your name right. :-(

--
Geoff
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <60f995be-e9b3-492d-8184-eceef6931da7@g38g2000yqd.googlegroups.com>
On Feb 12, 9:51 am, Geoffrey Summerhayes <·······@gmail.com> wrote:
> On Feb 12, 9:35 am, Marco Antoniotti <·······@gmail.com> wrote:
>
>
>
> > Nope.  It prints just fine.  Check the INITIALLY clause.
>
> Ah well, at least he got your name right. :-(
>
> --
> Geoff

My apology. Sorry. CC.
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <d2795b66-6b06-41b1-8678-a1af158e2a85@j39g2000yqn.googlegroups.com>
On Feb 12, 9:35 am, Marco Antoniotti <·······@gmail.com> wrote:
> > ;;;------------------Marco Antoniotti--------------------
> > ;;; doesn't prompt for input on the first instance
> > (defun gr-anton ()
> >    (loop with avg   = 0.0
> >         initially (princ "Enter next grade, 'Q' to quit: ")
> >         for grade = (read *standard-input* nil t)
> >         while (numberp grade)
> >         sum grade into total
> >         count grade into count
> >         do (setf avg (/ total count))
> >         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
> >                            Enter next grade, 'Q' to quit: "
> >                    grade total count avg)
> >         finally (format t "~&Average is ~G~%" avg)))
>
> Nope.  It prints just fine.  Check the INITIALLY clause.
>
> Cheers
> --
> Marco

Just ran it again. I'm using clisp with slime. It still doesn't prompt
for the first input. Since it works for you and doesn't for me, could
it be something that is implementation dependent?

I'm not trying to break anything, just trying to get everything to
run. I've spend the last two hours going through all the examples, and
have learned quite a bit - mostly the intricacies of loop.

CC
From: Marco Antoniotti
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <4792bc38-17a9-4d7c-b794-4223d5ff1ae8@r41g2000yqm.googlegroups.com>
On Feb 12, 3:51 pm, cartercc <········@gmail.com> wrote:
> On Feb 12, 9:35 am, Marco Antoniotti <·······@gmail.com> wrote:
>
>
>
> > > ;;;------------------Marco Antoniotti--------------------
> > > ;;; doesn't prompt for input on the first instance
> > > (defun gr-anton ()
> > >    (loop with avg   = 0.0
> > >         initially (princ "Enter next grade, 'Q' to quit: ")
> > >         for grade = (read *standard-input* nil t)
> > >         while (numberp grade)
> > >         sum grade into total
> > >         count grade into count
> > >         do (setf avg (/ total count))
> > >         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
> > >                            Enter next grade, 'Q' to quit: "
> > >                    grade total count avg)
> > >         finally (format t "~&Average is ~G~%" avg)))
>
> > Nope.  It prints just fine.  Check the INITIALLY clause.
>
> > Cheers
> > --
> > Marco
>
> Just ran it again. I'm using clisp with slime. It still doesn't prompt
> for the first input. Since it works for you and doesn't for me, could
> it be something that is implementation dependent?
>
> I'm not trying to break anything, just trying to get everything to
> run. I've spend the last two hours going through all the examples, and
> have learned quite a bit - mostly the intricacies of loop.

Probably something to do with flushing of the buffers in CLisp.  I use
LWM most of the time.

Cheers
--
Marco
From: Pascal J. Bourguignon
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <7ctz6z7fu9.fsf@pbourguignon.anevia.com>
cartercc <········@gmail.com> writes:

> On Feb 12, 9:35�am, Marco Antoniotti <·······@gmail.com> wrote:
>> > ;;;------------------Marco Antoniotti--------------------
>> > ;;; doesn't prompt for input on the first instance
>> > (defun gr-anton ()
>> > � �(loop with avg � = 0.0
>> > � � � � initially (princ "Enter next grade, 'Q' to quit: ")
>> > � � � � for grade = (read *standard-input* nil t)
>> > � � � � while (numberp grade)
>> > � � � � sum grade into total
>> > � � � � count grade into count
>> > � � � � do (setf avg (/ total count))
>> > � � � � do (format t �"Grade: ~a, total: ~a, count: ~a, average: ···@
>> > � � � � � � � � � � � � � �Enter next grade, 'Q' to quit: "
>> > � � � � � � � � � �grade total count avg)
>> > � � � � finally (format t "~&Average is ~G~%" avg)))
>>
>> Nope. �It prints just fine. �Check the INITIALLY clause.
>>
>> Cheers
>> --
>> Marco
>
> Just ran it again. I'm using clisp with slime. It still doesn't prompt
> for the first input. Since it works for you and doesn't for me, could
> it be something that is implementation dependent?
>
> I'm not trying to break anything, just trying to get everything to
> run. I've spend the last two hours going through all the examples, and
> have learned quite a bit - mostly the intricacies of loop.

It shouldn't prompt fir the first input.  There's nothing in that code
saying that it should.


First, for interactive querying, you should use *QUERY-IO*, not
*standard-output* / *standard-input*.  It could be tolerated to use
*TERMINAL-IO*, but in cases such as those of slime, there's no
directly accessible terminal.  Use *QUERY-IO* to dialog with the user!
                  
Then if you want to ensure that the user sees what you print, you
should use FORCE-OUTPUT or FINISH-OUTPUT.

-- 
__Pascal Bourguignon__
From: Wolfgang Mederle
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <yj9vdrffze5.fsf@elvis.mederle.de>
Marco Antoniotti wrote:

> Nope.  It prints just fine.  Check the INITIALLY clause.

Worked for me on clisp 2.40, not on sbcl 1.0.12. OS X 10.5.6.
From: Slobodan Blazeski
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <6a63258d-0411-483b-bd19-e2053030bba0@m42g2000yqb.googlegroups.com>
On Feb 12, 3:24 pm, cartercc <········@gmail.com> wrote:
> On Feb 11, 11:34 am, cartercc <········@gmail.com> wrote:
>
> > The following script averages a series of grades from console input. I
> > wrote it as if I would write a C program -- obviously not in idiomatic
> > Lisp. How would one rewrite this in idiomatic Lisp?
>
> Thanks to all. Here is a clean copy of the scripts so far submitted,
> warts and all.

> ;;;-----------------Slobodan Blazeski---------------------------------
> (defun gr-blaze (&optional  (s 0) (n 0))
>   (princ "Enter next grade, 'Q' to quit: ")
>   (let ((g (read)))
>      (if (numberp g)
>         (progn
>           (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
>            g (+ g s) (1+ n) (/  (+ g s) (1+ n)))
>           (avg (+ g s) (1+ n)))
>        (format t "~%Average is ~g~%" (/ s n)))))
>
(gr-blaze)
Enter next grade, 'Q' to quit: 22
Grade: 22, total: 22, count: 1, average: 22

Error: Undefined operator AVG in form (AVG (+ G S) (1+ N)).
  1 (continue) Try invoking AVG again.
  2 Return some values from the form (AVG (+ G S) (1+ N)).
  3 Try invoking something other than AVG with the same arguments.
  4 Set the symbol-function of AVG to another function.
  5 Set the macro-function of AVG to another function.
  6 (abort) Return to level 0.
  7 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other
options

Do you know what have you done wrong?

bobi
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <a328ab72-f491-4cbd-a935-d33286a0f1c8@v15g2000yqn.googlegroups.com>
On Feb 12, 11:58 am, Slobodan Blazeski <·················@gmail.com>
wrote:
> On Feb 12, 3:24 pm, cartercc <········@gmail.com> wrote:
>
>
>
> > On Feb 11, 11:34 am, cartercc <········@gmail.com> wrote:
>
> > > The following script averages a series of grades from console input. I
> > > wrote it as if I would write a C program -- obviously not in idiomatic
> > > Lisp. How would one rewrite this in idiomatic Lisp?
>
> > Thanks to all. Here is a clean copy of the scripts so far submitted,
> > warts and all.
> > ;;;-----------------Slobodan Blazeski---------------------------------
> > (defun gr-blaze (&optional  (s 0) (n 0))
> >   (princ "Enter next grade, 'Q' to quit: ")
> >   (let ((g (read)))
> >      (if (numberp g)
> >         (progn
> >           (format t "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
> >            g (+ g s) (1+ n) (/  (+ g s) (1+ n)))
> >           (avg (+ g s) (1+ n)))
> >        (format t "~%Average is ~g~%" (/ s n)))))
>
> (gr-blaze)
> Enter next grade, 'Q' to quit: 22
> Grade: 22, total: 22, count: 1, average: 22
>
> Error: Undefined operator AVG in form (AVG (+ G S) (1+ N)).
>   1 (continue) Try invoking AVG again.
>   2 Return some values from the form (AVG (+ G S) (1+ N)).
>   3 Try invoking something other than AVG with the same arguments.
>   4 Set the symbol-function of AVG to another function.
>   5 Set the macro-function of AVG to another function.
>   6 (abort) Return to level 0.
>   7 Return to top loop level 0.
>
> Type :b for backtrace, :c <option number> to proceed,  or :? for other
> options
>
> Do you know what have you done wrong?
>
> bobi

Yes, I didn't rename the recursive call. When I copied all the
functions to one file, I had renamed it, but this must have come from
my intermediate version. Anyway, the code works, and I think I like
your version the best, mainly because it avoids the loop.

Thanks, CC.
From: Chris Riesbeck
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <6vjkg9FkikorU1@mid.individual.net>
cartercc wrote:
> On Feb 11, 11:34 am, cartercc <········@gmail.com> wrote:
>> The following script averages a series of grades from console input. I
>> wrote it as if I would write a C program -- obviously not in idiomatic
>> Lisp. How would one rewrite this in idiomatic Lisp?
> 
> Thanks to all. Here is a clean copy of the scripts so far submitted,
> warts and all.

Adding my own approach. In my idiom, I would not limit this to one 
function. I start with a vision of a simple loop that does the job, 
basically something that says

   while next grade
     update and print stats
   print final average

Then I work as hard as possible to make that loop the first thing anyone 
sees, e.g.,

(defun gr-riesbeck ()
   (let ((stats (make-instance 'stats)))
     (loop while (prin1 (add-grade (read-grade) stats)))
     (format t "~%Average is ~g~%" (stats-average stats))))

(defun read-grade ()
   (princ "Enter next grade, 'Q' to quit: ")
   (read))

(defclass stats ()
   ((grade :initform 0)
    (total :initform 0)
    (count :initform 0)
    (average :initform 0 :accessor stats-average)))

(defmethod add-grade (n (s stats))
   (if (numberp n)
     (with-slots (grade total count average) s
       (setq grade n)
       (incf total n)
       (incf count)
       (setq average (/ total count))
       s)))

(defmethod print-object ((s stats) stream)
   (with-slots (grade total count average) s
     (format stream "Grade: ~a, total: ~a, count: ~a, average: ~a~%"
       grade total count average)))
From: Kaz Kylheku
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <20090219063346.310@gmail.com>
On 2009-02-12, cartercc <········@gmail.com> wrote:
> On Feb 11, 11:34 am, cartercc <········@gmail.com> wrote:
>> The following script averages a series of grades from console input. I
>> wrote it as if I would write a C program -- obviously not in idiomatic
>> Lisp. How would one rewrite this in idiomatic Lisp?
>
> Thanks to all. Here is a clean copy of the scripts so far submitted,
> warts and all.

``Scripts''? ;)

How quaint.
From: Kaz Kylheku
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <20090219063425.57@gmail.com>
On 2009-02-12, cartercc <········@gmail.com> wrote:
> On Feb 11, 11:34 am, cartercc <········@gmail.com> wrote:
>> The following script averages a series of grades from console input. I
>> wrote it as if I would write a C program -- obviously not in idiomatic
>> Lisp. How would one rewrite this in idiomatic Lisp?
>
> Thanks to all. Here is a clean copy of the scripts so far submitted,
> warts and all.
>
> ;;;---------------------Charles Carter---------------------
> (defun gr-carter ()
>   (progn
>     (setq total 0)
>     (setq count 0)
>     (setq avg 0)

This is no good. You function has free references to symbols which have no
definition in sight. Worse, you are assigning to them.

In Lisp you cannot use a symbolic form without defining it somewhere as a
lexical variable or symbol macro, dynamic variable, constant, or global symbol
macro.

Because assigning to an unbound symbol actually has some kind of effect
in many Lisps (but not the exact same effect across all of them), the ANSI
standard does not require the situation to be diagnosed as an unbound error.

The behavior is simply undefined!

> ;;;------------------Marco Antoniotti--------------------
> ;;; doesn't prompt for input on the first instance
> (defun gr-anton ()
>    (loop with avg   = 0.0
>         initially (princ "Enter next grade, 'Q' to quit: ")
>         for grade = (read *standard-input* nil t)
>         while (numberp grade)
>         sum grade into total
>         count grade into count
>         do (setf avg (/ total count))
>         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
>                            Enter next grade, 'Q' to quit: "
>                    grade total count avg)
>         finally (format t "~&Average is ~G~%" avg)))

Nice. This one gets my vote, if there were to be a poll. :)
From: cartercc
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <8d9f260f-3bf0-4098-a79c-888cb1d8d5cd@z1g2000yqn.googlegroups.com>
On Feb 12, 5:47 pm, Kaz Kylheku <········@gmail.com> wrote:
> > ;;;---------------------Charles Carter---------------------
> > (defun gr-carter ()
> >   (progn
> >     (setq total 0)
> >     (setq count 0)
> >     (setq avg 0)
>
> This is no good. You function has free references to symbols which have no
> definition in sight. Worse, you are assigning to them.

Which was one of the reasons I posted this thread. Due to my
ignorance, I simply did not know how to do it.

> In Lisp you cannot use a symbolic form without defining it somewhere as a
> lexical variable or symbol macro, dynamic variable, constant, or global symbol
> macro.

Unlike C, or Perl, where you can declare a variable without assigning
it a value. It's not enough to know that you can't do it, but WHY you
can't do it.

> Because assigning to an unbound symbol actually has some kind of effect
> in many Lisps (but not the exact same effect across all of them), the ANSI
> standard does not require the situation to be diagnosed as an unbound error.

Okay, how would you explain that in language that someone who was not
familiar with Lisp would understand? What is a symbol? Other languages
don't seem to have them. Is it a variable? Why say that it is
'unbound' rather than saying that it has been declared but not yet
assigned a value?

> The behavior is simply undefined!

Which means what? In Perl, my day-to-day language, undefined objects
can play important, positive roles, that is, an object can exist but
not be defined, you can test for that state, and use it as a boolean
test for iteration or selection structures.

> > ;;;------------------Marco Antoniotti--------------------
> > ;;; doesn't prompt for input on the first instance
> > (defun gr-anton ()
> >    (loop with avg   = 0.0
> >         initially (princ "Enter next grade, 'Q' to quit: ")
> >         for grade = (read *standard-input* nil t)
> >         while (numberp grade)
> >         sum grade into total
> >         count grade into count
> >         do (setf avg (/ total count))
> >         do (format t  "Grade: ~a, total: ~a, count: ~a, average: ···@
> >                            Enter next grade, 'Q' to quit: "
> >                    grade total count avg)
> >         finally (format t "~&Average is ~G~%" avg)))
>
> Nice. This one gets my vote, if there were to be a poll. :)

Why do you like it more than the others? (Not interested in right or
wrong, but simply in your reasons for liking this one.)

CC
From: Slobodan Blazeski
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <8ee78f17-fe40-45ee-a49f-7e50eed4a609@k8g2000yqn.googlegroups.com>
On Feb 13, 5:04 am, cartercc <········@gmail.com> wrote:
> On Feb 12, 5:47 pm, Kaz Kylheku <········@gmail.com> wrote:
>
> > > ;;;---------------------Charles Carter---------------------
> > > (defun gr-carter ()
> > >   (progn
> > >     (setq total 0)
> > >     (setq count 0)
> > >     (setq avg 0)
>
> > This is no good. You function has free references to symbols which have no
> > definition in sight. Worse, you are assigning to them.
>
> Which was one of the reasons I posted this thread. Due to my
> ignorance, I simply did not know how to do it.

Though its nice to share your code here in cll, it would be probably
be better to go through some nice book first
http://tourdelisp.blogspot.com/2009/02/learning-common-lisp.html if
you got stuck or you have problem to understand anything feel free  to
ask here, or even better use (describe 'some-symbol) first than ask.
Unlike some lazy bastards like this
http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/a88d5f4902545c61?hl=en

bobi
From: Kenneth Tilton
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <499507f3$0$20281$607ed4bc@cv.net>
cartercc wrote:
> On Feb 12, 5:47 pm, Kaz Kylheku <········@gmail.com> wrote:
>>> ;;;---------------------Charles Carter---------------------
>>> (defun gr-carter ()
>>>   (progn
>>>     (setq total 0)
>>>     (setq count 0)
>>>     (setq avg 0)
>> This is no good. You function has free references to symbols which have no
>> definition in sight. Worse, you are assigning to them.
> 
> Which was one of the reasons I posted this thread. Due to my
> ignorance, I simply did not know how to do it.
> 
>> In Lisp you cannot use a symbolic form without defining it somewhere as a
>> lexical variable or symbol macro, dynamic variable, constant, or global symbol
>> macro.
> 
> Unlike C, or Perl, where you can declare a variable without assigning
> it a value.

Did you just change the subject? Aside from that, not sure you want to 
say "unlike" when Lisp does the same as what you are unliking:

(defvar *wtf*)

> It's not enough to know that you can't do it, but WHY you
> can't do it.

Because that is what the spec says? Too easy? If you were looking for a 
good reason, I would say that since the lamnguage has  both dynamic and 
lexical scope that if a compiler comes across a variable it simply has 
never seen before then it is forced into guessing at whether someone 
forget defvar or let and it really hates guessing. so it guesses but 
yells (my lisp anyway).


> 
>> Because assigning to an unbound symbol actually has some kind of effect
>> in many Lisps (but not the exact same effect across all of them), the ANSI
>> standard does not require the situation to be diagnosed as an unbound error.
> 
> Okay, how would you explain that in language that someone who was not
> familiar with Lisp would understand? 

(1) become familiar with Lisp
(2) read that again

> What is a symbol? 

a data structure, in effect, with a name unique within a package. I 
think you are starting at the wrong end.

> Other languages
> don't seem to have them. Is it a variable? Why say that it is
> 'unbound' rather than saying that it has been declared but not yet
> assigned a value?

because unbound is about ten words shorter?

> 
>> The behavior is simply undefined!
> 
> Which means what? 

nose. demons. please note order.

 > In Perl, my day-to-day language, undefined objects
> can play important, positive roles, that is, an object can exist but
> not be defined, you can test for that state, and use it as a boolean
> test for iteration or selection structures.

Sure. Ill-considered hacks of languages do all sorts of whacky things 
until they grow up if they do before they die.

kt
From: Andrew Reilly
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <6vko0jFkjon1U1@mid.individual.net>
On Fri, 13 Feb 2009 00:41:09 -0500, Kenneth Tilton wrote:

> Sure. Ill-considered hacks of languages do all sorts of whacky things
> until they grow up if they do before they die.

Always, it seems.

After your mention of Richard Gabriel the other day, I read a few papers 
from his web site, including "A Pattern of Language Evolution" (with Guy 
Steele, Jr.), which I thought was really interesting.  There was a cool 
bit where some of the MacLisp users were complaining that one of the 
trade-offs intended to make it and Interlisp more similar was that (car 
nil) -> nil and (cdr nil) -> nil.  The *reason* that they didn't like 
this is that up until then they'd been able to (cdr symbol) to get the 
property list for  symbol (just because that's where it was stored in 
memory).  They weren't concerned about the great boon that this would 
bring to the conciseness of their code (ref the thread on the finer 
points of car), but that this required that nil be treated differently 
from all of the other symbols.  History is neat, huh?

Cheers,

-- 
Andrew
From: Pascal J. Bourguignon
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <87zlgqadp2.fsf@galatea.local>
cartercc <········@gmail.com> writes:
>> The behavior is simply undefined!
>
> Which means what? 

Which means that the standard doesn't say what will happen.

An implementation may say what will happen, but there could be
implementation where this would still be undefined.  That's where
nasal demons enter the scene.

> In Perl, my day-to-day language, undefined objects
> can play important, positive roles, that is, an object can exist but
> not be defined, you can test for that state, and use it as a boolean
> test for iteration or selection structures.

Perl is not defined.  There's no perl standard.  There's no
alternative implementation. 

-- 
__Pascal Bourguignon__
From: Thomas A. Russ
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <ymid4dlu805.fsf@blackcat.isi.edu>
cartercc <········@gmail.com> writes:

> On Feb 12, 5:47��pm, Kaz Kylheku <········@gmail.com> wrote:

[snip undeclared variable example]

> > In Lisp you cannot use a symbolic form without defining it somewhere as a
> > lexical variable or symbol macro, dynamic variable, constant, or global symbol
> > macro.
> 
> Unlike C, or Perl, where you can declare a variable without assigning
> it a value. It's not enough to know that you can't do it, but WHY you
> can't do it.

Well, you can declare global (special = dynamic) variable without giving them a
value.  They are then UNBOUND.  But since there is a difference in the
behavior of special and lexical variables, it is good practice to
declare any variables you wish to have be treated as special, since this
is often a globally pervasive decision and affects the treatment of
variables bound in LET blocks.

In fact, since the behavior is so different, Lisp coding style has
adopted the very strong and nearly universal convention of denoting
special variables by naming them so that they begin and end with
asterisk ("*") characters.  In fact, there are some lisps that will give
a style warning for globally special variables that are not so named.

> > Because assigning to an unbound symbol actually has some kind of effect
> > in many Lisps (but not the exact same effect across all of them), the ANSI
> > standard does not require the situation to be diagnosed as an unbound error.
> 
> Okay, how would you explain that in language that someone who was not
> familiar with Lisp would understand? What is a symbol? Other languages
> don't seem to have them. 

That is correct.  Most other languages DON'T have them.  Symbols are one
of the basic objects that exist in Common Lisp.  They have many
properties, but among them is that they can be bound to values, which
makes them be variables.

> Is it a variable?

No.  It is a first-class object in its own right.  It may be used to
name a variable, and when bound to values it acts like a variable.  But
it has additional functions as well.  It can name a function and a class
in addition to having a (lexical or dynamic) value.

> Why say that it is
> 'unbound' rather than saying that it has been declared but not yet
> assigned a value?

Because that is the lisp terminology.  The association of a symbol with
a value is called a "binding" of that symbol.  So if there is no such
binding, then the logical name for the state is "unbound".  This is a
fundamental term in lisp, so it's good to get used to it.


> > The behavior is simply undefined!
> 
> Which means what?

It means that if you do that, you can't predict what a conforming
implementation of Common Lisp will do.  Now, all known implementations
do something "reasonable", but exactly what that reasonable behavior is
does vary, perhaps in subtle ways, between implementations.

The majority of lisps will treat references to undeclared variables as
special (=dynamic) references to those variables.  But that is done each
time the variable is encountered, and doesn't affect the global state of
declarations.  In other lisps, notably CMUCL, setting the undeclared
variable makes it be proclaimed to be globally special, on the
assumption that the user reallly meant that, but forgot.  That is
different behavior because it affects the state of global definitions.

In all cases I'm aware of, the compiler will complain (issue a warning).

Those two compilers will treat the following code differently, and give
you different answers:


    (defun foo () (print a))

    (setf a 10)

    (let ((a 5))
      (foo))

One implementation will print 5 and the other 10.  And you can't
complain because the behavior is not defined by the standard.  That is
precisely what "undefined behavior" means.

> In Perl, my day-to-day language, undefined objects
> can play important, positive roles, that is, an object can exist but
> not be defined, you can test for that state, and use it as a boolean
> test for iteration or selection structures.

There is an important difference between a value being undefined and
behavior being undefined.  Even in Perl, you would probably not want to
do something where the implementation says the effects are undefined
(and thus not predictable).

Actually, Perl probably doesn't really have undefined objects, but
rather it refers to pointers (variables) that don't point to any
particular object.  (Or else to a special value, "null", that isn't any
object.  I'm not really up on the details of Perl semantics).

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Kaz Kylheku
Subject: Re: idiomatic Lisp style
Date: 
Message-ID: <20090220110338.161@gmail.com>
On 2009-02-13, cartercc <········@gmail.com> wrote:
> On Feb 12, 5:47 pm, Kaz Kylheku <········@gmail.com> wrote:
>> > ;;;---------------------Charles Carter---------------------
>> > (defun gr-carter ()
>> >   (progn
>> >     (setq total 0)
>> >     (setq count 0)
>> >     (setq avg 0)
>>
>> This is no good. You function has free references to symbols which have no
>> definition in sight. Worse, you are assigning to them.
>
> Which was one of the reasons I posted this thread. Due to my
> ignorance, I simply did not know how to do it.
>
>> In Lisp you cannot use a symbolic form without defining it somewhere as a
>> lexical variable or symbol macro, dynamic variable, constant, or global symbol
>> macro.
>
> Unlike C, or Perl, where you can declare a variable without assigning
> it a value.

I don't follow this. I didn't say that in Lisp you had to provide a value while
defining a variable, but that you had to define a variable before using it.

You certainly can define a dynamic variable in Lisp without giving it a value.

> It's not enough to know that you can't do it, but WHY you
> can't do it.

Why you can't use a variable without defining it is simply because that's
how the language is.

There are languages in which you can just use a previously unknown name, and it
magically becomes a variable right there, and even has some default value.

In the POSIX shell language you can evaluate $anything, and it works---unless
checking for unset variables been turned on with ``set -u''. So the POSIX shell
language is two languages in one: one in which variables must be defined before
use, and a language in which they don't have to be.

>> Because assigning to an unbound symbol actually has some kind of effect
>> in many Lisps (but not the exact same effect across all of them), the ANSI
>> standard does not require the situation to be diagnosed as an unbound error.
>
> Okay, how would you explain that in language that someone who was not
> familiar with Lisp would understand?

The prof teaching the course is supposed to understand the above language, and
it's his job to teach that in a way that the students understand.

> What is a symbol? Other languages
> don't seem to have them.

The term symbol is certainly used in other languages. C toolchains typically
refer to object files has having ``symbols'', etc.

I wasn't using ``symbol'' as a Lisp data type here.

>? Is it a variable? Why say that it is
> 'unbound' rather than saying that it has been declared but not yet
> assigned a value?

Because unbound is roughly the opposite of defined or declared. 

I.e. why would I say ``X'', if I really wanted to say ``not X''?

>> The behavior is simply undefined!
>
> Which means what? 

Which means that the American national standard for the language does not
impose any requirements about how a language implementation should respond
to the construct.

If demons fly out of the programmer's nose, that is conforming behavior.

This is what ``undefined behavior'' commonly means in the definitions of many
programming languages, not only in Lisp.

> In Perl, my day-to-day language, undefined objects

Well, your day-to-day language is a moving target that is defined by the
behavior of its latest source code tarball.

> can play important, positive roles

``Undefined object'' is not the same thing as ``undefined behavior''.

A program defining a variable is a completely different ``defining'' from a
language standard defining a requirement that a program or language
implementation must mean.

> Why do you like it more than the others? (Not interested in right or
> wrong, but simply in your reasons for liking this one.)

Because it neatly meets all of the requirements using features of LOOP, which
are missed by some of the other implementations. So, in effect, it's all
written in one programming language: the LOOP programming language.