Pull to refresh

Comments 127

Ошибка в названии статьи. Перед словом, начинающимся с согласной буквы предлог «в» заменяется на «во»
Ага, я в курсе. Название взял из дайджеста, и решил оставить так, как есть.
Если очень мозолит глаз — исправлю.
Проблема заголовка — 3 согласные подряд. Правильный пример с рыбой звучал бы как рыба во мраке.

В данном случае это наречие "Обход вглубину". А вот тут уже существительное с предлогом: "во глубине веков".

Тоже так думал, но в подавляющем большинстве источников по computer science на русском пишется раздельно. Думаю, в заголовке статьи играет роль факт, что следующий звук, [ф], является глухой парой звука [в], и интуитивно хочется их разделить заменой предлога на «во». В других случаях, например, «в глубину», «в примечании», «в предложении» такого желания не возникает. Жалко, у меня нет лингвистического образования, интересный вопрос. Прошу прощения за флейм.

После изучения Японского после каждой согласной хочется влепить гласную :-) "во голубину", "во поримечании"

А почему ваша статья «Используем возможности CSS4 уже сегодня с cssnext» не называется «Используем возможности CSS4 уже сегодня со cssnext»?

<зануда> c CиЭсЭс… </зануда> ну и подставь теперь сюда со

После позитивного опыта с Clojure, у меня сложилось мнение, что
писать на JavaScript в функциональном стиле, это лучший способ
испортить себе все впечатление об ФП. Как ни крути но JS это ООП язык
и функциональный стиль привнесен туда через сомнительного удобства
костыли. Кто хочет использовать функциональный подход, который сделает
разработку фронтенд приложений приятным времяпровождением, смотрите — Elm, ClojureScript, PureScript.

А по каким критериям вы определяете ООП язык и функциональный?

Представьте, что вы создаёте мир, и создаёте новую функцию — двери. Они могут быть закрыты или открыты, ограничивают или открывают доступ в комнату. [...] myDoor не будет видоизменяться (если мы будем придерживаться функционального подхода), поэтому мы получим новый объект "дверь", если мы откроем её

То есть на самом деле, мы больше не можем открыть или закрыть дверь. Мы можем получить новую дверь, которая открыта или закрыта… но мы не можем открыть существующую. И мы не можем заменить дверь в той комнате, куда мы хотим попасть, с закрытой на открытую, потому что для этого понадобится изменить комнату. И так далее.


Так что — в рамках метафоры — задача-то на самом деле не решена. М?


В функциональной версии, функция open может может открыть всё, что имеет boolean locked свойство.

Это, простите, преимущество функционального подхода? В ООП все, что имеет контракт Openable, имеет метод Open, который делает все то же самое, и свойство IsLocked, который отвечает на вопрос, заперт ли объект — и при этом это свойство нельзя назначить снаружи.


При этом в реальности ваша простота достигается за счет того, что JS — динамический язык, и вы делаете копирование любого объекта средствами языка, и вам не нужны проверки компилятора на наличие изменяемого вами свойства. А теперь попробуйте сделать все то же самое в статически типизируемом языке.


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


ФП позволяет писать небольшие, чистые функции, которые следуют Unix концепции: Do One Thing and Do It Well.

А ООП не позволяет? SRP, не?


В версии с ФП, myDoor это чистые данные, которые могут быть импортированы из файла JSON или получены из REST API.

… и изменены любым образом без контроля со стороны бизнес-логики, ага. Это же "просто данные".


Например в языке Elm, компилятор предупредит тебя, если ты забудешь о case в операторе switch.

Эээ, статический анализатор для перечислений есть для любого языка, в котором есть нормальные перечисления.


Функциональный стиль передаёт больше информации о цели программиста,

А на чем основано это громкое утверждение?


При этом, хочу заметить, что я ничего не имею против ФП, я сам с удовольствием его использую. Но вот применяемые в статье аргументы… гм.

Отличные комментарии, действительно, примеры возможно не самые подходящие. Но для новичка в ФП, они достаточно наглядно показывают его в действии.
Единственно предназначение этой статьи, показать что функциональное программирование можно использовать в JavaScrip, заинтересовать. Поэтому автор в конце оставил несколько ссылок, чтобы читатель мог подробнее ознакомиться, и сделать для себя вывод: использовать или нет.
К сожалению, ответить на ваши вопросы я не могу, потому что не я автор статьи и с ФП только начал своё знакомство.
Но для новичка в ФП, они достаточно наглядно показывают его в действии.

… показывают неправильно и вызывают вопросы.


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

Чтобы заинтересовать, надо показывать преимущества. А в коде в вашем посте не видно никакого преимущества от использования ФП.


К сожалению, ответить на ваши вопросы я не могу, потому что не я автор статьи и с ФП только начал своё знакомство.

Вот за это я и не люблю переводы на хабре.

Для новичка они ужасны, т.к. вместо того, чтобы показать в чем достоинство ФП, они будут смотреть на этот пример с дверью не понимая, нафига козе баян.

Но самое главное. Все эти попытки противопоставления ФП и ООП, они подобны потивопоставлению картошки и апельсин. Зачем они?
То есть на самом деле, мы больше не можем открыть или закрыть дверь. Мы можем получить новую дверь, которая открыта или закрыта… но мы не можем открыть существующую. И мы не можем заменить дверь в той комнате, куда мы хотим попасть, с закрытой на открытую, потому что для этого понадобится изменить комнату. И так далее.

Напомнило анекдот про пепельницу в «Мерседесе». Функциональный подход, когда это еще не было мейнстримом )
… показывают неправильно и вызывают вопросы.

В конкретном примере нет никаких ошибок.
Вызывают вопросы? Прекрасно, есть стимул продолжить изучение!
А в коде в вашем посте не видно никакого преимущества от использования ФП.

Все преимущества так же расписаны.
Вызывают вопросы? Прекрасно, есть стимул продолжить изучение!

Скорее стимул не тратить зря время и пользоваться более перспективными подходами.
В конкретном примере нет никаких ошибок.

Есть: задача не решена.


Все преимущества так же расписаны.

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

JavaScript обычно используется в ООП, но ничто не мешает нам использовать его в функциональном программировании.

Мешает отсутствие гарантий и соответствующих оптимизаций.


Краткость. По мере роста кода, его сложнее поддерживать, а функциональный код более краток.

const open = obj => obj.locked = false

const myDoor = {
  color: 'red',
  locked: true,
}

open(myDoor)

Этот код делает ровно то, что и ваш функциональный. А тот код, что вы привели для ооп делает несколько большее — он использует инкапсуляцию для обеспечения полиморфизма.


Переиспользование. В функциональной версии, функция open может может открыть всё, что имеет boolean locked свойство. В будущем, мы можем сделать сундук и использовать ту же функцию, чтобы открыть его.

В итоге у вас будет сундук в состоянии "открыт" и состоянии "опечатан" одновременно, ведь ваша функция open знать не знает, что у сундука (но не у имейла) при открытии должна разрываться "печать". Для переиспользования нужен полиморфизм. В ФП полиморфизм тоже возможен, но для этого нужна множественная диспетчеризация, которую в JS не завезли, что делает "как бы ФП" в JS ещё более бессмысленным.


Неизменность. По мере роста кода, будет всё сложнее отслеживать объект myDoor в ОО версии (он уже был открыт на строке х?)

Вешаем "акцессор" и можем в нём хоть брейкпоинт ставить, хоть логгер вызывать.


Данные. В версии с ФП, myDoor это чистые данные, которые могут быть импортированы из файла JSON или получены из REST API.

А преимущество в чём? Состояние объекта вы так же легко можете десериализовать, при этом объект сразу же и проверит всё ли правильно пришло. А где выстрелит ваше ружьё — одному демону Максвелла известно.

> использует инкапсуляцию для обеспечения полиморфизма.

Ваш код полиморфизм обеспечивает не хуже, строго говоря.Инкапсуляция тут ни при чём.

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

Кстати, почему решили, что locked обязано быть boolean? А если это 3-х позиционный замок: открыто, закрыто, открыто но на цепочке? И вот, весь показанный бонус от ФП пошел лесом. В то время как в солучае ООП мы проблем не получили.
Состояние объекта вы так же легко можете десериализовать

А состояние всей системы? :)

Это ещё проще — обычный дамп памяти.

Обычный дамп памяти — это сериализация. А вот обратно...

А обратно просто загружаем образ и продолжаем работать. SmallTalk так работает.

Еще одна статья, которая имеет лишь громкий заголовок, но при этом не показывает ни достоинства ФП, ни недостатков ООП. Зачем?

Каждая статья из серии «ФП лучше ООП», всегда выглядит одинаково:
— «вот есть неизменяемость!» (которая дает преимущество ТОЛЬКО в многопоточной среде, но при этом имеет огромный ряд недостатков; лепить его везде — глупо! этим инструментом нужно пользоваться осмысленно!),
— «вот есть чистые функции!» (это хорошо, но без побочных эффектов невозможно построить ни одно приложение),
— «а ООП — это вообще фу-фу-фу!»

На самом деле, чисто ООП — не самая лучшая парадигма, но и чисто ФП — тоже!
Идеал — золотая середина между ООП и ФП!
А есть интересные статьи на тему ООРП?

Конечно.


Кроме того можно погуглить по следующим ключевикам: KnockoutJS, CellX, MobX,

А что-то более абстрактное, теоретическое, а не привязанное к определенным библиотекам в JS?
На самом деле, проблема этой статьи видна уже в первой строке:
Заинтересовался темой функционального программирования, увидел здесь статью, и решил перевести


Проблема не в том, что статья плохая, неправильная и т.д. А в том, что для того, чтобы сравнивать достоинства и недостатки различных подходов программирования нужно потратить хотя бы пару лет используя эти подходы на практике. Причем практика должна быть не уровня «Hello world», а реальные и желательно большие проекты, чтобы писать их не в одиночку стдя на удобном диване, а в команде из хотя бы нескольких человек, и что бы то, что вы пишите потом интегрировалось с кодом написанным другими командами.
В ООП тоже никто не отменял иммутабельность.

Я бы так переписал приведённый пример:

    public interface IDoor 
    { 
        IDoor Open();
        IDoor Close();
        bool Locked();
    }

    public class OpendDoor: IDoor 
    {
        private readonly string _color;
        private bool _isOpend = true;
        public OpendDoor(string color) 
        {
            _color = color;
        }

        public IDoor Open() 
        {
            return this;
        }

        public IDoor Close() 
        {
            return new ClosedDoor(_color);
        }

        public bool Locked() 
        {
            return !_isOpend;
        }
    }

    public class ClosedDoor: IDoor 
    {
        private readonly string _color;
        private bool _isOpend = false;
        public ClosedDoor(string color) 
        {
            _color = color;
        }

        public IDoor Open() 
        {
            return new OpendDoor(_color);
        }

        public IDoor Close() 
        {
            return this;
        }

        public bool Locked() 
        {
            return !_isOpend;
        }
    }

    var myDoor = new OpendDoor("red");
    myDoor = myDoor.Close();
… и зачем так сложно?

Не говоря уже о том, что в ООП как-то принято[кем?] как раз изменяемое состояние, и есть ожидания, что метод Close не вернет новую дверь, а закроет существующую.
А необходимо неизменяемо — всегда можно сделать door.Clone().Open(). И, главное, такой подход имеет ожидаемое поведение.
Принято — это относительно. Половина заточенного на fluent возвращает новые классы.
Хотя переименовать myDoor = myDoor.GetClosed(); для ожиданий было бы лучше
Зависит от того, какой именно fluent. Например, builder часто просто мутирует внутренний объект конфигурации, и возвращает сам себя.

А так — любые конвенции относительны.
Это выглядит сложным и избыточным на таком простом примере.

А может кадый раз содаётся новая вселенная когда её состояние меняется?! Или их изначально безконечное количество, а момент набудения реализует его в конкретном состоянии. )) Это в шутку.

А вообще гараздо легче создать всё заного, чем задавать переход от каждого состояния в другое. Ведь если состоянии N количество, то возможность всех переходов N * (N-1). А создание всех возможных состоянии изначально, дает возможность описать программу декларативно. Будет писаться, не как доидти до конкретного состояния, а просто потребовать воссоздать конечный результат.

Хорошим примером здесь будет, то как React подходит к решении этой проблемы в фронте.

Кароче суть одна и та же, как я считаю.

Вам вовсе не нужно описывать все возможные переходы.

Это выглядит сложным и избыточным на таком простом примере.

Ну так приведите пример, где это не выглядит избыточным. Зачем нам плохие примеры?


А может кадый раз содаётся новая вселенная когда её состояние меняется?!

Угу. Накладные расходы посчитайте.


А вообще гараздо легче создать всё заного, чем задавать переход от каждого состояния в другое

Вам не нужны переходы из каждого состояния в каждое — только валидные. И, скажите мне, как вы создадите заново новое состояние на основании старого, не описав переход из старого состояния в новое?


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

Серьезно? Вот у вас все возможные состояния результата калькулятора — это все множество чисел. И как бишь вы декларативно опишете такую программу?


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

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


(кстати, интересно, как машины состояний пишутся на прологе)

Ну так приведите пример, где это не выглядит избыточным. Зачем нам плохие примеры?

Выглядит сложным и избыточным, совсем не означает, что он таким является. Ключевое слово «выглядит». А плохим примером, он вовсе не является и я такого не писал. Раз этот для вас плохой, может просвятите хорошим примером?!

Угу. Накладные расходы посчитайте.

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

Вам не нужны переходы из каждого состояния в каждое — только валидные.

Я сказал что если состоянии N количество, то возможность всех переходов N * (N-1). Ключевое слово «возможность».

Серьезно?

Да преставте себе такое, не трудно.

new Sum(x, y).Result()


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

Вот именно, нужно знать, каким условиям он удовлетворяет и я опишу это конечное состояние, удовлетворяя эти условия, а не путь как до него дойти с предыдущего состояния.
Императивный код всегда можно спрятать под красивую абстракцию. (Это чтобы вы не подумали что я всегда буду писать декларативно и не буду пользоваться if-ом или о чём вы там подумаете). Если поддерживаемость кода важна, то к такому всегда нужно стремиться.

(кстати, интересно, как машины состояний пишутся на прологе)

Да мне тоже интересно, могли бы вы привести пример, а не писать раздражающие комментарии?!

Выглядит сложным и избыточным, совсем не означает, что он таким является. Ключевое слово «выглядит».

Ну тогда покажите, почему он не избыточный.


Раз этот для вас плохой, может просвятите хорошим примером?!

Нет, не просвещу.


Там был и второй вариант, но мне и первый нравится.

У второго варианта тоже очень высокие накладные расходы.


Можете придумать свой и посчитать.

Да легко. Изменяющееся состояние — O(1) по операциям, O(1) по памяти (для того же примера с дверью, конечно).


Я сказал что если состоянии N количество, то возможность всех переходов N * (N-1). Ключевое слово «возможность».

А зачем мне все возможные переходы?


Да преставте себе такое, не трудно. new Sum(x, y).Result()

Это не декларативное описание. Точнее, оно ничем не декларативнее x + y.


Вот именно, нужно знать, каким условиям он удовлетворяет и я опишу это конечное состояние, удовлетворяя эти условия, а не путь как до него дойти с предыдущего состояния.

Но конечное состояние зависит от предыдущего. Значит, вам придется описывать то же множество условий (и то же множество переходов).


Императивный код всегда можно спрятать под красивую абстракцию.

Не всегда. Точнее, можно — но им будет нельзя пользоваться (в определенных случаях, конечно).


Если поддерживаемость кода важна, то к такому всегда нужно стремиться.

К какому "такому"?


Да мне тоже интересно, могли бы вы привести пример

Нет, я не разбираюсь в Прологе.

Раз этот для вас плохой, может просвятите хорошим примером?!

Я, собственно, считаю, что лучшие примеры на неизменямое состояние — это конкурентность. Но это сложные примеры, и у меня сейчас готового под рукой нет.

А создание всех возможных состоянии изначально, дает возможность описать программу декларативно. Будет писаться, не как доидти до конкретного состояния, а просто потребовать воссоздать конечный результат.
Есть два банковских аккаунта, с одного нужно списать, на другой зачислить, в конкурентной среде. Будет интересно посмотреть на ваш подход с воссозданием всех конечных результатов на неизменяемых объектах.
Сталкивался с мнением, что основная фишка ООП, по сравнению с классическим императивным программированием, это «идентити» объектов. То есть если у нас две ссылки на один и тот же объект, то изменения, сделанные через одну из них будут видны и через вторую.
А без мутабельности объектов это смысла не имеет.
Человек, от которого я этот тезис слышал, занимался тогда трансформацией программ на уровне исходного кода — возможно, это специфический для этой области взгляд.
Сталкивался с мнением, что основная фишка ООП, по сравнению с классическим императивным программированием, это «идентити» объектов. То есть если у нас две ссылки на один и тот же объект, то изменения, сделанные через одну из них будут видны и через вторую.

В "классическом императивном программировании" это тоже прекрасно работает, безо всякого ООП.

Собственно в той беседе утверждалось, что с появлением malloc программу можно считать объектно-ориентированной. А наследование, полиморфизм и инкапсуляция не принципиальны.

Ну на этом беседу можно и закончить, потому что ни к одному традиционному определению ООП это отношения не имеет.

И еще раз кстати. Уж если вы говорите о выражении доступных состояний, то:


    interface IDoor  
    { 
        bool IsOpen {get;}
    }

    interface IClosedDoor: IDoor
    { 
        IOpenDoor Open();
    }

    interface IOpenDoor: IDoor
    { 
        IClosedDoor Close();
    }

Но мы, по факту, пришли к нормальному такому типу-перечислению, осталось только избавиться от IsLocked в пользу type tag.

так много интерфейсов… кажется что здесь нет абстракций, а какая-то функциональщина.

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

я согласен с вашими словами, но мне кажется здесь слишком много букв и строк для написания простых вещей, на каждый чих писать интерфейс мне кажется перебор… скорее всего проблема уже складывается в том что нужна предметная область, а уже потом городить кучу интерфейсов… на мой взгляд
скорее всего проблема уже складывается в том что нужна предметная область, а уже потом городить кучу интерфейсов…

А это и есть предметная область — выраженная в коде. Более того, в этом коде сразу, статически описаны допустимые переходы состояний.

просто я не понимаю чем выше привиденный пример лучше чем
doorOpen :: Boolean, в плане того что мы не знаем предметной области, так для шутки…

Например тем, что если вы попробуете открыть открытую дверь, ваш код не скомпилируется.

долго думал об этом…
Интерфейс как мне кажется это нереализованный протокол, если код `не скомпилируется` это конечно лучше того что он `скомпилируется`.
Но все равно не понятно для какого случая столько интерфейсов?
Может в таком случае выделить дверь как сущность? для этого надо только будет определить возможные состояния с требованиями бизнес логики и избавится от лишних предсказываний.
Интерфейс как мне кажется это нереализованный протокол,

Нет, интерфейс — это формализованная договоренность.


Но все равно не понятно для какого случая столько интерфейсов?

Не "столько интерфейсов", а "столько типов". Для случая, когда каждое состояние описано типом.


Может в таком случае выделить дверь как сущность?

Ну так она и выделена.


для этого надо только будет определить возможные состояния

Они и определены: закрыто и открыто.

«Нет, интерфейс — это формализованная договоренность.»- о чем я и говорю, но протокол это уже реализованная…

«Не „столько интерфейсов“, а „столько типов“. Для случая, когда каждое состояние описано типом.» — Вы сейчас это оговариваете в ФП стиле? или я ошибаюсь?(я с Вами согласен в таком случае, да и вообще согласен)

«Может в таком случае выделить дверь как сущность?» — интерфейс не выделяет сущностей, я с Вами не соглашусь если вас правильно понял.

«Они и определены: закрыто и открыто.» — Вы определили интерфейсы, но к двери(как к модели предметной области это не как не относится(хотя меня уже здесь обругали что это пример и я зря придираюсь, но все же? у нас нет контекста для обсуждения приведенных примеров))
*на автомате скопировал*
«Ну так она и выделена.» — это интерфейс, но не реализация
о чем я и говорю, но протокол это уже реализованная…

Нет, "протокол" — это тоже договоренность. Реализация существует отдельно.


Вы сейчас это оговариваете в ФП стиле?

Нет, не важно, ООП или ФП.


интерфейс не выделяет сущностей

Почему это?


это интерфейс, но не реализация

И что? Для доменной модели это не важно.


Вы определили интерфейсы, но к двери(как к модели предметной области это не как не относится

Почему не относится?

1) интерфейс — «это тоже договоренность», «Реализация существует отдельно» — протокол общения, тут уж слишком мы зависим от языка, я английский не очень понимаю, но на русский язык это перекладывается имено так…
и да… на русском языке протокол это уже реализация, а не бумажки и интерфейс.

2) `Не «столько интерфейсов», а «столько типов». Для случая, когда каждое состояние описано типом.` — описать каждое состояние типом… ну мне кажется это уже перебор, тут скорее всего надо включать не типы а абстракции и коллекции типов… вообщем лучше абстрагироваться… хотя вполне возможно. я Вас не так понял

3)это интерфейс, но не реализация — `И что? Для доменной модели это не важно.` — доменная модель также проекцируется и на реализацию, если не реализовывать в рамках доменной модели, тогда и модель теряется…

4) Вы определили интерфейсы, но к двери(как к модели предметной области это не как не относится

`Почему не относится?` — вы не определили сам контекст… ради бога я могу еще больше накатать интерфесов… но где их оправдание, так же как нет оправдание этой статьи…
описать каждое состояние типом… ну мне кажется это уже перебор

Зависит только от того, насколько сильные гарантии вы хотите в статическом анализе. Кто-то вообще считает статические системы типов перебором.


тут скорее всего надо включать не типы а абстракции и коллекции типов… вообщем лучше абстрагироваться…

Тип — это и есть абстракция.


доменная модель также проекцируется и на реализацию,

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


вы не определили сам контекст

Контекст определен постом.


но где их оправдание

Их оправдание — желание статической верификации корректных переходов.

ну и я надеюсь эта тема утихла, что бы можно было общаться без превличения особо неспокойных пользователей этого ресурса
если к этому прибавить preg maching то получается совсем ерунда и излишества
Object -> close or open
function switch()…

"Если бы у бабушки были яйца..."


Это не то что бы излишества, это пример type-driven-программирования в парадигме, которая для этого не очень подходит. Зато статическое выражение возможных переходов и операций.

Так и изначальный пример был избыточен, потому что нет никакого смысла в иммутабельности для такой задачи. Но уж если мы решили брать иммутабельность, то почему бы заодно и не взять type-driven?

вот тут я туплю если честно.
в плане определения type-driven. Пример явно глупый, настолько глупый что он не показывает даже 30% ФП, но я не думаю что в данном случае надо применять ООП для примера, скорее надо показывать примеры из ФП, то есть вместо осуждения, привести примеры где это может пригодится. Замечу еще раз… Я могу ошибаться.
скаже так, я сейчас пишу детский проект для себя(потренироваться), на выходе должен быть игрок и поле, через какое-то время должна появится куча зомби, у игрока есть возможность скрыться в доме, тоетсь не смысла городить кучу интерфейсов… есть просто дверь в которую можно войти или нет.
Есть смысл городить именно столько интерфейсов, сколько необходимо, но не больше. Для примера, чтобы объяснить какую-нибудь концепцию можно нагородить больше интерфейсов, чем было бы необходимо в детском проекте для себя и при этом их будет значительно меньше, чем необходимо в огромном проекте про двери.

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

bool isDoorOpened = true;

isDoorOpened = false; // закрыли
isDoorOpened = true; // открыли

А дальше просто усложняем соответственно необходимым бизнес-требованиям.
Я могу ошибаться… сразу подчеркну этот момент.
дело не в уничтожении и создании двери(я так понимаю Вы говорите про ФП), На первых порах можно воспринимать ФП как своеобразный гибкий конвейер ответов.
Потом уже можно воспринимать как гибкую систему, сама проблема восприятия ФП такими недопрограммистами как я — это терминология.
Меня по началу сбивало с толку тот момент что функция применяется к аргументам(я привык к терминологии что в функцию передаются аргументы). Дело не в создании двери, а в ответе, скажем так, на Ваш вопрос что это за дверь, можно на каком-то этапе забыть про то как работает ПК. код вам просто возвращает дверь к которой вы обратились и т.д… просто попробуйте ФП язык. Я думаю Вы работали с SQL, он такой же как и ФП
Дело не в создании двери, а в ответе, скажем так, на Ваш вопрос что это за дверь

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

технически… я сейчас рассуждаю о императивном и декларативном стиле

Угу, а теперь покажите, как программа "отвечает на вопрос, что за дверь" в декларативном и императивном стиле, и так, чтобы была видна разница между этими стилями.

И какой из них какой?


(вторую запись, впрочем, я вообще не могу прочитать)

preg matching — это что-то из PHP, я так понимаю? то есть, императивный стиль? Извините, но что он делает, понять невозможно.


А вот первая ваша запись (getDoor(val)) может быть как из процедурного (а они императивны), так и из функционального (а они считаются декларативными) языка, так что и вовсе не понятно, что вы чему противопоставляете.

я устал, Вы и так знаете что я меньше вас знаю и у меня меньше практики… так зачем этот каламбур?
я и так знаю что Вы меня уделаете знаниями и практикой, стоит ли продолжать?
и за что минус?(обычный вопрос на хабре как я заметил, аргументируйте или вам не хватает смелости? я лично признаю свои ошибки...)
Дело не в создании двери, а в ответе, скажем так, на Ваш вопрос что это за дверь, можно на каком-то этапе забыть про то как работает ПК. код вам просто возвращает дверь к которой вы обратились и т.д… просто попробуйте ФП язык

Простите, у вас какая-то каша. Как минимум в комметарии. Что-то намешали — на разгребтись.
Я прекрасно понимаю концепцию ФП, к чему это ваше «попробуйте»?

Если у меня в игре есть огромный мир, в котором есть дверь, которую персонаж может открыть, то при чем тут «вам просто возвращает дверь к которой вы обратились»? Есть вполне логичная задача — открыть закрытую дверь, а не вернуть дверь.

Вы можете себе представить крупное приложение на SQL? И еще вопрос:
const open = obj => Object.assign({}, obj, {locked: false}) 


Вы считаете, что это декларативно? Обычная императивщина. Я не понимаю, почему ФП называют декларативным. Практически все примеры, которые я видел что из практики, что из комментариев «отличные примеры ФП» — глубоко императивны — «сделай А, сделай Б, сделай В». Иногда проскакивает декларативность, но она точно так же проскакивает и в других парадигмах.
А почему list? С каких пор дверь — список?
это такой намек…
DDD — проектируйте модель — подберите парадигму — да вообще проектируйте моделью предметной областью.

декларативный
императивный
сумашедший
недоразвитый

включайте ум… ум… ум… о… грибок)))) о чем я?
я не вижу смысла обсуждать с Вами эти вопросы.
включайте ум

Очевидно, вы сообственным советом решили не пользоваться, когда писали сообщение.

Из-за этого все остальное не понял.

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

Эх не могу плюсануть, но я думаю что я еще не дорос до такого диалога, еще слаб в знаниях и практике… но спасибо за feedback.
тут нет смысла радоваться, определена предметная область и границы… но я не собираюсь заранее создавать кучу кучу кучу… которую потом разбирать
самое главное из всего этого текста и много букв одно…
не какой связи со статьей, прям даже стыдно, стыдно должно быть… а только философские размышления и притянутые за уши примеры.

Какой глубокий и оригинальный комментарий. Вы не потрудитесь его, может быть, развернуть, привести цитаты и примеры?

Немного позже…
Забегая вперед. Речь в статье о ФП, а комментарии бог знает о чем, вместо того чтобы добавить хоть пару копеек к статье и по теме статьи у нас как всегда(runet). Закидали комментариями и за каким-то чертом прикрутили сюда ООП и вообще о чем мы сейчас беседуем?
О чем вы? Как можно ТАК выпасть из контекста? Статья сравниваниет ФП с ООП и указывает о каких-то мифических, притянутых за уши преимуществах. Об этом и идет спор в комментариях. Например, цитата из статьи:

во-первых, функциональным образом:
// код ФП

И теперь, объектно-ориентированный:
// код ООП

Итак, какие преимущества ФП мы можем здесь увидеть?


То есть при чем тут комментарии? Статья своей слабостью сама привела к такому обсуждению.
Ну так вы человек очень разумный, почему вы не можете указать на минусы и указать как лучше было бы сделать все сказанное в статье ближе к ФП?
Я, как человек разумный, считаю, что в JS ФП как замена ООП — не более чем хайп, практического смысла не имеет и несет вред, а не пользу, потому на ваш вопрос ответа нету. ФП уместно применять в некоторых, узких и подходящих для него задачах, а потому данная тема в такой постановке вопроса в любом случае будет ошибочной.

фп хорошо применяется в паралельщине(как один из вариантов), и уберите ваши учебники...

фп хорошо применяется в паралельщине

Опять мимо — этот аргумент абсолютно бессмысленен в JavaScript. А я акцентировал, что речь именно об этом языке.

что в JS ФП как замена ООП — не более чем хайп

Выключите, наконец, гугл и включите мозг.
за каким-то чертом прикрутили сюда ООП

Открываем статью, видим заголовок:


Функциональное против Объектно-ориентированного

Так за каким же чертом автор статьи прикрутил сюда ООП?


(то же и в комментариях: сравнивают реализации одного и того же в ОО и функциональном стиле)

Ну я думаю Вы больше можете сказать где проблема в статье, и как лучше было бы это все написать в ФП стиле… хотя это не Ваша забота, Вы же архитектор.

Так я уже сказал, где проблема в статье. И именно поэтому не вижу смысла в вопросе "как лучше было бы это все написать в ФП-стиле", потому что тут нет задачи, которую надо решать в ФП-стиле.

может быть, по этому Вы написали 3 интерфейса к двери… ну что могу сказать хвалебно, похлопаю дверью))) той которою вы описали… в трех интерфейсах, ну да такую еще надо найти...)))
я приторможу… вы хотя бы сами определитесь что такое ФП. А потом по возможности сделайте примеры, а то как то от Вас скудно все это…

А зачем мне это?

ну вот вам дверь… вот вам бизнес модель, вот вам ddd… зачем нам нужны ваши 3 интерфейса?

Как — снова — говорилось выше, вам 3 интерфейса, возможно, низачем не нужны. Это не значит, что нет людей, которым они нужны (точнее, три типа, а не три интерфейса).

так дайте это в ФП… хватит уже ваших филосовских размышлений, дайте код уже наконец-то… прошу Вас Архитектор

"Дайте" что в ФП? Код чего?

я бы с радостью поставил минус, но не моугу…
Код двери хотябы… ну что Вы совсем не можете? ну определите в моделе, ну в рамках задачи, ну хватит дурачится, напишите уже пожалуйста. пожалуйста в рамках ФП, вы же можете…

"Код двери" — это бессмысленная просьба, за этим нет ни бизнеса, ничего. И совершенно не понятно, зачем эту задачу решать в функциональной парадигме.

Классическая статья по функциональному программированию на хабре
1. ООП — плохо
2. Надуманный простенький пример, на основе которого делаются далеко идущие выводы
3. Три строчки, запланированные на статью, израсходованы, поэтому до свидания!
Вы читаете заголовок вообще? Это перевод. Тут от меня ни слова. Про то что ООП — плохо, в статье тоже нет ничего.
Очень показательное первое знакомство с аудиторией хабры.
Ну так надо же выбирать, что переводите.
Я и выбрал. Статья из еженедельной подборки по фронтенду, ссылка в самом начале моего перевода.
Мне казалось, что эту подборку делают компетентные люди. Но получается, что там не качественные статьи выкладывают? Хорошо, в следующий раз, буду тщательнее выбирать статью
Но получается, что там не качественные статьи выкладывают?

Получается так.


Просто не надо переводить статью по теме, в которой вы ничего не понимаете. Это со всех точек зрения опасно.

Я читал заголовок. И он о функциональном программировании во фронтэнде. Единственный же приведенный пример в статье — какая-то непонятная дверь. Если она и имеет какое-то отношение к фронтэнду, то это никак не поясняется. Или тему раскрывает список ссылок в конце? Тогда это совсем несерьезно. Ну а то что это перевод, автоматически качество материала не повышает.

Под капотом функциональных фронтенд-языков лежит вполне себе императивный браузер. Сомневаюсь, что без императивного движка можно нарисовать интерфейс. Поэтому не стоит возводить ФП или ООП в абсолют. Использование ООП в императивных программах имеет свои преимущества.


Делал как-то в университете лабу на Прологе с GUI. Так себе удовольствие. Например, надо как-то отрисовывать меню на экране, хранить номер выделенного пункта и при этом реагировать на нажатия клавиатуры, изменяя его. Это помимо основного состояния, которое тоже меняется при выполнении команды меню. Хранил счетчики во встроенной базе данных. Может и по-другому как-то можно было.

под любым ФП лежит ИП(императивное программирование, ну оно как бы выросло из инструкций ЦП)
Благодарю за перевод статьи. Правда со старта не понятно, как ФП можно применять в Angular, в полной мере. Но тем ни менее, знать и уметь очень хорошо.
Sign up to leave a comment.

Articles