Path: ...!weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: "B. Pym" Newsgroups: comp.lang.lisp Subject: Re: map and reduce Date: Fri, 19 Jul 2024 15:48:02 -0000 (UTC) Organization: A noiseless patient Spider Lines: 54 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Injection-Date: Fri, 19 Jul 2024 17:48:03 +0200 (CEST) Injection-Info: dont-email.me; posting-host="adff5a388ff6d0ae53c744bdb00d17f0"; logging-data="3212875"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18U3nPu+TY4zvPkpJzbedSf" User-Agent: XanaNews/1.18.1.6 Cancel-Lock: sha1:WrXsORZW1DpUpMEDYFLx6eKbGbo= Bytes: 2301 > > Consider n vectors (or lists) v1, ..., vn of equal length, an n- > > variate function f, and a bivariate function g. > > > > I want to calculate (reduce g (map 'vector f v1 v2 ... vn)), eg > > > > (reduce #'+ (map 'vector #'* '(1 2 3) '(4 5 6))) ; => 32 > > > > but without the intermediate vector (my vectors are long). I can of > > course write a function to do this, but I am wondering if there is a > > clever way to do it with CL library functions. > > I don't think there is a way to do this sort of thing directly. It's > not difficult (or even particularly ugly) to do using LOOP, though. For > the case G = #'+, it's particularly nice: > > (loop for x across first-vector > for y across second-vector > sum (funcall f x y)) That cannot handle any number of vectors. > > but for general G, you need > > (loop for x across first-vector > for y across second-vector > for temp = (funcall f x y) > for result = temp then (funcall result temp) Wrong. Try (funcall G result temp) > finally (return result)) Gauche Scheme (use srfi-43) ;; vector ops. (define (vec-map-reduce red-func seed map-func . vectors) (apply vector-fold (lambda (i accum . elements) (red-func accum (reduce map-func #f elements))) seed vectors)) (vec-map-reduce + 0 * #(9 2 3 4) #(5 6 7 8) #(20 22 23 24)) ===> 2415