Groups | Search | Server Info | Login | Register


Groups > comp.lang.scheme > #6558

Re: Reduce of alternating terms

From tpeplt <tpeplt@gmail.com>
Newsgroups comp.lang.lisp, comp.lang.scheme
Subject Re: Reduce of alternating terms
Date 2025-08-25 15:20 -0400
Organization A noiseless patient Spider
Message-ID <87y0r7yzrx.fsf@gmail.com> (permalink)
References <108g8jr$348l1$1@dont-email.me>

Cross-posted to 2 groups.

Show all headers | View raw


"B. Pym" <Nobody447095@here-nor-there.org> writes:

> Pascal Costanza wrote:
>
>> On 19/05/2014 22:33, Kay Hamacher wrote:
>> > Hi there,
>> > 
>> > I want to map/reduce a vector:
>> > 
>> > (reduce #'+
>> >   (map 'vector
>> >      #'(lambda(x)  BODY )
>> >   )
>> > )
>> > 
>> > However, BODY has alternating signs for the
>> > terms to be added up (first term is positive,
>> > second is negative, third is positive,....).
>> > One could definitely do this with some global/state
>> > variable in the lambda.
>> > 
>> > But I guess there's a much more elegant
>> > alternative in LISP. Any hints?
>> 
>> (defun example (vector)
>>   (loop for index below (length vector)
>>         sum (* (svref vector index)
>>                (- 1 (* (rem index 2) 2)))))
>> 
>
> Gauche Scheme
>
> "!" is similar to "do".
>
> (define (example vec)
>   (! (sum + (* x sign)
>       sign 1 (- sign)
>       x :across vec)
>     (not x)))
>
> (example #(400 2 500 3))

Common Lisp’s ‘loop’ macro also supports iterating over
vectors, much as the ‘dolist’ macro does for lists.

"The for-as-across subclause":
http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_6-1-2-1-5.html

This eliminates the need for accessing sequence items
through indexing and eliminates the possibility of an
off-by-one error.

The for-as-equals subclause allows a variable to be set to
an initial value and, optionally, then be set to a different
value on subsequent iterations.

"The for-as-equals-then subclause":
http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_6-1-2-1-4.html

Using these constructs, the above solution can be written
either as:

(defun alternating-signs (vector)
  (loop
    for item across vector and sign = 1 then (- sign)
    sum (* item sign)))

or,

(defun alternating-signs (vector)
  (loop
    for item across vector
    for sign = 1 then (- sign)
    sum (* item sign)))

(alternating-signs #(4 -9 11 -19))
;;=> 43

-- 
The lyf so short, the craft so long to lerne.
- Geoffrey Chaucer, The Parliament of Birds.

Back to comp.lang.scheme | Previous | NextPrevious in thread | Find similar


Thread

Re: Reduce of alternating terms "B. Pym" <Nobody447095@here-nor-there.org> - 2025-08-24 23:52 +0000
  Re: Reduce of alternating terms tpeplt <tpeplt@gmail.com> - 2025-08-25 15:20 -0400

csiph-web