Я хотел бы запустить сеанс о Clojure. Не могли бы вы порекомендовать проблему, которая может быть элегантно решена с помощью функционального программирования с Clojure? Можете ли вы указать на ресурсы, которые охватывают эту тему?Что такое хорошая витрина для Clojure?
ответ
Много аргументов для использования Clojure, как представляется, связано с его обработкой параллелизм, но я не буду касаться этого вопроса здесь.
Я расскажу о некоторых проблемах, с которыми я вынужден работать неделю, неделю с Java, и как я их решаю в Clojure.
Неизменность
В Java достижение неизменности очень и очень трудно. Помимо строгих правил кодирования, вам придется очень тщательно выбирать свои структуры и библиотеки. Кроме того, в качестве побочного эффекта вы либо напишите много кода, чтобы сделать чистый и полезный API, либо просто заставите клиента справиться с этим.
final Person person = personDao.getById(id);
// I would like to "change" the person's email, but no setters... :(
В Clojure вы модель данных на основе неизменных структур данных, поэтому все объекты являются неизменяемыми по умолчанию, и из-за этого Clojure предлагает мощные функции, которые работают в этих структурах.
(let [person (get-by-id person-dao id)
person-with-email (assoc person :email email)]
; Use person-with-email...
Конверсия
В Java у вас есть домен класс Person
с полями id
, name
, email
, socialSecurityNumber
и другими. Вы создаете веб-службу для получения имен и писем всех лиц в вашей базе данных. Вы не хотите раскрывать свой домен, чтобы создать класс PersonDto
, содержащий name
и email
. Это было легко, поэтому теперь вам нужна функция для сопоставления данных от Person
до PersonDto
. Возможно, что-то вроде этого:
public class PersonPopulator {
public PersonDto toPersonDto(Person person) {
return new PersonDto(person.getName(), person.getEmail());
}
public List<PersonDto> toPersonDtos(List<Person> persons) {
List<PersonDto> personDtos = new ArrayList<PersonDto>();
for (Person person : persons) {
personDtos.add(toPersonDto(person));
}
return personDtos;
}
}
Хорошо известно, что не так уж плохо, но что, если вы хотите поместить больше данных в DTO? Ну код конструктора в toPersonDto
будет расти немного, не стоит беспокоиться. Что делать, если есть два разных варианта использования: один, как указано выше, и другой, где мы хотим отправить только электронные письма? Ну, мы могли бы оставить name
нулевой (плохая идея) или создать новый DTO, возможно PersonWithEmailDto
. Таким образом, мы бы создали новый класс, несколько новых методов для заполнения данных ... вы, вероятно, видите, где это происходит?
Clojure, динамически типизированный язык с неизменяемыми структурами данных, позволяет мне сделать это:
(defn person-with-fields [person & fields]
(reduce #(assoc %1 %2 (get person %2)) {} fields))
(person-with-fields {:id 1
:name "John Doe"
:email "[email protected]"
:ssn "1234567890"} :name :email)
; -> {:email "[email protected]", :name "John Doe"}
И манипулировать список лиц:
(map #(person-with-fields % :name :email) persons)
Кроме добавления специальных данных к человеку будет легко:
(assoc person :tweets tweets)
И это ничего не сломает. В Java, если ваши объекты неизменяемы, у них, вероятно, нет сеттеров, поэтому вам нужно будет написать много шаблонов, чтобы изменить одно поле (new Person(oldPerson.getName(), oldPerson.getEmail(), tweets
)) или создать совершенно новый класс. Объекты Mutable предлагают хороший API (oldPerson.setTweets(tweets)
), но их трудно проверить и понять.
Тестирование
Много Java кода основана на некотором состоянии даже тогда, когда нет необходимости в этом. Это означает, что вы можете либо издеваться над этим состоянием, что обычно означает дополнительный шаблон и становится сложнее, если вы не создали свой код с возможностью проверки. С другой стороны, тесты без издевательств, как правило, медленны и зависят от доступа к базе данных или времени или чего-то еще, что будет время от времени терпеть неудачу.
При кодировании Clojure я заметил, что на самом деле мне не нужно столько состояния. Практически единственные ситуации, когда я извлекаю что-то из «снаружи», будь то база данных или какой-либо веб-сервис.
Резюме
Мой код трубы, с одной стороны я получаю некоторые данные, затем эти данные изменены в трубе с помощью фильтрации, преобразования или присоединения к нему с некоторыми другими данными, пока он не достигнет конца труба. Внутри трубы нет необходимости действительно изменять данные, но во многих случаях полезны мощные функции и неизменные структуры данных, поэтому Clojure работает с таким кодом.
Ничего себе, отличный пример. – defhlt
Мне понравилось резюме. Именно так я чувствовал себя во время работы с Clojure в течение трех месяцев. –
Классическая проблема параллелизма «Спящий парикмахер» может быть хорошей.
Вот несколько примеров
http://www.bestinclass.dk/index.clj/2009/09/scala-vs-clojure-round-2-concurrency.html
https://github.com/bitsai/clojure-actors/blob/master/sleeping_barber.clj
Пару месяцев назад я столкнулся с той же проблемой, и мы решили решить проблему «Моны Лизы» в Клоджуре. В результате получилось this presentation. В основном мы показали, что Clojure чрезвычайно крут для решения проблем, для которых «код как данные» дает элегантное решение. Например, в генетических алгоритмах.
- 1. Что такое Celery для Clojure?
- 2. Что такое Clojure?
- 3. Что такое Clojure volatile?
- 4. Что такое спецификация Clojure?
- 5. Что такое хорошая PHP CMS?
- 6. Что такое хорошая альтернатива для gitbash?
- 7. Что такое хорошая библиотека сжатия для Java?
- 8. Что такое хорошая многопоточная книга для Delphi?
- 9. Что такое хорошая функция поиска для словаря
- 10. Что такое хорошая среда для редактирования javascript
- 11. Что такое хорошая структура для создания игр?
- 12. Что такое хорошая графика для .Net?
- 13. Что такое хорошая система шаблонов для PHP?
- 14. Что такое хорошая замена для перечисления?
- 15. Что такое хорошая СУБД для архивации?
- 16. Что такое хорошая практика для абстрагирования дженериков?
- 17. Что такое хорошая стратегия для интеграции переключателей?
- 18. Что такое хорошая библиотека RDF для .net?
- 19. Что такое хорошая основа для мыльного обслуживания?
- 20. Что такое хорошая модель для атрибутов продукта
- 21. Что такое хорошая IDE для кодирования NASM?
- 22. Что такое хорошая архитектура для клиента API?
- 23. Что такое хорошая замена для matlabFunction?
- 24. Что такое хорошая система разрешений?
- 25. Хорошая альтернатива GWT для Clojure
- 26. Что такое Clojure для реализации for-loop?
- 27. Что такое эквивалент Clojure для seq.reduceOption Scala?
- 28. Что такое эквивалент Clojure для zipWithIndex Scala?
- 29. Что такое эквивалент clojure для Haskell's <-?
- 30. Что такое эквивалент Scala для Atom Clojure?
Какая сессия? Вы ищете проблему и решение, которое можно объяснить через час, день, неделю? Есть много возможностей. –
У нас есть регулярное мероприятие, посвященное компании, для демонстрации новых технологий. Он предназначен для 2-х рук на сеансе. – spa