From: Matthias Buelow
Subject: duplicates in lambda-list, let bindings, etc.
Date: 
Message-ID: <6dh5bnF2i3k1U1@mid.dfncis.de>
I stumbled across this interesting discrepancy between implementations:

CLisp:

(let ((x 1) (x 2))
  x)
==> 2

ECL:

(let ((x 1) (x 2))
  x)
==> 1

SBCL:

(let ((x 1) (x 1))
  x)
...
; caught ERROR:
;   The variable X occurs more than once in the lambda list.
...

It is similar but different for actual lambda lists:

CLisp+ECL:

(funcall (lambda (x x) x) 1 2)
==> 2

SBCL again brings the above error.

Is this unspecified by the standard? SBCL's behaviour seems to make most
sense to me, in terms of catching errors but maybe there's a reason why
there should not be an error.

From: Rainer Joswig
Subject: Re: duplicates in lambda-list, let bindings, etc.
Date: 
Message-ID: <joswig-025CAF.17411108072008@news-europe.giganews.com>
In article <··············@mid.dfncis.de>,
 Matthias Buelow <···@incubus.de> wrote:

> I stumbled across this interesting discrepancy between implementations:
> 
> CLisp:
> 
> (let ((x 1) (x 2))
>   x)
> ==> 2
> 
> ECL:
> 
> (let ((x 1) (x 2))
>   x)
> ==> 1
> 
> SBCL:
> 
> (let ((x 1) (x 1))
>   x)
> ...
> ; caught ERROR:
> ;   The variable X occurs more than once in the lambda list.
> ...
> 
> It is similar but different for actual lambda lists:
> 
> CLisp+ECL:
> 
> (funcall (lambda (x x) x) 1 2)
> ==> 2
> 
> SBCL again brings the above error.
> 
> Is this unspecified by the standard? SBCL's behaviour seems to make most
> sense to me, in terms of catching errors but maybe there's a reason why
> there should not be an error.

I can't find in the HyperSpec if duplicates are allowed or not.
But several implementations give warnings or errors for
duplicate parameters in lambda lists.

Genera:

Command: (defun test (a a) a)
Error: The variable A appears more than once in the lambda list.


LispWorks:

CL-USER 1 > (defun test (a a) a)
TEST

CL-USER 2 > (compile 'test)
;;;*** Warning in TEST: Variable name duplicated in lambda list or LET: A
;;;*** Warning in TEST: A is bound but not referenced
TEST


CL-USER 3 > (defun test (foo) (let ((foo foo) (foo foo)) foo))
TEST

CL-USER 4 > (compile 'test)
;;;*** Warning in TEST: Variable name duplicated in lambda list or LET: FOO
;;;*** Warning in TEST: FOO is bound but not referenced
TEST

-- 
http://lispm.dyndns.org/
From: Pascal J. Bourguignon
Subject: Re: duplicates in lambda-list, let bindings, etc.
Date: 
Message-ID: <7czloscoys.fsf@pbourguignon.anevia.com>
Matthias Buelow <···@incubus.de> writes:

> I stumbled across this interesting discrepancy between implementations:
>
> CLisp:
>
> (let ((x 1) (x 2))
>   x)
> ==> 2
>
> ECL:
>
> (let ((x 1) (x 2))
>   x)
> ==> 1
>
> SBCL:
>
> (let ((x 1) (x 1))
>   x)
> ...
> ; caught ERROR:
> ;   The variable X occurs more than once in the lambda list.
> ...
>
> It is similar but different for actual lambda lists:
>
> CLisp+ECL:
>
> (funcall (lambda (x x) x) 1 2)
> ==> 2
>
> SBCL again brings the above error.
>
> Is this unspecified by the standard? SBCL's behaviour seems to make most
> sense to me, in terms of catching errors but maybe there's a reason why
> there should not be an error.

ISTM that lambda and let cannot be compared here.

AFAIR, in the case of LAMBDA the behavior of clisp is what is specified.
Notably when there are initializers, they may refer the previous parameters:
((lambda (x &optional (y x)) ...) parameter-for-x)
<=> (let* ((x parameter-for-x) (y x)) ...)

In the case of LET, since the bindings are made in parallel, both
clisp and ecl are valid, but I don't see anything preventing sbcl to
raise an error. 


-- 
__Pascal Bourguignon__
From: Vassil Nikolov
Subject: Re: duplicates in lambda-list, let bindings, etc.
Date: 
Message-ID: <snz1w23ncct.fsf@luna.vassil.nikolov.name>
On Tue, 08 Jul 2008 14:37:10 +0200, Matthias Buelow <···@incubus.de> said:

| [what is supposed to happen with]
| (let ((x 1) (x 2))
|   x)
| [and]
| ((lambda (x x) x) 1 2)

  CLHS 3.1.1, Introduction to Environments, says that there can be at
  most one binding per name per namespace per environment [*], so the
  above are not allowed (it is another matter that not all
  implementations signal an error, which is not, after all,
  specifically required).

  3.1.3, Lambda Expressions, establishes that there is a single
  environment for a lambda expression.  I don't think there is an
  equally explicit specification that LET establishes a single
  environment, but I believe it is quite reasonable to presume that if
  that hadn't been the case, there would have been an explicit
  specification to the contrary.  (And (LET ((var value) ...) . body)
  is practically the same as ((LAMBDA (var ...) . body) value ...).)

  By the way, this is a non-issue with lambda terms, at least with the
  usual syntax rules, where {\lambda}xy.T is nothing but
  {\lambda}x.{\lambda}y.T and thus obviously there is nothing special
  about {\lambda}xx.T.

  _________
  [*] Very pedantically speaking, is ((lambda (x x) x) 'a 'a) legal?

  ---Vassil.


-- 
Peius melius est.  ---Ricardus Gabriel.