[LISPWORKS][Common Lisp HyperSpec (TM)] [Previous][Up][Next]


Issue READ-SUPPRESS-CONFUSING Writeup

Forum:		Public Review

Issue: READ-SUPPRESS-CONFUSING

References: Margolin's PR comment #2 (X3J13/92-1402)

Margolin's PR comment #18 (X3J13/92-1418)

Flanagan's PR comment #7 (X3J13/92-1907)

Philpot's PR comment #1 (X3J13/92-2901)

Barrett's PR comment #9 (X3J13/92-3109), part 2

*READ-SUPPRESS* (X3J13/92-102 pp.23-21..22)

Sharpsign P (X3J13/92-102 sec.2.4.8.14)

Sharpsign C (X3J13/92-102 sec.2.4.8.11)

Category: CHANGE

Edit history: 5 Jan 1993, Version 1 by Margolin

22 May 1993, Version 2 by Loosemore (delete bogus reference

to ":" and "@" in dispatching macro syntax)

Status: Proposal GENERALIZE passed 9-2 on letter ballot 93-302

Problem description:

The description of *READ-SUPPRESS* is confusing and incomplete. By

specifying the behavior of particular read syntaxes rather than a simple,

general strategy, some syntaxes (#C, #P, and#') have unintentionally been

omitted. And the wording of the description of the behavior of #(...) is

unclear as to whether the vector syntax is parsed and ignored or a vector

is actually constructed (there's a subtle difference between the CLtL and

dpANS wording, due to the lack of a pair of parentheses in the dpANS).

A strict reading of the current description of *READ-SUPPRESS* implies

that the reader must still construct objects in response to these

syntaxes (as well as user-defined reader macros that don't check the

variable). This is pretty wasteful considering that *READ-SUPPRESS*

exists primarily to support #+ and #-, which discard what they read with

*READ-SUPPRESS* true anyway.

In the case of #P, the lack of specification of its *READ-SUPPRESS*

behavior is a real annoyance, because some implementations have extended

it to allow non-strings to follow it. Users expect to be able to hide

such extensions using #+, but this isn't valid.

Proposal (READ-SUPPRESS-CONFUSING:GENERALIZE):

1) Replace the portion of the Description of *READ-SUPPRESS* from

"Extended tokens" through the entry for "#A, #S, #:" with:

When *READ-SUPPRESS* is true, READ, READ-PRESERVING-WHITESPACE,

READ-DELIMITED-LIST, and READ-FROM-STRING all return a first value of

NIL when they complete successfully; however, they continue to parse

the representation of an object in the normal way, in order to skip

over the object, and continue to indicate end-of-file in the normal

way. Except as noted below, any standard macro character (including

dispatching macro sub-characters) that is defined to read a following

object or token will do so, but not signal an error if the object

read is not of an appropriate type or syntax. Standard syntaxes and

macro characters will not construct any new objects (e.g. when

reading the representation of a symbol, no symbol will be constructed

or interned).

Dispatching macro characters (including #)

Dispatching macro characters continue to parse an infix numerical

argument, and invoke the

dispatch function. The standard # dispatching macro characters

do not enforce any constraints on the value or existence of the

numerical argument.

2) Create a Notes section that recommends that user-defined and

implementation-defined macro characters behave analogously to the

standard macro character, i.e. when *READ-SUPPRESS* is true they should

ignore type errors when reading a following object and dispatching macro

characters should allow NIL as an infix parameter.

3) Change the specifications of #C and #P to specify that they are

followed by the representation of an object. Then specify how they are

interpreted when those objects are a list of two real numbers (for #C) or

a string (for #P).

Examples:

(let ((*read-suppress* t))

(dolist (string '("#(foo bar baz)" "#P(:type :lisp)" "#c1.2" "foo"))

(unless

(ignore-errors

(progn (print (read-from-string string))

t))

(print 'error))))

could print

#(NIL NIL NIL)

ERROR

ERROR

Test Cases:

(let ((*read-suppress* t))

(mapcar #'read-from-string

'("#(foo bar baz)" "#P(:type :lisp)" "#c1.2")))

-> (NIL NIL NIL)

Rationale:

1) Specifies a general behavior for *READ-SUPPRESS* that is applicable to

all reader syntaxes that are described in terms of the representations of

objects.

2) Encourages implementors and users to extrapolate from this standard

behavior.

3) Specifies #P and #C in such a way that change 1 applies.

Current practice:

For the Example form, Genera 8.1 prints NIL, NIL, NIL (it seems to

implement the proposal); Lucid 4.1 and CMU CL 16d print NIL, ERROR, NIL;

WCL 2.1 prints #(NIL NIL NIL), ERROR, ERROR.

Cost to Implementors:

Should be minor.

Cost to Users:

When *READ-SUPPRESS* is bound via #+ or #-, the change should be upward

compatible, since any objects constructed by the reader will not be

visible. Direct users of *READ-SUPPRESS* may notice the difference, but

it seems unlikely that anyone is depending on any of the current

behaviors.

Cost of non-adoption:

Users will have to avoid using some implementation-dependent syntaxes in

#P macros.

Performance impact:

Minor.

Benefits:

More ability to include implementation-dependent syntax extensions in

portable source code.

Esthetics:

A general description of behavior is better than lots of specific cases.

Editorial Impact:

Minor. The changes are confined to the three sections mentioned above.

Discussion:

Barmar originally wanted to specify that standard dispatching macros

would parse the numerical argument but ignore it (always passing NIL to

the dispatch function). Flanagan convinced him to leave that part as it

was originally (the numeric argument is parsed but standard dispatch

functions don't enforce restrictions on it). It doesn't seem to be a big

deal either way.


[Starting Points][Contents][Index][Symbols][Glossary][Issues]
Copyright 1996-2005, LispWorks Ltd. All rights reserved.