All streams
Search
Write a publication
Pull to refresh
52
0
Dmitry Non @Nondv

Software Engineer

Send message

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


На самом деле, большая часть проблем всех этих дискуссий связана с разной интерпретацией терминов.
Как по мне, в ФП вообще нет переменных (хотя я и использую это слово по привычке).


Например, в функции f(x) = x*x x правильнее называть "параметром" или "аргументом" в зависимости от контекста, что тоже порой может некоторую путаницу вызывать. Когда мы говорим о x как о чем-то абстрактном, это параметер. Когда мы говорим непосредственно о его значении, это аргумент (f(5) = 25). Как-то так.


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


Я почему-то вспомнил какое-то изречение Алана Кея (не вспомню источник). Если совсем коротко, то тезис был примерно таким, что мы слишком усложнили понятие ООП, т.к. изначально он всего-лишь подразумевал такие понятия, как "объект" и "посылка сообщений объекту".


Может быть, мы действительно слишком сильно пытаемся углубиться в высшие замыслы ФП, что отстраняемся от простых вещей вроде "mutability — зло", "side-effects — зло", которые по сути уже очень многое дают сами по себе.

писал сейчас большой ответ с примерами кода, но потом понял Ваш "point" и стер.
Собственно, признаю Вас правым, хоть и к некоторым вещам я все равно буду продолжать относиться по-своему (все мы видим мир по-разному, верно? Дайте мне насладиться своим личным безумием:D).


Спасибо, что уделили мне время

В таком определении у Вас состояние — это вся база данных + redis + ещё что-то. Слишком глобально и внешне к самому приложению.

Ну это уже в крайность. Все-таки, система взаимодействует с БД/редисом/чем-то еще, а не включает их в себя. (upd. да, видимо, я еще и неправильно пользуюсь термином "система")


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


Грубо говоря, вычисление выглядит так: f(g(h(k(x)))), где x — параметры запроса. Собственно, нас слабо волнует, что именно за запрос, нас волнует то, как в зависимости от этого запроса будет вычисляться результат. Например, k(x) может обращаться к БД и извлекать оттуда данные (params[:id]), h — как-то обрадабывать эти данные, например, преобразовать их в список чисел, следующая функция может возвести их в квадрат.


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


Как Вам?

Возможно, я что-то не то подразумеваю под состоянием.


Давайте разберемся. Я предполагаю, что в данном контексте состоянием является некоторый переменный(upd.) набор данных, принадлеащий системе.
Например, при добавлении значения в стек мы меняем его состояние, а именно:


  • количество элементов в нем
  • "верхний" элемент*
  • и т.д.
  • и т.п.

Функция-квадрат сама по себе никакого состояния не меняет. Функция — просто правило, по которому элементы одного множества сопоставляются другому. О каком состоянии может быть речь?


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


Примерно так выглядит мое понимание такого явления как функциональное программирование. Как же выглядит Ваше? Буду признателен, если поделитесь или укажите, где я не прав.

Как я успел осознать, неизменяемое состояние в ФП — это миф. Без изменения состояния невозможно что-либо "напрограммировать" (я не математик, поэтому не возьмусь доказывать это свое утверждение, а просто с умным видом поставлю восклицательный знак) !


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


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

Если честно, без особых объективных причин. Просто захотелось.


За Clojure стоит JVM, за Elixir, если не ошибаюсь, Erlang. Я встречал мнение, что чтобы использовать Erlang, нужно четко знать, в чем его преимущества и нужны ли они вам.


К тому же немаловажным фактором является то, что мне нравится Лисп с его простотой и однородной структурой. Можно сказать, что Clojure — это современный диалект Лиспа. А так работу можно найти и по тому, и по тому (видел таких людей). Тем более, что со временем количество вакансий будет только увеличиваться, имхо, причем в случае Clojure это будет происходить быстрее, поскольку некоторые компании, которые работают с Java начинают все чаще смотреть в сторону Scala, а там и Clojure недалеко.

Те, кто помнят экосистему Rails и Django времён 2008-2010 годов, могут оценить, что в том же Elixir ситуация с экосистемой уже гораздо лучше.

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

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

Зачем Вы меня перефразировали?:)

Мое мнение, как я уже упомянул, нельзя считать авторитетным:)
Под очевидными причинами я имел в виду:


  • приученность к императивной парадигме (если заставить школьника, который писал на паскале, писать на лиспе, то он будет писать на нем точно так же, как на паскале, просто со скобочками)
  • сложность обучения (частично вытекает из первого пункта).
  • отсутствие (пока что) развитой инфраструктуры. По Rails/Django/etc можно найти ответ практически на любой вопрос на SO, документация в рельсах достаточно неплоха (т.к. проект опенсорсный и при этом популярный, то понятное дело, что она постоянно улучшается), количество плагинов/гемов/модулей просто зашкаливает. Может этим похвастаться Haskell/Elixir? Сомневаюсь. Говоря о плагинах, можно упомянуть JVM, но:
    • по тому, что я успел увидеть в Clojure, у меня сложилось мнение, что использование Java-библиотек выглядит не очень естественно.
    • а Scala, видимо превращается в Scala-Java, что тоже по сути не ФП. Но это лишь предположение

На Хабре где-то была статья, где автор рассказал, что их компания отказалась от Scala в пользу Go. Всю статью не помню, но запомнил следующие тезисы:


  • Код был слишком разношерстный (кто-то писал функционально, кто-то писал в стиле Scala-Java)
  • Некоторые конструкции невозможно было гуглить из-за "странных" символов (это не проблема ФП, но все равно интересный факт. Я не в курсе, но, возможно, у Haskell могут быть похожие проблемы)
  • Сложно было нанимать новых программистов

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

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

Я изучаю Clojure в данный момент;)


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


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


Мне нравится, что есть такой прекрасный фреймворк (который я иногда называю: "одна большая DSL") и что я с ним работаю (а не с 1С-битрикс, как в начале карьеры, упаси боже). Когда представится возможность, и я с ним распрощаюсь, потому что люблю изучать новые штуки (и мода на ФП меня тоже коснулась). Но распрощаюсь без какой-либо критики:)

Как я и сказал, за все нужно платить:)
Я им почти не пользуюсь (воспользовался пару раз, когда в чужих костылях нужно было что-то поправить. Собственно, как раз тот случай, который вы описали: непродуманная валидация данных), но сама идея мне нравится. В упомянутом мною случае (правки в костылях) оно сократило количество изменений и при этом в diff все было очень ясно и четко (хоть сам код и говно, прямо скажем).


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


Упомянутый Haskell, возможно, шикарный язык (не могу оценить его в силу слабого владения ФП и всеми этими математическими штуками в целом), но сомневаюсь, что с его помощью можно быстро обучить команду программистов и делать продукты с той же скоростью и легкостью (до поры до времени), как в Rails.


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


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


IMHO, естественно

К вопросу о высоте порога.


Хоть у языка и очень красивый синтаксис (на мой личный вкус), но все равно некоторые штуки могут принести боль на начальных этапах.
Например, последний аргумент-хеш. Я когда очень давно познакомился с руби, на какое-то время завис над чем-то вроде:
object.method { key1: 1, key2: 2 }


Тема с блоками кода вообще достаточно сложная, мне кажется.
Например, у меня есть предположение, что далеко не все начинающие rails-программисты смогут провести разницу между лямбдой и обычным блоком.


Плюс к тому, знаю людей, для которых первое время вызывало некую боль отсутствие Си-подбного синтаксиса. Ну, собственно, такие проблемы будут почти у всех людей, которые слишком долго писали на Java и т.п.


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

Мне кажется, или автор не уважает абстракции типа «черный ящик»?
Вроде, главное преимущество рельс в их сложности, которая позволяет, не задумываясь о том, что там внутри, решать задачи.
Да, понятное дело, что порой возникают проблемы, приходится копать глубже, а там уже черная магия. Но не бывает ничего идеального, нужно быть готовым к этому.
Например, думаю, все понимают, что monkey-patching — это плохо. Но ведь это одна из сильнейших фич Руби! Да, ей можно отстрелить себе ногу (или что там обычно отстреливают?), но вы не можете не согласиться с тем, что среди этих патчей есть много хороших решений. Лично мне, например, ну очень нравится простой метод #try(:method). Некоторые вещи из ActiveSupport и вовсе становятся практически неотъемлемой частью жизни разработчиков, это и обуславливает некоторые вопросы на SO, связанные с тем, что вне рельс какие-то методы undefined.

Еще я заметил, что после повального увлечения темой функционального программирования (мне, кстати, она тоже очень интересна), началась повальная критика существующих устоявшихся подходов.
Но ведь все те недостатки, которые перечисляют авторы подобных статей, существовали в нынешних подходах и раньше. Это как «разоблачение», что АНБ следит за людьми.

Нужно задаться вопросом, почему наши подходы имеют такой успех и разделить сферы влияния новых «веяний моды» от «старого доброго».
хмм… но в Дзене Питона говорится, что лучше всего иметь один очевидный способ решения задачи…

На самом деле, не увидел в статье разного мышления. По-моему, это одно и то же решение, которое улучшается со временем. Единственное, что выделяется — решение с помощью регулярок и то… В общем, имхо способы одинаковые, никакого разного мышления здесь нет, просто лаконичность меняется.
Я не спец, но, мне кажется неправильным делать статьи вроде «Переход из ПХП в Лисп».

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

Мое отношение:
Для секса — почему бы и нет. Но девушку/жену они не заменят. Во всяком случае, пока не создан «трушный» ИИ (который, на мой взгляд, будет тем же самым человеческим мозгом, просто искусственным).

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

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

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

Переключатели-то вам чем не угодили?:)

А вот металлическую пластину я бы отнес не к плюсам, а к особенностям, поскольку это увеличивает цену, массу (хотя обычно это все-таки плюс), а преимущества от нее весьма сомнительны, если вы не хотите в будущем ударить своего начальника ей по лицу (как в фильме «Особо опасен»)

Но в целом, разумеется, в данном случае лучше, чтобы что-то было, чем не было:) Но это удар по карману.

P.S. привет от Das Keyboard ultimate.
Это не показатель.

В отместку могу сказать, что в ИТ-сфере больше открытий сделано учеными с «заграничным образованием». Но и это не показатель…

Information

Rating
Does not participate
Date of birth
Registered
Activity

Specialization

Backend Developer, Fullstack Developer
Senior