Пытаясь понять clojure - PullRequest
       0

Пытаясь понять clojure

0 голосов
/ 04 февраля 2019

Друг пытается убедить меня в преимуществах clojure, и я делаю все возможное, чтобы понять язык.Я просмотрел множество веб-сайтов и пролистал книгу «Clojure for the Brave and True», но мне все еще чего-то не хватает.

Мой опыт в объектно-ориентированном программировании, и для меня это вторая натурачто программный объект представляет собой объект реального мира.Я читал, что clojure не является OO, но я не могу понять, что вместо этого делает clojure.

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

Пенсионный класс имеет годовой доход и годовой процентный прирост.У этого тоже есть метод снятия, но снимаемая сумма всегда является годовым доходом (увеличивается на процент каждый год).т.е. он рассчитывается не так, как Сберегательный счет.

В моей OO-программе оба эти класса реализуют протокол, который определяет метод Withdraw, поэтому мой код может обрабатывать их одинаковым образом без необходимости учитывать ихразличия.

Что в закрытом мире будет представлять Сберегательный счет и Пенсию.т.е. какие структуры собирают вместе данные для экземпляров и методы, которые работают с этими данными?В ОО класс определяет данные и методы.Экземпляр является уникальным вхождением данных.Мой файл кода, который определяет класс, говорит мне все об объекте, который представляет класс.Как clojure делает это, или что он делает вместо этого?

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

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

Большинство известных мне объектно-ориентированных программистов не программируют таким образом ,Когда я программирую на ОО-языках, я не программирую таким образом.За исключением возможных gamedev, большинство объектов в объектно-ориентированной программе имеют только самые незначительные соединения с объектами бизнес-доменов по той же причине, что most из моих таблиц SQL, как правило, только самые незначительные соединения с сущностями бизнес-доменов.

Деловые люди не заботятся о URIProcurerAbstractFactoryManagers или мостовых таблицах, потому что у них нет реального-world аналог.

Я упоминаю выше (а также немного о таблицах SQL), потому что дело в том, что большая часть того, что мы создаем в терминах программных артефактов, обязательно, но косвенно, связана с решением проблемы.Бэкенды HTTP для совершенно не связанных между собой вещей, скажем, банка и национальной благотворительной организации, будут выглядеть очень очень похоже (до такой степени, что имена файлов / каталогов / таблиц могут быть лучшим ключом к тому, на какой вы смотрите).Больше того, что мы пишем, больше связано с ограничениями типа проблемы, чем со спецификой самой проблемы.

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

Вы можете попытаться обрабатывать структуры данных clojure так же, как вы относитесь к объектам.Вы можете попытаться обращаться с реляционными таблицами так же, как с объектами.Но это не будет работать очень хорошо (см. Тернистую и проблемную историю ORM). Вы можете попытаться трактовать все объектно-ориентированные программные объекты как реальные аналоги, но это также не приведет вас слишком далеко.

Вы должны изучить новый способ думая о проблемах, и я бы даже сказал, что вы не сможете выбрать лучших , если вы хотя бы до некоторой степени не знакомы с большинством из них(спасибо за попытку выучить новое!).

0 голосов
/ 05 февраля 2019

@ M0skit0 имеет очень хороший ответ.Я хочу назвать конкретное упоминание.Вы спросили:

В моей OO-программе оба эти класса реализуют протокол, который определяет метод Withdraw

. Вы можете использовать методы класса без инкапсуляции.Посмотрите более внимательно на протоколы .Если ваш мозг уже мыслит в ОО, тогда вам следует подумать, что подход clojure состоит в том, чтобы позволить вам использовать протоколы, но вам это не нужно.Таким образом, термин «а ля карт полиморфизм».Ищите только некоторые ресурсы по этому термину, и вы найдете хорошие дискуссии, которые многие сочтут запутанными, но, возможно, вы найдете, что говорит с вашим мозгом.

0 голосов
/ 04 февраля 2019

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

У Clojure есть инструменты ООП, например, у вас есть defrecord и defprotocol.Но в своей основе он более функциональный, чем объектно-ориентированный, и вы ощутите его реальную выгоду, только если начнете мыслить функционально и неизменность .

Чтобы написать идиоматическую Clojure, вам необходимо переключитьсяваше мышление от объектов к функциям.На функциональном языке все вращается вокруг функций, а не данных (объектов).Данные представлены с использованием тривиальных структур данных, таких как карты.Вы не связываете функции с их данными, как в ООП.В вашем случае вместо класса Savings Account и класса Pension вам просто нужна структура данных для представления этих данных, например карта:

(def saving-account {:balance 0.0, :interest-rate 0.0})
(def pension {:annual-income 0.0, :annual-increase 0.0})

Метод Withdraw будет простобыть функцией для каждого случая, например:

(defn withdraw-from-saving-account [sa amount] ( <return updated saving account map> ))
(defn withdraw-from-pension [p] ( <return updated pension map> ))

В Clojure вы обычно хотите сохранить все неизменяемым, поэтому вышеприведенные функции возвращают новую обновленную карту и не изменяют никакого существующего состояния в существующих картах.Это дает некоторое время, чтобы привыкнуть к парадигме изменчивого состояния, такой как ООП Java.Идиоматическая Clojure (как и большинство функциональных языков программирования) в значительной степени основана на композиции функций (которая подразумевает короткие функции одной задачи, когда это возможно) и очень ограниченном использовании переменных.Если вы когда-либо использовали оболочку * nix, это очень похоже на команду piping / chaining.

Обратите внимание, что вы также можете упростить вышеуказанные функции, объявив один Withdraw multimethod .И если вы предпочитаете, вы также можете использовать типы данных для более точного определения данных и использовать протоколы для реализации интерфейса для этих записей, что ближе к тому, что вы делаете в Java.Главное, что вам нужно понять, это то, что, хотя Java вращается вокруг классов, Clojure вращается вокруг функций и неизменяемых данных, и чем больше pure функция, тем лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...