Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

reading #.

4 views
Skip to first unread message

Pascal Bourguignon

unread,
May 14, 2003, 2:47:22 PM5/14/03
to

Is there a better way to read #. without evaluating and without an
error than this:

(let (;; useless: (*read-eval* nil)
(*readtable* (copy-readtable nil)))
(set-dispatch-macro-character #\# #\. (function list))
(read-from-string " #.(+ 1 2) "))

?


--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------
Do not adjust your mind, there is a fault in reality.

Kent M Pitman

unread,
May 14, 2003, 3:06:08 PM5/14/03
to
Pascal Bourguignon <sp...@thalassa.informatimago.com> writes:

> Is there a better way to read #. without evaluating and without an
> error than this:
>
> (let (;; useless: (*read-eval* nil)
> (*readtable* (copy-readtable nil)))
> (set-dispatch-macro-character #\# #\. (function list))
> (read-from-string " #.(+ 1 2) "))
>
> ?

Why is this going to work? Setting #. to #'list means that it will make
a list of its arguments, and will basically cause #.(+ 1 2) to be read as
two forms. The #. will read as a form returning the arguments giving to
the #. readmacro, as a list; then the (+ 1 2) will be read separately.
What you want is more likely:

(defvar *test-readtable* (copy-readtable nil))

(defclass sharpdot ()
((form :initarg :form :accessor sharpdot-form)
(char :initarg :char :accessor sharpdot-char :initform #\.)
(arg :initarg :arg :accessor sharpdot-arg :initform nil)))

(defmethod print-object ((obj sharpdot) stream)
(with-slots (form char arg) obj
(format stream "#~@[~D~]~C~S" arg char form)))

(defun read-sharpdot-exp (stream subchar arg)
(make-instance 'sharpdot
:form (read stream)
:char subchar
:arg arg))

(set-dispatch-macro-character #\# #\. 'read-sharpdot-exp *test-readtable*)

(let ((*readtable* *test-readtable*))

Pascal Bourguignon

unread,
May 14, 2003, 3:58:18 PM5/14/03
to
Kent M Pitman <pit...@world.std.com> writes:

> Pascal Bourguignon <sp...@thalassa.informatimago.com> writes:
>
> > Is there a better way to read #. without evaluating and without an
> > error than this:
> >
> > (let (;; useless: (*read-eval* nil)
> > (*readtable* (copy-readtable nil)))
> > (set-dispatch-macro-character #\# #\. (function list))
> > (read-from-string " #.(+ 1 2) "))
> >
> > ?
>
> Why is this going to work?

Because for now I was not interested with the #. but in reading over
it without evaluating it :-)

> Setting #. to #'list means that it will make
> a list of its arguments, and will basically cause #.(+ 1 2) to be read as
> two forms. The #. will read as a form returning the arguments giving to
> the #. readmacro, as a list; then the (+ 1 2) will be read separately.
> What you want is more likely:
>
> (defvar *test-readtable* (copy-readtable nil))
>
> (defclass sharpdot ()
> ((form :initarg :form :accessor sharpdot-form)
> (char :initarg :char :accessor sharpdot-char :initform #\.)
> (arg :initarg :arg :accessor sharpdot-arg :initform nil)))
>
> (defmethod print-object ((obj sharpdot) stream)
> (with-slots (form char arg) obj
> (format stream "#~@[~D~]~C~S" arg char form)))
>
> (defun read-sharpdot-exp (stream subchar arg)
> (make-instance 'sharpdot
> :form (read stream)
> :char subchar
> :arg arg))
>
> (set-dispatch-macro-character #\# #\. 'read-sharpdot-exp *test-readtable*)
>
> (let ((*readtable* *test-readtable*))
> (read-from-string " #.(+ 1 2) "))

That's a cleaner solution. I'll keep it. Thank you.

0 new messages