[slime-devel] Feature suggestion
Pascal Bourguignon
pjb at informatimago.com
Thu Aug 24 21:39:47 UTC 2006
Michael Price writes:
> On 8/24/06, Marco Antoniotti <marcoxa at cs.nyu.edu> wrote:
> > Hi
> >
> > I would like to suggest a feature for SLIME taken from Lispworks.
> >
> > In LW I can type
> >
> > prompt> member 42 '((3 2 3) (1 42 33) (42 11 22)) :key #'second
> > ((1 42 33) (42 11 22))
> >
> > I.e. a line gets parenthesized if it is not already an expression (of
> > course there are cases where things get hairy, but in general I find it
> > useful).
>
> CL-USER> (defvar a 4)
>
> A
> CL-USER> (defvar b 9)
>
> B
> CL-USER> a b
>
> 4
> CL-USER>
> 9
> CL-USER> (defun a (x) (sqrt x))
>
> A
> CL-USER> (a b)
>
> 3.0
>
> So what happens in lispworks if I do this:
>
> CL-USER> a b
>
> Do I get a separate 4 and 9 again or do I get 3.0?
Well, you can still get the variables with list or values:
(defmacro handling-errors (&body body)
`(HANDLER-CASE (progn , at 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* "~&")
(finish-output))
(condition
(ERR)
(format *error-output* "~&~A: ~% ~S~%"
(class-name (class-of err)) err)
(finish-output))))
(defun line-repl ()
(do ((+eof+ (gensym))
(hist 1 (1+ hist)))
(nil)
(format t "~%~A[~D]LINE> " (package-name *package*) hist)
(finish-output)
(handling-errors
(let ((operator (read *standard-input* nil +eof+)))
(if (member operator '(quit exit continue) :test (function equal))
(return-from line-repl)
(let ((arguments (read-line *standard-input* nil +eof+)))
(if (eql arguments +eof+)
(return-from line-repl)
(setf - (read-from-string
(format nil "(~A ~A)" operator arguments))))))
(let ((results (multiple-value-list (eval -))))
(setf +++ ++ ++ + + -
/// // // / / results
*** ** ** * * (first /)))
(format t "~& --> ~{~S~^ ;~% ~}~%" /)
(finish-output)))))
[61]> (line-repl)
COMMON-LISP-USER[1]LINE> defvar a 3
--> A
COMMON-LISP-USER[2]LINE> defvar b 6
--> B
COMMON-LISP-USER[3]LINE> defun a () 3.14
--> A
COMMON-LISP-USER[4]LINE> a
--> 3.14
COMMON-LISP-USER[5]LINE> defun a (x) (* 3.0 x)
--> A
COMMON-LISP-USER[6]LINE> a b
--> 18.0
COMMON-LISP-USER[7]LINE> list a b
--> (1 6)
COMMON-LISP-USER[8]LINE> values a b
--> 1 ;
6
COMMON-LISP-USER[9]LINE> quit
NIL
[62]>
Using an implementation dependant function such as #+clisp EXT:ARGLIST
you can even read the first token, see if it's a function, get the
argument list expected for the function and further parse the number
of sub expressions needed. You can even do it recursively, to parse
correctly expressions such as:
append cons car items cddr items cons parse-integer "123" :radix 5 nil
to:
(append (cons (car items) (cddr items))
(cons (parse-integer "123" :radix 5) nil))
The limit goes when you want to use functions with &REST:
list + 1 2 3 - 4 5 * 6 7 0
is totally ambiguous. For &rest, you have to reintroduce parentheses,
or at least an end of list mark:
list + 1 2 3) - 4) 5 * 6 7 0
can then be parsed as:
(list (+ 1 2 3) (- 4) 5 (* 6 7 0))
while:
list + 1 2 3 - 4 5)) * 6 7 0
can then be parsed as:
(list (+ 1 2 3 (- 4 5)) (* 6 7 0))
You still have a problem with lisp-2 ambiguous symbols:
cons car list 2 3
could be either:
(cons (car list) 2) 3
(cons (car (list 2)) 3)
(cons (car (list 2 3)))
If we assume we have all the input before parsing it, we can still
resolve some of these ambiguities (only the second one would be a
correct single form), but there could remain a lot of unresolvable
cases.
Parentheses are a necessity in lisp-2 with &rest.
--
__Pascal Bourguignon__ http://www.informatimago.com/
CAUTION: The mass of this product contains the energy equivalent of
85 million tons of TNT per net ounce of weight.
More information about the slime-devel
mailing list