Size: a a a

Clojure — русскоговорящее сообщество

2020 February 09

YK

Yurii Khmelevskii in Clojure — русскоговорящее сообщество
собственно это не получится тогда нормально сделать в компайл тайме
источник

DL

Dmytro Lispyvnyi '(🌲 🍺) in Clojure — русскоговорящее сообщество
Внутри эвала анквот
источник

YK

Yurii Khmelevskii in Clojure — русскоговорящее сообщество
можно пример? не понимаю что именно unquote
источник

YK

Yurii Khmelevskii in Clojure — русскоговорящее сообщество
(defmacro bar
 [v]
 (let [v' (map inc (eval (unquote v)))]
   `(identity ~v’)))
источник

YK

Yurii Khmelevskii in Clojure — русскоговорящее сообщество
так не получится
источник

DL

Dmytro Lispyvnyi '(🌲 🍺) in Clojure — русскоговорящее сообщество
Но это плохо
источник

DL

Dmytro Lispyvnyi '(🌲 🍺) in Clojure — русскоговорящее сообщество
Макросы с эвалами, в смысле
источник

YK

Yurii Khmelevskii in Clojure — русскоговорящее сообщество
да, я уже понял что это плохайя идея. думаю о другом интерфейсе…
спасибо
источник

DL

Dmytro Lispyvnyi '(🌲 🍺) in Clojure — русскоговорящее сообщество
Yurii Khmelevskii
да, я уже понял что это плохайя идея. думаю о другом интерфейсе…
спасибо
А если всё-таки функцией и замемоизировать "inc"?
источник

DL

Dmytro Lispyvnyi '(🌲 🍺) in Clojure — русскоговорящее сообщество
Если оно, конечно, на числах или другом ограниченном множестве аргументов работает
источник

DL

Dmytro Lispyvnyi '(🌲 🍺) in Clojure — русскоговорящее сообщество
У меня была подобная ситуация, мемоизация inc  и bar дала очень приличный прирост, вплоть до нескольких порядков
источник

VM

Vyacheslav Mikushev in Clojure — русскоговорящее сообщество
Yurii Khmelevskii
Подскажите возможно ли написать такой макрос:

(defmacro bar
 [v]
 (let [v' (map inc v)]
   `(identity ~v')))


он работает если я передам в него простой вектор

(macroexpand-1
'(bar [1 2 3]))

но по какой-то причине не работает в таком случае

(macroexpand-1
'(bar (when true [1 2 3])))


можно ли как-то это исправить так, что бы map выполнялся в компайл тайме?
Что мешает написать (when true (bar [1 2 3]))? Ведь там где true - это какие-то вычисления, которые будут в runtime? Если это вычисления, которые будут в compile time, то можно производить эти вычисления внутри макроса bar.
источник

YK

Yurii Khmelevskii in Clojure — русскоговорящее сообщество
я правильно понимаю что в clojurescript я не могу написать макрос, который в компайл тайме использует cljs. То есть такое я сделать не могу:

(defmacro deftest
 [sym value]
 (let [value (cljs.core/clj->js value)]
   `(def ~sym ~value)))
источник

YK

Yurii Khmelevskii in Clojure — русскоговорящее сообщество
использую 2х файловый паттерн, где макрос в .clj и реквайрится этот макрос в .cljs
источник

A

Artem in Clojure — русскоговорящее сообщество
Yurii Khmelevskii
использую 2х файловый паттерн, где макрос в .clj и реквайрится этот макрос в .cljs
На сколько помню, других вариантов использования макросов в cljs не было
источник

VM

Vyacheslav Mikushev in Clojure — русскоговорящее сообщество
Yurii Khmelevskii
использую 2х файловый паттерн, где макрос в .clj и реквайрится этот макрос в .cljs
Если я не ошибаюсь, макросы, которые используют возможности cljs, нужно помещать в cljc.
источник

VM

Vyacheslav Mikushev in Clojure — русскоговорящее сообщество
Вот пример использования cljs'ного кода
(ns foo
 (:require [cljs.analyzer :as analyzer]))

(defn resolve-sym
 "Resolves a var for the analysis environment and symbol specified in `env` and `sym`
 parameters. Returns a vector with a resolved var and it's meta."
 [env sym]
 (let [[var meta] (try
                    (let [var (analyzer/resolve-var env
                                                    sym
                                                    (analyzer/confirm-var-exists-throw))]
                      [var (analyzer/var-meta var)])
                    (catch #?@(:clj [Throwable t] :cljs [:default e])
                        [(analyzer/resolve-var env sym) nil]))
       resolved (vary-meta (:name var) assoc ::analyzer/no-resolve true)]
   [resolved meta]))

(defn resolved->var
 "Converts `[resolved meta]` tuple to a var."
 [[resolved meta]]
 `(cljs.core/Var. (fn [] ~resolved) '~resolved ~meta))

(defmacro component-spec-def
 "Registers function specs (fdef) for the `component-sym`."
 [component-sym]
 (let [env &env
       [resolved-sym component-meta] (resolve-sym env component-sym)
       component-fn-sym (-> component-meta
                            :component-fn
                            (second)
                            (normalize-symbol component-meta))
       [_ component-fn-meta] (resolve-sym env component-fn-sym)
       default-parameters-keys (-> component-fn-meta
                                   :arglists
                                   second first first
                                   :or
                                   keys
                                   (->> (map keyword))
                                   set)
       required? (fn [p] (not (contains? default-parameters-keys (:name p))))
       params (second (:params component-meta))
       ns-name (str (get-in env [:ns :name]))
       req-un (mapv #(->> % :name name (keyword ns-name)) (filter required? params))
       opt-un (mapv #(->> % :name name (keyword ns-name)) (filter (comp not required?) params))]
   `(when ^boolean js/goog.DEBUG
      ~@(for [p params
              :let [s (:spec p)]
              :when (and (keyword? s) (not= (namespace s) ns-name))]
          `(cljs.spec.alpha/def ~(keyword ns-name (name (:name p))) ~s))
      (cljs.spec.alpha/fdef ~component-sym
        :args (cljs.spec.alpha/cat
               :args (cljs.spec.alpha/keys :req-un ~req-un :opt-un ~opt-un)))
      (cljs.spec.test.alpha/instrument (quote ~resolved-sym)))))
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Vyacheslav Mikushev
Вот пример использования cljs'ного кода
(ns foo
 (:require [cljs.analyzer :as analyzer]))

(defn resolve-sym
 "Resolves a var for the analysis environment and symbol specified in `env` and `sym`
 parameters. Returns a vector with a resolved var and it's meta."
 [env sym]
 (let [[var meta] (try
                    (let [var (analyzer/resolve-var env
                                                    sym
                                                    (analyzer/confirm-var-exists-throw))]
                      [var (analyzer/var-meta var)])
                    (catch #?@(:clj [Throwable t] :cljs [:default e])
                        [(analyzer/resolve-var env sym) nil]))
       resolved (vary-meta (:name var) assoc ::analyzer/no-resolve true)]
   [resolved meta]))

(defn resolved->var
 "Converts `[resolved meta]` tuple to a var."
 [[resolved meta]]
 `(cljs.core/Var. (fn [] ~resolved) '~resolved ~meta))

(defmacro component-spec-def
 "Registers function specs (fdef) for the `component-sym`."
 [component-sym]
 (let [env &env
       [resolved-sym component-meta] (resolve-sym env component-sym)
       component-fn-sym (-> component-meta
                            :component-fn
                            (second)
                            (normalize-symbol component-meta))
       [_ component-fn-meta] (resolve-sym env component-fn-sym)
       default-parameters-keys (-> component-fn-meta
                                   :arglists
                                   second first first
                                   :or
                                   keys
                                   (->> (map keyword))
                                   set)
       required? (fn [p] (not (contains? default-parameters-keys (:name p))))
       params (second (:params component-meta))
       ns-name (str (get-in env [:ns :name]))
       req-un (mapv #(->> % :name name (keyword ns-name)) (filter required? params))
       opt-un (mapv #(->> % :name name (keyword ns-name)) (filter (comp not required?) params))]
   `(when ^boolean js/goog.DEBUG
      ~@(for [p params
              :let [s (:spec p)]
              :when (and (keyword? s) (not= (namespace s) ns-name))]
          `(cljs.spec.alpha/def ~(keyword ns-name (name (:name p))) ~s))
      (cljs.spec.alpha/fdef ~component-sym
        :args (cljs.spec.alpha/cat
               :args (cljs.spec.alpha/keys :req-un ~req-un :opt-un ~opt-un)))
      (cljs.spec.test.alpha/instrument (quote ~resolved-sym)))))
что-то не видно clojure script кода на этапе компиляции
источник

VM

Vyacheslav Mikushev in Clojure — русскоговорящее сообщество
Функция resolve-sym.
источник

VM

Vyacheslav Mikushev in Clojure — русскоговорящее сообщество
Использует cljs.analyzer.
источник