1

I am trying to do the following exercice:

Given a DNA string, compute how many times each nucleotide occurs in the string.

DNA is represented by an alphabet of the following symbols: 'A', 'C', 'G', and 'T'.

Here is a simple unit test to better understand what's expected:

(ert-deftest count-all-nucleotides-test ()
  (should (equal (sort-pairs (nucleotide-count "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC") #'<)
             '((?A . 20) (?C . 12) (?G . 17) (?T . 21)))))

Here is the function I've written:

(defun nucleotide-count (s)
  "Return the count of nucleotides in S."
  (let ((result '((?A . 0) (?C . 0) (?G . 0) (?T . 0))))
    (seq-reduce
     (lambda (result c)
       (let ((count (cdr (assoc c result))))
         (if (equal c nil)
             (error (format "Invalid nucleotide %c" c))
           (setf (cdr (assoc c result)) (1+ count)))
         result))
     s
     result)))

This seems to work... but only once. It seems the function re-uses the previous alist and updates it but I don't understand why:

ELISP> (nucleotide-count "ACGT")
((65 . 1)
 (67 . 1)
 (71 . 1)
 (84 . 1))

ELISP> (nucleotide-count "ACGT")
((65 . 2)
 (67 . 2)
 (71 . 2)
 (84 . 2))

ELISP> (nucleotide-count "ACGT")
((65 . 3)
 (67 . 3)
 (71 . 3)
 (84 . 3))

Why is that?

  • 2
    It's very important to understand that ', which means (quote ...), is not a shorthand for making lists. It's a form which causes lisp to return, unevaluated, the object that was created by the lisp reader. If you quote a list and then modify the quoted list, it stays modified. If you want to create a list and then modify it, create it with (list ...) – phils May 21 '19 at 10:21
  • That's exactly the problem indeed! I read the question you linked and understood why it's wrong. Thank you @phils ! – little-dude May 21 '19 at 10:24
  • 1
    You're welcome. I recommend doing some reading about the distinct read and eval phases of lisp execution. Once you understand the distinction, quote will make much more sense. – phils May 21 '19 at 10:25

Browse other questions tagged or ask your own question.