From: Pascal Bourguignon
Subject: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87wt7x5boq.fsf@thalassa.informatimago.com>
Considering:

2.2 Reader Algorithm

    The reader macro function may return zero values or one value. If
    one value is returned, then that value is returned as the result
    of the read operation; the algorithm is done. If zero values are
    returned, then step 1 is re-entered.


2.4.8.6 Sharpsign Dot

   #.foo is read as the object resulting from the evaluation of the
    object represented by foo. The evaluation is done during the read
    process, when the #. notation is encountered. The #. syntax
    therefore performs a read-time evaluation of foo.


Function EVAL

   eval form => result*

   results---the values yielded by the evaluation of form. 


Therefore, I'd expect (read-from-string "#.(values) 42") to return 42.


sbcl 0.9.12, cmucl 19c and alegro cl 8.0 return 1 as expected.

clisp 2.39, ecl 0.9g and gcl 2.6.7 return NIL, surprizingly.


Could we agree that when *read-supress* is NIL, 
  (read-from-string "#.(values) 42") should return 42?



% clall \
  '(let ((*read-suppress* nil)) (read-from-string "#.(values) 42"))' \
  '(let ((*read-suppress* t  )) (read-from-string "#.(values) 42"))'

------------------------------------------------------------------------
CLISP 2.39 (2006-07-16) (built 3364813332) (memory 3364813914) 


(LET ((*READ-SUPPRESS* NIL)) (READ-FROM-STRING "#.(values) 42"))
--> NIL ;
    10


(LET ((*READ-SUPPRESS* T)) (READ-FROM-STRING "#.(values) 42"))
--> NIL ;
    10

------------------------------------------------------------------------
SBCL 0.9.12 


(LET ((*READ-SUPPRESS* NIL))
  (READ-FROM-STRING "#.(values) 42"))
--> 42 ;
    13


(LET ((*READ-SUPPRESS* T))
  (READ-FROM-STRING "#.(values) 42"))
--> NIL ;
    10

------------------------------------------------------------------------
CMU Common Lisp 19c (19C) 


(LET ((*READ-SUPPRESS* NIL))
  (READ-FROM-STRING "#.(values) 42"))
--> 42 ;
    13


(LET ((*READ-SUPPRESS* T))
  (READ-FROM-STRING "#.(values) 42"))
--> NIL ;
    11

------------------------------------------------------------------------
GNU Common Lisp (GCL) GCL 2.6.7 


(LET ((*READ-SUPPRESS* NIL)) (READ-FROM-STRING "#.(values) 42"))
--> NIL ;
    10


(LET ((*READ-SUPPRESS* T)) (READ-FROM-STRING "#.(values) 42"))
--> NIL ;
    10

------------------------------------------------------------------------
ECL 0.9g 


(LET ((*READ-SUPPRESS* NIL))
  (READ-FROM-STRING "#.(values) 42"))
--> NIL ;
    11


(LET ((*READ-SUPPRESS* T))
  (READ-FROM-STRING "#.(values) 42"))
--> NIL ;
    11

------------------------------------------------------------------------
International Allegro CL Free Express Edition 8.0 [Linux (x86)] (Jun 6, 2006 16:01) 


(LET ((*READ-SUPPRESS* NIL)) (READ-FROM-STRING "#.(values) 42"))
--> 42 ;
    13


(LET ((*READ-SUPPRESS* T)) (READ-FROM-STRING "#.(values) 42"))
--> NIL ;
    11

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

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
You never feed me.
Perhaps I'll sleep on your face.
That will sure show you.

From: Kalle Olavi Niemitalo
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87ac4shpq3.fsf@Astalo.kon.iki.fi>
Pascal Bourguignon <···@informatimago.com> writes:

> 2.4.8.6 Sharpsign Dot
>
>    #.foo is read as the object resulting from the evaluation of the
>     object represented by foo. The evaluation is done during the read
>     process, when the #. notation is encountered. The #. syntax
>     therefore performs a read-time evaluation of foo.

I think the wording "the object" can be interpreted to mean
the primary value will be used.

Possibly no real program cares what #.(values) does.
However, something like #.(floor 65536 pi) may occur in a program.
The result of reading this syntax may now be undefined in principle, 
but implementations agree that only the primary value gets used.
If you modified CLISP to make #. propagate all values,
then such expressions would begin failing:

*** - READ from #<INPUT CONCATENATED-STREAM #<INPUT STRING-INPUT-STREAM>
      #<IO TERMINAL-STREAM>>: dispatch macro character definition for #\.
      after #\# may not return 2 values, only one value.

So you would have to either remove this check from CLISP
or onerously require users to write #.(values (floor 65536 pi)).

An EXPLICITLY-VAGUE option may be the safest one.
Users who want a specific behaviour can define their own reader macros.
From: Rob Warnock
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <Kc6dnSryRfrO6I7YnZ2dnUVZ_vednZ2d@speakeasy.net>
Kalle Olavi Niemitalo  <···@iki.fi> wrote:
+---------------
| Possibly no real program cares what #.(values) does.
+---------------

No, but it certainly cares what "#-(and) (dont read me)" does, e.g.:

    cmu> (read-from-string "#-(and) (dont read me) :read-me")

    :READ-ME
    31
    cmu> 

It was my understanding that the whole "#.(values)" functionality
is there specifically so feature expressions will work [or at least
was put there with them in mind].

Or said another way, given that you have to have a way for "#+" and
"#-" to suppress things, the principle of orthogonal design suggests
allowing *all* readmacros to use the same mechanism, if they so choose.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Kalle Olavi Niemitalo
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87psdobd3t.fsf@Astalo.kon.iki.fi>
····@rpw3.org (Rob Warnock) writes:

> Or said another way, given that you have to have a way for "#+" and
> "#-" to suppress things, the principle of orthogonal design suggests
> allowing *all* readmacros to use the same mechanism, if they so choose.

Sure, if the #. readmacro returns no values for some input, then
READ must keep reading, as if #+(or)t had been seen.  I don't
think anybody contested that.

The issue was whether the #. readmacro should return the same
multiple values it gets from EVAL, and how requiring this might
hurt compatibility.
From: Rob Warnock
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <ZbKdnd5oDujiBI7YnZ2dnUVZ_uidnZ2d@speakeasy.net>
Kalle Olavi Niemitalo  <···@iki.fi> wrote:
+---------------
| The issue was whether the #. readmacro should return the same
| multiple values it gets from EVAL, and how requiring this might
| hurt compatibility.
+---------------

Uh... If you look at the "Subject:", you'll see that the original
issue was actually some implementations [which the OP listed] that
return NIL for (READ-FROM-STRING "#.(VALUES) 42") instead of 42!!

[I'm not sure how/where the "spreading multiple values" sidetrack
crept in...]


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87bqp83qni.fsf@thalassa.informatimago.com>
····@rpw3.org (Rob Warnock) writes:

> Kalle Olavi Niemitalo  <···@iki.fi> wrote:
> +---------------
> | The issue was whether the #. readmacro should return the same
> | multiple values it gets from EVAL, and how requiring this might
> | hurt compatibility.
> +---------------
>
> Uh... If you look at the "Subject:", you'll see that the original
> issue was actually some implementations [which the OP listed] that
> return NIL for (READ-FROM-STRING "#.(VALUES) 42") instead of 42!!
>
> [I'm not sure how/where the "spreading multiple values" sidetrack
> crept in...]

That's because reader macros can return 0 or 1 value.

Indeed, if they return two or more values, only the first one is kept
and returned by READ.  The question is what happens when they return 0
values.  The reader algorithm specifies what happens.  But in some
implementations, #. doesn't do the right thing.


Still, I don't see any advantage of having implementations diverge on
this point.  It would be preferable if all implementation returned the
same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 42].



On the other hand, we could say that #. is implementation specific and
nothing prevents programs that want to be portable to provide their own
implementation of this reader macro.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-CF2AD4.13262422092006@news.gha.chartermi.net>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Still, I don't see any advantage of having implementations diverge on
> this point.  It would be preferable if all implementation returned the
> same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 42].

Why?  (values) is equivalent to NIL is all other contexts (except those 
specifically designed to accept multiple values).  Why should #. be any 
different?

rg
From: Geoffrey Summerhayes
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <1158958417.860869.158490@e3g2000cwe.googlegroups.com>
Ron Garret wrote:
> In article <··············@thalassa.informatimago.com>,
>  Pascal Bourguignon <···@informatimago.com> wrote:
>
> > Still, I don't see any advantage of having implementations diverge on
> > this point.  It would be preferable if all implementation returned the
> > same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 42].
>
> Why?  (values) is equivalent to NIL is all other contexts (except those
> specifically designed to accept multiple values).  Why should #. be any
> different?

That would disallow users from creating a reader macro that could
discard it's input. If you want to give that ability, #.(values) should
do
the same.

Think of it as empowerment.

---
Geoff
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-E66C4A.22570226092006@news.gha.chartermi.net>
In article <························@e3g2000cwe.googlegroups.com>,
 "Geoffrey Summerhayes" <·······@hotmail.com> wrote:

> Ron Garret wrote:
> > In article <··············@thalassa.informatimago.com>,
> >  Pascal Bourguignon <···@informatimago.com> wrote:
> >
> > > Still, I don't see any advantage of having implementations diverge on
> > > this point.  It would be preferable if all implementation returned the
> > > same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 42].
> >
> > Why?  (values) is equivalent to NIL is all other contexts (except those
> > specifically designed to accept multiple values).  Why should #. be any
> > different?
> 
> That would disallow users from creating a reader macro that could
> discard it's input.

No it wouldn't, it would just disallow the #. reader macro from 
discarding its input, which seems like the Right Thing to me.

rg
From: Geoffrey Summerhayes
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <1159372440.232956.318720@m7g2000cwm.googlegroups.com>
Ron Garret wrote:
> In article <························@e3g2000cwe.googlegroups.com>,
>  "Geoffrey Summerhayes" <·······@hotmail.com> wrote:
>
> > Ron Garret wrote:
> > > In article <··············@thalassa.informatimago.com>,
> > >  Pascal Bourguignon <···@informatimago.com> wrote:
> > >
> > > > Still, I don't see any advantage of having implementations diverge on
> > > > this point.  It would be preferable if all implementation returned the
> > > > same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 42].
> > >
> > > Why?  (values) is equivalent to NIL is all other contexts (except those
> > > specifically designed to accept multiple values).  Why should #. be any
> > > different?
> >
> > That would disallow users from creating a reader macro that could
> > discard it's input.
>
> No it wouldn't, it would just disallow the #. reader macro from
> discarding its input, which seems like the Right Thing to me.

Yes it would, the best you could do would be to write a reader
macro that replaced the input with NIL, because the only way
to return zero values is (values) and you've disallowed that.

The only way for "The reader macro function may return zero
values or one value." to work is if the reader is aware of multiple
values.

---
Geoff
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-40D062.10224227092006@news.gha.chartermi.net>
In article <························@m7g2000cwm.googlegroups.com>,
 "Geoffrey Summerhayes" <·······@hotmail.com> wrote:

> Ron Garret wrote:
> > In article <························@e3g2000cwe.googlegroups.com>,
> >  "Geoffrey Summerhayes" <·······@hotmail.com> wrote:
> >
> > > Ron Garret wrote:
> > > > In article <··············@thalassa.informatimago.com>,
> > > >  Pascal Bourguignon <···@informatimago.com> wrote:
> > > >
> > > > > Still, I don't see any advantage of having implementations diverge on
> > > > > this point.  It would be preferable if all implementation returned 
> > > > > the
> > > > > same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 
> > > > > 42].
> > > >
> > > > Why?  (values) is equivalent to NIL is all other contexts (except those
> > > > specifically designed to accept multiple values).  Why should #. be any
> > > > different?
> > >
> > > That would disallow users from creating a reader macro that could
> > > discard it's input.
> >
> > No it wouldn't, it would just disallow the #. reader macro from
> > discarding its input, which seems like the Right Thing to me.
> 
> Yes it would, the best you could do would be to write a reader
> macro that replaced the input with NIL, because the only way
> to return zero values is (values) and you've disallowed that.

No, I've only disallowed it in the #. reader macro.  I've not disallowed 
it in any other reader macro.

> The only way for "The reader macro function may return zero
> values or one value." to work is if the reader is aware of multiple
> values.

I think you're conflating two different issues.  One is whether reader 
macros in general can return zero values and thereby not contribute 
anything to the data structure being read.  That they can do this is not 
in dispute (otherwise #+ and #- would not work).

What is in dispute is whether the #. reader macro specifically should 
avail itself of this capability, i.e. whether the reader macro function 
for #. should be (eval (read stream)) or (identity (eval (read 
stream))).  That is a design issue for which reasonable arguments exist 
on both sides IMHO.

rg
From: Geoffrey Summerhayes
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <1159381060.092318.41170@d34g2000cwd.googlegroups.com>
Ron Garret wrote:
> In article <························@m7g2000cwm.googlegroups.com>,
>
> I think you're conflating two different issues.  One is whether reader
> macros in general can return zero values and thereby not contribute
> anything to the data structure being read.  That they can do this is not
> in dispute (otherwise #+ and #- would not work).
>
> What is in dispute is whether the #. reader macro specifically should
> avail itself of this capability, i.e. whether the reader macro function
> for #. should be (eval (read stream)) or (identity (eval (read
> stream))).  That is a design issue for which reasonable arguments exist
> on both sides IMHO.

IMO, adding another inconsistency when none is needed is just
annoying: (values) works in all reader macros except #.(values)
I'd much prefer it to work as Pascal has outlined, after all if I want
NIL, I can write #.nil, it saves keystrokes. :-)

---
Geoff
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-AE120D.12534827092006@news.gha.chartermi.net>
In article <·······················@d34g2000cwd.googlegroups.com>,
 "Geoffrey Summerhayes" <·······@hotmail.com> wrote:

> Ron Garret wrote:
> > In article <························@m7g2000cwm.googlegroups.com>,
> >
> > I think you're conflating two different issues.  One is whether reader
> > macros in general can return zero values and thereby not contribute
> > anything to the data structure being read.  That they can do this is not
> > in dispute (otherwise #+ and #- would not work).
> >
> > What is in dispute is whether the #. reader macro specifically should
> > avail itself of this capability, i.e. whether the reader macro function
> > for #. should be (eval (read stream)) or (identity (eval (read
> > stream))).  That is a design issue for which reasonable arguments exist
> > on both sides IMHO.
> 
> IMO, adding another inconsistency when none is needed is just
> annoying: (values) works in all reader macros except #.(values)

Huh?  You mean #\(values) works?  #'(values)?  You must be using a 
different definition of the word "works" than most people.

The interesting case IMO is not #.(values) but rather:

(1 2 #.(foo) 4 5)

Personally I think it would be useful to be able to assume 
unconditionally that the above reads as a list of length 5.  Another 
example:

(let ((x #.(foo)) ...)

I think it's useful that the above not break if foo happens to return 
zero values.

rg
From: Christophe Rhodes
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <sqd59hca4q.fsf@cam.ac.uk>
Ron Garret <·········@flownet.com> writes:

> (let ((x #.(foo)) ...)
>
> I think it's useful that the above not break if foo happens to return 
> zero values.

It doesn't break under either interpretation of #.'s behaviour in
these circumstances.

Christophe
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-19B152.15351627092006@news.gha.chartermi.net>
In article <··············@cam.ac.uk>,
 Christophe Rhodes <·····@cam.ac.uk> wrote:

> Ron Garret <·········@flownet.com> writes:
> 
> > (let ((x #.(foo)) ...)
> >
> > I think it's useful that the above not break if foo happens to return 
> > zero values.
> 
> It doesn't break under either interpretation of #.'s behaviour in
> these circumstances.
> 
> Christophe

Hm, good point.  OK, let's try that again.  How about:

(defconstant x #.(foo))

rg
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <878xk5x6wt.fsf@thalassa.informatimago.com>
Ron Garret <·········@flownet.com> writes:
> The interesting case IMO is not #.(values) but rather:
>
> (1 2 #.(foo) 4 5)

I'd prefer it to be able to handle:

   '(1 2 #.(if some-condition-p (value 3) (values)) 4 5)


> Personally I think it would be useful to be able to assume 
> unconditionally that the above reads as a list of length 5.  Another 
> example:
>
> (let ((x #.(foo)) ...)
>
> I think it's useful that the above not break if foo happens to return 
> zero values.

There's no breakage. Both:

  (let ((x)) ...)

  (let ((x 'some-value)) ...)

are valid.

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

CAUTION: The mass of this product contains the energy equivalent of
85 million tons of TNT per net ounce of weight.
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-DC2C44.18100627092006@news.gha.chartermi.net>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Ron Garret <·········@flownet.com> writes:
> > The interesting case IMO is not #.(values) but rather:
> >
> > (1 2 #.(foo) 4 5)
> 
> I'd prefer it to be able to handle:
> 
>    '(1 2 #.(if some-condition-p (value 3) (values)) 4 5)

Why not:

`(1 2 ,@#.(if some-condition-p (list 3) nil) 4 50

rg
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87odt0wphd.fsf@thalassa.informatimago.com>
Ron Garret <·········@flownet.com> writes:

> In article <··············@thalassa.informatimago.com>,
>  Pascal Bourguignon <···@informatimago.com> wrote:
>
>> Ron Garret <·········@flownet.com> writes:
>> > The interesting case IMO is not #.(values) but rather:
>> >
>> > (1 2 #.(foo) 4 5)
>> 
>> I'd prefer it to be able to handle:
>> 
>>    '(1 2 #.(if some-condition-p (value 3) (values)) 4 5)
>
> Why not:
>
> `(1 2 ,@#.(if some-condition-p (list 3) nil) 4 50

The question is not ,@. As far as I know, all the implementation
behave the same for ,@.  



The question is that implementations behave differently for #.(values).

We're trying to find what the standard mandates or wanted to mandate
with this respect.


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

NEW GRAND UNIFIED THEORY DISCLAIMER: The manufacturer may
technically be entitled to claim that this product is
ten-dimensional. However, the consumer is reminded that this
confers no legal rights above and beyond those applicable to
three-dimensional objects, since the seven new dimensions are
"rolled up" into such a small "area" that they cannot be
detected.
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-33BB67.22333627092006@news.gha.chartermi.net>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Ron Garret <·········@flownet.com> writes:
> 
> > In article <··············@thalassa.informatimago.com>,
> >  Pascal Bourguignon <···@informatimago.com> wrote:
> >
> >> Ron Garret <·········@flownet.com> writes:
> >> > The interesting case IMO is not #.(values) but rather:
> >> >
> >> > (1 2 #.(foo) 4 5)
> >> 
> >> I'd prefer it to be able to handle:
> >> 
> >>    '(1 2 #.(if some-condition-p (value 3) (values)) 4 5)
> >
> > Why not:
> >
> > `(1 2 ,@#.(if some-condition-p (list 3) nil) 4 50
> 
> The question is not ,@. As far as I know, all the implementation
> behave the same for ,@.

Yes, which makes it a reliable substitute for the behavior you say you 
want from #.


> The question is that implementations behave differently for #.(values).
> 
> We're trying to find what the standard mandates or wanted to mandate
> with this respect.

That is simple to answer:

2.4.8.6 Sharpsign Dot

#.foo is read as THE OBJECT resulting from the evaluation of the object 
represented by foo.

(Emphasis added.)

I take this to mean that the reader macro function for the #. reader 
macro will always return a value (even if the form it evaluates doesn't).

rg
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87k63owfj4.fsf@thalassa.informatimago.com>
Ron Garret <·········@flownet.com> writes:
> That is simple to answer:
>
> 2.4.8.6 Sharpsign Dot
>
> #.foo is read as THE OBJECT resulting from the evaluation of the object 
> represented by foo.
>
> (Emphasis added.)
>
> I take this to mean that the reader macro function for the #. reader 
> macro will always return a value (even if the form it evaluates doesn't).

Not so simple, if 3 of the 6 implementations I tested, including
Allegro 8.0, implement otherwise.

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

"Our users will know fear and cower before our software! Ship it!
Ship it and let them flee like the dogs they are!"
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-83EA26.10043828092006@news.gha.chartermi.net>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Ron Garret <·········@flownet.com> writes:
> > That is simple to answer:
> >
> > 2.4.8.6 Sharpsign Dot
> >
> > #.foo is read as THE OBJECT resulting from the evaluation of the object 
> > represented by foo.
> >
> > (Emphasis added.)
> >
> > I take this to mean that the reader macro function for the #. reader 
> > macro will always return a value (even if the form it evaluates doesn't).
> 
> Not so simple, if 3 of the 6 implementations I tested, including
> Allegro 8.0, implement otherwise.

You keep bouncing back and forth between three different issues: 1) what 
the standard says, 2) what implementations do, and 3) what they ought to 
do.

The question you posed most recently (which you snipped) concerned the 
first of these three:

"We're trying to find what the standard mandates or wanted to mandate
with this respect."

What implementations do is irrelevant to that question.  The could all 
be doing it wrong and that wouldn't change the fact that it was wrong.

rg
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87fyebvrs9.fsf@thalassa.informatimago.com>
Ron Garret <·········@flownet.com> writes:

> In article <··············@thalassa.informatimago.com>,
>  Pascal Bourguignon <···@informatimago.com> wrote:
>
>> Ron Garret <·········@flownet.com> writes:
>> > That is simple to answer:
>> >
>> > 2.4.8.6 Sharpsign Dot
>> >
>> > #.foo is read as THE OBJECT resulting from the evaluation of the object 
>> > represented by foo.
>> >
>> > (Emphasis added.)
>> >
>> > I take this to mean that the reader macro function for the #. reader 
>> > macro will always return a value (even if the form it evaluates doesn't).
>> 
>> Not so simple, if 3 of the 6 implementations I tested, including
>> Allegro 8.0, implement otherwise.
>
> You keep bouncing back and forth between three different issues: 1) what 
> the standard says, 2) what implementations do, and 3) what they ought to 
> do.
>
> The question you posed most recently (which you snipped) concerned the 
> first of these three:
>
> "We're trying to find what the standard mandates or wanted to mandate
> with this respect."
>
> What implementations do is irrelevant to that question.  The could all 
> be doing it wrong and that wouldn't change the fact that it was wrong.

If the standard wasn't ambiguous, the implementations wouldn't diverge.

If the majority of the implementation went into the same dirrection,
there'd would be a concensus in the correct interpretation of the
standard.

Unfortunately, we're apparently in a case where 50% of the
implementaters interpreted one way and 50% the other way.

So what ought they do?

As a user of lisp implementation, my choice would go to one that
intreprets the standard as I do, in this case, #.  should return the
values returned by the form it evaluates, nothing more, nothing less.

If enough users agree with me, we may have enough weight to ask the
bad implementations to change their intepretation, and consitute a
de-facto interpretation of the standard, therefore being one step
closer to a CL-2020 standard.


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

This is a signature virus.  Add me to your signature and help me to live.
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-632739.13040728092006@news.gha.chartermi.net>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Ron Garret <·········@flownet.com> writes:
> 
> > In article <··············@thalassa.informatimago.com>,
> >  Pascal Bourguignon <···@informatimago.com> wrote:
> >
> >> Ron Garret <·········@flownet.com> writes:
> >> > That is simple to answer:
> >> >
> >> > 2.4.8.6 Sharpsign Dot
> >> >
> >> > #.foo is read as THE OBJECT resulting from the evaluation of the object 
> >> > represented by foo.
> >> >
> >> > (Emphasis added.)
> >> >
> >> > I take this to mean that the reader macro function for the #. reader 
> >> > macro will always return a value (even if the form it evaluates doesn't).
> >> 
> >> Not so simple, if 3 of the 6 implementations I tested, including
> >> Allegro 8.0, implement otherwise.
> >
> > You keep bouncing back and forth between three different issues: 1) what 
> > the standard says, 2) what implementations do, and 3) what they ought to 
> > do.
> >
> > The question you posed most recently (which you snipped) concerned the 
> > first of these three:
> >
> > "We're trying to find what the standard mandates or wanted to mandate
> > with this respect."
> >
> > What implementations do is irrelevant to that question.  The could all 
> > be doing it wrong and that wouldn't change the fact that it was wrong.
> 
> If the standard wasn't ambiguous, the implementations wouldn't diverge.

The standard is not ambiguous.  It says very clearly and unambiguously 
that "#.foo is read as THE OBJECT resulting from the evaluation of the 
object represented by foo."  In English, the article "the" in 
conjunction with a singular noun implies one and only one.

> If the majority of the implementation went into the same dirrection,
> there'd would be a concensus in the correct interpretation of the
> standard.

Yes, but that consensus would be wrong.

> Unfortunately, we're apparently in a case where 50% of the
> implementaters interpreted one way and 50% the other way.
> 
> So what ought they do?

They ought to follow the standard.

> As a user of lisp implementation, my choice would go to one that
> intreprets the standard as I do, in this case, #.  should return the
> values returned by the form it evaluates, nothing more, nothing less.

But that's not what the standard says.  Leaving aside the fact that 
reader macros don't "return" anything (reader macro functions return 
things) the standard specifically does NOT say, as you wish it did, that 
#. "returns the values returned by the form" (whatever that might mean).  
The standard says what it says and the meaning is quite unambiguous.

> If enough users agree with me, we may have enough weight to ask the
> bad implementations to change their intepretation, and consitute a
> de-facto interpretation of the standard, therefore being one step
> closer to a CL-2020 standard.

If enough users disagree with you the same end could be achieved.

rg
From: Duane Rettig
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <o0ejtvljfk.fsf@franz.com>
Ron Garret <·········@flownet.com> writes:

> In article <··············@thalassa.informatimago.com>,
>  Pascal Bourguignon <···@informatimago.com> wrote:
> 
>> If the standard wasn't ambiguous, the implementations wouldn't diverge.
>
> The standard is not ambiguous.  It says very clearly and unambiguously 
> that "#.foo is read as THE OBJECT resulting from the evaluation of the 
> object represented by foo."  In English, the article "the" in 
> conjunction with a singular noun implies one and only one.

I agree with this reading of the spec.  I haven't kept up with this
thread, so I'm not sure if others arguing for ambiguity are citing the
third paragraph of 2.1.4.4 or not; but clearly, 2.4.8.6 is more
specific, and thus it stands.

Now; what does the standard say about #.(values) ?  Absolutely
nothing.  It talks about the object returned from #., but it does not
provide any guidance on what to do if no object is returned by the
evaluation, either with a statement of Exceptional Situations or
with a description.

So what does this mean?  It means that a conforming program cannot
count on a particular behavior for this situation.

>> If the majority of the implementation went into the same dirrection,
>> there'd would be a concensus in the correct interpretation of the
>> standard.
>
> Yes, but that consensus would be wrong.

I agree.

>> Unfortunately, we're apparently in a case where 50% of the
>> implementaters interpreted one way and 50% the other way.
>> 
>> So what ought they do?
>
> They ought to follow the standard.

This is not an implementation issue; it is a usage issue.  Conforming
programs can't assume what isn't promised.

>> As a user of lisp implementation, my choice would go to one that
>> intreprets the standard as I do, in this case, #.  should return the
>> values returned by the form it evaluates, nothing more, nothing less.
>
> But that's not what the standard says.  Leaving aside the fact that 
> reader macros don't "return" anything (reader macro functions return 
> things) the standard specifically does NOT say, as you wish it did, that 
> #. "returns the values returned by the form" (whatever that might mean).  
> The standard says what it says and the meaning is quite unambiguous.
>
>> If enough users agree with me, we may have enough weight to ask the
>> bad implementations to change their intepretation, and consitute a
>> de-facto interpretation of the standard, therefore being one step
>> closer to a CL-2020 standard.
>
> If enough users disagree with you the same end could be achieved.

Or perhaps the standard is fine in this case and we must shift focus
on programs not counting on a particular behavior.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-B43A11.15184529092006@news.gha.chartermi.net>
In article <··············@franz.com>, Duane Rettig <·····@franz.com> 
wrote:

> So what does this mean?  It means that a conforming program cannot
> count on a particular behavior for this situation.

That is manifestly true since it is an objective fact that different 
implementations handle this case differently.  However, I think everyone 
would agree that not being able to count on things is, all else being 
equal, a Bad Thing.  So we can make the world a better place by agreeing 
on one behavior or the other.  I am trying to argue that interpreting 
"the object returned by" as "the principal value of" is consistent with 
both the letter and spirit of the standard, and that it is the only 
interpretation with those properties.  It should therefore be the 
preferred interpretation.

> Or perhaps the standard is fine in this case and we must shift focus
> on programs not counting on a particular behavior.

But that's bad because it means that to use the #. macro reliably you 
must do more than just avoid #.(values), you must avoid #.(foo) for any 
function foo that might return zero values.

rg
From: Duane Rettig
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <o0y7s2p7cw.fsf@franz.com>
Ron Garret <·········@flownet.com> writes:

> In article <··············@franz.com>, Duane Rettig <·····@franz.com> 
> wrote:
>
>> So what does this mean?  It means that a conforming program cannot
>> count on a particular behavior for this situation.
>
> That is manifestly true since it is an objective fact that different 
> implementations handle this case differently.

Not only is it manifestly true, but it is also explicitly true.
1.5.2: Conforming Programs (bullet 1):  "Conforming code shall use only
those features of the language syntax and semantics that are either
specified in this standard or defined using the extension mechanisms
specified in the standard."

> However, I think everyone would agree that not being able to count
> on things is, all else being equal, a Bad Thing.

But all things aren't equal; they seem to be divided by 50%
manifestly, and in fact the standard says that you can't count on
things that it hasn't said you can count on.  There are reasons for
this, of course, but I as an implementor would not agree to waste time
changing the behavior of something that is undefined except by either a
standardization effort to define it, or a very good reason to why such
a behavior guarantee is needed (Note again as I stated in my last
message that I haven't kept up on this thread; it may be that good
reasons have been given, but I'm personaly not interested in this
particular issue, only the meta-issue that it represents).

> So we can make the world a better place by agreeing 
> on one behavior or the other.

Ahh, a standardization effort!  Well, for this class of issue, where
clarification an otherwise very good spec on yet another minor point
is needed, you should add it to the list:

http://www.cliki.net/Proposed%20ANSI%20Revisions%20and%20Clarifications

>  I am trying to argue that interpreting 
> "the object returned by" as "the principal value of" is consistent with 
> both the letter and spirit of the standard, and that it is the only 
> interpretation with those properties.  It should therefore be the 
> preferred interpretation.

Again, I'm not concerned about the particular point you're making,
though I understand of course that you are - I am concerned with the
larger issue of pseudo-standardization.  There are a lot of other
issues, though, that may or may not be of equal relevance to more or
less people (see above), and it is not a trivial process to force
agreement even amongst users, let alone vendors.  That is in fact the
whole pain and victory of a standardization effort.

>> Or perhaps the standard is fine in this case and we must shift focus
>> on programs not counting on a particular behavior.
>
> But that's bad because it means that to use the #. macro reliably you 
> must do more than just avoid #.(values), you must avoid #.(foo) for any 
> function foo that might return zero values.

As you said in another message, foo is not the character macro here,
but the function which the character macro calls.  So if you want to
write portable programs, and can legislate to users who are willing
to go along with it, then you can have everyone wrap (values...)
around the call, as in #.(values (foo))

CL-USER(1): (defun foo () (values))
FOO
CL-USER(2): (foo)
CL-USER(3): (values (foo))
NIL
CL-USER(4): 

In that way you don't have to wait for vendors to respond (or not) to
your mini-standardization effort, and you can then have your
portability as soon as you get fellow users to code that way.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-3FA900.16474929092006@news.gha.chartermi.net>
In article <··············@franz.com>, Duane Rettig <·····@franz.com> 
wrote:

> > So we can make the world a better place by agreeing 
> > on one behavior or the other.
> 
> Ahh, a standardization effort!

Damn, Duane, nothing gets past you does it?  ;-)

> So if you want to
> write portable programs, and can legislate to users who are willing
> to go along with it, then you can have everyone wrap (values...)
> around the call, as in #.(values (foo))

Yeah, but that's annoying.  Still, your point is well taken.

rg
From: Barry Margolin
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <barmar-3442A1.20144628092006@comcast.dca.giganews.com>
In article <·······························@news.gha.chartermi.net>,
 Ron Garret <·········@flownet.com> wrote:

> In article <··············@thalassa.informatimago.com>,
>  Pascal Bourguignon <···@informatimago.com> wrote:
> > If the standard wasn't ambiguous, the implementations wouldn't diverge.
> 
> The standard is not ambiguous.  It says very clearly and unambiguously 
> that "#.foo is read as THE OBJECT resulting from the evaluation of the 
> object represented by foo."  In English, the article "the" in 
> conjunction with a singular noun implies one and only one.

But that implication assumes that foo always evaluates to one and only 
one object.  If foo is (values), THE OBJECT has no reference -- it's 
like THE KING OF ENGLAND.

So maybe it's not the implications that are wrong -- perhaps #.(values) 
and #.(values 1 2 3) are not valid syntax, and it doesn't matter what 
implementations do with them.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87y7s3t4yr.fsf@thalassa.informatimago.com>
Barry Margolin <······@alum.mit.edu> writes:

> In article <·······························@news.gha.chartermi.net>,
>  Ron Garret <·········@flownet.com> wrote:
>
>> In article <··············@thalassa.informatimago.com>,
>>  Pascal Bourguignon <···@informatimago.com> wrote:
>> > If the standard wasn't ambiguous, the implementations wouldn't diverge.
>> 
>> The standard is not ambiguous.  It says very clearly and unambiguously 
>> that "#.foo is read as THE OBJECT resulting from the evaluation of the 
>> object represented by foo."  In English, the article "the" in 
>> conjunction with a singular noun implies one and only one.
>
> But that implication assumes that foo always evaluates to one and only 
> one object.  If foo is (values), THE OBJECT has no reference -- it's 
> like THE KING OF ENGLAND.
>
> So maybe it's not the implications that are wrong -- perhaps #.(values) 
> and #.(values 1 2 3) are not valid syntax, and it doesn't matter what 
> implementations do with them.

If they weren't valid syntax, wouldn't it be nice if ALL the
implementations raised an error in such a case?

Or perhaps the rule that (values) in a call site where one value is
expected still gives NIL should apply and then then implementations
who read NIL for #.(values) are right, and the other are wrong?
Perhaps that's what the standard says?


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

"You question the worthiness of my code? I should kill you where you
stand!"
From: Barry Margolin
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <barmar-BE867A.19564629092006@comcast.dca.giganews.com>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Barry Margolin <······@alum.mit.edu> writes:
> 
> > In article <·······························@news.gha.chartermi.net>,
> >  Ron Garret <·········@flownet.com> wrote:
> >
> >> In article <··············@thalassa.informatimago.com>,
> >>  Pascal Bourguignon <···@informatimago.com> wrote:
> >> > If the standard wasn't ambiguous, the implementations wouldn't diverge.
> >> 
> >> The standard is not ambiguous.  It says very clearly and unambiguously 
> >> that "#.foo is read as THE OBJECT resulting from the evaluation of the 
> >> object represented by foo."  In English, the article "the" in 
> >> conjunction with a singular noun implies one and only one.
> >
> > But that implication assumes that foo always evaluates to one and only 
> > one object.  If foo is (values), THE OBJECT has no reference -- it's 
> > like THE KING OF ENGLAND.
> >
> > So maybe it's not the implications that are wrong -- perhaps #.(values) 
> > and #.(values 1 2 3) are not valid syntax, and it doesn't matter what 
> > implementations do with them.
> 
> If they weren't valid syntax, wouldn't it be nice if ALL the
> implementations raised an error in such a case?

Sure.  But there are lots of errors that implementations aren't required 
to diagnose.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-708EAC.11363929092006@news.gha.chartermi.net>
In article <····························@comcast.dca.giganews.com>,
 Barry Margolin <······@alum.mit.edu> wrote:

> In article <·······························@news.gha.chartermi.net>,
>  Ron Garret <·········@flownet.com> wrote:
> 
> > In article <··············@thalassa.informatimago.com>,
> >  Pascal Bourguignon <···@informatimago.com> wrote:
> > > If the standard wasn't ambiguous, the implementations wouldn't diverge.
> > 
> > The standard is not ambiguous.  It says very clearly and unambiguously 
> > that "#.foo is read as THE OBJECT resulting from the evaluation of the 
> > object represented by foo."  In English, the article "the" in 
> > conjunction with a singular noun implies one and only one.
> 
> But that implication assumes that foo always evaluates to one and only 
> one object.

No it doesn't.  It assumes that "the object" really means "the principal 
value."  There is ample precedent for making this assumption.  For 
example, the standard says:

"The form (LET ...) first evaluates the expressions init-form-1, 
init-form-2, and so on, in that order, saving the resulting values. Then 
all of the variables varj are bound to the corresponding values;"

It is universally agreed that "the resulting values" means the resulting 
principal values even though the standard does not explicitly say so.  
So unless you wish to entertain the possibility that:

(let ((x (values 1 2)) y) (list x y))

might return (1 2) you need to apply a little common sense.

> So maybe it's not the implications that are wrong -- perhaps #.(values) 
> and #.(values 1 2 3) are not valid syntax, and it doesn't matter what 
> implementations do with them.

That is possible, but there are at least two reasons to reject that 
interpretation: first, if it were true then the behavior of #.(foo) 
would be unpredictable in the case where you don't have control over the 
behavior of foo.  That is by any rational measure undesirable, and is 
IMO grounds for rejecting that interpretation.  Second, syntactic 
correctness ought to be as much as possible a static property of the 
program text.  That ship has already sailed in CL with the introduction 
of reader macros, but there's no reason to choose an interpretation that 
introduces gratuitous dynamic errors with no payoff.

rg
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-877692.15243429092006@news.gha.chartermi.net>
In article <····························@comcast.dca.giganews.com>,
 Barry Margolin <······@alum.mit.edu> wrote:

> In article <·······························@news.gha.chartermi.net>,
>  Ron Garret <·········@flownet.com> wrote:
> 
> > In article <··············@thalassa.informatimago.com>,
> >  Pascal Bourguignon <···@informatimago.com> wrote:
> > > If the standard wasn't ambiguous, the implementations wouldn't diverge.
> > 
> > The standard is not ambiguous.  It says very clearly and unambiguously 
> > that "#.foo is read as THE OBJECT resulting from the evaluation of the 
> > object represented by foo."  In English, the article "the" in 
> > conjunction with a singular noun implies one and only one.
> 
> But that implication assumes that foo always evaluates to one and only 
> one object.  If foo is (values), THE OBJECT has no reference -- it's 
> like THE KING OF ENGLAND.

This just occurred to me:

No, it is not like the king of England because the existence (or not) of 
the KofE is not under our control.  But the existence of The Object 
returned by a reader macro function IS under our control.  We can 
therefore cause The Object to exist in a way that we cannot cause the 
KofE to exist.  The standard's use of the phrase "the object" implies 
that it requires us to do exactly that.

Another important thing to note: in #.(foo), foo is NOT the reader-macro 
function for the #. reader macro.  The reader-macro function for #. must 
call foo to do its job (in this case), but they are not the same thing.  
Just because foo returns zero values does not mean that the reader-macro 
function for #. has to.

rg
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <873babujsb.fsf@thalassa.informatimago.com>
Ron Garret <·········@flownet.com> writes:

> In article <··············@thalassa.informatimago.com>,
>  Pascal Bourguignon <···@informatimago.com> wrote:
>
>> If the standard wasn't ambiguous, the implementations wouldn't diverge.
>
> The standard is not ambiguous.  It says very clearly and unambiguously 
> that "#.foo is read as THE OBJECT resulting from the evaluation of the 
> object represented by foo."  In English, the article "the" in 
> conjunction with a singular noun implies one and only one.
>
>> If the majority of the implementation went into the same dirrection,
>> there'd would be a concensus in the correct interpretation of the
>> standard.
>
> Yes, but that consensus would be wrong.
>
>> Unfortunately, we're apparently in a case where 50% of the
>> implementaters interpreted one way and 50% the other way.
>> 
>> So what ought they do?
>
> They ought to follow the standard.
>
>> As a user of lisp implementation, my choice would go to one that
>> intreprets the standard as I do, in this case, #.  should return the
>> values returned by the form it evaluates, nothing more, nothing less.
>
> But that's not what the standard says.  Leaving aside the fact that 
> reader macros don't "return" anything (reader macro functions return 
> things) the standard specifically does NOT say, as you wish it did, that 
> #. "returns the values returned by the form" (whatever that might mean).  
> The standard says what it says and the meaning is quite unambiguous.
>
>> If enough users agree with me, we may have enough weight to ask the
>> bad implementations to change their intepretation, and consitute a
>> de-facto interpretation of the standard, therefore being one step
>> closer to a CL-2020 standard.
>
> If enough users disagree with you the same end could be achieved.

Indeed.  I'm of the opinion that a standard specification should
specify, to be of any use.  Therefore, if CL specifies anything for
#.(values), right now, half the implementations are wrong.


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

"You question the worthiness of my code? I should kill you where you
stand!"
From: Barry Margolin
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <barmar-8F67CD.13323028092006@comcast.dca.giganews.com>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Unfortunately, we're apparently in a case where 50% of the
> implementaters interpreted one way and 50% the other way.
> 
> So what ought they do?
> 
> As a user of lisp implementation, my choice would go to one that
> intreprets the standard as I do, in this case, #.  should return the
> values returned by the form it evaluates, nothing more, nothing less.

As a user, if there's an ambiguity in the spec, you should avoid 
depending on any particular interpretation.  Treat it as if the spec 
explicitly says that the consequences are undefined, since that's 
effectively what it is.

If the standards body were still active you could file a request for 
their interpretation, and then pass their reply on to implementors who 
don't conform.  But AFAIK the CL standardization committee is moribund, 
so the best you can do is try to convince implementors that your 
interpretation is the right one, and in the meanwhile just avoid that 
aspect of the language.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <877iznujwm.fsf@thalassa.informatimago.com>
Barry Margolin <······@alum.mit.edu> writes:

> In article <··············@thalassa.informatimago.com>,
>  Pascal Bourguignon <···@informatimago.com> wrote:
>
>> Unfortunately, we're apparently in a case where 50% of the
>> implementaters interpreted one way and 50% the other way.
>> 
>> So what ought they do?
>> 
>> As a user of lisp implementation, my choice would go to one that
>> intreprets the standard as I do, in this case, #.  should return the
>> values returned by the form it evaluates, nothing more, nothing less.
>
> As a user, if there's an ambiguity in the spec, you should avoid 
> depending on any particular interpretation.  Treat it as if the spec 
> explicitly says that the consequences are undefined, since that's 
> effectively what it is.
>
> If the standards body were still active you could file a request for 
> their interpretation, and then pass their reply on to implementors who 
> don't conform.  But AFAIK the CL standardization committee is moribund, 
> so the best you can do is try to convince implementors that your 
> interpretation is the right one, and in the meanwhile just avoid that 
> aspect of the language.

Indeed, that's exactly what I'm doing here.

You see,  last time I raised such a question to my favorite
implementors, they asked me to raise it in c.l.l to see what the
concensus was.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
You're always typing.
Well, let's see you ignore my
sitting on your hands.
From: Barry Margolin
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <barmar-0AF090.23045927092006@comcast.dca.giganews.com>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Ron Garret <·········@flownet.com> writes:
> > The interesting case IMO is not #.(values) but rather:
> >
> > (1 2 #.(foo) 4 5)
> 
> I'd prefer it to be able to handle:
> 
>    '(1 2 #.(if some-condition-p (value 3) (values)) 4 5)
> 
> 
> > Personally I think it would be useful to be able to assume 
> > unconditionally that the above reads as a list of length 5.  Another 
> > example:
> >
> > (let ((x #.(foo)) ...)
> >
> > I think it's useful that the above not break if foo happens to return 
> > zero values.
> 
> There's no breakage. Both:
> 
>   (let ((x)) ...)
> 
>   (let ((x 'some-value)) ...)
> 
> are valid.

How about

(let ((x '#.(foo))) ...)

which is likely to be what you'd want to write (unless you know that FOO 
always returns a self-evaluating object).

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Joerg Hoehle
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <uk63iznxo.fsf@users.sourceforge.net>
Hi,

I'm in favour of having all CL "standardize" or converge on what's
perceived as useful behaviour by the community.  It helps portability
(at least of new software), which many people here think is a great
asset of CL.

The question is, what's the most valueable behaviour to converte to?

I wouldn't want to debate whether #. "skip" behaviour can be derived
from the wording of the CLHS (or ANSI-CL spec).

What I'd like to question is the merits of choosing the one over the
other.  Why is "ignore" better than the opposite?
Is it just a matter of shouting the loudest right now in this thread?
We've had this #. topic here and there in comp.lang.lisp already.


Barry Margolin <······@alum.mit.edu> writes:
> > Ron Garret <·········@flownet.com> wrote:
> > > Personally I think it would be useful to be able to assume 
> > > unconditionally that the above reads as a list of length 5.  Another 
> > > example:
> > > (let ((x '#.(foo)) ...)
[quote added above]

> > > I think it's useful that the above not break if foo happens to return 
> > > zero values.
> How about
> (let ((x '#.(foo))) ...)
> which is likely to be what you'd want to write (unless you know that FOO 
> always returns a self-evaluating object).

So that's a clear, correct and understandable concern against the "skip" case.

I can myself come up with a case in favour of the "skip" case, e.g.
CLISP's (FFI:DEF-CALL-OUT ... [(:library ...)] #)
Whether the (:library #) clause is present or not leads to completely
different behaviour. #.(values)-as-ignore would be useful in that context.

What else is there to put up for the judges?
Pros? Cons?

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: Pascal Costanza
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <4ocvjpFe3afoU1@individual.net>
Joerg Hoehle wrote:

> What else is there to put up for the judges?
> Pros? Cons?

I haven't followed the discussion in this thread, so maybe this is 
completely irrelevant. But in my experience, one good principle in 
language design is this: If you have two design choices, check which of 
the two allows expressing the respective other. If one isn't capable of 
doing what the other does, choose the other one. In this way, you serve 
more potential users, especially in cases where it's not clear what the 
"obvious right way" (tm) is.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-ECFFCD.12442602102006@news.gha.chartermi.net>
In article <··············@individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> Joerg Hoehle wrote:
> 
> > What else is there to put up for the judges?
> > Pros? Cons?
> 
> I haven't followed the discussion in this thread, so maybe this is 
> completely irrelevant. But in my experience, one good principle in 
> language design is this: If you have two design choices, check which of 
> the two allows expressing the respective other. If one isn't capable of 
> doing what the other does, choose the other one. In this way, you serve 
> more potential users, especially in cases where it's not clear what the 
> "obvious right way" (tm) is.

This is not about capability, it is about invariance.  Either 
possibility can easily "do" what the other one does at the expense of 
some additional typing.  What this is about is what one can or cannot 
count on.  Can I count on e.g.:

(defconstant x #.(foo))

not producing a syntax error, or do I have to always remember to write:

(defconstant x #.(values (foo)))

IMHO allowing #. to read as nothing is not a feature but a pitfall, not 
unlike those for which C++ is often and rightly derided.

rg

P.S. I note in passing that on the criterion above, *combination-hook* 
is an improvement on CL's design, and that your objections to 
*combination-hook* are of exactly the same form as my objections to #. 
reading as nothing.  The difference is that adding *combination-hook* 
cannot cause currently correct code to break, whereas allowing #. to 
read as nothing can.
From: Geoffrey Summerhayes
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <1159824294.765816.198560@c28g2000cwb.googlegroups.com>
Ron Garret wrote:
> In article <··············@individual.net>,
>
> This is not about capability, it is about invariance.  Either
> possibility can easily "do" what the other one does at the expense of
> some additional typing.  What this is about is what one can or cannot
> count on.  Can I count on e.g.:
>
> (defconstant x #.(foo))
>
> not producing a syntax error, or do I have to always remember to write:
>
> (defconstant x #.(values (foo)))
>
> IMHO allowing #. to read as nothing is not a feature but a pitfall, not
> unlike those for which C++ is often and rightly derided.

Given the current variation in implementations, expecting a no value
return not to break code is obviously problematic.

I also find it difficult to accept that a function that can return no
values used in a defconstant #. pairing can really be considered
correct, or at the very least, good code under either interpretation.

It would be nice to have a way of mimicking a <user-created
reader macro that may return no values> when readtable
modifications are difficult to make and maintain due to other
packages in play. Sorry about that sentence. :-(

For instance, under normal circumstances the package could
use #!, but if it found the dispatch in use by another package,
it could switch to #. and be capable of still writing a readable
form that behaved identically.

The alternative would be to specify an additional reader macro
that behaved exactly like #. except for its behaviour when it
returns no values.

---
Geoff
From: Pascal Costanza
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <4od9vuFe4fa0U1@individual.net>
Ron Garret wrote:
> In article <··············@individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>> Joerg Hoehle wrote:
>>
>>> What else is there to put up for the judges?
>>> Pros? Cons?
>> I haven't followed the discussion in this thread, so maybe this is 
>> completely irrelevant. But in my experience, one good principle in 
>> language design is this: If you have two design choices, check which of 
>> the two allows expressing the respective other. If one isn't capable of 
>> doing what the other does, choose the other one. In this way, you serve 
>> more potential users, especially in cases where it's not clear what the 
>> "obvious right way" (tm) is.
> 
> This is not about capability, it is about invariance.  Either 
> possibility can easily "do" what the other one does at the expense of 
> some additional typing.  What this is about is what one can or cannot 
> count on.  Can I count on e.g.:
> 
> (defconstant x #.(foo))
> 
> not producing a syntax error, or do I have to always remember to write:
> 
> (defconstant x #.(values (foo)))
> 
> IMHO allowing #. to read as nothing is not a feature but a pitfall, not 
> unlike those for which C++ is often and rightly derided.

As I said, I haven't followed the discussion, so I cannot judge this.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Alan Crowe
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <86y7rw3utb.fsf@cawtech.freeserve.co.uk>
Ron Garret <·········@flownet.com> writes:

> This is not about capability, it is about invariance.  Either 
> possibility can easily "do" what the other one does at the expense of 
> some additional typing.  What this is about is what one can or cannot 
> count on.  Can I count on e.g.:
> 
> (defconstant x #.(foo))
> 
> not producing a syntax error, or do I have to always remember to write:
> 
> (defconstant x #.(values (foo)))
> 

You really want that syntax error. If you had meant x to be
nil you would have written (defconstant x nil). What you've
done is remember foo as

(defun foo (stuff)
  (setf *remember* (compute-foo stuff)))

but for some reason foo is actually

(defun foo (stuff)
  (setf *remember* (compute-foo stuff))
  (values))

The invarience that you care about is (eql x *remember*)
Having (defconstant x #.(foo)) shaft you with an unexpected
nil is a loss.

Alan Crowe
Edinburgh
Scotland
  
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87mz8eob7q.fsf@thalassa.informatimago.com>
Pascal Costanza <··@p-cos.net> writes:

> Joerg Hoehle wrote:
>
>> What else is there to put up for the judges?
>> Pros? Cons?
>
> I haven't followed the discussion in this thread, so maybe this is
> completely irrelevant. But in my experience, one good principle in
> language design is this: If you have two design choices, check which
> of the two allows expressing the respective other. If one isn't
> capable of doing what the other does, choose the other one. In this
> way, you serve more potential users, especially in cases where it's
> not clear what the "obvious right way" (tm) is.


That's what I think too.



Assuming the function f returns 0 or 1 value,
we may want to read:


  With the behavior of allegro,sbcl,cmucl:

       nothing when f returns 0 value
       the value when f returns 1 value

              #.(f) 


       nil when f returns 0 value
       the value when f returns 1 value

              #.(values (f))


  With the behavior of clisp,gcl,ecl:

       nothing when f returns 0 value
       the value when f returns 1 value

              #+(cl:if (cl:null (cl:multiple-value-list (cl-user::f)))
                       '(or) '(and)) 
              #.(values (f))

              ;; which can be done only when f is a pure function
              ;; (without side effect)


              ;; Perhaps something like:
              #+(cl:progn
                  (cl:defparameter cl-user::*rt-values*
                           (cl:multiple-value-list (cl-user::f)))
                  (cl:if (cl:null cl-user::*rt-values*)
                       '(or) '(and)))
              #.(first *rt-values*)
              ;; when f has side-effects.


       nil when f returns 0 value
       the value when f returns 1 value

              #.(f)





(when the function returns two or more values, there's no ambiguity
apparently, since all the implementations I have read the same thing,
the first value:


[···@thalassa pjb]$ clall '(read-from-string "#.(values 1 2) 42")'

------------------------------------------------------------------------
CLISP 2.39 (2006-07-16) (built 3364813332) (memory 3364813914) 


(READ-FROM-STRING "#.(values 1 2) 42")
--> 1 ;
    14

------------------------------------------------------------------------
SBCL 0.9.12 


(READ-FROM-STRING "#.(values 1 2) 42")
--> 1 ;
    15

------------------------------------------------------------------------
CMU Common Lisp 19c (19C) 


(READ-FROM-STRING "#.(values 1 2) 42")
--> 1 ;
    15

------------------------------------------------------------------------
GNU Common Lisp (GCL) GCL 2.6.7 


(READ-FROM-STRING "#.(values 1 2) 42")
--> 1 ;
    14

------------------------------------------------------------------------
ECL 0.9g 


(READ-FROM-STRING "#.(values 1 2) 42")
--> 1 ;
    15

------------------------------------------------------------------------
International Allegro CL Free Express Edition 8.0 [Linux (x86)] (Jun 6, 2006 16:01) 


(READ-FROM-STRING "#.(values 1 2) 42")
--> 1 ;
    15

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

)


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

READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.
From: Barry Margolin
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <barmar-3BD878.15410027092006@comcast.dca.giganews.com>
In article <·······················@d34g2000cwd.googlegroups.com>,
 "Geoffrey Summerhayes" <·······@hotmail.com> wrote:

> Ron Garret wrote:
> > In article <························@m7g2000cwm.googlegroups.com>,
> >
> > I think you're conflating two different issues.  One is whether reader
> > macros in general can return zero values and thereby not contribute
> > anything to the data structure being read.  That they can do this is not
> > in dispute (otherwise #+ and #- would not work).
> >
> > What is in dispute is whether the #. reader macro specifically should
> > avail itself of this capability, i.e. whether the reader macro function
> > for #. should be (eval (read stream)) or (identity (eval (read
> > stream))).  That is a design issue for which reasonable arguments exist
> > on both sides IMHO.
> 
> IMO, adding another inconsistency when none is needed is just
> annoying: (values) works in all reader macros except #.(values)

What does this mean?  What other reader macros allow the end user to 
tell the macro how many values it should return?  #. is unique in this 
regard, so you can't reason by analogy.

What should #.(values 1 2 3) do?

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Geoffrey Summerhayes
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <1159389789.973472.22260@k70g2000cwa.googlegroups.com>
Barry Margolin wrote:
> In article <·······················@d34g2000cwd.googlegroups.com>,
>  "Geoffrey Summerhayes" <·······@hotmail.com> wrote:
>
> > Ron Garret wrote:
> > > In article <························@m7g2000cwm.googlegroups.com>,
> > >
> > > I think you're conflating two different issues.  One is whether reader
> > > macros in general can return zero values and thereby not contribute
> > > anything to the data structure being read.  That they can do this is not
> > > in dispute (otherwise #+ and #- would not work).
> > >
> > > What is in dispute is whether the #. reader macro specifically should
> > > avail itself of this capability, i.e. whether the reader macro function
> > > for #. should be (eval (read stream)) or (identity (eval (read
> > > stream))).  That is a design issue for which reasonable arguments exist
> > > on both sides IMHO.
> >
> > IMO, adding another inconsistency when none is needed is just
> > annoying: (values) works in all reader macros except #.(values)
>
> What does this mean?  What other reader macros allow the end user to
> tell the macro how many values it should return?  #. is unique in this
> regard, so you can't reason by analogy.

Well there's the argument that #+ and #- return zero or one values
depending on conditions that an end user can determine.

If you're not convinced that's a valid argument, what about #!, #?,
#[, #], #{, and #} ?

Should the end user be allowed to create his own read-time conditional
macro like #+? If so, why should #.(values) do the same thing as #.nil?

> What should #.(values 1 2 3) do?

I'd prefer 1 over 1 2 3 or an error. All implementations I tested
seem to agree in this case, thank goodness. De facto standard.

2.2 could really do with a rewrite to make both issues clearer, but
I feel Pascal's interpretation is closer to the original intent.

---
Geoff
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87d59hx70y.fsf@thalassa.informatimago.com>
Barry Margolin <······@alum.mit.edu> writes:
> What should #.(values 1 2 3) do?

There doesn't seem to be any ambiguity here, all implementations return 1:


[···@thalassa lisp]$ clall '(read-from-string "#.(values 1 2 3)")'

------------------------------------------------------------------------
CLISP 2.39 (2006-07-16) (built 3364813332) (memory 3364813914) 


(READ-FROM-STRING "#.(values 1 2 3)")
--> 1 ;
    16

------------------------------------------------------------------------
SBCL 0.9.12 


(READ-FROM-STRING "#.(values 1 2 3)")
--> 1 ;
    16

------------------------------------------------------------------------
CMU Common Lisp 19c (19C) 


(READ-FROM-STRING "#.(values 1 2 3)")
--> 1 ;
    16

------------------------------------------------------------------------
GNU Common Lisp (GCL) GCL 2.6.7 


(READ-FROM-STRING "#.(values 1 2 3)")
--> 1 ;
    16

------------------------------------------------------------------------
ECL 0.9g 


(READ-FROM-STRING "#.(values 1 2 3)")
--> 1 ;
    16

------------------------------------------------------------------------
International Allegro CL Free Express Edition 8.0 [Linux (x86)] (Jun 6, 2006 16:01) 


(READ-FROM-STRING "#.(values 1 2 3)")
--> 1 ;
    16

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

[···@thalassa lisp]$ 


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

CAUTION: The mass of this product contains the energy equivalent of
85 million tons of TNT per net ounce of weight.
From: Christophe Rhodes
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <sqslijbp7f.fsf@cam.ac.uk>
Ron Garret <·········@flownet.com> writes:

> In article <··············@thalassa.informatimago.com>,
>  Pascal Bourguignon <···@informatimago.com> wrote:
>
>> Still, I don't see any advantage of having implementations diverge on
>> this point.  It would be preferable if all implementation returned the
>> same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 42].
>
> Why?  (values) is equivalent to NIL is all other contexts (except those 
> specifically designed to accept multiple values).  Why should #. be any 
> different?

Because the reader is specified to treat read macros which return 0
values specially?  That would seem to be a good reason to suggest that
the read macro for #. to preserve the zero-value-ness, if any.

Christophe
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87slij1v8n.fsf@thalassa.informatimago.com>
Ron Garret <·········@flownet.com> writes:

> In article <··············@thalassa.informatimago.com>,
>  Pascal Bourguignon <···@informatimago.com> wrote:
>
>> Still, I don't see any advantage of having implementations diverge on
>> this point.  It would be preferable if all implementation returned the
>> same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 42].
>
> Why?  (values) is equivalent to NIL is all other contexts (except those 
> specifically designed to accept multiple values).  Why should #. be any 
> different?

To be consistent with #+ and #-, because it's called in a context
where it is already expected to get 0 or 1 values, and because to have
it return NIL you have to write more code.  

#. is specified to do that:

(defun reader-dispatch-macro-read-eval         (stream sub-char arg)
  (declare (ignore sub-char arg))
  (if *read-eval*
      (eval (read stream t nil t))
      (error 'reader-error :stream stream)))

The implementations who return NIL for it have to write more complex
code, like:

(defun reader-dispatch-macro-read-eval         (stream sub-char arg)
  (declare (ignore sub-char arg))
  (if *read-eval*
      (values (eval (read stream t nil t)))
      (error 'reader-error :stream stream)))


With a well behavied #., instead of writing:

   #+(cl:if (cl-user::some-condition-p) '(and) '(or)) something

we could write:

   #.(if (some-condition-p) 'something (values))


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

Nobody can fix the economy.  Nobody can be trusted with their finger
on the button.  Nobody's perfect.  VOTE FOR NOBODY.
From: Barry Margolin
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <barmar-B748B2.18575022092006@comcast.dca.giganews.com>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Ron Garret <·········@flownet.com> writes:
> 
> > In article <··············@thalassa.informatimago.com>,
> >  Pascal Bourguignon <···@informatimago.com> wrote:
> >
> >> Still, I don't see any advantage of having implementations diverge on
> >> this point.  It would be preferable if all implementation returned the
> >> same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 42].
> >
> > Why?  (values) is equivalent to NIL is all other contexts (except those 
> > specifically designed to accept multiple values).  Why should #. be any 
> > different?
> 
> To be consistent with #+ and #-, because it's called in a context
> where it is already expected to get 0 or 1 values, and because to have
> it return NIL you have to write more code.  
> 
> #. is specified to do that:
> 
> (defun reader-dispatch-macro-read-eval         (stream sub-char arg)
>   (declare (ignore sub-char arg))
>   (if *read-eval*
>       (eval (read stream t nil t))
>       (error 'reader-error :stream stream)))
> 
> The implementations who return NIL for it have to write more complex
> code, like:
> 
> (defun reader-dispatch-macro-read-eval         (stream sub-char arg)
>   (declare (ignore sub-char arg))
>   (if *read-eval*
>       (values (eval (read stream t nil t)))
>       (error 'reader-error :stream stream)))

The problem may be that you need this extra code to prevent it from 
returning more than 1 value in the following case:

(read-from-string "#.(values 1 2)")

The spec says that reader macros are only permitted to return 0 or 1 
values.

So to get it to return 0 values in the #.(values) case, but prevent 2+ 
values, you need even *more* code:

(defun read-dispatch-macro-read-eval (stream sub-char arg)
  (declare (ignore sub-char arg))
  (if *read-eval*
      (let ((values (values-list (eval (read stream t nil t)))))
        (if values
            (car values)
            (values)))
      (error 'reader-error :stream stream)))

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Pascal Bourguignon
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <87odt74ho0.fsf@thalassa.informatimago.com>
Barry Margolin <······@alum.mit.edu> writes:
> The problem may be that you need this extra code to prevent it from 
> returning more than 1 value in the following case:
>
> (read-from-string "#.(values 1 2)")
>
> The spec says that reader macros are only permitted to return 0 or 1 
> values.
>
> So to get it to return 0 values in the #.(values) case, but prevent 2+ 
> values, you need even *more* code:
>
> (defun read-dispatch-macro-read-eval (stream sub-char arg)
>   (declare (ignore sub-char arg))
>   (if *read-eval*
>       (let ((values (values-list (eval (read stream t nil t)))))
>         (if values
>             (car values)
>             (values)))
>       (error 'reader-error :stream stream)))

Well, usually the limits on the number of return values are enacted on
the receiving side.

(let ((values (multiple-value-list (funcall reader-macro))))
  (when (null values) (go :step-1))
  (return-from read (first values)))


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

This is a signature virus.  Add me to your signature and help me to live.
From: Barry Margolin
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <barmar-C507B5.19303422092006@comcast.dca.giganews.com>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <···@informatimago.com> wrote:

> Barry Margolin <······@alum.mit.edu> writes:
> > The problem may be that you need this extra code to prevent it from 
> > returning more than 1 value in the following case:
> >
> > (read-from-string "#.(values 1 2)")
> >
> > The spec says that reader macros are only permitted to return 0 or 1 
> > values.
> >
> > So to get it to return 0 values in the #.(values) case, but prevent 2+ 
> > values, you need even *more* code:
> >
> > (defun read-dispatch-macro-read-eval (stream sub-char arg)
> >   (declare (ignore sub-char arg))
> >   (if *read-eval*
> >       (let ((values (values-list (eval (read stream t nil t)))))
> >         (if values
> >             (car values)
> >             (values)))
> >       (error 'reader-error :stream stream)))
> 
> Well, usually the limits on the number of return values are enacted on
> the receiving side.
> 
> (let ((values (multiple-value-list (funcall reader-macro))))
>   (when (null values) (go :step-1))
>   (return-from read (first values)))

Probably, but the spec doesn't require this.  It says that read macros 
may return 0 or 1 values.  So it's an error for a reader macro to return 
more than 1 value, and there's no requirement for the implementation to 
handle this properly.

Of course, since the reader and the #. macro are both part of the 
implementation, they can take advantage of internal knowledge of each 
other.  If the reader is as you describe, #. can simply do (eval (read)).

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Alan Crowe
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <861wpx1lid.fsf@cawtech.freeserve.co.uk>
Ron Garret <·········@flownet.com> writes:

> In article <··············@thalassa.informatimago.com>,
>  Pascal Bourguignon <···@informatimago.com> wrote:
> 
> > Still, I don't see any advantage of having implementations diverge on
> > this point.  It would be preferable if all implementation returned the
> > same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 42].
> 
> Why?  (values) is equivalent to NIL is all other contexts (except those 
> specifically designed to accept multiple values).  Why should #. be any 
> different?
> 
> rg

These questions don't make sense. Superficially they appeal
to the notion that computer programming languages should be
uniform: similar constructs should do similar things,
similar operations should be expressed in similar ways.

Computer programming languages are artifacts and
tools. Their designers intend them to be useful. So the
notion of similarity appropriate to making a computer
programming language uniform is similarity of purpose. It
only makes sense to ask "Why should #. be any different from
contructs with a similar purpose?" If you don't say what you
think the purpose is, you aren't saying anything at all.

Well, what do I think is the purpose of 

    Upon encountering a macro character, the Lisp reader
    calls its reader macro function, which parses one
    specially formatted object from the input stream. The
    function either returns the parsed object, or else it
    returns no values to indicate that the characters
    scanned by the function are being ignored (e.g., in the
    case of a comment). Examples of macro characters are
    backquote, single-quote, left-parenthesis, and
    right-parenthesis.

I think the idea is to permit macro characters that
side-effect the read time environment (or not - but comments
are built in) but do not contribute anything to the
expression being read.

What is the purpose of #. ? It obviously includes

   For an object that does not have a convenient printed
   representation, a form that computes the object can be
   given using the #.  notation.

because that is explicit in the spec, but it has other uses
as well. It lets you run code at read time, just like a
macro character does. Since it has a similar purpose it
should work in a similar way. Given that macro characters
let you do this:

CL-USER> (set-macro-character #\! (lambda(stream char)
                                    (declare (ignore char))
                                    (write (read stream))))
                              
T

CL-USER> '(1 2 ! "Half Way!" 3 4)
"Half Way!"
(1 2 "Half Way!" 3 4)

CL-USER> (set-macro-character #\! (lambda(stream char)
                                    (declare (ignore char))
                                    (write (read stream))
                                    (values)))
                              
T

CL-USER> '(1 2 ! "Half Way!" 3 4)
"Half Way!"
(1 2 3 4)

Then the doctrine of uniformity dictates that #. should
behave in a similar way.

CL-USER> '(1 2 #.(write "Half way!") 3 4)
"Half way!"
(1 2 "Half way!" 3 4)

CL-USER> '(1 2 #.(progn (write "Half way!")
                        (values))
                        3 4)
"Half way!"
(1 2 3 4)

The doctrine of orthogonality dictates the same
point. Whether code that is run at read time contributes to
the data structure or not should be independent of how it
was invoked, whether read macro or #. 

Another way of thinking about it is to spot that #. is in a
sense the same kind of construct as eval-when. They are both
escape hatches, #. from the reader, eval-when from the file compiler.

#.(progn (this)(that)) 

is like 

(eval-when (:compile-toplevel :load-toplevel)
  (this)
  (that))

because it runs code and contributes to the data structure
being read/object file being written

while

#.(progn (this)(that)(values))

is like

(eval-when (:compile-toplevel)
  (this)
  (that))

because it runs code without adding anything to the data
structure being read/object file being written.

#.(values) doesn't put a nil in the data structure being
read, to be the same as (eval-when (:compile-toplevel))
which doesn't put irritating crud in the object file.

Alan Crowe
Edinburgh
Scotland
From: Ron Garret
Subject: Re: (read-from-string "#.(values) 42")
Date: 
Message-ID: <rNOSPAMon-CE3C2A.10165827092006@news.gha.chartermi.net>
In article <··············@cawtech.freeserve.co.uk>,
 Alan Crowe <····@cawtech.freeserve.co.uk> wrote:

> Ron Garret <·········@flownet.com> writes:
> 
> > In article <··············@thalassa.informatimago.com>,
> >  Pascal Bourguignon <···@informatimago.com> wrote:
> > 
> > > Still, I don't see any advantage of having implementations diverge on
> > > this point.  It would be preferable if all implementation returned the
> > > same for: (read-from-string "#.(values) 42") [and I'd prefer it to be 42].
> > 
> > Why?  (values) is equivalent to NIL is all other contexts (except those 
> > specifically designed to accept multiple values).  Why should #. be any 
> > different?
> > 
> > rg
> 
> These questions don't make sense.

[Much snippage]

I would have put it slightly differently and simply said that reader 
macros ARE a context specifically designed to accept multiple values.

But your point is well taken.

rg