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