From: Szymon
Subject: broken (?) MAP-INTO in CMUCL (2004-09).
Date: 
Message-ID: <87k6tmwovh.fsf@eva.rplacd.net>
Hi.

"
CMU Common Lisp Snapshot 2004-09, running on eva
With core: /home/ssb/site/cmucl/lib/cmucl/lib/lisp.core
Dumped on: Thu, 2004-09-02 02:26:06+02:00 on lorien
See <http://www.cons.org/cmucl/> for support information.
Loaded subsystems:
    Python 1.1, target Intel x86
    CLOS based on Gerd's PCL 2004/04/14 03:32:47

* (map-into (make-string 10) #'char-upcase '#0=(#\a #\b . #0#))"

<< looping forever >>

Regards, Szymon.

From: Tim Bradshaw
Subject: Re: broken (?) MAP-INTO in CMUCL (2004-09).
Date: 
Message-ID: <1098213409.651118.325510@f14g2000cwb.googlegroups.com>
Szymon wrote:
> Hi.
>
> "
> CMU Common Lisp Snapshot 2004-09, running on eva
> With core: /home/ssb/site/cmucl/lib/cmucl/lib/lisp.core
> Dumped on: Thu, 2004-09-02 02:26:06+02:00 on lorien
> See <http://www.cons.org/cmucl/> for support information.
> Loaded subsystems:
>     Python 1.1, target Intel x86
>     CLOS based on Gerd's PCL 2004/04/14 03:32:47
>
> * (map-into (make-string 10) #'char-upcase '#0=(#\a #\b . #0#))"
>
> << looping forever >>
>

I don't think that's a bug, although it's possibly annoying.  MAP-INTO
is probably allowed to take the length of all the sequences to find
the shortest one, and that is not going to terminate here.  On the
other hand it `should be prepared' to signal an error if one of its
sequence arguments isn't a proper sequence, and I think that a
circular list probably is not.  But that check is quite expensive to
do (as it's an occurs check).

Anyway, I'd never rely on this working, and would be hesitant to rely
on an error being signaled.

--tim
From: Szymon
Subject: Re: broken (?) MAP-INTO in CMUCL (2004-09).
Date: 
Message-ID: <87sm8a76m8.fsf@eva.rplacd.net>
"Tim Bradshaw" <··········@tfeb.org> writes:

> Szymon wrote:

> [.....]

> > * (map-into (make-string 10) #'char-upcase '#0=(#\a #\b . #0#))"
> >
> > << looping forever >>
> >
> 
> I don't think that's a bug, although it's possibly annoying.  MAP-INTO
> is probably allowed to take the length of all the sequences to find
> the shortest one, and that is not going to terminate here.  On the
> other hand it `should be prepared' to signal an error if one of its
> sequence arguments isn't a proper sequence, and I think that a
> circular list probably is not.  But that check is quite expensive to
> do (as it's an occurs check).
> 
> Anyway, I'd never rely on this working, and would be hesitant to rely
> on an error being signaled.

Ok. Fine answer, thank you.

Btw, in cmucl MAP(*) can handle circular (improper) lists. I think that
MAP-INTO should inherit this ability (because symmetry is GoodThing).

(*) (map 'string
         (lambda (a b) (declare (ignore b)) (char-upcase a))
         '#0=(#\a #\b . #0#)
         (make-list 10))

===> "ABABABABAB"


I just wrote _toy_ MAP-INTO implementation to 'point my thought' (about
'inheritance'):

;; =========================================================================
;; If MAP can handle circular things, then MAP-INTO can too. ===============
;; If MAP signals error, MAP-INTO do the same.
;; for example (in my CMUCL)
;; (my-map-into (make-string 10) #'char-upcase '#0=(#\a #\b . #0#))
;; ==> "ABABABABAB"
;; Because I'm still young lispnik (less than year of experience) ---
;; comments welcomed.
;; Time: 40 minutes :(
(macrolet ((m (symb) `(symbol-function
                        (car (nth-value 3 (get-setf-expansion '(,symb)))))))
  (let ((svref (m svref))
	(aref (m aref))
	(schar (m schar))
	(char (m char))
	(sbit (m sbit))
	(bit (m bit))
        (set-f (lambda ()))
	(next (lambda ())))
    (declare (function set-f next))
    (defun my-map-into (rseq f &rest seqs &aux i)
      (declare (function f) (optimize speed))
      (etypecase rseq
	(list (setq set-f #'rplaca next #'cdr i rseq))
	(vector (when (array-has-fill-pointer-p rseq)
		  (setf (fill-pointer rseq) (array-dimension rseq 0)))
		(setq set-f ((lambda (setter-func)
			       (lambda (a b) (funcall setter-func rseq a b)))
			     (etypecase rseq
			       (simple-vector svref)
			       (simple-string schar)
			       (simple-bit-vector sbit)
			       (string char)
			       (bit-vector bit)
			       (vector aref)))
		      next #'1+ i 0)))
;;
;; ====== m a i n  l o o p ======
;;
      (apply #'map nil
	     (lambda (&rest args)
	       (funcall set-f i (apply f (cdr args)))
	       (setq i (funcall next i)))
	     rseq seqs)
      rseq)))
;;
;; ================ E N D.


Btw, built-in MAP-INTO performs strangely:

CL-USER> (progn (funcall
                  (compile nil
		    (lambda (&aux (a (make-list 5000))
                                  (b (make-string 5000 :initial-element #\X)))
                      (time
                        (map-into a #'char-upcase b)))))
                nil)

;;; 151,814,967 CPU cycles

;;; 80,032 bytes consed.

;;; my-map-into

CL-USER> (progn (funcall
                  (compile nil
                           (lambda (&aux (a (make-list 5000))
                                         (b (make-string 5000 :initial-element #\X)))
			     (time
                               (my-map-into a #'char-upcase b)))))
                nil)

;;;   1,438,375 CPU cycles

;;; 80,072 bytes consed.

Regards, Szymon.
From: Tim Bradshaw
Subject: Re: broken (?) MAP-INTO in CMUCL (2004-09).
Date: 
Message-ID: <1098266057.033067.302450@f14g2000cwb.googlegroups.com>
Szymon wrote:
>
> Btw, in cmucl MAP(*) can handle circular (improper) lists. I think
that
> MAP-INTO should inherit this ability (because symmetry is GoodThing).
>
Yes, although I think it clearly `should not' work it seems to me that
the most plausible implementation probably would, because it would
just iterate over all the sequences until it hit the end of one, and
then stop (signaling an error if the one it hit the end of was
improper).  That means it would never even notice a circular list.
--tim
From: Raymond Toy
Subject: Re: broken (?) MAP-INTO in CMUCL (2004-09).
Date: 
Message-ID: <sxdvfd5v7zo.fsf@edgedsp4.rtp.ericsson.se>
>>>>> "Tim" == Tim Bradshaw <··········@tfeb.org> writes:

    Tim> Szymon wrote:
    >> Hi.
    >> 
    >> "
    >> CMU Common Lisp Snapshot 2004-09, running on eva
    >> With core: /home/ssb/site/cmucl/lib/cmucl/lib/lisp.core
    >> Dumped on: Thu, 2004-09-02 02:26:06+02:00 on lorien
    >> See <http://www.cons.org/cmucl/> for support information.
    >> Loaded subsystems:
    >> Python 1.1, target Intel x86
    >> CLOS based on Gerd's PCL 2004/04/14 03:32:47
    >> 
    >> * (map-into (make-string 10) #'char-upcase '#0=(#\a #\b . #0#))"
    >> 
    >> << looping forever >>
    >> 

    Tim> I don't think that's a bug, although it's possibly annoying.  MAP-INTO
    Tim> is probably allowed to take the length of all the sequences to find
    Tim> the shortest one, and that is not going to terminate here.  On the

Nice analysis!  That is exactly what map-into is doing.

Ray