Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

It may or may not be worthwhile, but it still has to be done.


comp / comp.lang.lisp / Re: Lisp Question

SubjectAuthor
o Re: Lisp QuestionB. Pym

1
Subject: Re: Lisp Question
From: B. Pym
Newsgroups: comp.lang.lisp, comp.lang.scheme
Organization: A noiseless patient Spider
Date: Mon, 26 Aug 2024 23:31 UTC
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Nobody447095@here-nor-there.org (B. Pym)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: Lisp Question
Date: Mon, 26 Aug 2024 23:31:02 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 94
Message-ID: <vaj37h$2lak7$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Injection-Date: Tue, 27 Aug 2024 01:31:02 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="2d9bc304c3dee41453738ac9739c34c1";
logging-data="2796167"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/VVzmxqk7wmJnJJgXAoYwl"
User-Agent: XanaNews/1.18.1.6
Cancel-Lock: sha1:JQ1N2jIULZXUDPkwLm+ZzO4mgw0=
View all headers

Kent M. Pitman wrote:

> > I'm doing the DNA problem. The function is
> > supposed to count the bases A, T, G, C in either a single dna
> > (represented as a list, e.g (a a t t)) or a complement dna
> > (represented as a table, e.g ((a t) (a t)
> > (t a) (c g))). My function count rights but the viriable result get
> > accumulated on subsequent calls. I don't understand why. Could you
> > shed some light?
> >
> > Thanks very much.
> >
> > (defun count-bases (strand)
> > (let ((result '((a 0) (t 0) ( g 0) (c 0))))
> > (dolist (base strand result)
> > (cond ((atom base)(incf (second (assoc base result))))
> > (t (incf (second (assoc (first base) result)))
> > (incf (second (assoc (second base) result))))))))
>
> You're modifying the constant structure. QUOTE just returns the object
> (think of it as a pointer to a constantly allocated language if you're
> used to that in other languages). On subsequent calls, this will have
> the modified results. (Actually, in some implementations you may get an
> error before that point, but if you don't, that's the most likely result.
> From a language point of view, what you've done is simply undefined and
> pretty much anything that happens is valid from the implementation's point
> of view since you violated your contract as a user when you did that.)
>
> You'll want to use calls to LIST, as in (list (list 'a ...) ...) rather
> than that quoted structure.
>
> In fact, if this is not homework, or some other form of learning
> exercise specifically aimed at figuring out ASSOC, this is not how I'd
> recommend you do this. All those calls to ASSOC are high overhead for
> the value you're getting. I'd suggest the following. I'll show the code
> since no one ever seems to make homework that allows one to use really
> useful primitives--sigh.
>
> (defun count-bases (strand)
> (let ((na 0) (nc 0) (ng 0) (nt 0))
> (macrolet ((notice (ref)
> `(let ((r ,ref))
> (ecase r
> ((a) (incf na))
> ((c) (incf nc))
> ((g) (incf ng))
> ((t) (incf nt))))))
> (dolist (base strand)
> (cond ((atom base) (notice base))
> (t
> (notice (first base))
> (notice (second base)))))
> (values na nc ng nt))))

Testing:

(count-bases '(a c g (a t) (c t) (g t)))

2
2 2
3

Gauche Scheme

(define (count-bases strand)
(let1 counts '()
(dolist (x strand)
(if (pair? x)
(begin (ainc! counts (car x))
(ainc! counts (last x)))
(ainc! counts x)))
(apply values (map (cut assoc-ref counts <>) '(a c g t)))))

2 2
2 3

Given:

(define-syntax ainc!
(syntax-rules ()
[(_ alist key val func default)
(let ((pair (assoc key alist)))
(if pair
(set-cdr! pair (func val (cdr pair)))
(set! alist (cons (cons key (func val default)) alist))))]
[(_ alist key val func)
(ainc! alist key val func 0)]
[(_ alist key val)
(ainc! alist key val +)]
[(_ alist key)
(ainc! alist key 1)]))

1

rocksolid light 0.9.8
clearnet tor