[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

Re: sequence iteration

William James

4/3/2015 3:23:00 AM

Pascal Bourguignon wrote:

> > I wonder why they didn't allow the loop macro to genericaly iterate over a
> > sequence.
>
> Because there's no efficient generic iteration operator.
>
> You can use ELT, but it's O(N) on lists, for each access, therefore
> O(Nn++) for the loop.
>
>
> > Can't be much more of a syntactic mess than it is right now anyways =P
>
> This is not a syntax problem. You get the sequence at run time, so
> you have to choose between CDR or AREF at run time.
>
> You can do your own GLOOP (or checkout ITERATE or some similar package)
> which would map:
>
> (gloop for item inside sequence do (stuff item))
>
> to:
>
> (if (listp sequence)
> (loop for item in seqeunce do (stuff item))
> (loop for item on seqeunce do (stuff item)))
>
>
> Or you can write:
>
> (loop with iterator = (iterator container)
> for item = (iterator-next iterator)
> while item
> do (stuff item))
>
>
> (defun iterator-next (iterator) (funcall iterator))
>
> (defmethod iterator ((self null))
> (lambda () (values nil t)))
>
> (defmethod iterator ((self cons))
> (lambda () (let ((done (not self))) (values (pop self) done))))
>
> (defmethod iterator ((self vector))
> (let ((i 0))
> (lambda ()
> (if (< i (length self))
> (multiple-values-prog1 (values (aref self i) nil) (incf i))
> (values nil t)))))
>
> ;; and you can add a method of any kind of container...


When using Scheme's SRFI-42, it is optional to specify
the type of container.

Gauche Scheme:

(use srfi-42) ; do-ec

(define big-size 999888)

(for-each
(lambda (xs) (print "\nTiming without and with a specified type.")
(time (do-ec (: x xs) (identity x)))
(cond ((list? xs) (time (do-ec (:list x xs) (identity x))))
((vector? xs) (time (do-ec (:vector x xs) (identity x))))
(else (time (do-ec (:string x xs) (identity x))))))
(list
(make-list big-size 2)
(make-vector big-size 2)
(make-string big-size #\2)))


Timing without and with a specified type.
;(time (do-ec (: x xs) (identity x)))
; real 0.156
; user 0.156
; sys 0.000
;(time (do-ec (:list x xs) (identity x)))
; real 0.062
; user 0.063
; sys 0.000

Timing without and with a specified type.
;(time (do-ec (: x xs) (identity x)))
; real 0.156
; user 0.140
; sys 0.000
;(time (do-ec (:vector x xs) (identity x)))
; real 0.078
; user 0.094
; sys 0.000

Timing without and with a specified type.
;(time (do-ec (: x xs) (identity x)))
; real 0.219
; user 0.250
; sys 0.000
;(time (do-ec (:string x xs) (identity x)))
; real 0.125
; user 0.125
; sys 0.000
1 Answer

William James

4/5/2015 4:04:00 AM

0

WJ wrote:

> Pascal Bourguignon wrote:
>
> > > I wonder why they didn't allow the loop macro to genericaly iterate over a
> > > sequence.
> >
> > Because there's no efficient generic iteration operator.
> >
> > You can use ELT, but it's O(N) on lists, for each access, therefore
> > O(Nn++) for the loop.
> >
> >
> > > Can't be much more of a syntactic mess than it is right now anyways =P
> >
> > This is not a syntax problem. You get the sequence at run time, so
> > you have to choose between CDR or AREF at run time.
> >
> > You can do your own GLOOP (or checkout ITERATE or some similar package)
> > which would map:
> >
> > (gloop for item inside sequence do (stuff item))
> >
> > to:
> >
> > (if (listp sequence)
> > (loop for item in seqeunce do (stuff item))
> > (loop for item on seqeunce do (stuff item)))
> >
> >
> > Or you can write:
> >
> > (loop with iterator = (iterator container)
> > for item = (iterator-next iterator)
> > while item
> > do (stuff item))
> >
> >
> > (defun iterator-next (iterator) (funcall iterator))
> >
> > (defmethod iterator ((self null))
> > (lambda () (values nil t)))
> >
> > (defmethod iterator ((self cons))
> > (lambda () (let ((done (not self))) (values (pop self) done))))
> >
> > (defmethod iterator ((self vector))
> > (let ((i 0))
> > (lambda ()
> > (if (< i (length self))
> > (multiple-values-prog1 (values (aref self i) nil) (incf i))
> > (values nil t)))))
> >
> > ;; and you can add a method of any kind of container...
>
>
> When using Scheme's SRFI-42, it is optional to specify
> the type of container.
>
> Gauche Scheme:
>
> (use srfi-42) ; do-ec
>
> (define big-size 999888)
>
> (for-each
> (lambda (xs) (print "\nTiming without and with a specified type.")
> (time (do-ec (: x xs) (identity x)))
> (cond ((list? xs) (time (do-ec (:list x xs) (identity x))))
> ((vector? xs) (time (do-ec (:vector x xs) (identity x))))
> (else (time (do-ec (:string x xs) (identity x))))))
> (list
> (make-list big-size 2)
> (make-vector big-size 2)
> (make-string big-size #\2)))
>
>
> Timing without and with a specified type.
> ;(time (do-ec (: x xs) (identity x)))
> ; real 0.156
> ; user 0.156
> ; sys 0.000
> ;(time (do-ec (:list x xs) (identity x)))
> ; real 0.062
> ; user 0.063
> ; sys 0.000
>
> Timing without and with a specified type.
> ;(time (do-ec (: x xs) (identity x)))
> ; real 0.156
> ; user 0.140
> ; sys 0.000
> ;(time (do-ec (:vector x xs) (identity x)))
> ; real 0.078
> ; user 0.094
> ; sys 0.000
>
> Timing without and with a specified type.
> ;(time (do-ec (: x xs) (identity x)))
> ; real 0.219
> ; user 0.250
> ; sys 0.000
> ;(time (do-ec (:string x xs) (identity x)))
> ; real 0.125
> ; user 0.125
> ; sys 0.000

Racket:

(require srfi/42)

(define big-size 999888)

(for-each
(lambda (xs) (displayln "\nTiming without and with a specified type.")
(time (do-ec (: x xs) (identity x)))
(cond ((list? xs) (time (do-ec (:list x xs) (identity x))))
((vector? xs) (time (do-ec (:vector x xs) (identity x))))
(else (time (do-ec (:string x xs) (identity x))))))
(list
(make-list big-size 2)
(make-vector big-size 2)
(make-string big-size #\2)))

Timing without and with a specified type.
cpu time: 31 real time: 31 gc time: 0
cpu time: 0 real time: 0 gc time: 0

Timing without and with a specified type.
cpu time: 15 real time: 32 gc time: 0
cpu time: 0 real time: 0 gc time: 0

Timing without and with a specified type.
cpu time: 32 real time: 16 gc time: 0
cpu time: 0 real time: 16 gc time: 0