From: Mark Tarver
Subject: READ-CHAR-NO-HANG and the read-evaluate-print-loop
Date: 
Message-ID: <cf325f48.0410080407.36f3d3c4@posting.google.com>
I've been experimenting with a read-evaluate-print loop using 
READ-CHAR-NO-HANG - eventually it will allow inputs from multiple
streams.  

But I cannot get the damn thing to work - even though its a very
short program.  Here is a short form of the program using READ-CHAR.
It works fine.  

;;THIS PROGRAM WORKS!

(DEFUN read-eval-print-loop ()
 (PROG (CHARS)
       ;;chuck out a character
       (READ-CHAR)
       LOOP 
       ;;read a character from standard input
       (LET ((CHAR (READ-CHAR)))
            (SETQ CHARS (eval-print CHAR CHARS))) 
       (GO LOOP)))

(DEFUN eval-print (CHAR CHARS)
;;if the 'character' is NIL, skip    
  (COND ((NULL CHAR) CHARS)
;;if a newline - evaluate and print the result
        ((CHAR-EQUAL CHAR #\Newline) 
         (FORMAT T "~A" (EVAL (READ-FROM-STRING (COERCE (REVERSE
CHARS) 'STRING))))
         (TERPRI))  
;;else add the character to the input       
        (T (CONS CHAR CHARS)))) 

But if (LET ((CHAR (READ-CHAR-NO-HANG))) ... is used, the program
becomes
mute - not even showing user input. Moreover the CHAR in
read-eval-print-loop is always NIL except when the user hits RETURN.

;;THIS PROGRAM DOES NOT WORK!

(DEFUN read-eval-print-loop ()
 (PROG (CHARS)
       ;;chuck out a character
       (READ-CHAR)
       LOOP 
       ;;read a character from standard input
       (LET ((CHAR (READ-CHAR-NO-HANG)))
            (SETQ CHARS (eval-print CHAR CHARS))) 
       (GO LOOP)))

(DEFUN eval-print (CHAR CHARS)
;;if the 'character' is NIL, skip    
  (COND ((NULL CHAR) CHARS)
;;if a newline - evaluate and print the result
        ((CHAR-EQUAL CHAR #\Newline) 
         (FORMAT T "~A" (EVAL (READ-FROM-STRING (COERCE (REVERSE
CHARS) 'STRING))))
         (TERPRI))  
;;else add the character to the input       
        (T (CONS CHAR CHARS)))) 

I'm missing something here - what?

Mark Tarver

From: Pascal Bourguignon
Subject: Re: READ-CHAR-NO-HANG and the read-evaluate-print-loop
Date: 
Message-ID: <87y8ihxpno.fsf@thalassa.informatimago.com>
··········@ukonline.co.uk (Mark Tarver) writes:

> I've been experimenting with a read-evaluate-print loop using 
> READ-CHAR-NO-HANG - eventually it will allow inputs from multiple
> streams.  
> 
> But I cannot get the damn thing to work - even though its a very
> short program.  Here is a short form of the program using READ-CHAR.
> It works fine.  
> [...]
> But if (LET ((CHAR (READ-CHAR-NO-HANG))) ... is used, the program
> becomes
> mute - not even showing user input. Moreover the CHAR in
> read-eval-print-loop is always NIL except when the user hits RETURN.
> [...]
> I'm missing something here - what?

Are you testing it in an xterm, or under slime?

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

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Mark Tarver
Subject: Re: READ-CHAR-NO-HANG and the read-evaluate-print-loop
Date: 
Message-ID: <cf325f48.0410081128.630fc5f7@posting.google.com>
> Are you testing it in an xterm, or under slime?

Not sure what you mean here.  I'm using CLisp 2001 with no frills.
The program is run as is - typed into the top level Lisp.
From: Pascal Bourguignon
Subject: Re: READ-CHAR-NO-HANG and the read-evaluate-print-loop
Date: 
Message-ID: <87pt3syk7k.fsf@thalassa.informatimago.com>
··········@ukonline.co.uk (Mark Tarver) writes:

> > Are you testing it in an xterm, or under slime?
> 
> Not sure what you mean here.  I'm using CLisp 2001 with no frills.
> The program is run as is - typed into the top level Lisp.

clisp has progressed a lot in the last three years! You should try
clisp 2.33.2!

From what you write, one could infer that you're working directly with
clisp (in xterm or other "terminal"). In that case it should work.

When running a common-lisp implementation under slime on emacs, the
standard input and standard output stream are not the usual terminal
stream connected to the terminal, so there are quite a number of
differences in behavior then.

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

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Mark Tarver
Subject: Re: READ-CHAR-NO-HANG and the read-evaluate-print-loop
Date: 
Message-ID: <cf325f48.0410081900.5a49a731@posting.google.com>
> clisp has progressed a lot in the last three years! You should try
> clisp 2.33.2!

OK, I've downloaded CLisp 2.33.1. This is what happens.

=====================================
[3]>  (TRACE READ-FROM-STRING)
READ-FROM-STRING

[4]>  (read-eval-print-loop)
(* 7 8)

=====================================

Nothing happens here - also READ-FROM-STRING is not called.
The expression is not evaluated and 56 is not printed.

This is what happens under Clisp 2001.

=====================================
[5]> (TRACE READ-FROM-STRING)
;; Tracing function READ-FROM-STRING.
(READ-FROM-STRING)
[6]> (read-eval-print-loop)
(* 7 8)

1. Trace: (READ-FROM-STRING '"")
*** - READ: input stream #<INPUT STRING-INPUT-STREAM> has reached its end
=====================================

READ-FROM-STRING is called - but READ-CHAR-NO-HANG has not accumulated any
characters.  READ-FROM-STRING tries to read the empty string and complains.
Still looks odd to me.
From: Pascal Bourguignon
Subject: Re: READ-CHAR-NO-HANG and the read-evaluate-print-loop
Date: 
Message-ID: <87d5zsxblk.fsf@thalassa.informatimago.com>
(Your "non-working" program works in my xterm too).

··········@ukonline.co.uk (Mark Tarver) writes:
> READ-FROM-STRING is called - but READ-CHAR-NO-HANG has not accumulated any
> characters.  READ-FROM-STRING tries to read the empty string and complains.
> Still looks odd to me.

Also, you may want to have a look at LISTEN and at the SCREEN and
TERMINAL extensions of clisp:

http://www.lispworks.com/reference/HyperSpec/Body/f_listen.htm
http://clisp.cons.org/impnotes/screen.html
http://clisp.cons.org/impnotes/terminal.html

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

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Gareth McCaughan
Subject: Re: READ-CHAR-NO-HANG and the read-evaluate-print-loop
Date: 
Message-ID: <87d5zsvnuz.fsf@g.mccaughan.ntlworld.com>
Mark Tarver wrote:

> (DEFUN read-eval-print-loop ()
>  (PROG (CHARS)
>        ;;chuck out a character
>        (READ-CHAR)
>        LOOP 
>        ;;read a character from standard input
>        (LET ((CHAR (READ-CHAR-NO-HANG)))
>             (SETQ CHARS (eval-print CHAR CHARS))) 
>        (GO LOOP)))
...
> I'm missing something here - what?

Forgive me for being rude and irrelevant, but: One thing
you're missing is about 30 years of evolution of Lisp
aesthetics. PROG and GO? TERPRI immediately after FORMAT?
Yow! :-)

As to the actual question ... Your code works OK for me
in recent versions of CLISP and CMU CL. (It throws away
the first character, but that's clearly by design.) It
doesn't actually read any of the characters I type until
I hit return, because standard input is line-buffered;
this behaviour may be different on different systems.

-- 
Gareth McCaughan
.sig under construc
From: Mark Tarver
Subject: Re: READ-CHAR-NO-HANG and the read-evaluate-print-loop
Date: 
Message-ID: <cf325f48.0410081746.6710944f@posting.google.com>
> Forgive me for being rude and irrelevant, but: One thing
> you're missing is about 30 years of evolution of Lisp
> aesthetics. PROG and GO? TERPRI immediately after FORMAT?
> Yow! :-)

Yes; better is

(FORMAT T "~A~%" (EVAL (READ-FROM-STRING (COERCE (REVERSE CHARS)
'STRING))))

which saves a line.

And I don't mind GO if the structure is so simple that confusion
cannot
arise. But none of that is very important here, because as you say, it
is irrelevant to the main question.

The answer I seem to be getting is download a later CLisp. I'll give
it a try.