Welcome! Please see the About page for a little more info on how this works.

0 votes
in REPL by
edited by

context: I have parsed some extensive XML data from the internet. Now I want to explore/filter/drill down in the REPL.

I have a LazySeq named xs of unknown length and of unknown content. I would like to explore the first few elements of xs at the REPL. For convenience, I would like to def some Vars like so:

(def x1 (nth xs 0 nil))
(def x5 (nth xs 4 nil))

This is tedious to type, especially when it needs to be done repeatedly, as I develop my "drill down"-function. Is there a convenience function (or macro) that can do this for me, perhaps like this

(defmany xs "x" 5)
;=> #'my.ns/x1
;=> ...
;=> #'my.ns/x5

I tried to write a function for this. It uses eval and is unsecure (and has other drawbacks as well). So, my questions are:

  1. Does something like this already exist somewhere?
  2. Do I need a macro for this or can it be done with a function? (I am unfamiliar with writing Clojure macros.)
  3. How can this function/macro be defined?

For amusements' sake, here is my attempt:

(defn def-many
  [xs prefix n]
  (map eval
       (for [i (range n)]
            (list 'def
                  (symbol (str prefix (inc i)))
                  (nth xs i nil)))))

(if (nth xs i nil) is a LazySeq or a list then eval will try to interpret it as a function call. This can be tested for and converted to a vector, for example. But yeah, this is not great.)

1 Answer

+2 votes
selected by
Best answer

You don't need eval for this (which also isn't insecure in your context since you control all that's actually being evaled):

(let [data (vec (range 10))]
  (dotimes [idx (count data)]
    (intern *ns* (symbol (str "x" idx)) (nth data idx))))

=> x5

But, instead of doing things like this, I would strongly suggest tap>ing that data and using tools like Portal, Reveal, REBL. Incomparably more convenient than browsing complex nested data in a plain text REPL.

`intern`, that's it! Thank you! Also, yeah solid advice regarding Portal/Reveal/REBL. Thanks again!