From: Ludix
Subject: "Correct" COND behavior?
Date: 
Message-ID: <7b5786fe1270938a6b7d760c8713fa8c@news.teranews.com>
I'm developing a Lisp interpreter, and have a question
about the "correct" behavior of COND.

While debugging my COND implementation, I
accidentally typed:

(COND (+ x 1))

My interpreter responded with 1 (the number one).

Corman Lisp responds the same way, but LispWorks
Personal Edition complains that "the symbol X is unbound."

What should Lisp do when it encounters this situation?

Thanks in advance!

- BM

From: Ari Johnson
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <7fllc.55003$Jy3.29801@fed1read03>
Note that COND is a macro, while IF is a special operator (according to 
the CLHS), and COND is typically implemented recursively, using IF.

Here's an implementation I just threw together to make sure I know what 
I'm talking about. ;)

(defmacro cond (&optional head &rest tail)
   (if head
     `(if ,(car head) (progn ,@(cdr head)) (cond ,@tail))
     nil))

Ari
From: Johan Kullstam
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <87d65ly3sc.fsf@sysengr.res.ray.com>
Ari Johnson <·····@hotmail.com> writes:

> Note that COND is a macro, while IF is a special operator (according
> to the CLHS), and COND is typically implemented recursively, using
> IF.

What is the distinction between special operator and macro that you
wish to make here?  Is there some practical upshot to this
difference?  Both macros and special forms can control the evaluation
of their arguments.

I see this in the hyperspec about COND as macro and IF as special
operator, but I have also seen in the newsgroup people refering to
some implementation wiggle room on implementating things as macro or
special form.  Could a Lisp be conforming and have COND the special
form and IF as a macro?

> Here's an implementation I just threw together to make sure I know
> what I'm talking about. ;)
> 
> (defmacro cond (&optional head &rest tail)
>    (if head
>      `(if ,(car head) (progn ,@(cdr head)) (cond ,@tail))
>      nil))
> 
> Ari

-- 
Johan KULLSTAM <··········@comcast.net> sysengr
From: Ari Johnson
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <wttlc.57608$Jy3.22629@fed1read03>
Johan Kullstam wrote:
> Ari Johnson <·····@hotmail.com> writes:
> 
> 
>>Note that COND is a macro, while IF is a special operator (according
>>to the CLHS), and COND is typically implemented recursively, using
>>IF.
> 
> 
> What is the distinction between special operator and macro that you
> wish to make here?  Is there some practical upshot to this
> difference?  Both macros and special forms can control the evaluation
> of their arguments.
> 
> I see this in the hyperspec about COND as macro and IF as special
> operator, but I have also seen in the newsgroup people refering to
> some implementation wiggle room on implementating things as macro or
> special form.  Could a Lisp be conforming and have COND the special
> form and IF as a macro?

I believe so, and I think some do.  The key, as I see it, is that you 
must be able to implement all of your macros in terms of your special 
operators.  Try (macroexpand-1 '(if t 1 2)) on a few Lisps until you 
find one that returns a COND form.

The upshot to using as few special operators and as many macros as 
possible is that the macros are written in the same Lisp you are writing 
the interpreter for, whereas the special operators probably are not.
From: Matthew Danish
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <20040503153020.GD25328@mapcar.org>
On Mon, May 03, 2004 at 10:38:11AM -0400, Johan Kullstam wrote:
> I see this in the hyperspec about COND as macro and IF as special
> operator, but I have also seen in the newsgroup people refering to
> some implementation wiggle room on implementating things as macro or
> special form.  Could a Lisp be conforming and have COND the special
> form and IF as a macro?

``An implementation is free to implement a Common Lisp special operator
as a macro. An implementation is free to implement any macro operator as
a special operator, but only if an equivalent definition of the macro is
also provided.'' -- CLHS 3.1.2.1.2.2

The reason for this is to support code-walkers, which can count on the
expansion of macros and a limited set of special operators to handle
otherwise.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Matthew Danish
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <20040503030650.GB25328@mapcar.org>
On Mon, May 03, 2004 at 02:50:46AM +0000, Ludix wrote:
> I'm developing a Lisp interpreter, and have a question
> about the "correct" behavior of COND.
> 
> While debugging my COND implementation, I
> accidentally typed:
> 
> (COND (+ x 1))
> 
> My interpreter responded with 1 (the number one).
> 
> Corman Lisp responds the same way, but LispWorks
> Personal Edition complains that "the symbol X is unbound."
> 
> What should Lisp do when it encounters this situation?
> 
> Thanks in advance!

Consider this: at the top-level, the variable named "+" is probably
bound to some form (the previous one entered), and so that branch of the
COND succeeds unless the form is ().  What happens next is that the
value of the variable named "X" is looked up and discarded, and then the
value of "1" is returned.  If X is unbound, I think this should signal
an error, however Corman (and your implementation) may be optimizing
this out since it has no effect otherwise.

A Lisp should of course attempt to evaluate the condition-form, and if
it evaluates to a true value then should evaluate the following forms as
if enclosed in a PROGN form.  Unbound variables should result in errors
at run-time, and perhaps warnings at compile-time, since if it is not a
lexical variable then it must be declared special somewhere for it to be
valid.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Rahul Jain
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <87oep6cd7r.fsf@nyct.net>
Matthew Danish <·······@andrew.cmu.edu> writes:

> A Lisp should of course attempt to evaluate the condition-form, and if
> it evaluates to a true value then should evaluate the following forms as
> if enclosed in a PROGN form.  Unbound variables should result in errors
> at run-time, and perhaps warnings at compile-time, since if it is not a
> lexical variable then it must be declared special somewhere for it to be
> valid.

The CLHS is quite clear about indicating that portable code should not
rely on the signalling of errors. Optimizations like this one seem
reasonable to me (elision of a side-effect-free form whose result is
discarded). Exceptional situations should not be expected/required. :)

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Paul Dietz
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <409655BA.73CE11D0@motorola.com>
Rahul Jain wrote:

> The CLHS is quite clear about indicating that portable code should not
> rely on the signalling of errors.

There are many situations ('error should be signaled', 'should be prepared
to signal an error') where portable code can count on errors being
signaled in safe code (that is, where the optimize setting SAFETY is 3.)

See CLHS, section 1.4.2.

	Paul
From: Christophe Rhodes
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <sqn04pyjnu.fsf@lambda.dyndns.org>
Rahul Jain <·····@nyct.net> writes:

> The CLHS is quite clear about indicating that portable code should not
> rely on the signalling of errors. 

What?  Where does it say that?

Christophe
-- 
http://www-jcsu.jesus.cam.ac.uk/~csr21/       +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b "~&Just another Lisp hacker~%")    (pprint #36rJesusCollegeCambridge)
From: Tim Bradshaw
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <fbc0f5d1.0405030648.77c9f904@posting.google.com>
Christophe Rhodes <·····@cam.ac.uk> wrote in message news:<··············@lambda.dyndns.org>...
> Rahul Jain <·····@nyct.net> writes:
> 
> > The CLHS is quite clear about indicating that portable code should not
> > rely on the signalling of errors. 
> 
> What?  Where does it say that?

I don't think it does.  I think it has some fairly careful definitions
of where exceptions need to be signaled &c, and where they don't.  I
also don't think that this case is anything to do with that, it's to
do with whether side-effect-free forms can be optimised-away at
compile time, even though at run-time they might cause errors or fail
to terminate.
From: Paul Dietz
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <40966242.5A6CA002@motorola.com>
Tim Bradshaw wrote:

> I don't think it does.  I think it has some fairly careful definitions
> of where exceptions need to be signaled &c, and where they don't.  I
> also don't think that this case is anything to do with that, it's to
> do with whether side-effect-free forms can be optimised-away at
> compile time, even though at run-time they might cause errors or fail
> to terminate.

Causing an error is a side effect, and in this case it's required
in safe code.

Section 3.1.2.1.1, paragraph 4:

 An error of type unbound-variable should be signaled if an unbound
 variable is referenced.

	Paul
From: Christophe Rhodes
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <sqy8o9wla3.fsf@lambda.dyndns.org>
··········@tfeb.org (Tim Bradshaw) writes:

> Christophe Rhodes <·····@cam.ac.uk> wrote in message news:<··············@lambda.dyndns.org>...
>> Rahul Jain <·····@nyct.net> writes:
>> 
>> > The CLHS is quite clear about indicating that portable code should not
>> > rely on the signalling of errors. 
>> 
>> What?  Where does it say that?
>
> I don't think it does.  I think it has some fairly careful definitions
> of where exceptions need to be signaled &c, and where they don't.  I
> also don't think that this case is anything to do with that, it's to
> do with whether side-effect-free forms can be optimised-away at
> compile time, even though at run-time they might cause errors or fail
> to terminate.

Failing to terminate is arguably not a side-effect, but I'd like to
hear your reasoning behind the suggestion that signalling an error
isn't one.

Christophe
-- 
http://www-jcsu.jesus.cam.ac.uk/~csr21/       +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b "~&Just another Lisp hacker~%")    (pprint #36rJesusCollegeCambridge)
From: Tim Bradshaw
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <ey3y8o9l3em.fsf@cley.com>
* Christophe Rhodes wrote:

> Failing to terminate is arguably not a side-effect, but I'd like to
> hear your reasoning behind the suggestion that signalling an error
> isn't one.

I think it is.  In fact I almost put in a comment that it was and so
it wasn't legitimate for a compiler to optimise the code away. I think
in *this* case - where the compiler could trivially tell that it was
optimising away something that would signal an error in safe code -
then (with suitable safety settings) it shouldn't do that (and with
unsafe settings it should probably signal a warning if it does do
it).

I think the problem with this kind of argument is that you have to be
careful not to take it too literally.  What about a compiler that can
(say) optimise tail-calls.  Such an optimisation might transform code
which would cause an error (stack overflow) to code that won't. Is
that legal?  I hope so!

--tim
From: Paul Dietz
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <4096AD29.80368758@motorola.com>
Tim Bradshaw wrote:

> I think the problem with this kind of argument is that you have to be
> careful not to take it too literally.  What about a compiler that can
> (say) optimise tail-calls.  Such an optimisation might transform code
> which would cause an error (stack overflow) to code that won't. Is
> that legal?  I hope so!

Sure -- because the standard does not require that stack overflows
cause the signalling of errors.

	Paul
From: Tim Bradshaw
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <ey3pt9l3zmw.fsf@cley.com>
* Paul Dietz wrote:

> Sure -- because the standard does not require that stack overflows
> cause the signalling of errors.

Ok, well think of a case where some transformation *could* prevent
errors being signaled, but where it's not something that's trivially
clear to the compiler (or even clear at all).

--tim
From: Rahul Jain
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <87llk1dq9n.fsf@nyct.net>
Christophe Rhodes <·····@cam.ac.uk> writes:

> Rahul Jain <·····@nyct.net> writes:
>
>> The CLHS is quite clear about indicating that portable code should not
>> rely on the signalling of errors. 
>
> What?  Where does it say that?

I can't find it quickly, but I could have sworn there was some entry in
the hyperspec that talked about forms like (progn (error ...) 
(end-of-the-world)). :\

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Joe Marshall
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <wu3tvkxm.fsf@comcast.net>
Rahul Jain <·····@nyct.net> writes:

[excerpted and paraphrased]
> Optimizations like elision of a side-effect-free form whose result
> is discarded seem reasonable to me.

I agree, but it is a matter of contention.  What about this case:

(defun foo ()
   (do ((i n (1- i)))
       ((zerop i) nil))
   42)

If N starts out as a negative number, the do loop would never finish,
so 42 would never be returned.  If N is positive, it could take an
arbitrary amount of time until N reaches zero.

On the other hand, the code is `observationally equivalent' to

(defun foo ()
   42)

because it is impossible to write a program that can tell the
difference between the two.  (By `tell the difference' I mean
conditionally test the return value.)

-- 
~jrm
From: Roger Corman
Subject: Re: "Correct" COND behavior?
Date: 
Message-ID: <3f58baac.0405132237.75c4ca95@posting.google.com>
Corman Lisp expands that expression to:
(IF + (PROGN X 1) NIL)
which will signal an error if x is not bound. I assume when you tried it x
was bound for some reason.

Roger Corman
-----
"Ludix" <····@ludix.com> wrote in message news:<································@news.teranews.com>...
> I'm developing a Lisp interpreter, and have a question
> about the "correct" behavior of COND.
> 
> While debugging my COND implementation, I
> accidentally typed:
> 
> (COND (+ x 1))
> 
> My interpreter responded with 1 (the number one).
> 
> Corman Lisp responds the same way, but LispWorks
> Personal Edition complains that "the symbol X is unbound."
> 
> What should Lisp do when it encounters this situation?
> 
> Thanks in advance!
> 
> - BM