* srfi-1 map! @ 2003-11-11 0:32 Kevin Ryde 2003-11-11 14:58 ` a circular dilemma . #0# (was Re: srfi-1 map!) Stephen Compall 0 siblings, 1 reply; 5+ messages in thread From: Kevin Ryde @ 2003-11-11 0:32 UTC (permalink / raw) [-- Attachment #1: Type: text/plain, Size: 194 bytes --] I've been finding it a bit annoying that map can handle long lists but map! can't. * srfi-1.scm (map!): Define as an alias for map, previous definition was not tail-recursive. [-- Attachment #2: srfi-1.scm.mapx.diff --] [-- Type: text/plain, Size: 702 bytes --] --- srfi-1.scm.~1.29.~ 1970-01-01 10:00:01.000000000 +1000 +++ srfi-1.scm 2003-11-11 10:28:35.000000000 +1000 @@ -572,22 +572,8 @@ '() (append! (apply f (map1 car l)) (lp (map1 cdr l))))))) -(define (map! f list1 . rest) - (if (null? rest) - (let lp ((l list1)) - (if (null? l) - '() - (begin - (set-car! l (f (car l))) - (set-cdr! l (lp (cdr l))) - l))) - (let lp ((l (cons list1 rest)) (res list1)) - (if (any1 null? l) - '() - (begin - (set-car! res (apply f (map1 car l))) - (set-cdr! res (lp (map1 cdr l) (cdr res))) - res))))) +;; OPTIMIZE-ME: Re-use cons cells of given list(s) +(define map! map) (define (pair-for-each f clist1 . rest) (if (null? rest) [-- Attachment #3: Type: text/plain, Size: 142 bytes --] _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 5+ messages in thread
* a circular dilemma . #0# (was Re: srfi-1 map!) 2003-11-11 0:32 srfi-1 map! Kevin Ryde @ 2003-11-11 14:58 ` Stephen Compall 2003-11-14 19:28 ` Kevin Ryde 0 siblings, 1 reply; 5+ messages in thread From: Stephen Compall @ 2003-11-11 14:58 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> writes: > I've been finding it a bit annoying that map can handle long lists > but map! can't. You're right, that is annoying. So annoying, I wrote a new version, and ran into some problems with circular lists. Here is the first version. I suppose I should have used any1 instead of the two hand-rollings, but I saw it too late. On the same note, you have to bring map1, an internal from srfi-1.scm, into scope. ;;see if any list in LISTLIST has only one element (define (any-alone? listlist) (cond ((null? listlist) #f) ((null? (cdar listlist)) #t) (else (any-alone? (cdr listlist))))) (define (s11-map! f list1 . rest) ;; First, make sure list1 is not empty, and rest contains no empty ;; lists. (if (or (null? list1) (let lp ((lists rest)) (cond ((null? lists) #f) ((null? (car lists)) #t) (else (lp (cdr lists)))))) ;; BTW, I'm going to return list1. (set! list1 '()) ;; OK, all cars are conses, with real elements to callback with (let nextelem ((clist1 list1) (crest rest)) (set-car! clist1 (apply f (car clist1) (map1 car crest))) ;; Will that be true on the next round? (if (or (null? (cdr clist1)) (any-alone? crest)) ;; If not, cut the list off here (set-cdr! clist1 '()) (nextelem (cdr clist1) (map1 cdr crest))))) list1) Which worked wonderfully for all sorts, even with circulars in REST, until I started setting circulars to LIST1 with "longer" (that is, those with more cons cells) but proper lists. guile> (define mylist (circular-list 1 2 3 4)) guile> mylist (1 2 3 4 . #0#) guile> (map + mylist '(0 0 0 0 0 0)) (1 2 3 4 1 2) guile> (s11-map! + mylist '(0 0 0 0 0 0)) (1 2) The problem is, of course, even larger when your function returns something other than its first argument. So I modified it like so: (define (s11-map! f list1 . rest) ;; First, make sure LIST1 is not empty, and rest contains no empty ;; lists. (if (or (null? list1) (let lp ((lists rest)) (cond ((null? lists) #f) ((null? (car lists)) #t) (else (lp (cdr lists)))))) ;; BTW, I'm going to return LIST1. (set! list1 '()) ;; OK, all cars are conses, with real elements to callback with (let nextelem ((clist1 list1) (crest rest)) (set-car! clist1 (apply f (car clist1) (map1 car crest))) (cond ;; circular LIST1...append new cells instead ((eq? (cdr clist1) list1) (set-cdr! clist1 (apply map f list1 (map1 cdr crest)))) ;; rest of system handles circulars in REST just fine ;; If no more elements, cut LIST1 off here ((or (null? (cdr clist1)) (any-alone? crest)) (set-cdr! clist1 '())) (else (nextelem (cdr clist1) (map1 cdr crest)))))) list1) Of course, this doesn't compensate for the circular list being a sublist of LIST1 (e.g. (cons* -1 0 (circular-list 1 2 3 4))), but at least produces a list of the proper length. guile> mylist (1 2 3 4 . #0#) guile> (s11-map! + mylist '(0 0 0 0 0 0)) (1 2 3 4 1 2) guile> mylist (1 2 3 4 1 2) But the values! guile> (set! mylist (circular-list 1 2 3 4)) guile> (s11-map! + mylist '(1 1 1 1 1 1)) (2 3 4 5 3 4) guile> (map + (circular-list 1 2 3 4) '(1 1 1 1 1 1)) (2 3 4 5 2 3) Well, that isn't good! And of course: guile> (set! mylist (cons* 1 2 (circular-list 3 4 5 6))) guile> (map + mylist '(1 1 1 1 1 1 1 1)) (2 3 4 5 6 7 4 5) guile> (s11-map! + mylist '(1 1 1 1 1 1 1 1)) (2 3 5 6) Which is the same problem the original had. So, is there any way out of this problem, other than to dump the second version (which is needlessly more complicated, I now think), and shunt any call where LIST1 doesn't meet list? to map? Or just live with "undefined behavior" given by the silly (IMHO) case of having a circular as LIST1 where a list in REST has more cells? Or what? Did I mention I like [my] original version better? Yeah. -- Stephen Compall or s11 or sirian Logic is a pretty flower that smells bad. SCUD missile cybercash Kosovo Ermes New World Order ASPIC KGB government munitions satellite imagery investigation csystems fissionable e-cash MIT-LL _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: a circular dilemma . #0# (was Re: srfi-1 map!) 2003-11-11 14:58 ` a circular dilemma . #0# (was Re: srfi-1 map!) Stephen Compall @ 2003-11-14 19:28 ` Kevin Ryde 2003-11-17 20:21 ` Stephen Compall 0 siblings, 1 reply; 5+ messages in thread From: Kevin Ryde @ 2003-11-14 19:28 UTC (permalink / raw) Stephen Compall <s11@member.fsf.org> writes: > > (define (s11-map! f list1 . rest) If you want to write some code, copying and adapting the current C code would probably be much better. > Or just > live with "undefined behavior" given by the silly (IMHO) case of > having a circular as LIST1 where a list in REST has more cells? I see the spec calls for list2 etc to have at least as many elements as list1. Which I guess means list1 is finite (ie. non-circular) and can be used to construct the return without further checking. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: a circular dilemma . #0# (was Re: srfi-1 map!) 2003-11-14 19:28 ` Kevin Ryde @ 2003-11-17 20:21 ` Stephen Compall 2003-11-18 22:57 ` Kevin Ryde 0 siblings, 1 reply; 5+ messages in thread From: Stephen Compall @ 2003-11-17 20:21 UTC (permalink / raw) Kevin Ryde <user42@zip.com.au> writes: > If you want to write some code, copying and adapting the current C > code would probably be much better. Would this be added to libguile-srfi-srfi-1.so? I just wrote it in Scheme to go with the context; it was a function eliminated from srfi-1.scm, eh? > I see the spec calls for list2 etc to have at least as many elements > as list1. Which I guess means list1 is finite (ie. non-circular) > and can be used to construct the return without further checking. Ah, I misinterpreted this. This makes my life much easier, now that I know I am not pathetic and weak. Thanks. :) -- Stephen Compall or s11 or sirian My method is to take the utmost trouble to find the right thing to say. And then say it with the utmost levity. -- G.B. Shaw chameleon man INSCOM Mantis Mena Geraldton Rule Psix offensive information warfare North Korea Skipjack Aldergrove Rubin Echelon Leuken-Baden counter intelligence bullion _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: a circular dilemma . #0# (was Re: srfi-1 map!) 2003-11-17 20:21 ` Stephen Compall @ 2003-11-18 22:57 ` Kevin Ryde 0 siblings, 0 replies; 5+ messages in thread From: Kevin Ryde @ 2003-11-18 22:57 UTC (permalink / raw) Cc: guile-devel Stephen Compall <s11@member.fsf.org> writes: > > Would this be added to libguile-srfi-srfi-1.so? srfi-1.c, which is where the current map lives. Making aliases or easy things may as well be done in the .scm. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2003-11-18 22:57 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2003-11-11 0:32 srfi-1 map! Kevin Ryde 2003-11-11 14:58 ` a circular dilemma . #0# (was Re: srfi-1 map!) Stephen Compall 2003-11-14 19:28 ` Kevin Ryde 2003-11-17 20:21 ` Stephen Compall 2003-11-18 22:57 ` Kevin Ryde
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).