From: Dave Watson
Subject: loop and eval problem
Date: 
Message-ID: <8d2fc94f.0407290228.2782ba98@posting.google.com>
My pet project at the moment is creating fmod bindings for lisp.

I am trying to make a loop that simply gets a number from the user,
with the option of pressing 'q' to quit:

---------
(loop with key and driver
	   do (setq key (peek-char))
	   until (eq #\q key)
	   do (setq driver (- (char-int (read-char)) (char-int #\0)))
	   (when (not (or (< driver 0) (>= driver (fsound:get-num-drivers))))
	     (fsound:set-driver driver)
	     (return t)))
---------

It seems to work fine when a number and then enter is pressed, but
when 'q' and then enter is pressed, I get weird error messages:
q unbound symbol
backtrace:
(eval q)

It seems my 'q' is getting executed on the top-level somehow, but the
how is a mystery to me...

Also, it seems that to get unbuffered behavior in streams, I need
something called gray streams.   Is this portable at all, or rather
implementation dependant? (I'm having a hard time finding information
on them)

Finally, I have a complete set of bindings for fmod so far, only
missing callbacks...but I see these are missing from uffi, does anyone
have any recommendations for a fairly portable way to do these?

Thank you much for your time!

From: Adam Warner
Subject: Re: loop and eval problem
Date: 
Message-ID: <pan.2004.07.29.10.55.26.758555@consulting.net.nz>
Hi Dave Watson,

> (loop with key and driver
> 	   do (setq key (peek-char))
> 	   until (eq #\q key)
> 	   do (setq driver (- (char-int (read-char)) (char-int #\0)))
> 	   (when (not (or (< driver 0) (>= driver (fsound:get-num-drivers))))
> 	     (fsound:set-driver driver)
> 	     (return t)))
> ---------
> 
> It seems to work fine when a number and then enter is pressed, but
> when 'q' and then enter is pressed, I get weird error messages:
> q unbound symbol
> backtrace:
> (eval q)
> 
> It seems my 'q' is getting executed on the top-level somehow, but the
> how is a mystery to me...

Because you peeked the character instead of consuming it via READ.

Compare:

* (peek-char)
q

#\q
*

Error in kernel::unbound-symbol-error-handler:  the variable q is unbound.
   [Condition of type unbound-variable]

Restarts:
  0: [abort] Return to Top-Level.

Debug  (type H for help)

(eval q)
Source: (symbol-value exp)
0] 0

* (read-char)
q

#\q
*


Also, never use EQ to test for character identity. It is not portable. Use
EQL instead:

   The value of eql is true of two objects, x and y, in the folowing cases:

   1. If x and y are eq.
   2. If x and y are both numbers of the same type and the same value.
   3. If they are both characters that represent the same character.

Otherwise the value of eql is false. 

If you refer to the definition of EQ you will find:

   An implementation is permitted to make ``copies'' of characters and
   numbers at any time. The effect is that Common Lisp makes no guarantee
   that eq is true even when both its arguments are ``the same thing'' if
   that thing is a character or number.

Regards,
Adam
From: Pascal Costanza
Subject: Re: loop and eval problem
Date: 
Message-ID: <ceamji$q40$1@f1node01.rhrz.uni-bonn.de>
Adam Warner wrote:

> Hi Dave Watson,
> 
> 
>>(loop with key and driver
>>	   do (setq key (peek-char))
>>	   until (eq #\q key)
>>	   do (setq driver (- (char-int (read-char)) (char-int #\0)))
>>	   (when (not (or (< driver 0) (>= driver (fsound:get-num-drivers))))
>>	     (fsound:set-driver driver)
>>	     (return t)))
>>---------
>>
>>It seems to work fine when a number and then enter is pressed, but
>>when 'q' and then enter is pressed, I get weird error messages:
>>q unbound symbol
>>backtrace:
>>(eval q)
>>
>>It seems my 'q' is getting executed on the top-level somehow, but the
>>how is a mystery to me...
> 
> Because you peeked the character instead of consuming it via READ.

Further note that you don't need the initial loop. The following should do.

(peek-char #\q)
(read-char)
(let ((driver (- (char-int (read-char)) (char-int #\0))))
   ...)


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  Römerstr. 164, D-53117 Bonn (Germany)