REPL
The Read Eval Print Loop of a Lisp listener.

Implementation of a REPL in Common Lisp

The most basic REPL implementation is just what it says:

(Loop (Print (Eval (Read))))

Given the order of evaluation imposed by the parentheses, READ is evaluated first, then EVAL, then PRINT, then LOOP. Hence REPL.

cl-user> (Loop (Print (Eval (Read))))
(+ 2 3)

5 (list 1 'apple 2 'orange)

(1 apple 2 orange) ; Evaluation aborted on #<com.informatimago.signal:user-interrupt #x302004E56F0D>.
cl-user> 

A more sophisticated REPL (conforming to the ANSI Common Lisp specification) could be:

(defmacro handling-errors (&body body)
  `(handler-case (progn ,@body)
     (simple-condition (err) 
       (format *error-output* "~&~A: ~%" (class-name (class-of err)))
       (apply (function format) *error-output*
              (simple-condition-format-control   err)
              (simple-condition-format-arguments err))
       (format *error-output* "~&"))
     (condition (err) 
       (format *error-output* "~&~A: ~%  ~S~%"
               (class-name (class-of err)) err))))

(defun repl ()
  (do ((+eof+ (gensym))
       (hist 1 (1+ hist)))
      (nil)
    (format t "~%~A[~D]> " (package-name *package*) hist)
    (handling-errors
     (setf +++ ++   ++ +   + -   - (read *standard-input* nil +eof+))
     (when (or (eq - +eof+)
               (member - '((quit)(exit)(continue)) :test (function equal)))
       (return-from repl))
     (setf /// //   // /   / (multiple-value-list (eval -)))
     (setf *** **   ** *   * (first /))
     (format t "~& --> ~{~S~^ ;~%     ~}~%" /))))

It provides the standard REPL variables, -, +, ++, +++, *, **, ***, /, // and ///, and handle errors reporting a message. In CL implementations, the debugger would be invoked upon errors.

cl-user> (repl)

COMMON-LISP-USER[1]> (* 3 4)

 --> 12

COMMON-LISP-USER[2]> (/ 1 0)

division-by-zero: 
  #<division-by-zero #x302004F8497D>

COMMON-LISP-USER[3]> (quit)
nil
cl-user> 

Examples and Comparison of REPL

Here are two examples of REPL interaction.

The first is with an ANSI Common Lisp implementation; all Common Lisp implementations have similar REPL, but they differ in the set of command they offer in the debugger. slime covers the differences with a common layer.

The second is with an ANSI C implementation. C implementations don't often provide a REPL, having an heritage of batch processing much more than interactive development, but there are a few C implementations that provide more or less limited REPL.

Langage: ANSI Common Lisp; Implementation: clisp Langage: ANSI C; Implementation: ch
[pjb@kuiper :0 ~]$ clisp -ansi -norc
  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Welcome to GNU CLISP 2.49+ (2010-07-17) &lt;http://clisp.org/&gt;

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2010

Type :h and hit Enter for context help.

[1]&gt; (defun f (x) (if (&lt; x 1) 1 (* x (f (1- x)))))
F
[2]&gt; (f 5)
120
[3]&gt; (defparameter *s* 0)
*S*
[4]&gt; (loop for i from 0 to 5 do (incf *s* (f i)))
NIL
[5]&gt; *s*
154
[6]&gt; (loop for i from 0 to 5 do (incf *s* (f (/ i))))

*** - /: division by zero
The following restarts are available:
ABORT          :R1      Abort main loop
Break 1 [7]&gt; :bt 4 1
&lt;1/246&gt; #&lt;SYSTEM-FUNCTION SHOW-STACK&gt; 3
&lt;2/239&gt; #&lt;COMPILED-FUNCTION SYSTEM::PRINT-BACKTRACE&gt;
&lt;3/233&gt; #&lt;COMPILED-FUNCTION SYSTEM::DEBUG-BACKTRACE&gt;
&lt;4/224&gt; #&lt;SYSTEM-FUNCTION SYSTEM::READ-EVAL-PRINT&gt; 2
&lt;5/221&gt; #&lt;COMPILED-FUNCTION SYSTEM::BREAK-LOOP-2-3&gt;
&lt;6/217&gt; #&lt;SYSTEM-FUNCTION SYSTEM::SAME-ENV-AS&gt; 2
&lt;7/203&gt; #&lt;COMPILED-FUNCTION SYSTEM::BREAK-LOOP-2&gt;
&lt;8/201&gt; #&lt;SYSTEM-FUNCTION SYSTEM::DRIVER&gt;
&lt;9/161&gt; #&lt;COMPILED-FUNCTION SYSTEM::BREAK-LOOP&gt;
&lt;10/158&gt; #&lt;SYSTEM-FUNCTION INVOKE-DEBUGGER&gt; 1
&lt;11/147&gt; #&lt;SYSTEM-FUNCTION /&gt; 1
[146] EVAL frame for form (/ I)
Printed 11 frames
Break 1 [7]&gt; i
0
Break 1 [7]&gt; :q
[8]&gt; (loop for i from 0 to 5 do (incf *s* (f (/ (1+ i)))))
NIL
[9]&gt; *s*
160
[10]&gt; (setf *s* 0)
0
[11]&gt; (loop for i from 0 to 5 do (incf *s* (f (/ (1+ i)))))
NIL
[12]&gt; *s*
6
[13]&gt; (f (/ 1 5))
1
[14]&gt; (f 30)
265252859812191058636308480000000
[15]&gt; (quit)
Bye.
[pjb@kuiper :0 ~]$ 

[pjb@kuiper :0 ~]$ ch
                              Ch (64-bit)
                  Standard edition, version 7.0.0.15151 
              Copyright (C) SoftIntegration, Inc. 2001-2011
                     http://www.softintegration.com
/home/pjb&gt; int f(int x){ return x&lt;1?1:x*f(x-1); }
int f(int x){ return x&lt;1?1:x*f(x-1); }
/home/pjb&gt; f(5)
f(5)
120 
/home/pjb&gt; int s=0;
int s=0;
/home/pjb&gt; {int i; for(i=0;i&lt;=5;i++){ s+=f(i); }}
{int i; for(i=0;i&lt;=5;i++){ s+=f(i); }}
/home/pjb&gt; s
s
154 
/home/pjb&gt; {int i; for(i=0;i&lt;=5;i++){ s+=f(1/i); }}
{int i; for(i=0;i&lt;=5;i++){ s+=f(1/i); }}
WARNING: integer divide by zero 
Segmentation fault
[pjb@kuiper :0 ~]$