0

I have a script containing this code:

(let
    ((JOURNALS
      '(

        ("abhandlungen aus dem mathematischen seminar der hamburgischen universitet" .
         "Abh. Math. Sem. Univ. Hamburg") ;; inSPIRE

        ("acm transactions on mathematical software" .
         "ACM Trans. Math. Software") ;; inSPIRE

        ("acs applied materials and interfaces" .
         "ACS Appl. Mater. Interfaces") ;; NLM Catalog

        )))

  ...

  )

and I need move the list of cons cells in a separate file. E.g.:

(let
    ((JOURNALS
      '( (read-file "list-of-cons-cells.el")

        )))

  ...

  )

Where the list-of-cons-cells.el file contents is:

("abhandlungen aus dem mathematischen seminar der hamburgischen universitet" .
 "Abh. Math. Sem. Univ. Hamburg") ;; inSPIRE

("acm transactions on mathematical software" .
 "ACM Trans. Math. Software") ;; inSPIRE

("acs applied materials and interfaces" .
 "ACS Appl. Mater. Interfaces") ;; NLM Catalog

What's the right way to load this file when I run my script?

Edit. This is a MWE of mi original idea (this is not the real function...):

(defun myfunction-orig ()
  (interactive) 
  (let ((JOURNALS '(

                    ("abhandlungen aus dem mathematischen seminar der hamburgischen universitet" .
                     "Abh. Math. Sem. Univ. Hamburg") ;; inSPIRE

                    ("acm transactions on mathematical software" .
                     "ACM Trans. Math. Software") ;; inSPIRE

                    ("acs applied materials and interfaces" .
                     "ACS Appl. Mater. Interfaces") ;; NLM Catalog

                    )
                  ))

    ;; Debug:
    (princ JOURNALS)
    (sit-for 2)

    (while JOURNALS
      (read-string (car (car JOURNALS)))
      (setq JOURNALS (cdr JOURNALS)))))

I tried to modified it on phils' suggestion:

(defun myfunction ()
  (interactive) 
  (with-temp-buffer 
    (insert-file-contents "./list-of-cons-cells.el")
    (let (JOURNALS form)
      (while (setq form (ignore-errors (read (current-buffer))))
        (push form JOURNALS))
      (nreverse JOURNALS)

      ;; Debug:
      (princ JOURNALS)
      (sit-for 2)

      (while JOURNALS
        (read-string (car (car JOURNALS)))
        (setq JOURNALS (cdr JOURNALS)))

      )))

but it doesn't work.

Solution. This is the solution based on the edited phils' answer:

(defun myfunction ()
  (interactive) 
  (let ((JOURNALS (with-temp-buffer
                    (insert-file-contents "./list-of-cons-cells.el")
                    (let (list form)
                      (while (setq form (ignore-errors
                                          (read (current-buffer))))
                        (push form list))
                      (nreverse list))))) 
    ;; Debug
    (princ JOURNALS)
    (sit-for 5)

    (while JOURNALS
      (read-string (car (car JOURNALS)))
      (setq JOURNALS (cdr JOURNALS)))))
  • 1
    I suggest that you insert the file into a temporary buffer and iteratively read each form from that buffer. – phils Feb 23 at 23:08
  • @phils I know how to use with-temp-buffer but I'm not sure of what you mean with "iteratively read each form from that buffer". – Gabriele Nicolardi Feb 23 at 23:14
  • 1
  • @GabrieleNicolardi What is the desired return value or outcome of the myfunction function you've added to the question? (You have done something really strange with the code I suggested.) – phils Feb 24 at 0:46
  • @phils Sorry, My mistake. I edited my question. – Gabriele Nicolardi Feb 24 at 10:55
1

Something along these lines?

(let ((JOURNALS (with-temp-buffer
                  (insert-file-contents FILENAME)
                  (let (list form)
                    (while (setq form (ignore-errors
                                        (read (current-buffer))))
                      (push form list))
                    (nreverse list)))))
  ...)
| improve this answer | |
  • I get this error: while: Wrong type argument: stringp, ("acs applied materials and interfaces" . "ACS Appl. Mater. Interfaces") – Gabriele Nicolardi Feb 23 at 23:42
  • I edite mi question with a minimal "not working" example – Gabriele Nicolardi Feb 23 at 23:54
  • 1
    You're passing a cons cell as the prompt argument to read-string in the code you've added, and the prompt must be a string. – phils Feb 24 at 1:46
  • Sorry, i edited my question. – Gabriele Nicolardi Feb 24 at 10:55
  • 1
    Please note the edit to my answer. You misinterpreted the original code -- it's important that you're using the return value of nreverse, but the way you've used the code you're ignoring it, which means your JOURNALS is pointing only to the final element of the list. The revised answer ought to make it more obvious how to use it. – phils Feb 24 at 12:02
1

You can throw the burden of iterating onto lisp's read. To do that you just need to realize that the list in journals is a lisp list with the beginning and ending parentheses missing. So fill-in the missing and read.

[Ive renamed your list-of-cons-cells.el to journals.txt since its a lisp data-structure but not lisp code]

(with-temp-buffer
    (insert "(")
    (insert-file-contents "journals.txt")
    (goto-char (point-max))
    (insert ")")       
    (goto-char (point-min))
    (read (current-buffer)))
| improve this answer | |
  • This also seems like a good solution. Do you think it is better for performance? (My list is huge). – Gabriele Nicolardi Feb 24 at 13:18
  • Well… Dunno! "Huge" is quite a relative term with machines nowadays having gigabytes of memory, megabytes of list may not be large. OTOH you are creating the list one way or other in memory — with or without read. So why not let the system do it? Bottom line (for performance questions): Test! Push huge to hugher until it breaks and see which version breaks first. And when!! – Rusi Feb 24 at 13:30
  • You're right, the term huge is inappropriate for the list itself (that is a big list), but is more appropriate for the tasks I do with it. Anyway, thanks. – Gabriele Nicolardi Feb 24 at 13:45
  • @GabrieleNicolardi : In issues of performance a kind of blindness is typical and endemic. "Miss the wood for the trees" "Penny-wise pound-foolish" etc are sayings that come to mind. If performance in the sense of size/number of tasks you are subjecting your list to is an issue, you may seriously want to consider a language other than elisp. eg in python you have numpy numba etc. Then you have performance-oriented languages like Julia. Then theres sqlite and the whole menagerie of database systems... Etc – Rusi Feb 24 at 13:51
  • Also if lisp is your thing, classic lisps (not emacs variety) can beat the pants off not just elisp but many of today's fashionable scripting languages – Rusi Feb 24 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.