From: Tel A.
Subject: Sharpdot
Date: 
Message-ID: <1149275036.123107.85460@y43g2000cwc.googlegroups.com>
Every now and then I've seen use of the sharpdot (#.) reader character.
I'm curious as to what it is.

Hyperspec says that sharpdot invokes "read-time evaluation". I have a
gist of what this means, but I can't think of a reason why you'd want
that to occur. Speculatively, I'd guess it might show up in a very
complex macro, but I really have no idea.

Thus, my questions: what exactly does #. do and why would you want to
use it?

Thanks.

From: Tel A.
Subject: Re: Sharpdot
Date: 
Message-ID: <1149276082.165200.218850@i40g2000cwc.googlegroups.com>
This might be addressed in an answer to the first question, but
experimentation with the read macro is producing very weird behavior...

CL-USER> (macroexpand-1 (quote (function +)))
#'+
NIL
CL-USER> (macroexpand-1 (quote #.(function +)))
#<Function + {1019A909}>
NIL
CL-USER> (macroexpand-1 (quote (function #.+)))
#'(MACROEXPAND-1 '#<Function + {1019A909}>)
NIL
CL-USER> (macroexpand-1 (quote (function #.+)))
#'(MACROEXPAND-1 '#'(MACROEXPAND-1 '#<Function + {1019A909}>))
NIL

This occurred in cmucl and clisp. Where am I making the giant error? ; )
From: rydis (Martin Rydstr|m) @CD.Chalmers.SE
Subject: Re: Sharpdot
Date: 
Message-ID: <w4c3bemkwnk.fsf@ladislasz.cd.chalmers.se>
"Tel A." <············@gmail.com> writes:
> This might be addressed in an answer to the first question, but
> experimentation with the read macro is producing very weird behavior...
> 
> CL-USER> (macroexpand-1 (quote (function +)))
> #'+
> NIL
> CL-USER> (macroexpand-1 (quote #.(function +)))
> #<Function + {1019A909}>
> NIL
> CL-USER> (macroexpand-1 (quote (function #.+)))
> #'(MACROEXPAND-1 '#<Function + {1019A909}>)
> NIL
> CL-USER> (macroexpand-1 (quote (function #.+)))
> #'(MACROEXPAND-1 '#'(MACROEXPAND-1 '#<Function + {1019A909}>))
> NIL
> 
> This occurred in cmucl and clisp. Where am I making the giant error? ; )

When you're evaluating + as a variable, as in the last two cases,
its value is that of the last form entered to the REPL.

',mr

-- 
[Emacs] is written in Lisp, which is the only computer language that is
beautiful.  -- Neal Stephenson, _In the Beginning was the Command Line_
From: Tel A.
Subject: Re: Sharpdot
Date: 
Message-ID: <1149358090.899229.85750@i40g2000cwc.googlegroups.com>
Ok, I can see some places where it's useful now. I think especially
interesting is how it can be used to evaluate lisp values within
strings. I suppose the sharpsign reader macros have a greater
precendence than the minimal built-in syntax.

Thanks for the examples and explanations.
From: Ken Tilton
Subject: Re: Sharpdot
Date: 
Message-ID: <fm0gg.7$U_7.4@fe12.lga>
Tel A. wrote:
> Every now and then I've seen use of the sharpdot (#.) reader character.
> I'm curious as to what it is.
> 
> Hyperspec says that sharpdot invokes "read-time evaluation". I have a
> gist of what this means, but I can't think of a reason why you'd want
> that to occur. Speculatively, I'd guess it might show up in a very
> complex macro, but I really have no idea.
> 
> Thus, my questions: what exactly does #. do and why would you want to
> use it?

(defconstant tcl-ok 0)
(defconstant tcl-error 1)

      (case (tcl-eval("hi mom")) ;; where tcl-eval returns 0 or 1
       (#.tcl-ok ...)
       (#.tcl-error ...))

CASE would not evaluate a plain tcl-ok, it would treat it as a symbol 
which would not match 0 or 1.

That is one good example, methinks.

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
    Attorney for Mary Winkler, confessed killer of her
    minister husband, when asked if the couple had
    marital problems.
From: ···········@gmail.com
Subject: Re: Sharpdot
Date: 
Message-ID: <1149316231.274482.85550@g10g2000cwb.googlegroups.com>
Tel A. wrote:
> Thus, my questions: what exactly does #. do and why would you want to
> use it?

An expression preceded by #. evaluates the expression, and parses as if
the result of the #. expression were written in place of the #.
expression. For instance:

[1]> (setf foo '(+ 1 1))
[2]> foo
(+ 1 1)
[3]> 'foo
foo
[4]> #.foo
2
[5]> '#.foo
(+ 1 1)
From: Pascal Bourguignon
Subject: Re: Sharpdot
Date: 
Message-ID: <878xoe7h3f.fsf@thalassa.informatimago.com>
···········@gmail.com writes:

> Tel A. wrote:
>> Thus, my questions: what exactly does #. do and why would you want to
>> use it?
>
> An expression preceded by #. evaluates the expression, and parses as if
> the result of the #. expression were written in place of the #.
> expression. For instance:

No. It doesn't need to parse anything, since the expression after
#. already returns lisp objects!

> [1]> (setf foo '(+ 1 1))
> [2]> foo
> (+ 1 1)
> [3]> 'foo
> foo

> [5]> '#.foo
> (+ 1 1)

Here, the cons cell (+ . (1 1)) is not parsed either, because there's
no string "(+ 1 1)", no characters '(' '+' ' ' '1' ' ' '1' or ')' to
be parsed.  The evaluation of foo returns this list, and the reader
inserts it as-in in the list it builds while reading '.

> [4]> #.foo
> 2

Here, the same occurs, but is not seen, the evaluation of foo returns
a list (actually, the first cons cell of this "list"), and the reader
returns it as-is.  Then EVAL evaluates it and computes 2 which it
returns to the printer to be printed. 

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

HEALTH WARNING: Care should be taken when lifting this product,
since its mass, and thus its weight, is dependent on its velocity
relative to the user.
From: Rainer Joswig
Subject: Re: Sharpdot
Date: 
Message-ID: <joswig-FD4ADB.11030703062006@news-europe.giganews.com>
In article <·······················@y43g2000cwc.googlegroups.com>,
 "Tel A." <············@gmail.com> wrote:

> Every now and then I've seen use of the sharpdot (#.) reader character.
> I'm curious as to what it is.
> 
> Hyperspec says that sharpdot invokes "read-time evaluation". I have a
> gist of what this means, but I can't think of a reason why you'd want
> that to occur. Speculatively, I'd guess it might show up in a very
> complex macro, but I really have no idea.
> 
> Thus, my questions: what exactly does #. do and why would you want to
> use it?
> 
> Thanks.

This is a facility by the Lisp reader. It allows you to have
Lisp expressions evauated during read-time.

Example:

a string

"#.(* 10 pi)"

CL-USER 1 > (read-from-string "#.(* 10 pi)")
31.41592653589793D0

So it allows you to embed programs in text and these
programs will be executed by the reader.
Note that it also works for streams:

(with-input-from-string (in-stream "#.(* 10 pi)")
   (read in-stream))

Similar it would work for reading from files and
network streams.

Note that you can switch of the evaluation. 

CL-USER 4 > (let ((*read-suppress* t)) (read-from-string "#.(* 10 pi)"))
NIL
11


Okay, one typical use is to embed Lisp expressions in input.
Here is another one.

Since the typical Lisp system uses READ to read Lisp code,
it can be used also in programs.

Say you have some variable defined somewhere:
CL-USER 5 > (defparameter *m* 100)
*M*

You can write code like this:
(defun foo (n)
   (* n #.(* *m* pi)))

For example the typical Lisp listener runs some kind
of glorified  (LOOP (PRINT (EVAL (READ))))).

So there is a read stage:

CL-USER 7 > (read)
(defun foo (n)
   (* n #.(* *m* pi)))
(DEFUN FOO (N) (* N 314.1592653589793D0))


Or in a simple expression

CL-USER 9 > (print (eval (print (read))))
(* 10 #.(* *m* pi))
(* 10 314.1592653589793D0) 
3141.5926535897934D0 
3141.5926535897934D0

Since you have the whole Common Lisp available at read
time, you can embed all kinds of complex computation
during read time.

Remember the REPL:

1) READ reads the program and generates a Lisp datastructure

you can use READTABLEs, READ Macros and Read-Time evaluation to
  change this stage

2) Your code gets Macroexpanded. Macros transform the code
from above to other code.

You can use Macros at this stage.

3) EVAL. your code gets compiled. The compiled code runs.
Alternatively the code gets evaluated by an interpreter.

4) The results will be printed.

There are various ways to influence how results are printed.
One thing is to write methods for PRINT-OBJECT

5) The REPL starts at 1)

Add error-handling and much more...

-- 
http://lispm.dyndns.org/
From: Pascal Bourguignon
Subject: Re: Sharpdot
Date: 
Message-ID: <87slml6bc4.fsf@thalassa.informatimago.com>
Rainer Joswig <······@lisp.de> writes:

> In article <·······················@y43g2000cwc.googlegroups.com>,
>  "Tel A." <············@gmail.com> wrote:
>
>> Every now and then I've seen use of the sharpdot (#.) reader character.
>> I'm curious as to what it is.
>> 
>> Hyperspec says that sharpdot invokes "read-time evaluation". I have a
>> gist of what this means, but I can't think of a reason why you'd want
>> that to occur. Speculatively, I'd guess it might show up in a very
>> complex macro, but I really have no idea.
>> 
>> Thus, my questions: what exactly does #. do and why would you want to
>> use it?
>> 
>> Thanks.
>
> This is a facility by the Lisp reader. It allows you to have
> Lisp expressions evauated during read-time.
> [...]
> CL-USER 1 > (read-from-string "#.(* 10 pi)")
> 31.41592653589793D0
>
> So it allows you to embed programs in text and these
> programs will be executed by the reader.

Well, of course, it can be used in programs (as long as programs are
read), but it can also be used in user data, as long as it's
eventually read with READ.

(defparameter *default-config* '((:speed . 3) (:email . "nobody")))
(defvar *config* 
   (with-open-file (conf (merge-pathnames
                            (make-pathname :name "MYAPP" :type "CONF"
                                           :case :common)
                            (user-homedir-pathname))
                          :if-does-not-exist nil)
      (if conf
           (read conf)
           *default-config*)))

Then the user could have in his configuration file:
---(~/myapp.conf)-------------------------------------------------------

(
  (:speed . #.(/ (* 10 1024 1024) 3600))
  (:email . #.(concatenate 'string ····@" 
                   (nth-value 1 (LINUX:|gethostname| #x7f000001))))
  . #.*default-config*
)

------------------------------------------------------------------------


And we would get 
*config*  --> ((:SPEED . 131072/45) (:EMAIL . ····@thalassa") (:SPEED . 3)
               (:EMAIL . "nobody"))

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

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
From: Thomas A. Russ
Subject: Re: Sharpdot
Date: 
Message-ID: <ymislmje9ad.fsf@sevak.isi.edu>
"Tel A." <············@gmail.com> writes:

> Thus, my questions: what exactly does #. do and why would you want to
> use it?

It evaluates expressions at read time.

It was at least sometimes used to provide computed values without the
need to rely on a compiler doing constant folding for you.  One such
example would be

(defvar *seconds-per-day* #.(* 60 60 24))

which is perhaps clearer about how the value is derived than writing the
equivalent

(defvar *seconds-per-day* 86400)


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal Bourguignon
Subject: Re: Sharpdot
Date: 
Message-ID: <87u06z3wyy.fsf@thalassa.informatimago.com>
···@sevak.isi.edu (Thomas A. Russ) writes:

> "Tel A." <············@gmail.com> writes:
>
>> Thus, my questions: what exactly does #. do and why would you want to
>> use it?
>
> It evaluates expressions at read time.
>
> It was at least sometimes used to provide computed values without the
> need to rely on a compiler doing constant folding for you.  One such
> example would be
>
> (defvar *seconds-per-day* #.(* 60 60 24))
>
> which is perhaps clearer about how the value is derived than writing the
> equivalent
>
> (defvar *seconds-per-day* 86400)

But you don't earn anything over:

(defvar *seconds-per-day* (* 60 60 24))

which evaluates the product at run-time. 




A "better" example would be:

(defun #.(progn (format *query-io* "What the name of this function should be?")
                (read *query-io*)) (args...)
    ...)


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

"Debugging?  Klingons do not debug! Our software does not coddle the
weak."
From: Kent M Pitman
Subject: Re: Sharpdot
Date: 
Message-ID: <u1wu3uh2t.fsf@nhplace.com>
Pascal Bourguignon <···@informatimago.com> writes:

> ···@sevak.isi.edu (Thomas A. Russ) writes:
> 
> > (defvar *seconds-per-day* #.(* 60 60 24))
> >
> > which is perhaps clearer about how the value is derived than writing the
> > equivalent
> >
> > (defvar *seconds-per-day* 86400)
> 
> But you don't earn anything over:
> 
> (defvar *seconds-per-day* (* 60 60 24))
> 
> which evaluates the product at run-time. 

Actually, it's a tiny savings in this case but a moral victory to use
#.  because you assure that the computation will be done in the
compiler and dumped to a compiled file as a constant rather than
having the expression to compute it be dumped into the fasl file
(taking up space) and loaded at load-time (taking up time repeatedly,
once for each load, rather than just once for compilation time for all
time ... and also assuming the compiler doesn't optimize it because it's
trivial--something you can't do in the general case).

> A "better" example would be:
> 
> (defun #.(progn (format *query-io* "What the name of this function should be?")
>                 (read *query-io*)) (args...)
>     ...)

Yes, this is probably a better example.  I just wanted to note that this
one being better doesn't make the prior one something about which you don't
earn anything. :)  In the general case, evaluation at readtime can still do
a long compilation earlier than the compiler would, or even in some cases
(because of the halting problem) earlier than the compiler would be able to.