graalvm

igrishaev 2023-04-03T12:55:44.662049Z

Can anyone give me a hint on how to use the *ns* dynamic variable in native image? Imagine I have a macro for logging:

(defmacro logf [level template & args]
  `(println (ns-name *ns*)
            (-> ~level name str/upper-case)
            (format ~template ~@args)))
In repl, it renders the corresponding ns like my.project.utils INFO ... . But when running a binary file, I see clojure.core INFO everywhere. Is it even possible with native image?

borkdude 2023-04-03T12:58:25.308379Z

Maybe you need to pull the ns deref to compile time outside of the expansion?

igrishaev 2023-04-03T12:59:56.878429Z

hm, do you mean an atom or a defer?

borkdude 2023-04-03T14:55:45.718949Z

@igrishaev I mean:

(defmacro logf [..] (let [nsn (ns-name *ns*)] `(println ... ~nsn)))
Not sure if that would help

igrishaev 2023-04-03T14:56:21.010229Z

hm, good idea, let me try

igrishaev 2023-04-03T16:51:43.846899Z

You were right! Here is the final version of my logging ns:

(ns lambda-demo.log
  (:require
   [clojure.string :as str]))


(defmacro logf [level template & args]
  (let [nsn (ns-name *ns*)]
    `(println '~nsn
              (-> ~level name str/upper-case)
              (format ~template ~@args))))


(defmacro debugf [template & args]
  `(logf :debug ~template ~@args))


(defmacro infof [template & args]
  `(logf :info ~template ~@args))


(defmacro errorf [template & args]
  `(logf :error ~template ~@args))

borkdude 2023-04-03T17:34:09.602019Z

👍