From: Blaino
Subject: Newbie question: Trouble with Chapter 9, _Practical Common Lisp_
Date: 
Message-ID: <1131024097.341379.286020@z14g2000cwz.googlegroups.com>
Hi, I'm a newbie working my way through Peter Seibel's _Practical
Common Lisp_.  When I run the code from this chapter (included below) I
get "EVAL: variable RESULT has no value".
More specfically, when I:

CL-USER> (deftest test-+ () (check (= (+ 1 2) 3)) (check (= (+ 1 1)
2)))

I get:

EVAL: variable RESULT has no value
   [Condition of type SYSTEM::SIMPLE-UNBOUND-VARIABLE]

Restarts:
  0: [STORE-VALUE] You may input a new value for RESULT.
  1: [USE-VALUE] You may input a value to be used instead of RESULT.
  2: [ABORT] Abort handling SLIME request.

Backtrace:
  0: frame binding variables (~ = dynamically):
  | ~ SYSTEM::*FASOUTPUT-STREAM* <--> NIL
  1: EVAL frame for form RESULT
  2: EVAL frame for form (LIST RESULT T)
  3: EVAL frame for form (LIST (LIST RESULT T))
  4: EVAL frame for form (LIST (LIST (LIST RESULT T)))
  5: EVAL frame for form (APPEND (LIST (LIST (LIST RESULT T))) (BLOCK
NIL (LET ((#1=#:G1009 FORMS)) (LET ((F NIL)) (LET
((#2=#:ACCULIST-VAR-1010 NIL)) (TAGBODY SYSTEM::BEGIN-LOOP (WHEN (ENDP
#1#) (GO SYSTEM::END-LOOP)) (SETQ F (CAR #1#)) (SETQ #2# (CONS (LIST
'UNLESS F (LIST 'SETF RESULT NIL)) #2#)) (PSETQ #1# (CDR #1#)) (GO
SYSTEM::BEGIN-LOOP) SYSTEM::END-LOOP (RETURN-FROM NIL
(SYSTEM::LIST-NREVERSE #2#))))))) (LIST RESULT))
  6: EVAL frame for form (CONS 'LET (APPEND (LIST (LIST (LIST RESULT
T))) (BLOCK NIL (LET ((#1=#:G1009 FORMS)) (LET ((F NIL)) (LET
((#2=#:ACCULIST-VAR-1010 NIL)) (TAGBODY SYSTEM::BEGIN-LOOP (WHEN (ENDP
#1#) (GO SYSTEM::END-LOOP)) (SETQ F (CAR #1#)) (SETQ #2# (CONS (LIST
'UNLESS F (LIST 'SETF RESULT NIL)) #2#)) (PSETQ #1# (CDR #1#)) (GO
SYSTEM::BEGIN-LOOP) SYSTEM::END-LOOP (RETURN-FROM NIL
(SYSTEM::LIST-NREVERSE #2#))))))) (LIST RESULT)))


I can't make any sense of the backtrace, so I'm at a loss for figuring
out my error.  I'm using Lisp-in-a-box with CLISP on a windows machine.
 Please help!  I'm so darned excited about working through this book -
I don't want to get discouraged so soon.

Thanks,
Blaine

-----------------------------------------------------------------------------------
Chapter 9, _Practical Common Lisp_ Code

(defmacro deftest (name parameters &body body)
  "Define a test function. Within a test function we can call other
test functions or use `check' to run individual test cases."
  `(defun ,name ,parameters
    (let ((*test-name* (append *test-name* (list ',name))))
      ,@body)))

(defmacro check (&body forms)
  "Run each expression in `forms' as a test case."
  `(combine-results
    ,@(loop for f in forms collect `(report-result ,f ',f))))

(defmacro combine-results (&body forms)
  "Combine the results (as booleans) of evaluating `forms' in order."
  (with-gensyms (result)
    `(let ((,result t))
      ,@(loop for f in forms collect `(unless ,f (setf ,result nil)))
      ,result)))

(defun report-result (result form)
  "Report the results of a single test case. Called by `check'."
  (format t "~:[FAIL~;pass~] ... ~a: ~a~%" result *test-name* form)
  result)

From: Timofei Shatrov
Subject: Re: Newbie question: Trouble with Chapter 9, _Practical Common Lisp_
Date: 
Message-ID: <436a136e.1656871@news.readfreenews.net>
On 3 Nov 2005 05:21:37 -0800, "Blaino" <·············@hotmail.com> tried
to confuse everyone with this message:

>Hi, I'm a newbie working my way through Peter Seibel's _Practical
>Common Lisp_.  When I run the code from this chapter (included below) I
>get "EVAL: variable RESULT has no value".

That's because CLISP has it's own with-gensyms macro with somewhat
different syntax. You should do (shadow :with-gensyms) and use the macro
from the book.

-- 
|a\o/r|,-------------.,---------- Timofei Shatrov aka Grue ------------.
| m"a ||FC AMKAR PERM|| mail: grue at mail.ru  http://grue3.tripod.com |
|  k  ||  PWNZ J00   || Kingdom of Loathing: Grue3 lvl 18 Seal Clubber |
`-----'`-------------'`-------------------------------------------[4*72]
From: Peter Seibel
Subject: Re: Newbie question: Trouble with Chapter 9, _Practical Common Lisp_
Date: 
Message-ID: <m24q6t8xy0.fsf@gigamonkeys.com>
····@mail.ru (Timofei Shatrov) writes:

> On 3 Nov 2005 05:21:37 -0800, "Blaino" <·············@hotmail.com> tried
> to confuse everyone with this message:
>
>>Hi, I'm a newbie working my way through Peter Seibel's _Practical
>>Common Lisp_.  When I run the code from this chapter (included below) I
>>get "EVAL: variable RESULT has no value".
>
> That's because CLISP has it's own with-gensyms macro with somewhat
> different syntax. You should do (shadow :with-gensyms) and use the
> macro from the book.

I also suspect that you're using Matthew Danish's Lisp in a Box
(available from common-lisp.net) rather than the Lispbox distro I
prepared (available from http://www.gigamonkeys.com/lispbox/) since in
my Lispbox I scrub the CL-USER package so it doesn't contain any
implementation-specific dodads like CLISP's WITH-GENSYMS, etc. Or
there's a bug in my Lispbox and I didn't scrub things as well as I
thought. (Though you would still need to load the WITH-GENSYMS
definition from Chapter 8 before the test framework code.)

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Pascal Bourguignon
Subject: Re: Newbie question: Trouble with Chapter 9, _Practical Common Lisp_
Date: 
Message-ID: <8764r9kyur.fsf@thalassa.informatimago.com>
····@mail.ru (Timofei Shatrov) writes:

> On 3 Nov 2005 05:21:37 -0800, "Blaino" <·············@hotmail.com> tried
> to confuse everyone with this message:
>
>>Hi, I'm a newbie working my way through Peter Seibel's _Practical
>>Common Lisp_.  When I run the code from this chapter (included below) I
>>get "EVAL: variable RESULT has no value".
>
> That's because CLISP has it's own with-gensyms macro with somewhat
> different syntax. You should do (shadow :with-gensyms) and use the macro
> from the book.

That's because all implementations are allowed to polute the
COMMON-LISP-USER package with whatever definitions the want.

There are two solutions:

- Either DO NOT use the package COMMON-LISP-USER.
  Every time you start an Common Lisp implementation, type:
        (defpackage :my-workplace (:use :common-lisp))
        (in-package :my-workplace)

- Or remove all imported packages from COMMON-LISP-USER.
  In the rc file of your Common Lisp implementation add:

   (MAPC (LAMBDA (USED) (UNUSE-PACKAGE USED "COMMON-LISP-USER"))
         (REMOVE (FIND-PACKAGE "COMMON-LISP")
                 (COPY-SEQ (PACKAGE-USE-LIST "COMMON-LISP-USER"))))



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

In a World without Walls and Fences, 
who needs Windows and Gates?
From: Kalle Olavi Niemitalo
Subject: Re: Newbie question: Trouble with Chapter 9, _Practical Common Lisp_
Date: 
Message-ID: <87ll047tg5.fsf@Astalo.kon.iki.fi>
Pascal Bourguignon <····@mouse-potato.com> writes:

>    (MAPC (LAMBDA (USED) (UNUSE-PACKAGE USED "COMMON-LISP-USER"))
>          (REMOVE (FIND-PACKAGE "COMMON-LISP")
>                  (COPY-SEQ (PACKAGE-USE-LIST "COMMON-LISP-USER"))))

Is UNUSE-PACKAGE allowed to mutate a list that PACKAGE-USE-LIST
has returned earlier?
From: Pascal Bourguignon
Subject: Re: Newbie question: Trouble with Chapter 9, _Practical Common Lisp_
Date: 
Message-ID: <87hdaskeji.fsf@thalassa.informatimago.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Pascal Bourguignon <····@mouse-potato.com> writes:
>
>>    (MAPC (LAMBDA (USED) (UNUSE-PACKAGE USED "COMMON-LISP-USER"))
>>          (REMOVE (FIND-PACKAGE "COMMON-LISP")
>>                  (COPY-SEQ (PACKAGE-USE-LIST "COMMON-LISP-USER"))))
>
> Is UNUSE-PACKAGE allowed to mutate a list that PACKAGE-USE-LIST
> has returned earlier?

Indeed.  PACKAGE-USE-LISP may return the actual internal list, which
UNUSE-PACKAGE modifies.

Actually, before I had DELETE instead of REMOVE, the situation was
worse.  But in anycase, REMOVE may return a common tail, and since
MAPC keeps a pointer to the current cons cell, it's better that this
cell (and the following) not be modified.

clhs remove

  The result of remove may share with sequence; the result may be
  identical to the input sequence if no elements need to be removed."


and:

  3.6 Traversal Rules and Side Effects

  The consequences are undefined when code executed during an object-traversing
  operation destructively modifies the object in a way that might affect the
  ongoing traversal operation. In particular, the following rules apply.

  List traversal

      For list traversal operations, the cdr chain of the list is not allowed to
      be destructively modified.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
From: Kalle Olavi Niemitalo
Subject: Re: Newbie question: Trouble with Chapter 9, _Practical Common Lisp_
Date: 
Message-ID: <877jbntjuc.fsf@Astalo.kon.iki.fi>
Pascal Bourguignon <····@mouse-potato.com> writes:

> Kalle Olavi Niemitalo <···@iki.fi> writes:
>
>> Pascal Bourguignon <····@mouse-potato.com> writes:
>>
>>>    (MAPC (LAMBDA (USED) (UNUSE-PACKAGE USED "COMMON-LISP-USER"))
>>>          (REMOVE (FIND-PACKAGE "COMMON-LISP")
>>>                  (COPY-SEQ (PACKAGE-USE-LIST "COMMON-LISP-USER"))))
>>
>> Is UNUSE-PACKAGE allowed to mutate a list that PACKAGE-USE-LIST
>> has returned earlier?
>
> Indeed.  PACKAGE-USE-LISP may return the actual internal list, which
> UNUSE-PACKAGE modifies.

I am surprised if this is the case.  In contrast, AMOP specifies
various reader functions so that the returned list will not be
modified by the implementation and must not be modified by the
caller.

For what it's worth, UNUSE-PACKAGE of CMU CL 18e manipulates
(package-%use-list package) with REMOVE rather than DELETE,
so the original list will remain unchanged.

If ANSI CL does not actually specify this, perhaps a later
version could either change that or add a note: "When use-package
or unuse-package is called, the implementation may destructively
modify any list returned by package-use-list for that package."

Are there any other symbols where such notes could be appropriate?
APROPOS-LIST affected by UNINTERN
ARRAY-DIMENSIONS affected by ADJUST-ARRAY
COMPUTE-APPLICABLE-METHODS affected by REMOVE-METHOD
PATHNAME-DIRECTORY affected by modification of the list that was
                   given to MAKE-PATHNAME
FILE-AUTHOR affected by renaming of users
FIND-ALL-SYMBOLS affected by UNINTERN
LISP-IMPLEMENTATION-VERSION affected by runtime patches
LONG-SITE-NAME affected by politics or moving the computer
MACHINE-INSTANCE affected by moving a saved Lisp image
PACKAGE-NAME affected by RENAME-PACKAGE
PACKAGE-NICKNAMES affected by RENAME-PACKAGE
PACKAGE-SHADOWING-SYMBOLS which already has a note, but
                          not exactly for this purpose
PACKAGE-USED-BY-LIST
SOFTWARE-VERSION affected by runtime patches

These return fresh sequences:
DIRECTORY
GET-OUTPUT-STREAM-STRING (apparently)
LIST-ALL-PACKAGES

These mutations are not permitted:
FORMATTER affected by SETF CHAR (I think)
SYMBOL-NAME affected by SETF CHAR of the string that was given
            to MAKE-SYMBOL

> Actually, before I had DELETE instead of REMOVE, the situation was
> worse.

If you already call COPY-SEQ, I suppose DELETE would be safe and
potentially faster (not that it matters much here).
From: Kalle Olavi Niemitalo
Subject: Re: Newbie question: Trouble with Chapter 9, _Practical Common Lisp_
Date: 
Message-ID: <87r79uqfnp.fsf@Astalo.kon.iki.fi>
Pascal Bourguignon <····@mouse-potato.com> writes:

> Kalle Olavi Niemitalo <···@iki.fi> writes:
>> If you already call COPY-SEQ, I suppose DELETE would be safe and
>> potentially faster (not that it matters much here).
>
> If MAPC fetches the CDR before calling the function, then it won't
> work with DELETE.

I meant

   (MAPC (LAMBDA (USED) (UNUSE-PACKAGE USED "COMMON-LISP-USER"))
         (DELETE (FIND-PACKAGE "COMMON-LISP")
                 (COPY-SEQ (PACKAGE-USE-LIST "COMMON-LISP-USER"))))

where DELETE (which used to be REMOVE) returns before MAPC is called.
From: R. Mattes
Subject: Re: Newbie question: Trouble with Chapter 9, _Practical Common Lisp_
Date: 
Message-ID: <pan.2005.11.03.15.38.47.823665@mh-freiburg.de>
On Thu, 03 Nov 2005 05:21:37 -0800, Blaino wrote:

> Hi, I'm a newbie working my way through Peter Seibel's _Practical
> Common Lisp_.  When I run the code from this chapter (included below) I
> get "EVAL: variable RESULT has no value".
> More specfically, when I:
> 
> CL-USER> (deftest test-+ () (check (= (+ 1 2) 3)) (check (= (+ 1 1)
> 2)))
> 
> I get:
> 
> EVAL: variable RESULT has no value
>    [Condition of type SYSTEM::SIMPLE-UNBOUND-VARIABLE]
> 
> Restarts:
>   0: [STORE-VALUE] You may input a new value for RESULT.
>   1: [USE-VALUE] You may input a value to be used instead of RESULT.
>   2: [ABORT] Abort handling SLIME request.
> 
> Backtrace:
>   0: frame binding variables (~ = dynamically):
>   | ~ SYSTEM::*FASOUTPUT-STREAM* <--> NIL
>   1: EVAL frame for form RESULT
>   2: EVAL frame for form (LIST RESULT T)
>   3: EVAL frame for form (LIST (LIST RESULT T))
>   4: EVAL frame for form (LIST (LIST (LIST RESULT T)))
>   5: EVAL frame for form (APPEND (LIST (LIST (LIST RESULT T))) (BLOCK
> NIL (LET ((#1=#:G1009 FORMS)) (LET ((F NIL)) (LET
> ((#2=#:ACCULIST-VAR-1010 NIL)) (TAGBODY SYSTEM::BEGIN-LOOP (WHEN (ENDP
> #1#) (GO SYSTEM::END-LOOP)) (SETQ F (CAR #1#)) (SETQ #2# (CONS (LIST
> 'UNLESS F (LIST 'SETF RESULT NIL)) #2#)) (PSETQ #1# (CDR #1#)) (GO
> SYSTEM::BEGIN-LOOP) SYSTEM::END-LOOP (RETURN-FROM NIL
> (SYSTEM::LIST-NREVERSE #2#))))))) (LIST RESULT))
>   6: EVAL frame for form (CONS 'LET (APPEND (LIST (LIST (LIST RESULT
> T))) (BLOCK NIL (LET ((#1=#:G1009 FORMS)) (LET ((F NIL)) (LET
> ((#2=#:ACCULIST-VAR-1010 NIL)) (TAGBODY SYSTEM::BEGIN-LOOP (WHEN (ENDP
> #1#) (GO SYSTEM::END-LOOP)) (SETQ F (CAR #1#)) (SETQ #2# (CONS (LIST
> 'UNLESS F (LIST 'SETF RESULT NIL)) #2#)) (PSETQ #1# (CDR #1#)) (GO
> SYSTEM::BEGIN-LOOP) SYSTEM::END-LOOP (RETURN-FROM NIL
> (SYSTEM::LIST-NREVERSE #2#))))))) (LIST RESULT)))
> 
> 
> I can't make any sense of the backtrace, so I'm at a loss for figuring
> out my error.  I'm using Lisp-in-a-box with CLISP on a windows machine.
>  Please help!  I'm so darned excited about working through this book -
> I don't want to get discouraged so soon.

Hmm, looks like "with-gensyms" isn't recognized as a macro. IIRC that
macro is developed earlier in the book. Have you loaded that code?

 HTH Ralf Mattes


> Thanks,
> Blaine
> 
> -----------------------------------------------------------------------------------
> Chapter 9, _Practical Common Lisp_ Code
> 
> (defmacro deftest (name parameters &body body)
>   "Define a test function. Within a test function we can call other
> test functions or use `check' to run individual test cases."
>   `(defun ,name ,parameters
>     (let ((*test-name* (append *test-name* (list ',name))))
>       ,@body)))
> 
> (defmacro check (&body forms)
>   "Run each expression in `forms' as a test case." `(combine-results
>     ,@(loop for f in forms collect `(report-result ,f ',f))))
> 
> (defmacro combine-results (&body forms)
>   "Combine the results (as booleans) of evaluating `forms' in order."
>   (with-gensyms (result)
>     `(let ((,result t))
>       ,@(loop for f in forms collect `(unless ,f (setf ,result nil)))
>       ,result)))
> 
> (defun report-result (result form)
>   "Report the results of a single test case. Called by `check'." (format
>   t "~:[FAIL~;pass~] ... ~a: ~a~%" result *test-name* form) result)
From: Blaino
Subject: Re: Newbie question: Trouble with Chapter 9, _Practical Common Lisp_
Date: 
Message-ID: <1131025694.004999.249450@g47g2000cwa.googlegroups.com>
Thank you.  That's it.  I thought "with-gensyms" was cl.

Again, thanks,
Blaine