From: ····@pobox.com
Subject: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <7er28h$5i0$1@nnrp1.dejanews.com>
This article was inspired by an exchange of messages between
Dr. Clinger and Dr. Feeley about external representation of uniform
vectors, which are proposed in SRFI-4. This post attempts to make a
rather sweeping generalization of Dr. Clinger's suggestion. It
proposes an extensible, new old way for external representation of
Scheme values: read-time _application_.


Motivation
Introduction
Proposed syntax
Examples
Representation of uniform vectors and matrices
Comparisons
        Comparisons with CL's #. reader-macro
How to extend the reader while it scans the code
Going ahead


Motivation

The exchange of messages mentioned above stemmed from a minor
incompatibility between SRFI-4 and some Scheme implementations: SRFI-4
says:
> [T]he external representation of instances of the datatype TAGvector is
> #TAG(... elements ...). ... Note that the syntax for float vectors
> conflicts with Standard Scheme which parses #f32() as 3 objects: #f, 32,
> and ().  For this reason, conformance to this SRFI implies this minor
> nonconformance to Standard Scheme.

In a message <http://srfi.schemers.org/srfi-4/mail-archive/msg00002.html>
Dr. Clinger proposed a general workaround for this incompatibility
problem:
> why not consume just one more octathorpe [that is, #]
> character (say 'v' for vector) as follows:
>    #vs8(...) #vu8(...) [elided] #vf64(...)
> Then some future SRFI for vectors of vectors of floating point numbers
> (or whatever) will have a notation that can be extended for the purpose,
> and we won't have to have this same discussion all over again for the
> second time, redundantly.

I'd like to discuss an even more generic, universal way of
representing an arbitrary Scheme data type. It is similar to
Smalltalk's object serialization and CL's #. reader-macro.


Introduction

In Smalltalk, any object that defines a 'writeOn:' method may be asked
to externalize itself. The result is a string that spells out a
particular invocation of object's constructor. Evaluation of this
string by an interpreter recreates the original object. LISP X3J13 document
<http://www.harlequin.com/education/books/HyperSpec/Body/sec_2-4-8-6.html>
expresses the goal of a read-time _evaluation_ with utmost clarity:
"For an object that does not have a convenient printed representation,
a form that computes the object can be given using the #. notation."

It appears however that a weaker alternative -- a read-time
_application_ -- may suffice. Most of the Scheme values -- with an
exceptions of ports, structures, wills, semaphores and other exotic
beasts -- have an external representation. The representations of
booleans, numbers, lists, vectors, strings, etc. are codified in
RnRS. Every Scheme reader has an in-born knowledge how to parse the
corresponding strings and build Scheme values they represent. The set
of these built-in constructors is however fixed, and not amenable. I'd
like to propose to lift this limitation.


Proposed syntax of a read-time application

        #`(tag arg1 ...)
A 'tag' must be an (external representation of an) identifier, and
'arg1' etc. are external representations of some values, including
other read-time applications. ·@ (rather than #`) seems to be another
good way to denote read-time applications.

Upon encountering an #` external form, the read procedure should
locate a read-constructor associated with the 'tag', read the
arguments 'arg1'... and apply the constructor to the arguments. The
result of the application is taken to be the value that corresponds to
the external form under consideration

There must be a way to declare an association between a tag and the
corresponding constructor-procedure. Regular 'define' introduces an
association between an identifier and a procedure applied at run time;
'define-macro' or 'define-syntax' introduce bindings for procedures
applicable at compile time. Thus 'define-reader-ctor' literally
suggest itself as a form to introduce a constructor to apply at read
time.

Examples:
If
        (define-reader-ctor 'vector vector)
then
        (with-input-from-string "#`(vector 1 2 3)" read) ==> '#(1 2 3)
        (equal? '#(1 2 3) '#`(vector 1 2 3)) ==> #t

Thus #`(vector 1 2 3) becomes another external representation for a
vector. With suitably defined reader-constructors, all standard Scheme
data types may be represented in an external form of
read-applications:

        #`(list 1 2 3)
        #`(list #`(string #\1 #\a) 1 2 #`(vector #f #f))

Furthermore, structures (records) and ports gain a printed form and
can be read in:

        #`(make-structure point (x 3) (y 5) (color read))
        #`(open-input-file "/tmp/a")
For example, an expression

        (with-input-from-string "#`(open-input-file \"/tmp/a\")"
                (lambda () (read-char (read))))
will return the first character of the file "/tmp/a"


Representation of uniform vectors and matrices

The proposed read-time application gives uniform vectors the following
generic external form:

        #`(vector-f32 1 2 3)
        #`(vector-u8 1 2 3), etc.

This notation also appears to help with a problem of representing a 2D
matrix with a zero dimension. This problem was mentioned by Dr. Feeley
in <http://srfi.schemers.org/srfi-4/mail-archive/msg00003.html>:
> The only problem with such a [SRFI-4] representation is that it is
> not possible to distinguish a 0 by 4 float vector from an empty
> one dimensional float vector, but a special notation could be used
> for this very unusual case,
>  #f32((0.0 0.0 0.0 0.0) ^ 0) ; a 0 by 4 float vector
>  #f32((0.0 ^ 4) ^ 0)         ; the same 0 by 4 float vector
>  #f32(() ^ 0)                ; a 0 by 0 float vector

The notation proposed in the present article can easily handle even
the unusual cases above. Assuming we have defined a procedure (define
(build-matrix-f32 dims values) ...) and an association
(define-reader-ctor 'matrix-f32 build-matrix-f32), we can write
        #`(matrix-f32 (2 3) (10. 1.0) (20. 2.0) (30. 4.0))
        #`(matrix-f32 (0 4)) ; a 0 by 4 float vector
        #`(matrix-f32 (4 0)) ; a 4 by 0 float vector
        #`(matrix-f32 (0 0)) ; a 0 by 0 float vector
        #`(matrix-f32 (0)) ; a 0 element one-dimensional float vector,
                which is the same as #`(vector-f32)

Comparisons

In Metcast Request Language
<http://pobox.com/~oleg/ftp/Scheme/Request-Language.html>, which is
used to describe an order for a great variety of weather-related data,
a form "(tag a b ...)" is interpreted as (apply OBJ-loader:tag a b
...) where given 'tag', a procedure OBJ-loader:tag is looked up in the
current dynamic "environment".

Guile allows a user to declare his own #-symbol dispatch. In this
proposal, the user is not limited to one letter after #.

Read-time application mechanism defined in this article is rather
close to Lisp reader's macro functions. Unlike CL, however, a
reader-constructor is not allowed to read from the input stream on its
own. It may only build values from other values, which must have
already been read and internalized. A reader-constructor must always
return one value; it may not return "nothing". It may however throw an
exception or simply return an "inappropriate" value such as #f, which
will be caught later. Unlike compile-time function applications (that
is, macro-expansions), a read-time application has no "second pass".

Common Lisp defines an external form #.obj, which instructs the Lisp
reader to evaluate 'obj' right after the reader parsed it. While #. is
a general-purpose read-evaluator:
        #.obj === (eval obj)
#` is merely an application:
        #`obj === (apply (lookup (car obj)) (cdr obj))
and obj must be an external representation of a list. Read-time
applications are further restricted to only those procedures that have
been specifically declared for that purpose (via
define-reader-ctor). The user thus has a fine-grained control over
which functions are being applied at read time.

The following examples will show the difference between #. and #`. The
examples are hypothetical - I don't have a CL system handy to verify
the Lisp reader returns what I think it does, and #` is still a
proposal.

(read-from-string "#.(+ 1 2)") ==> 3

(define-reader-ctor '+ +)
(with-input-from-string "#`(+ 1 2)" read) ==> 3

(read-from-string "#.(+ 1 (+ 2 3))") ==> 6

(define-reader-ctor '+ +)
(with-input-from-string "#`(+ 1 (+ 2 3))" read) ==> error: can't add
                a number 1 and a list '(+ 2 3)
(with-input-from-string "#`(+ 1 #`(+ 2 3))" read) ==> 6

(define-reader-ctor 'my-vector
        (lambda x (apply vector (cons 'my-vector-tag x))))
(with-input-from-string "#`(my-vector (my-vector 1 2))" read) ==>
        a vector whose second element is a list of a symbol my-vector,
        number 1, and number 2.
(with-input-from-string "#`(my-vector #`(my-vector 1 2))" read) ==>
        a vector whose second element is a my-vector constructed from
        numbers 1 and 2.

How to extend the reader while it scans the code

The remaining question is how and _when_ to define
reader-constructors.  If define-reader-ctor is a regular built-in
function, declaration of a new reader-constructor will affect the
Scheme reader only when the code has been completely read,
(byte)compiled and is being executed. We would like to be able to
extend the Scheme reader while it still reads the code. For example,
we want to declare (define-reader-ctor 'vector-f32 <constructor>) and
be able to write
        (let ((v1 #`(vector-f32 1 2 3)))
         ...)
further down the code. Fortunately, there are several ways code can
affect a compiler/interpreter while it scans the code. For example,
define-macro or define-syntax "extend" a Scheme compiler at compile
time. So do command-line switches and pragmas, which are present in
many systems. In Gambit, pragmas are called "declare forms". In
addition, Gambit allows customization via profile forms, which may
also be specified on command line:
        gsi -e "(set-case-conversion! #f)" /tmp/case-sensitive-code.scm


Going ahead

Implementation of the proposed reader-application scheme is relatively
straightforward, especially in Gambit. A Gambit reader is actually
quite close to the Lisp reader -- readtables and such. Introducing of
#` will require only few minor extensions. As Gambit reader is written
in Scheme, reader-constructors could immediately be ported to other
implementations. However, since the Gambit reader is written and
copyrighted by Marc Feeley, and is a big chunk of gambc30/lib/_io.scm
file, it is wise to seek Dr. Feeley's permission first. I can
implement reader-constructors relatively quickly -- provided it is
worth doing at all.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    

From: Vassil Nikolov
Subject: Re: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <7era2c$bq6$1@nnrp1.dejanews.com>
I had to choose between cross-posting and more people seeing this
post.  I apologise for choosing the former.

In article <············@nnrp1.dejanews.com>,
  ····@pobox.com wrote:
(...)
> an extensible, new old way for external representation of
> Scheme values: read-time _application_.

If this had been less Scheme-specific, I would have been happier
to see it posted to comp.lisp.lang as well.

This issue is interesting but I think Scheme and Common Lisp are
facing different specific problems regarding it.

(...)
> LISP X3J13 document

I don't know of a document that ought to be called in this way.

> <http://www.harlequin.com/education/books/HyperSpec/Body/sec_2-4-8-6.html>

This is in fact the Common Lisp HyperSpec which is essentially the
same as the actual ANSI Common Lisp standard, X3.226, providing
the content of the latter in HTML format and produced by Kent
Pitman, X3J13 editor.

> expresses the goal of a read-time _evaluation_ with utmost clarity:
> "For an object that does not have a convenient printed representation,
> a form that computes the object can be given using the #. notation."

See also _Common Lisp: the Language_ by Guy L. Steele, and there might
be even earlier references as well.

(...)
> Proposed syntax of a read-time application
>
>         #`(tag arg1 ...)
> A 'tag' must be an (external representation of an) identifier, and
> 'arg1' etc. are external representations of some values, including
> other read-time applications. ·@ (rather than #`) seems to be another
> good way to denote read-time applications.

Well, ·@ is better.  I can't associate #` with application (unless
someone suggests some mnemonic value of sharp-backquote that I fail
to see).  As I already wrote, I'd rather have #/fn/(arg...) in
the style of COMMON-LISP:FORMAT or perhaps #!fn(arg...) unless
the latter is seen as too unixish.

(...)

As to the comparison against Common Lisp, I expected to see *READ-EVAL*
mentioned and the fact highlighted that read-time application provides
an intermediate level of control between the two possibilities one
has with *READ-EVAL*.

Let me add that besides introducing new syntax, be it #`, ·@, #/, #!,
or whatever, there is also the (kludgy) approach of extending
(incompatibly) the definition of *READ-EVAL* in the following way:

  when the value of *READ-EVAL* is a function, the value returned
  of the #. reader on a list is to call this function with the
  car and cdr of the list as arguments.  In particular, if the
  value of *READ-EVAL* is #'APPLY, we would get read-time
  application.

The incompatibilty of the change and the relative obscurity of
the resulting syntax would be disadvantages of this approach;
a benefit are that #<whatever> remains free for use.

One could make the above meaning of *READ-EVAL* work only with
#0. or something.

Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Rob Warnock
Subject: Re: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <7es96v$1ndep@fido.engr.sgi.com>
Vassil Nikolov  <········@poboxes.com> wrote:
+---------------
| ...or perhaps #!fn(arg...) unless the latter is seen as too unixish.
+---------------

It's not that it's "too Unix-ish", it's that it's already widely
defined in most Schemes (and some Lisps?) as a kind of comment, to
support the Unix "#!/path/to/interp options" scripting convention.
You don't want all your scripts to suddenly start breaking, do you?


-Rob

-----
Rob Warnock, 8L-855		····@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
2011 N. Shoreline Blvd.		FAX: 650-933-0511
Mountain View, CA  94043	PP-ASEL-IA
From: Kent M Pitman
Subject: Re: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <sfwsoa6yrgq.fsf@world.std.com>
[ comp.lang.lisp only
  http://world.std.com/~pitman/pfaq/cross-posting.html ]

····@rigden.engr.sgi.com (Rob Warnock) writes:

> Vassil Nikolov  <········@poboxes.com> wrote:
> +---------------
> | ...or perhaps #!fn(arg...) unless the latter is seen as too unixish.
> +---------------
> 
> It's not that it's "too Unix-ish", it's that it's already widely
> defined in most Schemes (and some Lisps?) as a kind of comment, to
> support the Unix "#!/path/to/interp options" scripting convention.
> You don't want all your scripts to suddenly start breaking, do you?

Incidentally, while I'm thinking of it, the reason that

 #!/fn/(...args...)

and friends are bad is that this allows you to call any function in
data.  That's a huge trojan horse.  I would make a loose analogy between
Lisp "data" and Java "security" (well, it's pretty weak security so it
deserves being compared to something like this) and say that because
the programmer must presently "register" which functions are to be called
from the reader by using the syntax setters, and because one can disable
*READ-EVAL*, there is a bound on how destructive the calling of READ can
be which allows some programs to be "safe".  That isn't to say that programs
using only READ are always safe, just as it isn't to say Java programs
are always safe, but it's to say that a certain specific set of operations
are less dangerous than they might otherwise be.

This aspect of Lisp is fairly well destroyed if #. or any other
operation capable of calling an arbitrary function is enabled.  And if
setting *READ-EVAL* to nil is the cure, then you're making these data
representations second-class because they can't be relied upon in
secure environments.  The #S(...)  notation, because it requires
registration of particular operations as "ok", is safer.
From: Vassil Nikolov
Subject: Re: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <7f0nnb$10v$1@nnrp1.dejanews.com>
In article <···············@world.std.com>,
  Kent M Pitman <······@world.std.com> wrote:

> [ comp.lang.lisp only
>   http://world.std.com/~pitman/pfaq/cross-posting.html ]

> > Vassil Nikolov  <········@poboxes.com> wrote
[that a syntax like #/constructor-fn/(args...) or similar could
 be considered.]

> Incidentally, while I'm thinking of it, the reason that
>
>  #!/fn/(...args...)
>
> and friends are bad is that this allows you to call any function in
> data.  That's a huge trojan horse.
(...)

It is.  I did not imagine there wouldn't be a mechanism to control it;
I wanted to be brief (or perhaps it was too late at night to see I
should have been more explicit).

> if
> setting *READ-EVAL* to nil is the cure,

No, I didn't have that in mind.  I was thinking along the lines of
having a register of allowed functions, e.g. a list of symbols in
the variable *READ-APPLY*, which would contain initially MAKE-ARRAY,
MAKE-HASH-TABLE, and maybe MAKE-INSTANCE.  Setting or binding
*READ-APPLY* to NIL would disallow all use of #/ and giving it a value
of T would allow any function to be called.

Besides, I do like the symmetry to FORMAT's ~/.

>                                         then you're making these data
> representations second-class because they can't be relied upon in
> secure environments.  The #S(...)  notation, because it requires
> registration of particular operations as "ok", is safer.

It appears to me that such registration as by *READ-APPLY* would be
equivalent to the registration provided by #S and macro characters
in general, as far as safety is concerned.  (If someone could change
the value of *READ-APPLY*, they would be able to change the readtable,
and vice versa.)  Is there some trap here that I fail to notice?

It's not that I don't like the #S(type-specifier-symbol ...)
syntax (besides, with it one can use the type hierarchy to allow
or disallow whole trees of types at once, if that is deemed
necessary), but it is less general.

I hope this also qualifies as a response to a post by Barry Margolin
in the `Why can't a hash table be read/written as #S(HASH-TABLE ...)?'
thread.  (Would it be too much to want to be able to follow up to
more than one post (apart from the fact that this might confuse
newsreaders)?)

--
Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Vassil Nikolov
Subject: Re: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <7f0le2$v1j$1@nnrp1.dejanews.com>
In article <············@fido.engr.sgi.com>,
  ····@rigden.engr.sgi.com (Rob Warnock) wrote:
> Vassil Nikolov  <········@poboxes.com> wrote:
> +---------------
> | ...or perhaps #!fn(arg...) unless the latter is seen as too unixish.
> +---------------
>
> It's not that it's "too Unix-ish", it's that it's already widely
> defined in most Schemes (and some Lisps?) as a kind of comment, to
> support the Unix "#!/path/to/interp options" scripting convention.
> You don't want all your scripts to suddenly start breaking, do you?

Sorry for forgetting about this (stored in the wrong department of
my mind I guess), and thank you for correcting me.

(If one wanted to write obfuscated Lisp, one could define the
#! reader to do different things depending on whether the character
after the '!' is a slash, or whether the character after the extended
token following the #! is a space or a left parenthesis...  Whose is
the law that says that every problem has a perverse solution?)

--
Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Erik Naggum
Subject: Re: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <3133039209460041@naggum.no>
* Vassil Nikolov <········@poboxes.com>
| (If one wanted to write obfuscated Lisp, one could define the #! reader
| to do different things depending on whether the character after the '!'
| is a slash, or whether the character after the extended token following
| the #! is a space or a left parenthesis...  Whose is the law that says
| that every problem has a perverse solution?)

  I think the world is ready for LERP (Lisp Enhanced by Random Perversion),
  not unlike the Perversion Excused by Random Lispiness already accepted.

#:Erik
-- 
environmentalists are much too concerned with planet earth.  their geocentric
attitude prevents them from seeing the greater picture -- lots of planets are
much worse off than earth is.
From: Rob Warnock
Subject: Re: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <7f15lo$2hqe6@fido.engr.sgi.com>
Vassil Nikolov  <········@poboxes.com> wrote:
+---------------
|   ····@rigden.engr.sgi.com (Rob Warnock) wrote:
| > defined in most Schemes (and some Lisps?) as a kind of comment, to
| > support the Unix "#!/path/to/interp options" scripting convention.
...
| (If one wanted to write obfuscated Lisp, one could define the
| #! reader to do different things depending on whether the character
| after the '!' is a slash, or whether the character after the extended
| token following the #! is a space or a left parenthesis...  Whose is
| the law that says that every problem has a perverse solution?)
+---------------

Hey, many of the Schemes that support #! are *already* "perverse" in
*my* book, in that the special "this is a comment" behavior of #! is
only true if it is the first two characters of a file that's "load"ed
or "read" from!

And in at least one implementation, "#!" *isn't* equivalent to ";", but
rather more like "#|", and thus requires a closing "!#" to avoid gobbling
the rest of your file! (This is seen as a "benefit", since it allows multiple
lines of command-line options to be specified.)


-Rob

-----
Rob Warnock, 8L-855		····@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
2011 N. Shoreline Blvd.		FAX: 650-933-0511
Mountain View, CA  94043	PP-ASEL-IA
From: Kent M Pitman
Subject: Re: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <sfwg166k78q.fsf@world.std.com>
[Replying only to comp.lang.lisp.
 http://world.std.com/~pitman/pfaq/cross-posting.html]

····@pobox.com writes:

> Proposed syntax of a read-time application
>         #`(tag arg1 ...)
>         (define-reader-ctor 'vector vector)
>         (with-input-from-string "#`(vector 1 2 3)" read) ==> '#(1 2 3)
>         (equal? '#(1 2 3) '#`(vector 1 2 3)) ==> #t

We just talked about this issue about two days ago in another thread, but
you may not have seen my post on this.  

There is already an appropriate syntax in Common Lisp. 
  #S(typename . data)
It happens only to be used for structures right now in CL, but there is
no reason it can't be generalized, and I have long argued that it was
the right thing to do.

I recommend not taking #` for a variety of reasons, not the least of which
is that a new character is not needed and there are too few characters
available now.  But as a rule, people are very bad at telling ` from '
and some fonts make it even harder, so unless a really killer use for 
#` came along, I would not recommend using backquote.

Issue HASH-TABLE-PRINTED-REPRESENTATION (Version 2, 08-Jun-88) addressed
this issue obliquely, discussing notations like:
 #H(EQL (FOO 37) (BAR 42))
 #H(EQL (FOO . 37) (BAR . 42))
 #H(EQL FOO 37 BAR 42)
 #S(HASH-TABLE TYPE EQL SIZE 20 INITIAL-CONTENTS ((FOO 37) (BAR 42)))
The last of these is most relevant here since it is general and builds
off of existing syntax.  One would simply explain the use for STRUCTURE-CLASS
by saying that DEFSTRUCT generates a definition for the associated
constructor when a struct is defined.

My personal notes from 13-Jan-1989 say as follows, except bracketed text 
indicates my change in position since then:

   I think the right approach is this:
   * Use the original simple #H syntax where it doesn't lose info.

  [I no longer believe it's worth giving up #H for this.]

   * Extend #S to allow you to specify #S(ARRAY ...), #S(HASH-TABLE ...), etc.
     in cases where the simpler notations would lose information. For example,
     if U is a Unix, #S(:HOST "U" :NAME "JOE" :TYPE :UNSPECIFIC) 

  [I'm pretty sure I meant #S(PATHNAME :HOST "U" ...) here.]


     could print as #P"U:joe" but #S(:HOST "U" :NAME "JOE" :TYPE NIL)

  [Again I'm pretty sure I meant #S(PATHNAME :HOST "U" ....) here.]

     could have to print in #S notation so that it didn't get 
     confused with the other.
     Similarly, #H notation could be used for default hash tables, but
     #S notation would be used for hairy cases with odd qualities.

   * Define that the contents of a hash table are denoted in #S notation
     using :CONTENTS.
From: ·······@my-dejanews.com
Subject: Re: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <7espps$ie4$1@nnrp1.dejanews.com>
In article <············@nnrp1.dejanews.com>,
  ····@pobox.com wrote:
>         (define-reader-ctor 'vector vector)

How would scoping work?  Would the reador-ctor be global, associated with an
environment, or associated with a port?  I see pluses and minuses in each
case.

--
"It seems certain that much of the success of Unix follows from the
readability, modifiability, and portability of its software."
                              -- Dennis M. Ritchie, September, 1979

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Kent M Pitman
Subject: Re: Read-time _apply_: an external representation for any value
Date: 
Message-ID: <sfwemlq3qv4.fsf@world.std.com>
[ comp.lang.lisp only
  http://world.std.com/~pitman/pfaq/cross-posting.html ]

·······@my-dejanews.com writes:

> In article <············@nnrp1.dejanews.com>,
>   ····@pobox.com wrote:
> >         (define-reader-ctor 'vector vector)
> 
> How would scoping work?  Would the reador-ctor be global, associated with an
> environment, or associated with a port?  I see pluses and minuses in each
> case.

In CL, the package system would provide scoping.  In Scheme, where you
have semantics based on lexical environments and not on symbols, the
problem is more difficult.