Subject: Re: Readable output
From: Erik Naggum <erik@naggum.net>
Date: Sat, 23 Feb 2002 17:42:55 GMT
Newsgroups: comp.lang.lisp
Message-ID: <3223474979263343@naggum.net>

* lnp@healy.washington.dc.us
| Suppose I have an object "myobject" that is made with make-myobject,
| and I have a reader macro #_ that expands to make-myobject
| e.g. #_foo -> (make-myobject foo).

  Reader macros do not "expand".  A reader macro is a function that
  consumes input and returns Common Lisp objects.  Maybe "reader macro" is
  a misnomer and that it should be called "reader function" or something,
  but the historical reason is probably that all sorts of "macro languages"
  were around which allowed special interpretation of "macro characters".
  Some macro characters do indeed "expand", but that is their function, not
  the other way around.  E.g., 'x returns the list (quote x), but (x)
  returns the list (x) and "x" returns the string "x", because ( and " are
  macro characters that construct objects.  ' and #' are very special.

| Now for the print-object or print-function, I can test *print-readably*/
| *print-escape* and print "#_foo".  Of course, when read, this expands to
| the make-myobject form.  So far so good.

  Probably not.  The evaluation time appears to be completely wrong.

| Now if I have a vector of myobjects, it prints #(#_foo1 #_foo2 #_foo3)
| which is a vector consisting of the lists '(make-myobject foo1) etc.,
| which is bad - I want a vector of objects, not a vector of forms that
| when evaluated would make them.

  So it did not work in the above example, either.  #_foo was not read as
  myobject objects, but as a list.  This indicates a massive failure to
  grasp how reader macros work, and you need to retrace your steps back to
  where you thought you learned how to do what you did.  Incidentally, some
  code would make the amount of guesswork on my side a lot less, but I
  guess that you do something like this in your reader function:

    `(make-myobject ,(read ...))

| How can I do this?  The only thing that comes to mind is "#.".

  You could do something like this in your reader function

    (make-myobject (read ...))

| Is it appropriate to have my print method generate the full form?

  Not if *read-eval* is nil and *print-readably* is true.

  It is much better to create reader macros (syntax) for your special
  objects then try to depend on being able to depend on *read-eval*.

  "Unfortunately", there is no general constructor syntax for claseses like
  there is for structures, but you could of course try to create one using
  the same mold.

///
-- 
  In a fight against something, the fight has value, victory has none.
  In a fight for something, the fight is a loss, victory merely relief.