Имеет ли Clojure «постоянно» форму, которая выполняет функцию тела во время вызова? - PullRequest
0 голосов
/ 12 сентября 2018

Я хочу использовать constantly в тесте для моделирования сценария, который вызывает исключение.При постоянном использовании готового тела тело оценивается, когда код читается, а не выполняется.Т.е. я не могу сделать это:

(def x (constantly (throw (Exception. "X"))))
(x 1 2 3)

Вместо этого throw происходит немедленно.

Это работает:

(defn x [&] (throw (Exception. "X")))

Но constantly такИнтересно, есть ли встроенный эквивалент, который делает это, может быть, используя макрос?

Ответы [ 4 ]

0 голосов
/ 15 сентября 2018

Он не встроен, но его легко определить.Давайте назовем это defer:

(defmacro defer [exp]
  (list 'fn ['& '_] exp))

Ваш пример становится

(def x (defer (throw (Exception. "X"))))
=> #'user/x

(x 1 2 3)
=> Exception X  user/x (form-init7339591407440568822.clj:10)

Это не имеет практического преимущества по сравнению с использованием # читающей формы напрямую, так как нажмите , но это то, что вы просили.


Я изменил сгенерированную функцию, чтобы принимать аргументы, как и требовалось.Так что это уже не 1016 * thunk .

0 голосов
/ 12 сентября 2018

Одна альтернатива

#(throw (Exception. (str %&)))
0 голосов
/ 13 сентября 2018

Существует несколько способов отложить вычисления в Clojure

Наиболее очевидным является delay:

(def x (delay (throw (ex-info "myException" {}))))
@x ;; exception is thrown

Вы также можете использовать лямбду, аналогично тому, что должно бытьсделано на других языках, или используйте лень.

Учитывая ваш пример кода в вопросе, похоже, что вы ищете что-то вроде этого:

(defn x [& args]
  (throw (ex-info "myException" {:args args})))

(try
  (x 1 2 3)
  (catch Exception e
    (println "Exception! data is "  (ex-data e))))

Обратите внимание на использование ex-infoи ex-data, который может быть полезен для передачи информации.

0 голосов
/ 12 сентября 2018

постоянно - это функция , а не макрос , как fn, поэтому вам необходимо использовать (fn [& args]) для выполнения операций такого типа.

постоянно охотно оценивает свои параметры, поэтому сразу выходит из строя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...