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)))))
Gabriele Nicolardi
  • 1,199
  • 8
  • 17

2 Answers2

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)))))
  ...)
phils
  • 48,657
  • 3
  • 76
  • 115
  • I get this error: `while: Wrong type argument: stringp, ("acs applied materials and interfaces" . "ACS Appl. Mater. Interfaces")` – Gabriele Nicolardi Feb 23 '20 at 23:42
  • I edite mi question with a minimal "not working" example – Gabriele Nicolardi Feb 23 '20 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 '20 at 01:46
  • Sorry, i edited my question. – Gabriele Nicolardi Feb 24 '20 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 '20 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)))
Rusi
  • 329
  • 2
  • 13
  • This also seems like a good solution. Do you think it is better for performance? (My list is huge). – Gabriele Nicolardi Feb 24 '20 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 '20 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 '20 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 '20 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 '20 at 13:54