From: Hidayet Tunc Simsek
Subject: [#.] is there an equivalent lisp function to #.
Date: 
Message-ID: <38C6C543.C68D1031@EECS.Berkeley.Edu>
Hi,

I recently posted some questions on constants from reader macros and
still I have problems.

I guess I don't understand what #. is.  Basically, is there an
equivalent way of writing #.(+ a b)
without using the #. reader macro?

Thanks,
Tunc

From: Barry Margolin
Subject: Re: [#.] is there an equivalent lisp function to #.
Date: 
Message-ID: <XbAx4.79$Ag3.1680@burlma1-snr2>
In article <·················@EECS.Berkeley.Edu>,
Hidayet Tunc Simsek  <······@EECS.Berkeley.Edu> wrote:
>I recently posted some questions on constants from reader macros and
>still I have problems.
>
>I guess I don't understand what #. is.  Basically, is there an
>equivalent way of writing #.(+ a b)
>without using the #. reader macro?

Not that I can think of.  If you want something special to occur at read
time, you have to use a reader macro.  Perhaps if you provide more detail
about what you're trying to accomplish we could give an appropriate answer.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Hidayet Tunc Simsek
Subject: Re: [#.] is there an equivalent lisp function to #.
Date: 
Message-ID: <38C6E1D9.D1E5CDE2@EECS.Berkeley.Edu>
Here is a detailed explanation.

Take the baby example:

(defun parse-matrix-expression (stream char)
  (declare (ignore char))
  (let ((c (read-char stream t nil t)))
   
     (list 'make-array 1 :initial-contents (list 'list (read-from-string
(string c))))))

(set-macro-character #\[ #'parse-matrix-expression)

e.g.
----

* (defvar x 1)

X
* [x

#(1)

* (defmacro disp (arg)
    `',arg)

DISP

* (disp [x)

(MAKE-ARRAY 1 :INITIAL-CONTENTS (LIST X))

I would like to have:

* (disp [x)

#(1)

Thanks,
Tunc


Barry Margolin wrote:
> 
> In article <·················@EECS.Berkeley.Edu>,
> Hidayet Tunc Simsek  <······@EECS.Berkeley.Edu> wrote:
> >I recently posted some questions on constants from reader macros and
> >still I have problems.
> >
> >I guess I don't understand what #. is.  Basically, is there an
> >equivalent way of writing #.(+ a b)
> >without using the #. reader macro?
> 
> Not that I can think of.  If you want something special to occur at read
> time, you have to use a reader macro.  Perhaps if you provide more detail
> about what you're trying to accomplish we could give an appropriate answer.
> 
> --
> Barry Margolin, ······@bbnplanet.com
> GTE Internetworking, Powered by BBN, Burlington, MA
> *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
> Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Barry Margolin
Subject: Re: [#.] is there an equivalent lisp function to #.
Date: 
Message-ID: <OHBx4.94$Ag3.1621@burlma1-snr2>
In article <·················@EECS.Berkeley.Edu>,
Hidayet Tunc Simsek  <······@EECS.Berkeley.Edu> wrote:
>Here is a detailed explanation.
>
>Take the baby example:
>
>(defun parse-matrix-expression (stream char)
>  (declare (ignore char))
>  (let ((c (read-char stream t nil t)))
>   
>     (list 'make-array 1 :initial-contents (list 'list (read-from-string
>(string c))))))
>
>(set-macro-character #\[ #'parse-matrix-expression)
>
>e.g.
>----
>
>* (defvar x 1)
>
>X
>* [x
>
>#(1)
>
>* (defmacro disp (arg)
>    `',arg)
>
>DISP
>
>* (disp [x)
>
>(MAKE-ARRAY 1 :INITIAL-CONTENTS (LIST X))
>
>I would like to have:
>
>* (disp [x)
>
>#(1)

First of all, your reader macro needs to return the array, not a form that
evaluates to an array.  Second, if you want the X to be evaluated, you have
to evaluate it yourself in the reader macro.

(defun parse-matrix-expression (stream char)
  (declare (ignore char))
  (let ((c (read-char stream t nil t)))
    (make-array 1 :initial-element (eval (read-from-string (string c))))))

The #. reader macro is really pretty simple, something like:

(defun sharpsign-dot (stream subchar arg)
  (declare (ignore char arg))
  (if *read-eval*
      (eval (read stream t nil t)
      (error ...))))

If you want your reader macro to be like #., you have to call EVAL just
like it does.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Hidayet Tunc Simsek
Subject: Re: [#.] is there an equivalent lisp function to #.
Date: 
Message-ID: <38C6EAC7.E9AD48D2@EECS.Berkeley.Edu>
Barry Margolin wrote:
> 
> In article <·················@EECS.Berkeley.Edu>,
> Hidayet Tunc Simsek  <······@EECS.Berkeley.Edu> wrote:
> >Here is a detailed explanation.
> >
> >Take the baby example:
> >
> >(defun parse-matrix-expression (stream char)
> >  (declare (ignore char))
> >  (let ((c (read-char stream t nil t)))
> >
> >     (list 'make-array 1 :initial-contents (list 'list (read-from-string
> >(string c))))))
> >
> >(set-macro-character #\[ #'parse-matrix-expression)
> >
> >e.g.
> >----
> >
> >* (defvar x 1)
> >
> >X
> >* [x
> >
> >#(1)
> >
> >* (defmacro disp (arg)
> >    `',arg)
> >
> >DISP
> >
> >* (disp [x)
> >
> >(MAKE-ARRAY 1 :INITIAL-CONTENTS (LIST X))
> >
> >I would like to have:
> >
> >* (disp [x)
> >
> >#(1)
> 
> First of all, your reader macro needs to return the array, not a form that
> evaluates to an array.  Second, if you want the X to be evaluated, you have
> to evaluate it yourself in the reader macro.
> 
> (defun parse-matrix-expression (stream char)
>   (declare (ignore char))
>   (let ((c (read-char stream t nil t)))
>     (make-array 1 :initial-element (eval (read-from-string (string c))))))
> 
> The #. reader macro is really pretty simple, something like:
> 
> (defun sharpsign-dot (stream subchar arg)
>   (declare (ignore char arg))
>   (if *read-eval*
>       (eval (read stream t nil t)
>       (error ...))))
> 
> If you want your reader macro to be like #., you have to call EVAL just
> like it does.
> 

I follow that, but AFAIK (eval ... ) evaluates in an empty lexical
environment.

Thus (let ((x 1))
         [1)

would not work for your fix.

I understand that the reader macro should return an array and not the
code to get that array,
but then the X cannot be evaluated correctly.

Thanks,
Tunc
From: Tim Bradshaw
Subject: Re: [#.] is there an equivalent lisp function to #.
Date: 
Message-ID: <ey3zos9t1u2.fsf@cley.com>
* Hidayet Tunc Simsek wrote:
> I follow that, but AFAIK (eval ... ) evaluates in an empty lexical
> environment.

> Thus (let ((x 1))
>          [1)

> would not work for your fix.

That can not work as a readmacro!  At read time the bindings have not
yet happened, so nothing can access them.  If you want the readmacro
to return *the array* then it can't access any context established by
the form being read.  If you want it to return a form that will
construct the array, then that form can access the conbtext in the
normal way.  You can't have both.

If you want to be very devious indeed you can write a readmacro that
checks if the data is literal, and in that case will return the
literal array, but otherwise will return a form that will construct
it. 

--tim
From: Tunc Simsek
Subject: Re: [#.] is there an equivalent lisp function to #.
Date: 
Message-ID: <Pine.SOL.4.10.10003081921310.22007-100000@tudor.EECS.Berkeley.EDU>
On 9 Mar 2000, Tim Bradshaw wrote:

> * Hidayet Tunc Simsek wrote:
> > I follow that, but AFAIK (eval ... ) evaluates in an empty lexical
> > environment.
> 
> > Thus (let ((x 1))
> >          [1)
> 
> > would not work for your fix.
> 
> That can not work as a readmacro!  At read time the bindings have not
> yet happened, so nothing can access them.  If you want the readmacro
> to return *the array* then it can't access any context established by
> the form being read.  If you want it to return a form that will
> construct the array, then that form can access the conbtext in the
> normal way.  You can't have both.
> 
> If you want to be very devious indeed you can write a readmacro that
> checks if the data is literal, and in that case will return the
> literal array, but otherwise will return a form that will construct
> it. 
> 
> --tim
> 
> 
> 

I see what you're saying but the following works:

(eval-when (load eval compile)
  (defvar x 1))

(defvar y #.(+ x 1))

because x is known when #.(+ x 1) is read.  Similarily, if I typed
in 

(defvar x 1)

then

(defvar y #.(+ x 1))

x would be known at read time.

While I was working on this problem I thought of using symbol-boundp and
symbol-value but that turned out to be not so wise.

Thanks,
Tunc
From: Tim Bradshaw
Subject: Re: [#.] is there an equivalent lisp function to #.
Date: 
Message-ID: <ey34sag933s.fsf@cley.com>
* Tunc Simsek wrote:

> (eval-when (load eval compile)
>   (defvar x 1))

> (defvar y #.(+ x 1))

> because x is known when #.(+ x 1) is read.  Similarily, if I typed
> in 

> (defvar x 1)

> then

> (defvar y #.(+ x 1))

> x would be known at read time.

Yes, but that's a completely different case.  Nothing you can do is
going to let you compute things at read time which are not known until
eval time.

--tim
From: Joe Marshall
Subject: Re: [#.] is there an equivalent lisp function to #.
Date: 
Message-ID: <uityx1545.fsf@alum.mit.edu>
Hidayet Tunc Simsek <······@EECS.Berkeley.Edu> writes:

> 
> I guess I don't understand what #. is.  Basically, is there an
> equivalent way of writing #.(+ a b)
> without using the #. reader macro?
> 

Nope.  Here is how to understand it:  The reader takes a stream
of characters and returns a lisp object.  If the stream has
digits in it, you get a number.  If it has quote marks in it,
you'll get a string.  If it has parentheses in it, you'll get
a list.

Imagine the reader is walking down your input stream and it sees
an open paren.  It starts accumulating a list.  It continues
to read text and accumulate the resulting objects until it comes
to a corresponding close-paren and then it returns the accumulated
list.

The #. reader macro is an `escape mechanism' that allows
you to stuff a computed object into whatever the reader
is currently accumulating.  The text that follows the #. is
is passed immediately to the evaluator.  Whatever the
evaluator returns is accumulated as part of the list.

You almost never want to do this.

Here is an experiment to try:

Suppose you wanted to know the time that a lisp file is read.
This won't work:

(setq foo (list 'this 'was 'processed 'at (get-universal-time)))

Because it won't get the time until the form is *evaluated*.
But if you do this:

(setq foo '(this was processed at #.(get-universal-time)))

You will get the time as soon as the form is read.
In essence, you are faking out the reader:  it thinks it
read a list like this:  (this was processed at 3161542025)