Создать тему  Создать ответ 
Clojure-щоденник
30-09-2013, 01:45    
Сообщение: #21
Agrest

井蛙 / жабенєтко в керниці
Сообщений: 1556
Зарегистрирован: 08.08.12

 
(29-09-2013 22:57)Python писал(а):  
Код:
(defmacro -<>
   ([x y] (replace {'<> x} y))
   ([x y & more] `(-<> (-<> ~x ~y) ~@more)))
[21:40:00] Python says: Так би я реалізував це в кложурі

Що цікаво, орігінальний макрос, який я спробував відтворити, було написано без replace:
Код:
(defmacro -<>
  "the 'diamond wand': top-level insertion of x in place of single
positional '<>' symbol within the threaded form if present, otherwise
mostly behave as the thread-first macro. Also works with hash literals
and vectors."
  ([x] x)
  ([x form] `(-<>* ~form ~x :first))
  ([x form & forms] `(-<> (-<> ~x ~form) ~@forms)))
Правда, ця версія ще може вставляти аргумент на початок списку, якщо місце явно не вказане через <>.

«билингв мусорит в обоих языках — и первом, и втором» © Python
Вебсайт Найти все сообщения
Цитировать это сообщение
30-09-2013, 04:49    
Сообщение: #22
Python

Senior Member
Сообщений: 462
Зарегистрирован: 11.07.12

RE: Clojure-щоденник
Його було написано з replace в допоміжному макросі -<>*, який забезпечує роботу, коли <> в формі нема.

LF agent
Вебсайт Найти все сообщения
Цитировать это сообщение
02-10-2013, 00:08    
Сообщение: #23
Python

Senior Member
Сообщений: 462
Зарегистрирован: 11.07.12

RE: Clojure-щоденник
В продовження теми про стрілки.
Стрілка-комбайн (на основі ->>, доповнена можливостями ->, let, if):
Код:
(defmacro *>> [& elements]
(let [[prev-elements [k & rest-elements]] (split-with #(-> %
    #{:=> :=>* :-> :—- :? :?=> :?<=}         not) elements)]
; choise and resolve it:
    (cond
        ; :=> NAME - equal to (let [NAME (->> PREV ELEMENTS)] (->> NEXT ELEMENTS)) :
        (= k :=>)
            `(let [~(first rest-elements) (->> ~@prev-elements)]
                (*>> ~(first rest-elements) ~@(rest rest-elements)))
        ; :=>* NAME - the same but binding:
        (= k :=>*)
            `(binding [~(first rest-elements) (->> ~@prev-elements)]
                (*>> ~(first rest-elements) ~@(rest rest-elements)))
        ; :-> (ELEMENTS) - equal to (-> (->> PREV ELEMENTS) ELEMENTS):
        (= k :->) (let [tmp (gensym)]
            `(let [~tmp (-> (->> ~@prev-elements) ~@(first rest-elements))]
                (*>> ~tmp ~@(rest rest-elements))))
        ; :—- - may be used after :=>, :=>* to use the next element like the first:
        (= k :—-)
            `(do ~(if (seq prev-elements) `(->> ~@prev-elements))
                 (*>> ~@rest-elements))
        ; :? - if (->> PREV-ELEMENTS) then calculate with NEXT-ELEMENTS:
        (= k :?) (let [tmp (gensym)]
            `(if-let [~tmp (->> ~@prev-elements)]
                (*>> ~tmp ~@rest-elements)))
        ; :?<= EXPR - continue with EXPR if prev result is false:
        (= k :?<=) `(*>> (or (->> ~@prev-elements) ~(first rest-elements)) ~@(rest rest-elements))
        ; :?=> EXPR - return EXPR if prev is false:
        (= k :?=>) (let [tmp (gensym)]
            `(if-let [~tmp (->> ~@prev-elements)]
                (*>> ~tmp ~@(rest rest-elements))
                ~(first rest-elements)))
        ; none of them:
        (nil? k) `(->> ~@elements))))

LF agent
Вебсайт Найти все сообщения
Цитировать это сообщение
02-10-2013, 17:04    
Сообщение: #24
Python

Senior Member
Сообщений: 462
Зарегистрирован: 11.07.12

RE: Clojure-щоденник
Ще стрілки.
Код:
(defmacro fn->> [& exprs] `#(->> % ~@exprs))
(defmacro fn-> [& exprs] `#(-> % ~@exprs))
(defmacro fn*>> [& exprs] `#(*>> % ~@exprs))
Функції, що описуються стрілковим виразом без явно заданого аргумента. В принципі, замість цих макросів можна використовувати й просто вирази в стилі #(-> % ...), але в кложурі #(...) не можна робити вкладеними, а (fn-> ...) — можна (навіть незважаючи на те, що при описі цих макросів я використав #(...). Справа в тому, що скорочена форма запису функції перетворюється на повну на стадії читання — таким чином, коли ми спробуємо вкласти виклики цих макросів один в оден, ніяких скорочених функціональних виразів там вже не буде).

LF agent
Вебсайт Найти все сообщения
Цитировать это сообщение
Создать ответ 


Переход:


Пользователи просматривают эту тему: 1 Гость(ей)