Иерархия классов Clojure [дубликат]

В Win-Vector есть очень мощный новый пакет от ученых гениальных данных (люди, которые делали vtreat, seplyr и replyr), называемые cdata. Он реализует принципы «скоординированных данных», описанные в в этом документе , а также в этом сообщении в блоге . Идея заключается в том, что независимо от того, как вы организуете свои данные, должно быть возможно идентифицировать отдельные точки данных с помощью системы «координат данных». Вот отрывок из недавнего сообщения в блоге от John Mount:

Вся система основана на двух примитивах или операторах cdata :: moveValuesToRowsD () и cdata :: moveValuesToColumnsD (). Эти операторы имеют сводную, разворотную, однострочную кодировку, транспонирование, перемещение нескольких строк и столбцов и многие другие преобразования как простые частные случаи.

Легко написать много разных операций в терминах примитивов cdata. Эти операторы могут работать как в памяти, так и в больших масштабах данных (с базами данных и Apache Spark, для больших данных используются варианты cdata :: moveValuesToRowsN () и cdata :: moveValuesToColumnsN ()). Трансформации управляются таблицей управления, которая сама является диаграммой (или изображением) преобразования.

blockquote>

Сначала мы создадим контрольную таблицу (см. сообщение в блоге для получения подробной информации), а затем выполнить перемещение данных из строк в столбцы.

library(cdata)
# first build the control table
pivotControlTable <- buildPivotControlTableD(table = dat1, # reference to dataset
                        columnToTakeKeysFrom = 'numbers', # this will become column headers
                        columnToTakeValuesFrom = 'value', # this contains data
                        sep="_")                          # optional for making column names

# perform the move of data to columns
dat_wide <- moveValuesToColumnsD(tallTable =  dat1, # reference to dataset
                    keyColumns = c('name'),         # this(these) column(s) should stay untouched 
                    controlTable = pivotControlTable# control table above
                    ) 
dat_wide

#>         name  numbers_1  numbers_2  numbers_3  numbers_4
#> 1  firstName  0.3407997 -0.7033403 -0.3795377 -0.7460474
#> 2 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357

43
задан Sean Nilan 9 November 2011 в 21:21
поделиться

4 ответа

Мультиметоды более мощные и дорогие,

используют протоколы, когда они достаточны , но если вам нужно отправить на основе фазы луны, как видно из Марса, то многоточие ваш лучший выбор.

Существуют протоколы, позволяющие простым вещам оставаться простыми и предоставлять способ для клоувера генерировать очень похожий байт-код, который эквивалент java. Похоже, что большинство людей используют протоколы большую часть времени. Я использую multimethods, когда мне нужно отправлять более одного аргумента, хотя я должен признать, что это только один раз, и полные isa иерархии используются еще реже (по мне). поэтому вкратце используйте Multimethods, когда они вам понадобятся

лучший пример В моей экспирации прямо в начале, в core.clj

34
ответ дан TacticalCoder 22 August 2018 в 21:10
поделиться
  • 1
    Протоколы заставляют вас отказаться от большого уровня динамичности. Они вызывают очень запутывающее поведение при разработке при перезагрузке и блокируют вас при отправке только по типу первого аргумента, что очень затрудняет изменение кода в строке. Протоколы категорически не просты; это способ подключиться к низкоуровневой диспетчеризации JVM, чтобы получить скорость, необходимую для самостоятельного хостинга. Мультимед являются простыми - это просто вары с функциями отправки. – user 19 December 2012 в 23:28
  • 2
    С другой стороны, если вы новичок Clojure, и вы думаете, что вам нужен полиморфизм, есть хорошие шансы, что вы ошибаетесь. Настоящая потребность в определении новой полиморфной функциональности очень редко встречается в Clojure. – user 19 December 2012 в 23:30
  • 3
    @technomancy, не могли бы вы рассказать об этом? Для новичков clojure, которые используют мышление и работают определенным образом, сложно выполнять определенные задачи без полиморфизма. Можете ли вы придумать примеры, иллюстрирующие идиоматическую clojure над полиморфизмом? – Lindon 1 January 2017 в 22:17

Мне нравятся мультиметоды, когда вам не нужна иерархия классов. Например, если у вас есть база данных мультимедиа, и ваши записи похожи на {:media-type :video, :bytes ...}, то вы можете иметь мультиметод

(defmulti make-grayscale :media-type)

. Затем вы можете сделать различные

; in video.clj
(defmethod make-grayscale :video [record]
  (ffmpeg ... (:bytes record))

; in photo.clj
(defmethod make-grayscale :photo [record]
  (imagemagick ... (:bytes record))

. Таким образом, вы может избежать наличия центрального выражения cond, поэтому вы получаете модульность классов. Но вам не нужно проходить всю эту шаблонную иерархию классов «оболочка», которая для меня - это проклятие, которое нужно оставить для мира Java. Мультиметоды - это функции только и для меня больше clojuresque.

0
ответ дан Dax Fohl 22 August 2018 в 21:10
поделиться

Как упоминает Артур, мультиметоды более мощные и дорогие. В самом деле, протоколы можно рассматривать как частный случай mutlimethods, где функция отправки class. Конечно, на самом деле это не так, поскольку протоколы - это больше.

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

6
ответ дан M Smith 22 August 2018 в 21:10
поделиться

Протокол и мультиметоды являются взаимодополняющими и предназначены для немного разных вариантов использования.

  • Протоколы обеспечивают эффективную полиморфную отправку, основанную на типе первого аргумента. Поскольку он способен использовать некоторые очень эффективные функции JVM, протоколы дают вам лучшую производительность .
  • Мультиметоды позволяют очень гибкий полиморфизм, который может отправлять на основе любой функции аргументов метода. Мультиметоды медленнее, но очень гибкие

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

Случай, когда вы можете потребовать многоточие, выглядит примерно так:

(defn balance-available? [amount balance] (> balance amount))

(defmulti withdraw balance-available?)

(defmethod withdraw true [amount balance] 
  (- balance amount))

(defmethod withdraw false [amount balance] 
  (throw (Error. "Insufficient balance available!")))

Обратите внимание, что вы не можете использовать протоколы здесь по обоим причинам:

  • функция отправки должна использовать оба аргумента, чтобы определить, какую реализацию метода использовать (т. е. это многократный случай отправки).
  • Вы также не можете отличить тип первого аргумента (который предположительно всегда является числовым значением)
34
ответ дан tangrammer 22 August 2018 в 21:10
поделиться
  • 1
    спасибо за ответ, мне очень понравилось ваше объяснение – Sean Nilan 12 November 2011 в 03:16
Другие вопросы по тегам:

Похожие вопросы: