Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

summing in a loop and iterate

324 views
Skip to first unread message

Francogrex

unread,
Jun 14, 2012, 1:38:46 PM6/14/12
to
;;Use the iterate package

(let ((data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
("AB" A 450 10) ("AB" G 380 5))))

(iterate (for i in data)
(cond ((eql (cadr i) 'A)
(sum (caddr i) into V1)
(sum (cadddr i) into V2))
((eql (cadr i) 'G)
(sum (caddr i) into V3)
(sum (cadddr i) into V4)))
finally (return (list V2 V1 V4 V3))))

* (6 12 0 0)
Why is it not summing all 'as expected'?
Also the same issue with loop. (code not provided). Am I missing
something trivial here? I would appreciate some help (preferably with
the loop facility instead of iterate.

Barry Fishman

unread,
Jun 14, 2012, 2:30:48 PM6/14/12
to
--8<---------------cut here---------------start------------->8---
(let ((data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
("AB" A 450 10) ("AB" G 380 5))))

(loop for row in data
if (eql (second row) 'A)
sum (third row) into V1 and
sum (fourth row) into V2
if (eql (second row) 'G)
sum (third row) into V3 and
sum (fourth row) into V4
finally (return (list V1 V2 V3 V4))))
--8<---------------cut here---------------end--------------->8---

(518 25 393 9)

Seems to work for me.
--
Barry Fishman

Zach KS

unread,
Jun 14, 2012, 3:02:50 PM6/14/12
to
> On 2012-06-14 13:38:46 EDT, Francogrex wrote:
> > ;;Use the iterate package
> >
> > (let ((data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
> > ("AB" A 450 10) ("AB" G 380 5))))
> >
> > (iterate (for i in data)
> > (cond ((eql (cadr i) 'A)
> > (sum (caddr i) into V1)
> > (sum (cadddr i) into V2))
> > ((eql (cadr i) 'G)
> > (sum (caddr i) into V3)
> > (sum (cadddr i) into V4)))
> > finally (return (list V2 V1 V4 V3))))
> >
> > * (6 12 0 0)
> > Why is it not summing all 'as expected'?
> > Also the same issue with loop. (code not provided). Am I missing
> > something trivial here? I would appreciate some help (preferably with
> > the loop facility instead of iterate.
>

There is an error in your code. You forgot to wrap your finally clause in a set of parentheses. This should give you an error, unless you had previously defined "finally", if which case you would return on the first pass through the loop, giving you (6 12 0 0).

Should look like:

(let ((data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
("AB" A 450 10) ("AB" G 380 5))))
(iterate (for i in data)
(cond ((eql (cadr i) 'A)
(sum (caddr i) into V1)
(sum (cadddr i) into V2))
((eql (cadr i) 'G)
(sum (caddr i) into V3)
(sum (cadddr i) into V4)))
(finally (return (list V2 V1 V4 V3)))))

...but you should also be using first, second, third, fourth like Barry implicitly suggests as well.

Lieven Marchand

unread,
Jun 14, 2012, 4:37:13 PM6/14/12
to
Or use destructuring.

(let ((data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
("AB" A 450 10) ("AB" G 380 5))))
(loop for (s label i j) in data
when (eq label 'A)
sum i into v1
and
sum j into v2
when (eq label 'G)
sum i into v3
and
sum j into v4
finally (return (list v1 v2 v3 v4))))

WJ

unread,
Jul 17, 2012, 2:47:21 AM7/17/12
to
Racket:

(define data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
("AB" A 450 10) ("AB" G 380 5)))

(apply map +
(map (match-lambda [(list _ lab v ...)
(if (eq? 'A lab)
(append v '(0 0))
(append '(0 0) v))])
data))

=> '(518 25 393 9)

Mark Tarver

unread,
Jul 20, 2012, 7:05:14 AM7/20/12
to
You know that this style of code was dated in the '80s when I was
learning Lisp and SICP taught a better style than this. I'd like to
believe that people in this group are writing with LOOP and CADDDR
because they have not learnt better but I suspect that part of it is
wilful 'I'm gonna use this stuff cos LOOP and CADDDR is Lispy'.  Oh
dear.

WJ is right in pointing out how clunky this stuff is; (why he is
persisting I don't know, I would have given up yonks ago).  Perhaps
the only nit I'd pick with him is that he sometimes confuses the CL
language with the style in which people choose to write in it.  He
could write few elegant CL solutions. English allows you to write ugly
things, but is not therefore an ugly language.

FWIW in Shen

(define results
  {(list (string * symbol * number * number)) --> (list number)}
  Data -> (mapcan (function tot-up) (partition (function labels=?)
Data)))

(define labels=?
  {(string * symbol * number * number) --> (string * symbol * number *
number) --> boolean}
   (@p String Symbol _ _) (@p String Symbol _ _) -> true
   _ _ -> false)

(define tot-up
  {(list (string * symbol * number * number)) --> (list number)}
   [] -> [0 0]
   [(@p _ _ N1 N2) | Data] -> (let TotUp (tot-up Data)
                                   Fst (head TotUp)
                                   Snd (head (tail TotUp))
                                   [(+ N1 Fst) (+ N2 Snd)]))

(define partition
  {(A --> A --> boolean) --> (list A) --> (list (list A))}
  _ [] -> []
  R? [X | Y] -> (let EquivSet (find (/. Z (R? X Z)) [X | Y])
                     Difference (difference [X | Y] EquivSet)
                     [EquivSet | (partition R? Difference)]))

(define find
  {(A --> boolean) --> (list A) --> (list A)}
   _ [] -> []
   F [X | Y] -> (if (F X) [X | (find F Y)] (find F Y)))

(results
[(@p "AB" A 12 6)
 (@p "AB" G 13 4)
 (@p "AB" A 56 9)
 (@p "AB" A 450 10)
 (@p "AB" G 380 5)])
[518 25 393 9] : (list number)

This is longer than the LOOP solution but two things to note.

1. it defines a highly generic HOF 'partition' which is very useful.
2. If you strike out the types and the generic code you have the same
# lines pretty much as LOOP.

That's my 2c; liked the problem.

Mark

zermelo

unread,
Jul 20, 2012, 9:41:34 AM7/20/12
to
I have a great opinion of you as a computer scientist, but this time
you have completely missed the mark: your solution is barely readable
and betrays the simplicity of the problem. The input is a list of
record where an item is a tag and the others are numbers. The user
wants to add the numbers with the same tags. Therefore every “healthy”
solution must have a (sort of) loop consuming the records and a
selection discriminating the tags. In this way there is a one-to-one
mapping between the problem data and solution components, and the
program is easy to read and modify.

WJ

unread,
Jul 20, 2012, 12:55:57 PM7/20/12
to
(map (match-lambda [(list _ label x y)
(if (eq? label 'A)
(list x y 0 0)
(list 0 0 x y))])
data))

WJ

unread,
Jul 20, 2012, 1:15:15 PM7/20/12
to
Racket:


(define h (make-hash))

(for-each
(match-lambda
[(list _ label vals ...)
(hash-update! h label (curry map + vals) '(0 0))])
data)

==>

'#hash((A . (518 25)) (G . (393 9)))

WJ

unread,
Jul 20, 2012, 11:28:29 PM7/20/12
to
Racket:

"We don't need no stinkin' loops!"

(apply map +
(map (match-lambda [(list _ 'A x y) (list x y 0 0)]
[(list _ 'G x y) (list 0 0 x y)])
data))

==>
'(518 25 393 9)

John Thingstad

unread,
Jul 28, 2012, 7:46:11 AM7/28/12
to WJ
>>
>> (let ((data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
>> ("AB" A 450 10) ("AB" G 380 5))))
>> (loop for (s label i j) in data
>> when (eq label 'A)
>> sum i into v1
>> and
>> sum j into v2
>> when (eq label 'G)
>> sum i into v3
>> and
>> sum j into v4
>> finally (return (list v1 v2 v3 v4))))
>
> Racket:
>
> "We don't need no stinkin' loops!"
>
> (apply map +
> (map (match-lambda [(list _ 'A x y) (list x y 0 0)]
> [(list _ 'G x y) (list 0 0 x y)])
> data))
>
> ==>
> '(518 25 393 9)
>

Well the loop is easier to read. More important it is MUCH more efficient.
You are consing up a temporary list that is twice as large as your
original list. Then you apply add to it. This should make it some 20-40
times slower if it doesn't run out of memory as it might if the list was
large.. In real world terms this solution is inferior. Now if you could
make it run in parallel..

Mark Tarver

unread,
Jul 28, 2012, 4:29:14 PM7/28/12
to
Shen is written on top of a sort of 'RISC' Lisp of 46 instructions
defined from here

http://www.shenlanguage.org/Documentation/shendoc.htm#Kl

This Lisp has allowed us so far to port Shen to CL, Scheme, Clojure
and Javascript and we're working on a JVM port. Because of the focus
on portability we don't rely on exotic language specific features like
LOOP which is very CL. The focus is very much on recursion. Pretty
soon we'll integrate all the work of these developers into one
universal code engine so that you'll be able to generate type secure
stand-alone code in any of 6 or so languages from one Shen source.

I think whether something is intuitive is partly in the mind of the
beholder and what he is used to. The problem with LOOP is that seeing
and solving all your problems with this construct tends to ghettoise
your code.

Mark

Pascal J. Bourguignon

unread,
Jul 28, 2012, 7:55:41 PM7/28/12
to
Mark Tarver <dr.mt...@gmail.com> writes:

> I think whether something is intuitive is partly in the mind of the
> beholder and what he is used to. The problem with LOOP is that seeing
> and solving all your problems with this construct tends to ghettoise
> your code.

On the other hand, sicl implements the other Common Lisp functions in
function of LOOP :-)

--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

Mark Tarver

unread,
Jul 29, 2012, 10:40:55 AM7/29/12
to
On Jul 29, 12:55 am, "Pascal J. Bourguignon" <p...@informatimago.com>
wrote:
SICL is a good project and years ago I suggested something like it and
would have volunteered had I been able to raise a posse. It's good
that it has come into being. However the goals of SICL are different
from Shen; SICL is built from the ground up to be directed towards
CL. Shen is directed to a whole family of Lisplike languages and is
engineered to fit within whatever the developer is likely to find on
that platform; LOOP I'm afraid couldn't really fit in that prospectus.

Mark

Steven E. Harris

unread,
Jul 29, 2012, 5:28:47 PM7/29/12
to
Mark Tarver <dr.mt...@gmail.com> writes:

> Shen is written on top of a sort of 'RISC' Lisp of 46 instructions
> defined from here
>
> http://www.shenlanguage.org/Documentation/shendoc.htm#Kl

Thank you for sharing the link. This project is fascinating.

A simple thing is not yet obvious to me from reading the section
"Boolean Operators"¹: Does Ki have a /not/ operator? It's not listed in
the section "The Primitive Functions of Ki."² If /not/ is missing, how
does one emulate it? Is this how Ki would define it?

(defun not (exp)
(if exp false true))


Footnotes:
¹ http://www.shenlanguage.org/Documentation/shendoc.htm#Boolean%20Operators
² http://www.shenlanguage.org/Documentation/shendoc.htm#The%20Primitive%20Functions%20of%20K%20Lambda

--
Steven E. Harris

Mark Tarver

unread,
Jul 29, 2012, 8:05:38 PM7/29/12
to
On Jul 29, 10:28 pm, "Steven E. Harris" <s...@panix.com> wrote:
> Mark Tarver <dr.mtar...@gmail.com> writes:
> > Shen is written on top of a sort of 'RISC' Lisp of 46 instructions
> > defined from here
>
> >http://www.shenlanguage.org/Documentation/shendoc.htm#Kl
>
> Thank you for sharing the link. This project is fascinating.
>
> A simple thing is not yet obvious to me from reading the section
> "Boolean Operators"¹: Does Ki have a /not/ operator? It's not listed in
> the section "The Primitive Functions of Ki."² If /not/ is missing, how
> does one emulate it? Is this how Ki would define it?
>
>   (defun not (exp)
>     (if exp false true))
>
> Footnotes:
> ¹http://www.shenlanguage.org/Documentation/shendoc.htm#Boolean%20Opera...
> ²http://www.shenlanguage.org/Documentation/shendoc.htm#The%20Primitive...
>
> --
> Steven E. Harris

Exactly.

Mark

WJ

unread,
Dec 5, 2012, 9:41:02 PM12/5/12
to
EMACS Lisp:

(let ((data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
("AB" A 450 10) ("AB" G 380 5)))
(v1 0) (v2 0) (v3 0) (v4 0))
(mapc
($ ((s label i j))
(cond ((eq label 'A) (incf v1 i) (incf v2 j))
((eq label 'G) (incf v3 i) (incf v4 j))))
data)
(list v1 v2 v3 v4))

(518 25 393 9)

Given:

(require 'cl)
(defmacro $ (&rest exprs) `(function* (lambda ,@exprs)))

WJ

unread,
Dec 27, 2012, 1:12:28 AM12/27/12
to
newLISP:


(set 'data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
("AB" A 450 10) ("AB" G 380 5)))

(apply
(fn (accum datum)
(map + accum
(if (match '(? A ? ?) datum)
(2 datum)
(append '(0 0) (2 datum)))))
(cons '(0 0 0 0) data)
2)

(518 25 393 9)

WJ

unread,
Oct 2, 2013, 1:37:49 PM10/2/13
to
Clojure:

(def data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
("AB" A 450 10) ("AB" G 380 5)))

(apply map +
(map (fn [[_ k x y]] (if (= k 'A) (list x y 0 0) (list 0 0 x y)))
data))

(518 25 393 9)

WJ

unread,
Nov 8, 2014, 12:34:38 PM11/8/14
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
Gauche Scheme:

(use srfi-42)
(use util.match)
(let ((data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
("AB" A 450 10) ("AB" G 380 5))))
(fold-ec
'(0 0 0 0)
(: datum data)
(match-let1 (s label i j) datum
(if (eq? label 'A) (list i j 0 0) (list 0 0 i j)))
(pa$ map +)))

===>
(518 25 393 9)


WJ

unread,
Apr 9, 2015, 10:18:02 PM4/9/15
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
(let1 data '(("AB" A 12 6) ("AB" G 13 4) ("AB" A 56 9)
("AB" A 450 10) ("AB" G 380 5))
(define (fix s label . x) (if (eq? label 'A) `(,@x 0 0) `(0 0 ,@x)))
(fold
(^(x acc) (map + (apply fix x) acc))
'(0 0 0 0)
data))

WJ

unread,
Nov 26, 2015, 1:58:40 PM11/26/15
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
Ocaml:

["AB","A",12,6; "AB","G",13,4; "AB","A",56,9; "AB","A",450,10;
"AB","G",380,5] |>
List.fold_left
(fun acc (_,key,m,n) ->
List.map2 (+)
acc
(if "A"=key then [m;n;0;0] else [0;0;m;n]))
[0;0;0;0] ;;

===>
[518; 25; 393; 9]

--
"If a government uses the instruments of power in its hands for the purpose of
leading a people to ruin, then rebellion is not only the right but also the
duty of every individual citizen."

WJ

unread,
Feb 6, 2016, 6:53:52 PM2/6/16
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
MatzLisp (Ruby):

[["AB",:A,12,6,200],["AB",:G,13,4,0],["AB",:A,56,9,20],["AB",:A,450,10,2],
["AB",:G,380,5,-6],["AB",:C,22,33,44]].
map{|x| x.drop 1}.group_by(&:first).map{|key,val|
[key, val.map{|x| x.drop 1}.transpose.map{|x| x.reduce :+}]}

===>
[[:A, [518, 25, 222]], [:G, [393, 9, -6]], [:C, [22, 33, 44]]]

--
From the New York Times of October 11, 1991, ... we learn that ... researchers
at Boston University admitted that, "There is no question but that Dr. King
plagiarized in the dissertation." ... "Dr. Martin Luther King, Jr." [Michael
King] spent his last night on Earth having sexual intercourse with two women at
the motel and physically beating and abusing a third. -- K. A. Strom
0 new messages