Добавление необязательного аргумента в макрос - PullRequest
5 голосов
/ 20 августа 2011

Я пытаюсь добавить атрибут "message" опции в макрос Clojure time. В основном я хочу добавить дополнительное пользовательское сообщение к выводу времени. Я пытаюсь найти узкое место в моей программе, и было бы очень полезно добавить несколько описательных сообщений к выводу времени.

Я пробовал следующее:

;optional argument
(defmacro time
  "Evaluates expr and prints the time it took.  Returns the value of
 expr."
  {:added "1.0"}
  [expr & msg]
  `(let [start# (. System (nanoTime))
         ret# ~expr]
     (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " (first ~msg)))
     ret#))

и

(defmacro time
  "Evaluates expr and prints the time it took.  Returns the value of
 expr."
  {:added "1.0"}
  ([expr] (time expr ""))
  ([expr msg]
  `(let [start# (. System (nanoTime))
         ret# ~expr]
     (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " ~msg))
     ret#)))

Оба выдают исключения. Как мне сделать эту работу?

1 Ответ

4 голосов
/ 20 августа 2011

Выдает исключение, потому что msg - это список,

говорят, что вы вызываете его,

(time (+ 1 1) "asd")

msg в макросе становится вызовом функции ("asd"), который завершается неудачно,Просто деструктурируйте msg,

 [expr & [msg]]

и используйте

 ~msg

Вы также можете проверить, как макросы расширяются с помощью macroexpand,

(macroexpand '(time (+ 1 1) "asd"))

Также пара точек,

  • время уже в ядре
  • ваша версия принимает и умножает только одно выражение.

РЕДАКТИРОВАТЬ: время с необязательным сообщением,


(defmacro time
  "Evaluates expr and prints the time it took.  Returns the value of
 expr."
  {:added "1.0"}
  [expr & [msg]]
  (let [msg (if (nil? msg) "" msg)]
    `(let [start# (. System (nanoTime))
         ret# ~expr]
       (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " ~msg))
       ret#)))

(time (+ 1 1))
"Elapsed time: 0.068 msecs. "
2

(time (+ 1 1) "asd")
"Elapsed time: 0.067 msecs. asd"
2
...