1

I need to read a clojure function from an edn file which outputs hiccup to generate html content. But I'm stuck at the part where the function needs to be evaluated. I receive the error message:

java.lang.RuntimeException: Unable to resolve symbol: fn in this context, compiling:(null:1:1)

((eval (read-string "(fn [] (list [:div\"Hello\"]))")))

and

((load-string "(fn [] (list [:div\"Hello\"]))"))

are working inside a clojure REPL and output the expected result

([:div "Hello"])

project.clj

(defproject infocenter "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.9.225"]
                 [hiccup "1.0.5"]]
  :plugins [[lein-figwheel "0.5.4-7"]]
  :clean-targets ^{:protect false} [:target-path "out" "resources/public/cljs"]
  :cljsbuild {
              :builds [{:id "dev"
                        :source-paths ["src"]
                        :figwheel true
                        :compiler {:main "templ.core"
                                   :asset-path "cljs/out"
                                   :output-to  "resources/public/cljs/main.js"
                                   :output-dir "resources/public/cljs/out"}}]}
  :figwheel {
             :css-dirs ["resources/public/template"]})

core.cljs

(ns templ.core
  (:require-macros [templ.edn :refer [read-edn]]))
(let [div (. js/document getElementById "content")]
     (set! (. div -innerHTML) (read-edn "fn.edn")))

edn.clj

(ns templ.edn
  (:use [hiccup core form]))

(defmacro read-edn
  "Read template from file in resources/"
  [edn-name]
  ;(slurp edn-name)
  ;((eval (read-string "(fn [] (list [:div\"Hello\"]))")))
  ((load-string "(fn [] (list [:div\"Hello\"]))"))
  )

1 Answers1

0

Try this:

(ns xyz.core
  (:gen-class))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "main - enter")
  (println (eval '(+ 2 3)))
  (println ((eval (read-string "(fn [] (list [:div\"Hello\"]))"))))
  (println "main - exit")
)

with results:

> lein run
main - enter
5
([:div Hello])
main - exit

This is just plain Clojure, and I see you are using CLJS as well. There may be some problem in your setup with the CLJS part of it. What are you trying to do with read-edn and fn.edn? I would avoid macros completely whenever possible.

Alan Thompson
  • 29,276
  • 6
  • 41
  • 48
  • The whole thing is a small ClojureScript-App that generates a webpage from a template definition. The template is defined by a function inside the edn. In this example the fn.edn contains (fn [] (list [:div\"Hello\"])). I want to read the function inside the edn, evaluate it, convert the hiccup to html (I left this part out for simplicity of the question) and insert it into the target web page. read-edn is the macro to read the edn (fn.edn). To exclude the file reading as an error source I put an example string inside the load-string/eval function. – Hans Mikesen Aug 26 '16 at 19:03
  • Unless I am missing something, I think you should convert it from CLJS to pain clojure on the jvm. Also, I'm not sure why you are reading the file `fn.edn`, but this is a hint this belongs on the server, not the browser (i.e. Clojure/JVM instead of ClojureScript/JS) – Alan Thompson Aug 26 '16 at 19:31
  • I'm using figwheel to see the instant result in the browser if i change the template function inside the edn. Does figwheel work with pure clojure? Or is there a clojure alternative to figwheel? – Hans Mikesen Aug 28 '16 at 01:53
  • Without knowing your whole application I'm not sure of the best approach. Since it seems to work for me in Clojure, there maybe something in your CLJS setup that is causing the problem. Have you tried the Clojure version? If so, the clj -> cljs transition seems to hold the cause of the problem. – Alan Thompson Aug 29 '16 at 15:40
  • The Clojure version works. The whole app consists of the three files above and a simple index.html. It seems impossible to use Clojure eval for ClojureScript at compile time. Even (eval (read-string "(+ 1 2")) results in an error message "java.lang.RuntimeException: Unable to resolve symbol: + in this context" Maybe I'm switching to Clojure. – Hans Mikesen Aug 30 '16 at 11:35
  • Switched to Clojure app – Hans Mikesen Aug 30 '16 at 13:51
  • You could also ask for more detailed advice on using `eval` in CLJS on the CLJS mailing list: clojurescript googlegroups – Alan Thompson Aug 30 '16 at 17:09