Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed non-destructive list-insert for 0th position to a desctructiv… #369

Open
wants to merge 2 commits into
base: cl-compatible
Choose a base branch
from

Conversation

Hunter11zolomon
Copy link

Changed non-destructive list-insert for 0th position to a destructive one

Copy link
Member

@Affonso-Gui Affonso-Gui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution.

However, there are some problems that should be fixed before merging:

  1. You modify a total of 5 files, but we only have interest in common.l. Please remove the other 4 files from this PR (eusmap, include, Makefile and common.l~)
  2. It would also be nice to have destructive effect for null lists (not only for zero pos).
  3. nreverse is allowed to have arbitrary side effects. From CLHS:
 (setq l (list 1 2 3)) =>  (1 2 3)
 (nreverse l) =>  (3 2 1)
 l =>  implementation-dependent

In eus it appears to be granted to have the list match the result, but code should not depend on this.

EusLisp/lisp/c/sequence.c

Lines 249 to 301 in 9cfd655

pointer NREVERSE(ctx,n,argv)
register context *ctx;
int n;
pointer argv[];
{ register pointer a=argv[0],r=NIL, *vp;
register eusinteger_t i,k,s,kk,x,y;
register byte *cp;
ckarg(1);
if (a==NIL) return(NIL);
else if (islist(a)) {
i=0; r=a;
while (islist(r)) { ckpush(ccar(r)); r=ccdr(r); i++;}
r=a;
while (i>0) { pointer_update(ccar(r),vpop()); r=ccdr(r); i--;}
return(a);}
else if (isarray(a)) {
if (a->c.ary.rank>makeint(1)) error(E_NOSEQ);
s=intval(a->c.ary.offset);
k=intval(a->c.ary.dim[0]);
a=a->c.ary.entity;}
else if (isvector(a)) { k=vecsize(a); s=0;}
else error(E_NOSEQ);
kk=k/2; vp=a->c.vec.v;
cp=a->c.str.chars;
switch(elmtypeof(a)) {
case ELM_BIT:
for(i=0; i<kk; i++, s++) {
x=bitref(a,s);
y=bitref(a,k-i-1);
#if (WORD_SIZE == 64)
if (y) a->c.ivec.iv[s/64] |= (1L<<(s%64));
else a->c.ivec.iv[s/64] &= ~(1L<<(s%64));
if (x) a->c.ivec.iv[(k-i-1)/64] |= (1L<<((k-i-1)%64));
else a->c.ivec.iv[(k-i-1)/64] &= ~(1L<<((k-i-1)%64));
#else
if (y) a->c.ivec.iv[s/32] |= (1<<(s%32));
else a->c.ivec.iv[s/32] &= ~(1<<(s%32));
if (x) a->c.ivec.iv[(k-i-1)/32] |= (1<<((k-i-1)%32));
else a->c.ivec.iv[(k-i-1)/32] &= ~(1<<((k-i-1)%32));
#endif
}
break;
case ELM_FOREIGN: cp=a->c.foreign.chars;
case ELM_CHAR: case ELM_BYTE:
for(i=0; i<kk; i++, s++) {
x=cp[s]; cp[s]=cp[k-i-1]; cp[k-i-1]=x;}
break;
default:
vp=a->c.vec.v;
for(i=0; i<kk; i++, s++) {
r=vp[s]; pointer_update(vp[s],vp[k-i-1]); vp[k-i-1]=r;}
break; }
return(a);}

@Hunter11zolomon
Copy link
Author

Ok, Thanks

I will look into the changes. And can you please elaborate on the side effects of nreverse?

@Affonso-Gui
Copy link
Member

For nreverse, sequence might be destroyed and re-used to produce the result. 
The result might or might not be identical to sequence. 

In other words, the input may be destroyed as a way of optimizing the algorithm, having no guarantee that the result will correctly be stored in the input back again. In the case of sbcl, for example:

CL-USER> (setq lst (list 1 2 3))
(1 2 3)
CL-USER> (nreverse lst)
(3 2 1)
CL-USER> lst
(1)

@Hunter11zolomon
Copy link
Author

I will try to find a work around.
Thanks for the input

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants