Size: a a a

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

2020 January 25

AI

Andrey Ivanov in Clojure — русскоговорящее сообщество
да, согласен )
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Notes:
Note the difference between filter and keep.  filter returns the original items in a collection that satisfy the predicate.  keep returns the non-nil *results* of the given function.
keep is like a map that filters out nil values produced by f and could be defined as:

(def my-keep (comp (partial remove nil?) map))
or, perhaps more traditionally:

(defn my-keep [& args]
 (remove nil? (apply map args)))
Note that, unlike map, keep doesn’t accept multiple collections:

clojure
(filter identity (map get [{:a 1} {:b 2} {:d 3}] [:a :b :c]))
; => (1 2)

(keep get [{:a 1} {:b 2} {:d 3}] [:a :b :c])
; => ArityException Wrong number of args (3) passed to: core/keep
источник

VM

Vyacheslav Mikushev in Clojure — русскоговорящее сообщество
The2lb3oz4dr10½grOfHedgehogs
А вот почему нет keepcat не понятно. Слишком частный случай что ли
За все два года работы, мне ни разу не понадобился даже keep, не говоря уж о keepcat. И я его использование (keep) встречал только один раз в статье по оптимизации clojure.
источник

MK

Mikhail Kuzmin in Clojure — русскоговорящее сообщество
Andrey Ivanov
  (defmacro cond-let
   ([] nil)
   ([x] (throw (IllegalArgumentException. "cond-let error: last one form")))
   ([a b & forms] (if (vector? a)
                    `(let ~a (cond-let ~b ~@forms))
                    `(if ~a ~b (cond-let ~@forms)))))
Можно ввести макрос <<- , который пихает последнюю форму в конец предпоследней. Нужно сделать (->> (reverse body)).
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Я думаю, что весь сыр-бор по поводу keep возник из-за отсутствия аналога в хаскеле. Возможно, там это и не нужно, если композиция шагов обработки коллекций и ленивость выполнения бесплатны или незначительны с точки зрения производительности.

Но в кложе это явно не так, каждый шаг в цепочке несёт накладные расходы.

Поэтому вроде все понимают, что вместо двух мапов подряд лучше делать один мап с комбинированной функцией.

(->> '(0 1 2 3 4 5 6 7 8 9) (map identity) (map identity) (last))) ; 2,90 µs (~1.5× slower)

(->> '(0 1 2 3 4 5 6 7 8 9) (map (comp identity identity)) (last)) ; 1,75 µs


Поэтому, когда у нас возникает ситуация, когда для получения результата нужно сделать filter`→`map`→`filter, то очень хорошо, что это можно заменить на единичный keep.

Что касается «мне никогда не нужно было». Кто-то может быть никогда и mapv/filterv не использует (именно с точки зрения производительности, а не типа возвращаемого результата). А кто-то понимает, что ленивость в кложе не бесплатная, и где-то это приходится учитывать:

(->> '(0 1 2 3 4 5 6 7 8 9) (mapv (comp identity identity)) (last)) ; 678,00 ns (~2.5× faster)


Я работаю в команде, где коллеги пишут на других языках, и я не хочу услышать упрёки, зачем я перешёл со скалы на кложу, если у меня всё тормозит :-) . Поэтому мне keep нужен :-P
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Какие языковые конструкции я регулярно применяю при написании кода
Анонимный опрос
20%
Трансдьюсеры
20%
Паттерн матчинг `clojure.core.match`
12%
Улучшенные версии `cond` (cond-let, better-cond и т.п.)
4%
Свою собственную реализацию `dissoc-in`
32%
`keep` как замену комбинаций filter+map
60%
`mapv`/`filterv` для лучшей производительности
12%
Более производительные реализации стандартных функций из `clojure.core`
0%
Монадические библиотеки типа `funcool/cats`, `algo.monads`
16%
Библиотеки типа `medley` для компенсации недостающих функций в `clojure.core`
12%
Библиотеки типа `specter`, `meander` для работы со структурами данных
Проголосовало: 25
источник

T

The2lb3oz4dr10½grOfH... in Clojure — русскоговорящее сообщество
Dmitry M
привет, я правильно понимаю если я определил record в одном неймспейсе то в другом я могу использовать его только с помощью import?
Да, вроде верно
источник

T

The2lb3oz4dr10½grOfH... in Clojure — русскоговорящее сообщество
Использовать вроде можно без импорта, но надо прописать :gen-class в неймспейс с рекордом
источник

T

The2lb3oz4dr10½grOfH... in Clojure — русскоговорящее сообщество
Могу ошибаться. По памяти говорю
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Dmitry M
привет, я правильно понимаю если я определил record в одном неймспейсе то в другом я могу использовать его только с помощью import?
https://clojuredocs.org/clojure.core/defrecord

; If you define a defrecord in one namespace and want to use it
; from another, there are 2 options:
; 1. use the constructor (->Record)
; (only available in clojure >= 1.4)
;
; 2. first require the namespace and then import
; the record as a regular class.
; The require+import order makes sense if you consider that first
; the namespace has to be compiled--which generates a class for
; the record--and then the generated class must be imported.
; (Thanks to raek in #clojure for the explanations!)
источник

DM

Dmitry M in Clojure — русскоговорящее сообщество
Спасибо
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Про dissoc-in из книжки
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
источник

AI

Andrey Ivanov in Clojure — русскоговорящее сообщество
Mikhail Kuzmin
Можно ввести макрос <<- , который пихает последнюю форму в конец предпоследней. Нужно сделать (->> (reverse body)).
Уже. Только непонятно как это связано с обсуждаемым макросом
https://github.com/Ivana-/simple-datomic-cru/blob/master/test/ui/macroses.cljc#L11
источник

AI

Andrey Ivanov in Clojure — русскоговорящее сообщество
Sergey Trofimov
Я думаю, что весь сыр-бор по поводу keep возник из-за отсутствия аналога в хаскеле. Возможно, там это и не нужно, если композиция шагов обработки коллекций и ленивость выполнения бесплатны или незначительны с точки зрения производительности.

Но в кложе это явно не так, каждый шаг в цепочке несёт накладные расходы.

Поэтому вроде все понимают, что вместо двух мапов подряд лучше делать один мап с комбинированной функцией.

(->> '(0 1 2 3 4 5 6 7 8 9) (map identity) (map identity) (last))) ; 2,90 µs (~1.5× slower)

(->> '(0 1 2 3 4 5 6 7 8 9) (map (comp identity identity)) (last)) ; 1,75 µs


Поэтому, когда у нас возникает ситуация, когда для получения результата нужно сделать filter`→`map`→`filter, то очень хорошо, что это можно заменить на единичный keep.

Что касается «мне никогда не нужно было». Кто-то может быть никогда и mapv/filterv не использует (именно с точки зрения производительности, а не типа возвращаемого результата). А кто-то понимает, что ленивость в кложе не бесплатная, и где-то это приходится учитывать:

(->> '(0 1 2 3 4 5 6 7 8 9) (mapv (comp identity identity)) (last)) ; 678,00 ns (~2.5× faster)


Я работаю в команде, где коллеги пишут на других языках, и я не хочу услышать упрёки, зачем я перешёл со скалы на кложу, если у меня всё тормозит :-) . Поэтому мне keep нужен :-P
Правильно. Можно еще посмотреть какое решение по этому поводу принято в других строгих ФЯ типа той же Скалы и МЛ-я/Фшарпа. Но там даже с мапом не все так просто, если найду ссылку скину
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Andrey Ivanov
Правильно. Можно еще посмотреть какое решение по этому поводу принято в других строгих ФЯ типа той же Скалы и МЛ-я/Фшарпа. Но там даже с мапом не все так просто, если найду ссылку скину
в скале есть collect, я его там использовал, поэтому вопроса с keep в кложе даже не возникло
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Sergey Trofimov
в скале есть collect, я его там использовал, поэтому вопроса с keep в кложе даже не возникло
для хаскеля я увидел только вот это https://stackoverflow.com/questions/15634549/haskell-equivalent-of-scala-collect
источник

AI

Andrey Ivanov in Clojure — русскоговорящее сообщество
В Хаскеле лень и фьюзинг списков, поэтому там этого скорее всего и нет. Но могу ошибаться, нужно у настоящих хаскелистов спросить
источник

AI

Andrey Ivanov in Clojure — русскоговорящее сообщество
по поводу оптимизаций и всего такого - вот как люди в строгих ФЯ даже с банальным мапом мучаются (С) https://gist.github.com/klapaucius/1405389
источник