Clojure: Карты списков карт ... Как обойти любые анонимные структуры данных - PullRequest
1 голос
/ 14 января 2012

Привет, ребята: В java у всех нас был опыт использования нашего ide для «прохождения» глубины сложного типа данных:

dog.getCollar().getCollarTag().getName(); 

Однако в Clojure это становится нетривиальным, из-за отсутствия статической типизации.Как мы можем «защищать» или Clojure от комплексных объектов, которые могут поступать из вложенных структур данных?

1) Рекомендуемое «ограничение» глубины структур данных Clojure?

и

2) Распространенная идиома для работы со структурой аббревиатур с глубоко вложенными данными, которая предотвращает ошибки, такие как ошибочный выбор списка для карты или неправильный нижний / верхний регистр имени переменной?

Простите, если я немного озвучиваю здесь парадигму ... Возможно, такие ошибки эффективно ограничиваются постоянным тестированием в REPL. Однако мне было интересно, есть лиЕсть ли другие способы убедиться, что во время компиляции этот код является максимально корректным (например, модульные тесты, плагины IDE / emacs и т. д ...)

Ответы [ 5 ]

6 голосов
/ 14 января 2012

ключевые слова - ваш друг здесь

(def my-animals  { :dog {:collar {:tag {:name "fido"}}}})

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

(-> my-animals :dog :collar :tag :name)

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

Когда вы работаете в IDE с завершением кода, он анализирует код, а затем строит данные об этом коде, а затем анализирует эти данные, чтобы получить предложения.Если ваши данные являются декларативными (их можно «прочитать»), вы получите их даже без IDE.

ps: это приводит к тому, что стандартные слова о «коде это данные» неоднократно высказывались людьми, намного умнее меня:)

3 голосов
/ 14 января 2012

Проверка правильности ваших функций в REPL - хорошее начало. Хороший способ улучшить это - модульные тесты и, возможно, использование предварительных и постусловий (http://objectcommando.com/blog/2010/03/07/design-by-contract-with-clojure/).

При использовании ключевых слов ваш пример можно превратить в (get-in dog [:collar :tag :name]). И "модификации" с assoc-in или update-in.

2 голосов
/ 29 сентября 2013

Существует замечательная библиотека, которую я считаю действительно полезной в этом отношении, - библиотека Schema от парней, которые делают Prismatic. Он предоставляет возможность добавить необязательную типизацию для вложенных структур данных, таких как те, к которым вы обращаетесь в своем вопросе. Это может быть применено во время выполнения (или только при тестировании), чтобы подтвердить ввод ваших функций. Кроме того, он также служит отличной документацией, описывающей допущения, которые функция имеет при вводе (что немаловажно).

1 голос
/ 16 января 2012

How do we "defend" or Clojure against complexites that might arrive from nested data structures?

Вы не можете.Это один из недостатков этого языка.Если вы хотите статическую типизацию, тогда clojure - не ваша вещь.Многие люди рекомендуют использовать вложенные карты, которые являются медленными, не обеспечивают никакой безопасности и не являются типом данных.Карта - это тип данных, вложенных карт нет, они являются притворными объектами.Подобно javascript, clojure требует, чтобы программист следил за тем, чем на самом деле является содержимое различных фрагментов данных, так как фрагменты данных в Clojure являются составными частями, подобными 5 различным структурам данных, а не самими структурами данных.

1 голос
/ 14 января 2012

Цепные геттеры часто являются нарушением Закона Деметры . При этом вы связываете свой код со всей структурой данных, и это может быть сложно и сложно. В функциональных языках в качестве clojure более естественно использовать рекурсию и обработку последовательности, чтобы сделать ее простой и понятной. Итак:

  1. Скажи, не спрашивай. Вместо того, чтобы спрашивать «имя метки ошейника собаки», попробуйте попросить объект собаки или функцию высокого уровня сделать то, что вы хотите.
  2. Как говорит Понзао, тестируйте, тестируйте и тестируйте. Протестируйте репл, чтобы изучить ваши возможности и написать небольшие юнит-тесты как
...