From: scameung
Subject: Is concatenate implementation dependent?
Date: 
Message-ID: <1143250014.615622.298360@j33g2000cwa.googlegroups.com>
Hi

It seems to me that concatenate is implementation dependent.
Consider the following code

(concatenate (type-of (list 'a)) nil nil)

which is ok in CMUCL, but invokes an error in LispWorks 4.4 Personal
Edition.

Is concatenate implementation dependent?

From: Pascal Bourguignon
Subject: Re: Is concatenate implementation dependent?
Date: 
Message-ID: <878xqzl2dz.fsf@thalassa.informatimago.com>
"scameung" <·······@gmail.com> writes:
> It seems to me that concatenate is implementation dependent.
> Consider the following code
>
> (concatenate (type-of (list 'a)) nil nil)
>
> which is ok in CMUCL, but invokes an error in LispWorks 4.4 Personal
> Edition.
>
> Is concatenate implementation dependent?

CONCATENATE is perfectly implementation dependant.
TYPE-OF is not exactly.

(list 'a) == (cons 'a nil)

CONS is  subtype of LIST: (subtypep 'cons 'list) --> T


So LispWorks is perfectly right in returning CONS, as a more specific
type for (list 'a) than LIST.  


Try:

(concatenate (cond ((subtypep (type-of (list 'a)) 'list)   'list)
                   ((subtypep (type-of (list 'a)) 'string) 'string)
                   ((subtypep (type-of (list 'a)) 'vector) 'vector)
                   (t (error "What other kind of sequence is ~S a subtype of?"
                             (type-of (list 'a)))))  nil nil)



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Wanna go outside.
Oh, no! Help! I got outside!
Let me back inside!
From: Pascal Bourguignon
Subject: Re: Is concatenate implementation dependent?
Date: 
Message-ID: <873bh7l24a.fsf@thalassa.informatimago.com>
"scameung" <·······@gmail.com> writes:
> It seems to me that concatenate is implementation dependent.
> Consider the following code
>
> (concatenate (type-of (list 'a)) nil nil)
>
> which is ok in CMUCL, but invokes an error in LispWorks 4.4 Personal
> Edition.
>
> Is concatenate implementation dependent?

CONCATENATE is perfectly implementation dependant.
TYPE-OF is not exactly.

(list 'a) == (cons 'a nil)

CONS is  subtype of LIST: (subtypep 'cons 'list) --> T


So LispWorks is perfectly right in returning CONS, as a more specific
type for (list 'a) than LIST.  

Then, since NIL is not a CONS, it cannot be concatenated into a CONS
kind of sequence...

Try:

(concatenate (type-of (list 'a)) '(a) '(b) '(c)) 
  ;; all arguments are of same type: CONS

or :

(concatenate (cond ; promote the result-type to some wider type 
                   ; including the type of sequence of the arguments.
                   ((subtypep (type-of (list 'a)) 'list)   'list)
                   ((subtypep (type-of (list 'a)) 'string) 'string)
                   ((subtypep (type-of (list 'a)) 'vector) 'vector)
                   (t (error "What other kind of sequence is ~S a subtype of?"
                             (type-of (list 'a)))))  
             nil nil)

-- 
__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: Ivan Boldyrev
Subject: Re: Is concatenate implementation dependent?
Date: 
Message-ID: <datif3-5df.ln1@ibhome.cgitftp.uiggm.nsc.ru>
On 9424 day of my life Pascal Bourguignon wrote:
>> (concatenate (type-of (list 'a)) nil nil)
>>
>> which is ok in CMUCL, but invokes an error in LispWorks 4.4 Personal
>> Edition.

> CONS is  subtype of LIST: (subtypep 'cons 'list) --> T
>
> So LispWorks is perfectly right in returning CONS, as a more specific
> type for (list 'a) than LIST.  

CMUCL returns CONS too.  It just considers that
(concatenate 'cons nil nil) is valid.  I don't know if it a bug or not.

-- 
Ivan Boldyrev

                       Perl is a language where 2 x 2 is not equal to 4.
From: Pascal Bourguignon
Subject: Re: Is concatenate implementation dependent?
Date: 
Message-ID: <87k6agkhn0.fsf@thalassa.informatimago.com>
Ivan Boldyrev <···············@cgitftp.uiggm.nsc.ru> writes:

> On 9424 day of my life Pascal Bourguignon wrote:
>>> (concatenate (type-of (list 'a)) nil nil)
>>>
>> CONCATENATE is perfectly implementation dependant.
>> TYPE-OF is not exactly.

I meant: *in*dependant,
    CONCATENATE is perfectly implementation independant.

>>> which is ok in CMUCL, but invokes an error in LispWorks 4.4 Personal
>>> Edition.
>>
>> CONS is  subtype of LIST: (subtypep 'cons 'list) --> T
>>
>> So LispWorks is perfectly right in returning CONS, as a more specific
>> type for (list 'a) than LIST.  
>>
>> [...]
>> Then, since NIL is not a CONS, it cannot be concatenated into a CONS
>> kind of sequence...

Here I was wrong, see below.

> CMUCL returns CONS too.  It just considers that
> (concatenate 'cons nil nil) is valid.  I don't know if it a bug or not.

CONS is a subtype of LIST (OR CONS NULL) which is a substype of SEQUENCE.
So we can give CONS as result-type to CONCATENATE.

The result of CONCATENATE must be a sequence of type result-type, as
is specified by the first paragraph of the description, but the second
sentence of the third paragraph says:

     If the result-type is a subtype of list, the result will be
     a list.

Therefore, CMUCL is correct in returning the symbol NIL when given
CONS as result-type with empty sequences.  The other implementations
should do the same.

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

Pour moi, la grande question n'a jamais �t�: �Qui suis-je? O� vais-je?� 
comme l'a formul� si adroitement notre ami Pascal, mais plut�t: 
�Comment vais-je m'en tirer?� -- Jean Yanne
From: Christophe Rhodes
Subject: Re: Is concatenate implementation dependent?
Date: 
Message-ID: <sqhd5k75ep.fsf@cam.ac.uk>
Pascal Bourguignon <······@informatimago.com> writes:

> Ivan Boldyrev <···············@cgitftp.uiggm.nsc.ru> writes:
>
>> CMUCL returns CONS too.  It just considers that
>> (concatenate 'cons nil nil) is valid.  I don't know if it a bug or not.
>
> CONS is a subtype of LIST (OR CONS NULL) which is a substype of SEQUENCE.
> So we can give CONS as result-type to CONCATENATE.

Yes.

> The result of CONCATENATE must be a sequence of type result-type, as
> is specified by the first paragraph of the description, but the second
> sentence of the third paragraph says:
>
>      If the result-type is a subtype of list, the result will be
>      a list.
>
> Therefore, CMUCL is correct in returning the symbol NIL when given
> CONS as result-type with empty sequences.  The other implementations
> should do the same.

No, or at least not if we are executing safe code.  CLHS says:

  An error of type type-error should be signaled if result-type
  specifies the number of elements and the sum of sequences is
  different from that number.

The result-type specifier CONS does specify the number of elements in
the result: it must be at least one.  Therefore, in safe code, a type
error for (concatenate 'cons nil nil) must be signalled.

Christophe
From: Pascal Bourguignon
Subject: Re: Is concatenate implementation dependent?
Date: 
Message-ID: <87u09jhows.fsf@thalassa.informatimago.com>
Christophe Rhodes <·····@cam.ac.uk> writes:
>> The result of CONCATENATE must be a sequence of type result-type, as
>> is specified by the first paragraph of the description, but the second
>> sentence of the third paragraph says:
>>
>>      If the result-type is a subtype of list, the result will be
>>      a list.
>>
>> Therefore, CMUCL is correct in returning the symbol NIL when given
>> CONS as result-type with empty sequences.  The other implementations
>> should do the same.
>
> No, or at least not if we are executing safe code.  CLHS says:
>
>   An error of type type-error should be signaled if result-type
>   specifies the number of elements and the sum of sequences is
>   different from that number.
>
> The result-type specifier CONS does specify the number of elements in
> the result: it must be at least one.  Therefore, in safe code, a type
> error for (concatenate 'cons nil nil) must be signalled.

This is the very question, which of the two clauses is prioritary?

If you are right, then the sentence of the third paragraph is useless,
and it wouldn't have been included.  

When we give a subtype of LIST as first argument to CONCATENATE, the
result-type is not that argument, but LIST.  A null number of element
is compatible with LIST, therefore CMUCL is correct.  Even in safe code.

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

In a World without Walls and Fences, 
who needs Windows and Gates?
From: Christophe Rhodes
Subject: Re: Is concatenate implementation dependent?
Date: 
Message-ID: <sq7j6fx4ch.fsf@cam.ac.uk>
Pascal Bourguignon <······@informatimago.com> writes:

> When we give a subtype of LIST as first argument to CONCATENATE, the
> result-type is not that argument, but LIST.  A null number of element
> is compatible with LIST, therefore CMUCL is correct.  Even in safe code.

I don't think so.  (CMUCL might be correct in safe code, in that we
haven't tested the code in an unambiguously safe context, but...) when
there is a length mismatch between the type and the sequence that
would be constructed, then there is no result.  This is not in
contradiction with the constraints on the result, just as the
(non-normative) example given:
  (concatenate '(vector * 2) "a" "bc") should signal an error
is not in contradiction with the constraints on the result.

Christophe