Комментарии 404
>…
> код «под капотом» чрезвычайно сложен
От сложности никуда не деться, все что перечислено всеравно надо делать. И если сделать вместо одной «ручки» россыпь то код проще не станет. Более того, с россыпью появляется новая проблема: а все ли ручки дернуты.
> Как бы там ни было, я покидаю Ruby
Основной вопрос — а куда? Несмотря на свой почтенный возраст рельсам существует крайне мало альтернатив. Могу вспомнить только elixir/phoenix — кстати от людей из команды rails. И там, кстати, решены многие вопросы упомянутые тут (возможность переписать фреймворк с нуля развязывает руки, да)
В оригинале в комментах пишут про clojure. Что на нём прототипирование по скорости сравнимо с рельсами. Подробнее не читал, может там и либы предлагают.
И если сделать вместо одной «ручки» россыпь то код проще не станет.В том то и дело, что код станет именно проще, т.к. всё будет написано в явном виде. Пример из Elixir:
%User{}
|> User.changeset(params["user"])
|> Repo.insert!
где User.changeset — это обычная функция, определенная в модуле User
def changeset(struct, params \\ %{}) do
struct
|> cast(params, @allowed_fields)
|> validate_required(@required_fields)
end
И всё, никаких скрытых колбеков и никакой магии. Если данные пользователя редактируются через несколько форм с разными требованиями по обязательным полям, то можно создать changeset-функцию для каждой формы. Другими словами валидация полностью отвязана от модели и работа с БД тоже полностью отвязана от модели.
Основной вопрос — а куда?Пётр явно называет Clojure и Elixir, а также Hanami для тех, кто не готов изучать новые языки.
И сколько еще будет объявлено кастомных функций
Да, сейчас у некоторых разработчиков мода на копипасту.
В Rails долгим и мучительным путём пришли к тому, что вызывающий код должен преобразовать параметры самостоятельно:
def user_params(params)
params.require(:user).permit(@allowed_fields)
end
Но куда подобные методы помещать не придумали и пихают пока прямо в контролеры, что в нетривиальных случаях приводит к реализациям user_params, разбросанным по разным файлам.
А вот для создания разных правил валидации одной модели в Rails пока из коробки ничего нет.
Именно поэтому появляются проекты, подобные Trailblazer: в них как раз придумывают места, где это должно быть. Конкретно в нём для разных валидаций создаются отдельные форм-объекты, которые используются в операциях (это у них так сервисные объекты). Важно, что валидации выносятся с уровня хранения данных (модели) в отдельное, специальное место. См. http://trailblazer.to/#form
Как можно убить open-source проект? Не нравится — форкайся и продолжай пелить так, как нравится.
А чтобы форкаться и продолжать пилить нужны команда и ресурсы, а команда Merb как раз распалась в результате того «объединения».
Если недовольных вроде автора — больше одного, то они вполне могут этим заняться.
Не обязательно, что другие проекты хуже. А и потом что Rails слишком авторитетен.
Это и не дает развивать другие проекты в Ruby
— число проектов на рельсах снижается (старые все еще поддерживаются, а вот с новыми уже нет).
— растет число проектов на python (django).]
— растет число проектов на js-фреймах.
Поэтому только факты.
Стараюсь использовать рельсы, как запчасть, как завещал дядюшка Боб.
Через полтора года новый разработчик с ходу сделал довольно сложное задание.
Сами рельсы довольно продуманы и удобны в мелочах — миграции, ассеты, сиды, енв и пр. инфраструктурные штучки.
Есть с чем сравнить, Play, Spring Boot и т.п. Быстрый релоад в отличии от Play + Scala. Работа с ассетами в Spring Boot напомнился времена голого JSP и сервлетов).
Я не отказываюсь даже от Active Record, но работаю с ним очень осторожно, практически не применяя магии и скрыв за слоем репозиториев.
Стараюсь не использовать гемы, засоряющие глобальное пространство или сильно сорящие в ActiveController/ActiveRecord::Base. Они дают быстрый старт, но большое количество проблем в будущем. Как пример — karmi для elasticsearch. Работать с ним через модель поначалу удобно, но шаг в сторону (скажем маппинги сильно отличаются от схемы бд) — и ты получаешь массу проблем.
Если сначала потратить немножко времени, и написать сервис, используя более низкоуровневый механизм того же karmi, то в дальнейшем все находится под контролем и времени написание функционала уже особо не занимает. Гораздо экономнее, чем потом дебажить и писать воркэраунды.
Многие клиенты на эти практики реагируют довольно нервно. Чем менее привязан к rails community клиент, тем больше шансов, что он отнесется к ним позитивно.
Можно подробнее? Стало интересно в чем проблема.
Неуклюжие layouts. Еще подключение css/jss (тут скорее отсутствие asset pipeline, он в принципе для Spring Boot имеется, но мне неясно его качество и статус). Сурово как то все. Если вы наведете на средства сделать лучше, буду рад и признателен.
По поводу шаблонов — есть надежда, что jade спасет, но опять же неясно, насколько прямо он реализован именно для Spring Boot.
Оффтоп — а по миграциям — flyway уж очень суров.
Ни в одном веб-фреймворке я не видел миграций, сделанных хотя бы так же удобно, как в рельсах(
Пробовал еще Perl + Mojolicious, но там слишком много надо реализовывать из того, что в рельсах идет из коробки
Насколько далеко они разошлись сейчас я не в курсе, но в 2008-2010 годах был настоящий бум — фреймворк аля Rails писали на всех популярных языках :-)
А причём тут религия? Вы же сами написали, что AR нигде толком не получился. Я только добавил, что он by design не может толком получиться и неизбежно будет доставлять проблемы в нетривиальных случаях.
Ну и AR получился в Rails, 99% задач решаются через AR.
Т.е. Вы с проблемами от использования AR не сталкивались? И никаких неудобств от того, что логика предметной области находится в моделях AR не испытывали?
По-моему важно понимать, что если модели предметной области(классы, содержащие бизнес-логику), у вас не наследуют ActiveRecord::Base, то у вас нет паттерна ActiveRecord в проекте. Возможно вы используете рельсовый AR в качестве странной реализации паттерна Repository, возможно ещё как-то… но только не в качестве ActiveRecord.
это вовсе не означает, что эти классы должны отвечать за бизнес логику в обязательном порядке.
Ну вообще-то это следует напрямую из определения паттерна. Просто у Вас своё оригинальное видение ActiveRecord… поэтому мы тут тёплое с мягким сравниваем.
Объект AR не должен знать как снимать деньги со счета, но он должен знать как аз balance вычесть 10.
И нет в этом ничего оригинального, на AR возложены конкретные узкие обязанности.
AR — это когда логика сохранения данных помещена в модель предметной области, в ту самую в которой бизнес логика. Тупо по определению:
"An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data."
"Active Record uses the most obvious approach, putting data access logic in the domain object"
Я не вижу тут диррективы: «все должно быть так и только так», это пример
PaymentService
def withdraw(user, amount)
validate business logic here
user.withdraw!(amount)
end
end
PaymentService.withdraw(user, 10)
Вот я не знаю точно user.withdraw!(amount) — domain logic? помоему не очень но это AR
Логика доступа сохранена, не вижу противоречий
Я не вижу тут диррективы: «все должно быть так и только так»
Такой директивы нет ни у одного паттерна. Но если что-то не совсем так, то это уже не этот паттерн. Всё просто, в AR нет никаких Service, по сути AR — это и есть fat models. Всё остально — это не AR. Не усложняйте.
Я не предлагаю вмешивать в AR Services.
AR занимается своими обязанностями. Все остальное занимается своим делом.
Всем добра и Single Responsibility.
У юзера есть метод withdraw, но на юзера нельзя возлагать обязанности соблюдения бизнес логики всей системы, это не его обязанности.
Снять деньги у юзера — не обязанность юзера, а обязанность сервиса банка. Причем банк как сущность может вообще не иметь AR сущностей.
И это не усложнение, это — напротив — упрощение, сегрегация интерфейсов проще, чем порождение франкенштейнов. Собственно и в реальном мире с реальной бизнес логикой пользователь не может снять деньги со своего счета непосредственно.
И это не усложнение, это — напротив — упрощение
Это упрощение кода, но усложнение понятий. Паттерны хороши тем, что дают названия вместо длинных определений. Вместо того чтобы говорить "Каждый класс соответствует одной таблице в БД. Строка таблицы соответствует объекту класса. Логика работы с БД помещена в модель предметной области.", мы говорим одно название — ActiveRecord. И всем понятно, о чём это и чем это плохо в нетривиальных случаях. Когда Вы вводите свою интерпретацию понятия ActiveRecord вместо общепринятого определения, и пытаетесь строить свои выводы на ней, это выглядит очень странно.
В моем примере AR кладет в БД, и логика работы в БД там же. Но категорически нельзя Генератору светящихся лампочек просить AR что-то делать, но можно Генератор Светящихся Лампочек попросить Модель данных AR попросить что-то сделать.
Вы же предлагаете всю предметную область положить в AR, как быть с сущностями сервисами, которые не хранят свои данные в AR а являются сервисами?
Вот поэтому и получаются жирные модели, когда у нас юзер становится монстром делающим не свойственные ему вещи и отвечающим за не свойственные ему операции, никакой патерн не заставит и _не_заставляет_ меня это делать, и даже не рекомендует. Всему должна быть мера.
Вы же предлагаете всю предметную область положить в AR
Я в этом треде вообще ничего не предлагаю. Я просто констатирую определение этого паттерна и прямые следствия из него.
А то, что Вы по факту не используете паттерн Active Record — это даже хорошо. Путаница возникает из-за того, что Вы думаете, что Вы успешно и повсеместно применяете данный паттерн, хотя по факту отходите от него безумно далеко, и при этом пытаетесь других убедить, что 2+2=5.
Скрипты собираются с помощью Maven, настроили один раз и больше не трогаем.
Ну в целом понятно о чем вы, соглашусь есть неудобные места.
С одной стороны, когда отзываются о чем-то плохо, значит это что-то есть с чем сравнить. Потому что в моей ситуации, я сейчас не вижу ничего криминального, что описывает автор. И у меня еще больший диссонанс от того, что вроде бы автор работает долго с Rails и ему, возможно, просто уже он надоел, а возможно, что он попробовал что-то другое.
Сейчас я вижу это так: автору статьи надоели автомобили. Надо стоять в пробках и ездить только по дорогам с определенными правилами. Отсюда возникает мысль: или у автора в гараже стоит летающее авто и он так пытается сам себя убедить, что оно то лучше, или ему просто надоели машины и он собирается ходить пешком. Насколько я понял, летающие машины = elixir и scala по мнению автора?
> Одной из моих первых задач было… добавить ссылку на что-то на какой-то странице. Мне потребовалось несколько дней, чтобы добавить эту глупую ссылку.
У меня те же самые мотивы «нестандартного применения» рельсов. С чем сравнить есть — я нативно из java. Поддался на то самое «быстрое прототипирование». В этом рельсы хороши, слов нет. Настоящие проблемы начинаются после N месяцев разработки и эксплуатации.
В принципе зная и обходя минусы, можно вполне успешно работать. К сожалению, у клиентов особого понимания такой подход не встречает. Поэтому проще отползти.
Мне кажется, что это мог быть, например, просто не очень качественный проект, с первых версий рельс, и с большим историческим наследованием, как например, виденная мною ЦРМ с 10+ летней историей разработки с нуля под компанию и тоннами кода, удаление которого может поломать всё в очень и очень неожиданном месте.
А вот с теми, у кого не хватает понимания работы хостинга, например и «шаловливые ручки», и желание кому-то повыносить мозг «быстро сделайте шоб работало а то в суд подам», те звонят и жалуются, но и запоминаются в основном они.
большинство методов и компонентов Rails завязаны на некое глобальное состояние. Еще автор жалуется на засилье наследования. Все это, конечно же, приводит к слишком большой связности между сущностями. В результате это мешает использовать некоторые части Rails независимо.Мне кажется, что проблема в гемах. Автор, и люди в комментах, это немного затрагивают, намекая, что люди слишком сильно увлекаются ими. Возможно, я неправильно понял.
Я, как человек недавно познавший быстрое прототипирование Rails, в когнитивном диссонансе. Только недавно пришел к мысли о том, что вот оно — будущее (в сравнении с PHP).Не волнуйтесь. У автора статьи в 2007 году были такие же мысли о Rails, что и у Вас. Да и у меня было такое же ощущение в 2008-м.
Просто у Rails есть свои границы применимости, за которыми вся его магия оборачивается против программиста. С накоплением опыта участвуешь во всё более сложных проектах и всё чаще натыкаешься на эти границы. Поэтому со временем эта борьба с фреймворком утомляет и хочется иметь инструмент простой и предсказуемый.
Но Rails в ближайшие годы никуда не денется. И на простых проектах Вы вполне можете оставаться в рамках Rails Way и не испытывать никаких неудобств. А для сложных — посмотрите сразу в сторону trailblazer.
А к тому времени будете уже и сами знать. Не парьтесь понапрасну.
Хочется надеятся, что серьезные проекты вы получите, только став опытным разработчиком.Не совсем понял к чему это? К тому, чтобы сам себя не замучал костылями?
Однако, основная мысль статьи в том, что не стоит идеализировать Rails. Он симпатично выглядит снаружи, но внутри никогда особо не блистал понятностью или удобством. К тому же фреймворк оброс кучей функционала, часть из которого весьма спорна, и стал медленно развиваться в плане действительно важных вещей… В чём-то он уже пытается догнать конкурентов, к примеру, наконец-то добавляя поддержку веб-сокетов.
На тему самого Ruby тоже спохватились и пытаются угнаться за языками, на которые идёт массовый переход: Ruby 3x3, Concurrent Ruby
Очень рекомендую всем, кто имеет дело с Rails, книгу «Rails Anti-Patterns». В ней описаны многие анти-паттерны, на которые в какой-то мере провоцирует сам Rails.
Тут кто-то писал про Coldfusion, мол «фе». Пару лет назад я работал в прибыльной компании из штатов с 10М+ пользователей, добротной архитектурой приложений (не идеальной, но достаточно понятной для внесения изменений и поддержки меняющихся требований бизнеса), все на распоследних версиях фреймворков, в том числе Rails. И вот в один прекрасный момент нас купила фирма-конкурент, которая клонировала изначальную идею нашей фирмы (геймификация ритейла + персональные рекомендации), повела более грамотную маркетинговую политику, набрала больше инвестиций и выкупила нашу компанию (по сути покупался бренд и база пользователей). Весь наш чудесный код выкинули на помойку и заменили ужасным и кривущим кодом на Coldfusion (практически никто из нашей dev-команды не захотел работать с этим ужасом дальше и все уволились). Компания по прежнему процветает. Код по прежнему на Coldfusion. Делайте выводы, господа идеалисты. Рынку не нужна идеальная архитектура приложения, да никто про нее и не знает даже, кроме инженеров.
Весь наш чудесный код выкинули на помойку и заменили ужасным и кривущим кодом на ColdfusionКакая жестокая, но реальная правда. Такой «коммерческий» подход я часто встречал в русских компаниях. Команда зарубежная?
Maintainability это одно из качеств проекта, и если его отсутствие можно решить в лоб, ковбоями, да флаг им в руки.
Остальным же это экономит время.
Как написали ниже, основная проблемы с рельсами начинаются после нескольких месяц разработки. И, на самом деле, многие проблемы возникают от того что кто-то плохо знает рельсы и попросту делает костыли, эти костыли обрастают своими костылями и т.д. Либо от того что заложил неправильную архитектуру. И дальше уже повезет или нет. Рано заметешь что не так, и есть время на рефакторинг — исправил и проблемы нету. Но чаще бывают, что проблемы живут неосознанными достаточно долгое время чтоб пустить корни, и так просто от них не избавиться, да и клиент со сроками подгоняет, на рефакторинг времени не остается.
А вот тут параллельно решил React.js изучить. Redux'ы там всякие и т.п. Казалось бы вот оно «счастье» с точки зрения архитектуры. И что? Я форму логина делаю уже неделю. Простой логин по email и паролю. Перечитал уже тонну тутариалов. Просмотрел кучу примеров. Вот только для того чтоб понять примеры нужно прочитать еще тонну туториалов. И до сих пор кстати не доделал. Осталось сделать переход на новую страницу. Пытаюсь второй день понять откуда по правильному я должен вызывать это переход. Вы можете представить такую проблему в рельсах? Что там автор про простоту говорит? Что про модульность? Может где-то там и есть в рельсах лишняя связанность которая не дает автору жить и спокойно спать ночами, вот только разрабатывать на рельсах на порядок быстрее чем на других фрэймворках. Быстрее разрабатываешь, быстрее получаешь деньги. У тебя стало 100500 пользователь и рельсы не справляются? (хотя я лично поддерживал проект на рельсах с 10к запросами в минуту, и не сказал бы что это было очень сложно) Вот теперь время подумать и нанять разработчиков которые напишут тебе с нуля под высокую нагрузку хоть на хаскеле, избавившись от кучи костылей…
Это вот мои немного сумбурные мысли
И что? Я форму логина делаю уже неделю. Простой логин по email и паролю.Как это знакомо! Иногда кажется, что подобные технологии просто навязывают
А что для роутинга используете?
> А что для роутинга используете?
react-router пытюась использовать.
https://github.com/reactjs/react-router-redux
https://github.com/acdlite/redux-router
Как известный в очень узких кругах эксперт по реакту, хотелось бы подсказать.
Сначала несколько общее замечание:
React.js — это, все таки, буква V в паттерне MVC. То есть все остальные части (например, бизнес-логика) — она как бы и не должна быть проблемой реакта.
А конкретный хороший рецепт типа из самых последних трендов — используйте redux-saga. Самое то для авторизации.
Ну и последнее, в целом:
Если вы хотите простоты и понятности, смотрите скорее в сторону Angular.js с его богатейшим API на все случаи жизни и огромной коллекцией пакетов.
Если проводить аналогии между Ruby и Front-End JS, то, скорее:
Angular.js == Ruby on Rails
React.js + Redux == Sinatra (скорее, даже Padrino)
Если вам нравится вариант, когда вы с нуля тщательно отбираете только нужные вам либы и сами ваяете архитектуру, которую вам надо — лучше брать React.js
Если вам нравятся примеры типа "
А вот angular и прочие ember'ы как-то пробовал и сбежал от них нафик. По мне там никакого упрощения нету, только сложности лишние добавляет, и код еще более запутанный становится. Вот React мне сразу понравился своей идеей.
Сейчас в раздумьях по поводу миграции с Angular 1.3. Пока смотрим на Angular 2.0(+Typescript) и Ember.js.
Facebook, Instagram и AirBnB использует React.js и React Native весьма активно.
По заявлению инженера Facebook, у них больше 20 000 компонентов уже используется. Но исходники закрыты.
Khan Academy использует реакт для большей части рендера. Код открыт:
https://github.com/Khan/perseus
Марафон использует реакт:
https://github.com/mesosphere/marathon
Насколько я знаю, Atom (текстовый редактор от Github) использует React для рендера, код открыт.
Что же по поводу самой проблемы «Angular.js v2 vs Ember.js vs React.js» — так-то все хороши, тут подсказать не могу, самому все нравится. Смотрите куда хочется двигаться.
А так на реакте дофига всего пишется. В гугл-трендах запрос react.js обогнал angular.js
Общий список: https://github.com/facebook/react/wiki/Sites-Using-React
Те, что конкретно мне нравятся:
Просто хотел посмотреть как очень большое приложение живет от и до.
По sprintly: https://github.com/sprintly/sprintly-kanban/tree/master/app/actions вот тут получается 50+ файлов будет жить?
По размеру там в районе 1000 компонентов.
Но вот так, чтобы выложить вам ссылку на открытый код — боюсь, не знаю таких.
Про srpintly — вообще сами actions спорная инициатива, я бы не так сделал, но получается да, у них там и будет жить. Возможно по подпапкам еще разнесут, не знаю уж, на какой базе — каждому отдельно или будут группировать по смыслу.
WP Calypso
В целом близко к тому, что хотелось посмотреть и организация проекта норм.
Это типа boilerplate для Universal App на базе React.js + Redux + Reselect.
Примечателен тем, что все используемые библиотеки типа bleeding edge.
Вам будет полезно посмотреть, как делается авторизация с unidirectional data flow.
Если вам нравятся Рельсы, не обязательно с них уходить. Просто следует помнить, что они заточены под быстрое создание несложных приложений. Более сложные приложения на них писать можно, но нужно добавлять к Rails другие инструменты, которые будут помогать масштабироваться. Например, Trailblazer.
См. https://habrahabr.ru/post/301532/#comment_9623484
Из личного опыта — написание парсера на руби было очень веселым и быстрым. Книги по руби читаются легко. Все, что не касается напрямую Rails — очень удобно и просто.
Rails так-же имеет смысл установить, по играться, развить своё восприятие данного фрэймворка. Очень многое вам покажется правильным и вы решите использовать подобные схемы решения задач на PHP.
Используйте Руби в качестве трамплина для вашего развития как программиста в целом.
https://twitter.com/wycats/status/734991937862795264
https://twitter.com/wycats/status/734992848987258880
https://twitter.com/wycats/status/734993723029868544
Статья просто потрясная! Очень коррелирует с моими мыслями по поводу Rails.
Показушная "простота" работает хорошо только до тех пор, пока не надо чуток выйти за рамки. В тот момент когда это происходит, совершенно теряется понимание "что делать", код превращается в макароны из грязных хаков и теряет полностью свою простоту и привлекательность.
ЗА адептами Рельсов очень интересно наблюдать тогда, когда они пытаются написать что-то на… Ruby! ActiveSupport — это по сути новый язык программирования.
По моим ощущениям, создание rails приложения — это сборка камней/гемов — как в лего, только вся сложность начинается в тот момент, когда эти кубики надо собрать вместе. Когда гем подключается одной строчкой и делает кучу вещей — я его просто боюсь! А такие "батарейки" — везде.
Самое главное, API Рельсов не очевидное, не однозначное, и разработчика на Рельсах по сути ничего не заставляет его как то изучать и понимать. Можно создать десяток сайтов на Рельсах и так и не узнать, что скрывается за волшебным словом Rack, и чем middleware гемы отличаются от "не middleware"!
Ничего не имею против ActiveRecord, если чувствовать пределы, его использовать очень удобно. Но когда можно забрать модель из формы через :params и сохранить как есть одной строчкой как в статье — это рождает миллионы вопросов на SO — "Почему сохраняет пустую модель/не сохраняет ничего" которые просто нереально чинить — там всего одна строка!)
Очень бы хотелось обсудить предыдущую статью автора, в которой он осуждает monkey patching: если не ActiveSupport, то как? Если многим это удобно, то писать RFC к самому Руби? 10.years.ago — возможно это должно быть в стандартной библиотеке?
А что касается проблем ООП — мне кажется Руби — не показатель плохости такой парадигмы. Monkey patching и вся рефлексия — это по сути нарушение инкапсуляции. И это то, что самое крутое в руби, с его method_missing, символами и открытиями классов в любом месте вашего кода. А ведь именно на этом строится такая "классная" ActiveRecord, роутинг, ActiveSupport. Оставь в Рельсах "чистое" ООП — и от всей прелести Релься ничего не останется.
Очень бы хотелось обсудить предыдущую статью автора, в которой он осуждает monkey patching: если не ActiveSupport, то как?Нет ничего плохого в отдельных модулях для подобных методов, не обязательно их добавлять к базовым классам. По началу это даёт определённый вау-эффект, но не даёт реальных преимуществ, а вот весёлый дебаг временами обеспечивает.
Чел перерос технологию и закономерно направился в функциональное программирование. Все с порядке вещей.
Я так понял, главная проблема автора не столько в самом Rails, сколько в сообществе. Поскольку всё-таки можно сделать проект по всем правилам, создать обёртки вокруг функционала Rails, нагородить собственных классов и организовать всё так, чтобы проект был масштабируемым. Но любители Rails просто привыкли пользоваться готовыми функциями и мириться с возникающими проблемами. Конечно, с такой разницей во взглядах работать с этими людьми — одно мучение.
"… дает вам ложное чувство простоты, в то время как то, что происходит на самом деле заключается в том, что сложность спрятана за удобными интерфейсами"
Эта фраза актуальна вообще для всего, и не только в компьютерном мире :)
Точные у вас формулировки)
Можно. И да, так и есть, мучение, борьба Дон Кихота с ветряными мельницами.
«Борьба с ветряными мельницами», кстати, очень интересное занятие, сравнимое с поиском сокровищ по пиратской карте.
Я так понял, главная проблема автора не столько в самом Rails, сколько в сообществе.Автор хочет привлечь внимание сообщества к тому, что есть жизнь за пределами Rails. Как на Ruby, так и на других языках. В частности он является автором более чем десятка полезных гемов для Ruby.
Я куда чаще видел, когда человек, поначитавшись, бросает привычную технологию, строит что-то на новом (плюясь, разбираясь, но, в общем, радуясь), а потом понимает, что но новом он писал не так круто, как знаток нового (наоборот, прорывались подходы старого, уже отвергнутого), и что новое также нужно поддерживать.
В общем, «старый конь», пока он решает задачи, почему бы и не поработал? Тем более что выбирать сегодня инструмент, которые закроет все проблемы проекта на долгие годы — это нереально, и в чем-то безответственно. Даже банальный движок форума можно писать на php+mysql (и поиметь в будущем более-менее понятные проблемы — но «потом»), а можно на oracle+хранимые процедуры+веб-приблуды от уважаемого Oracle — будет круто до небес, никто никогда себе это не поднимет (стек сильно не массовый), и проект не взлетит, поддержка станет до небес дорогой, и будет вопрос «а зачем».
Если так и будет (дай-то Бог каждому проекту) — то просто кидай в него железом и всё, а потом перепишешь на чём-то более высокопроизводительном (если это вообще нужно будет к тому моменту). Большенство проектов не взлетит так и так и смысла делать всё круто с самого начало — нуль ))
А вообще, как мне кажется, чем дальше в сторону хайлоада, тем больше общих решений будет у всех языков и фреймворков — кэширование, низкоуровневое ковыряние и т.д.
А на будущее посмотрите ещё и в сторону Elixir+Phoenix. Конфет много не бывает xD
Красивейший язык, в самом деле.
За один синтаксис в стиле пролога можно уже простить многое.
Хотя, непонятно, зачем я это пишу — любой человек, изучающий эликсир, как минимум, погуглит, что такое Erlang ;)
Извините, спорить не буду. Мне нравится и elixir, и erlang. И, кроме того, я искренне считаю, что изучение erlang как минимум не повредит, а как максимум сильно расширит горизонты и возможности изучающего.
Вообще, я так понял из ваших комментариев ниже, вы уже много лет в вебе, поэтому первое что я посоветую — серьезно задумайтесь о смене фокуса. Неужели вам совсем неинтересны, например, IoT, VR? С вашим опытом на них реально найти вакансию джуниора как минимум, а в этих областях даже джуниоры получают вполне достойную плату, не меньше чем senior в вебе. Ну и кроме того, часто в этих проектах нужны как минимум веб-странички, а то и полноценные приложения, написанные на базе Electron.
По поводу же смены технологии именно для веба… Настоятельно рекомендую посмотреть и попробовать функциональный язык вроде Erlang|Closure|Haskell, крайне освежает. Тут нужно заметить, что перечисленные языки — они, вообще-то, очень сильно разные, с разной концепцией, и лучше посмотреть каждый.
Возможно, вы и не перейдете на них, но очень много полезного для себя найдете.
Не бойтесь тратить время на какой-нибудь Erlang, работы конкретно под функциональщину хватает: https://functionaljobs.com/.
Еще из неплохих вариантов в вебе я бы посоветовал Go и JS. Первый предлагает большую производительность и очень крутой параллелизм, второй мультипарадигменный, с возможностью писать и в ООП и функциональном стиле по желанию пользователя. И там и там есть работа, есть живая экосистема с огромным количеством библиотек.
Ну и чисто для вдохновения и расширения горизонта, хотелось бы посоветовать глянуть на вот эти два языка:
- Фунциональщина под веб, пока что очень новый язык, использовать осторожно, но заложенные концепции просто офигенны: http://elm-lang.org/
- Настоящее ООП в стиле SmallTalk. Как и в Ruby, все объект. После знакомства с этим языком вам динамичный руби с открытыми классами (вы еще называете это хаотичным) покажется заскорузлым монстром, на котором нельзя толком метапрограмминг писать. К сожалению, из-за своей динамической природы этот язык довольно медленный, так что годится скорее для изучения в академических целях, писать на нем реальные программы я бы не стал. Но для расширения сознания, получения нового опыта и оттопыривания чакр крайне рекомендую взглянуть.
Мне даже интересно потом Ваше мнение будет…
Nim логичнее сравнивать с Go, Rust, Crystal.
Язык интересный, но стабильной версии пока нет, да и библиотек пока тоже немного. Причём ощущение, что разработчики слегка подзабили в этом году… После выхода версии 0.13 уже 5 месяцев никаких новостей от них не слышно. Коммиты есть, но активность в разы меньше, чем в прошлом году.
Вообще для всех кто выбирает язык для веб-разработки, я бы посоветовал такой алгоритм:
- определяете наиболее популярный веб-фреймворк
- ищете актуальную книгу "Programming НазваниеФреймворка" или "Web Development with НазваниеФреймворка" или "Web Development with НазваниеЯзыка"
- Бегло читаете https://learnxinyminutes.com/ по языку, а затем найденную книгу
- По результатам прочтения книг делаете осознанный выбор что вам ближе
- Изучаете сам язык и вдумчиво перечитываете понравившуюся книгу
По вышеназванным языкам это книги:
Elixir — Programming Phoenix
Erlang — N2O — No Bullshit Sane Framework for Wild Web
Clojure — Web Development with Clojure
Haskell — Developing Web Applications with Haskell and Yesod
А как же оповещения о новых комментариях и прочих обновлениях на всех социально-ориентированных сайтах? На хабре, вон, вручную кнопку «обновить» нажимать надо. А в том же гитхабе новые комменты в ленте сами появляются.
Я понимаю что скорее всего это вопрос не столько к Django сколько к его области применимости. Но дело в том что начиная долгоживущий проект я вряд ли могу предсказать как он будет развиваться и как скоро мы упремся в границы Django-песочницы. И я не готов рисковать своим временем и деньгами выбирая столь ограниченный инструмент для долго живущих проектов. Если дело касается классического контент сайта (лендинга, страницы компании, какого-нибудь блога, вот этого всего) то к Django вопросов нет, отрабатывает на все деньги. Просто я такими проектами не занимаюсь.
Так же смотрим за рамки питона, интересны Java Spark или, чем черт не шутит Clojure Luminus ))
Продолжайте использовать Rails. Просто помните, что одних Rails не достаточно. Точнее, недостаточно трёх букв MVC, которые есть в них.
Пока у вас приложение маленькое (5-10 моделек) и с не очень большой логикой, всё будет окей. Когда число моделей перевалит за 50, а просто список функциональности перестанет помещаться в голове одного человека (а ещё помножьте на скорость разработки) — вы запутаетесь и будете погребены под приложением.
Решения есть, их много, но, к сожалению, ни одно из них пока не стало стандартом. Посмотрите на Trailblazer (мы его используем) — он добавляет новых уровней абстракции и этим снимает нагрузку с существующих букв MVC. Посмотрите, какие проблемы, решает этот инструмент — если они вас не волнуют, то вам ещё рано. Я же когда читал книжку по нему, плакал над каждой, потому что мы страдали просто от всех: к примеру — у нас было 500+ строк коллбэков в некоторых основных моделях, например.
После нескольких лет работы с Yii, на проекте сложнее среднее много усилий начинает уходить на борьбу с «удобствами» ActiveRecord, которую нельзя выкинуть из приложения и нагромождения собственных абстракций чтобы разбавить изкоробочную связанность компонентов фрейворка.
И да, начинаешь мечтать о DataMapper =)
тут и кроется отличие профессиональных программистов от веселых хипсто-хакеров. Датамаппер никогда не работал. Я сделал один проект на этом кошмаре и слава богу он разорился и закрылся до того, как кто-то начал его поддерживать.
Рельсы в некоторых вопросах огорчают, так что поменьше гемов пожалуйста, их итак слишком много.
ActiveRecord в 2008-м (2-е рельсы?) и ActiveRecord в 2016-м (5.0) — это две большие разницы.
В 2.х ActiveRecord был ужасен, в 4.х он уже был хорош (в первую очередь благодаря arel'у). И все 4-е рельсы он продолжал сильно перепиливаться (помнится, один мой pull request пришлось сильно переделывать с 4.1 на 4.2).
Читать один файл на 3 экрана гораздо проще, чем 10 файлов на пол-экрана каждый.
Простое распиливание кода на куски, которые вроде как должны быть в разных файлах по сути только ухудшает читаемость и не дает из коробки расширяемость кода.
Для тех, кто не знает, у Arel есть возможность вызывать SQL-функции, но только со скобками
Account.where{created_at == :now.func()} # работает
Account.where{created_at == :current_date.func()} # не работает
В общем, пока я воркэраунд писал, достаточно ознакомился с его исходниками. Мягко говоря, там реальный треш. Если не согласны, попробуйте решить вышеописанную задачу. У меня на тот момент была версия arel-4.0.2.
Account.where('created_at::date = current_date')
Нужно было предоставить пользователю возможность создавать сегменты по определённым моделям. Т.е. пользователь накидывает критерии в интерфейсе, а мы по этим критериям с помощью Arel генерируем SQL-запрос. Естественно давать пользователю вводить raw SQL в планы не входило. Переписывать без Arel было бы долго, потому что для заказчика это выглядило просто «а давайте добавим ещё 1 тип критериев в форму». При этом требования к скорости результирующего запроса были очень высокими, т.е. обернуть current_date в SQL-функцию тоже не прокатывало.
В вашем случае, может, не стоило тогда даже и рассматривать current_date
как функцию?
Arel — это, ИМХО, вещь не для прикладных разработчиков, а для разработчиков ActiveRecord'а и прочих вещей, напрямую общающихся с базой. В его исходный код не заглядывал, но простым он точно не будет, ведь его задача — генерить разный SQL для разных БД с их особенностями. Например, oracle_enhanced адаптер вместе с последним arel'ом научились генерить разные SQLи типа SELECT для 11-го и 12-го Ораклов.
Но ваша правда, даже документации толковой к нему нет, а чем хардкорнее вещь, тем она нужнее.
не стоило тогда даже и рассматривать current_date как функцию?Как не рассматривай, а как-то надо было её запихнуть в результирующий SQL и обойдясь при этом без raw SQL. Реальнее оказалось запихнуть как функцию )))
Я не хейтер Django, я работаю с ним много лет, и до сих пор поддерживаю на нем проекты, но это крайне не гибкий инструмент. И на долгоживущих проектах с не полностью определенным фичелистом я его не использую.
Про перегруженность я так сразу и сказал, куча невнятных мелочей есть, а нормальный явный left outer join или темплейт таг добавляющий класс к форме сделать уже который год не могут.
Если из Django выкинуть орм то останется уродливый парсинг урлов, половина форм и cbv и тормозной шаблонизатор. А админка, единственное в чем Django на голову превосходит аналоги, превратиться в тыкву. Зачем мне тогда вообще тянуть в проект Django если для всего этого есть более внятные инструменты?
Django гибкий на столько на сколько любой другой открытый проект. Понятно что при нужде все можно допилить, докостылить и т.д., исходный код открыт, гит в руки, «пилите Шура, пилите»… только Вы совершенно правильно сказали это требует серьзный уровень знания потрохов, потому что связанность высокая, интерфейсы магические и как только ты начинаете что то модифицировать под себя, в другом, неожиданном, месте что то начинает отваливаться. Зачем мне все это? Я выберу более подходящий инструмент, благо выбор есть.
А так же я не хочу тратить время на «серьезное изучение всех потрохов» что бы стать «настоящим гуру» этих потрохов. Если молоток требует знаний металлургии и сопромата для использования я не бросаюсь их изучать, я просто меняю молоток.
У меня есть один проект (первый) — дак он всё ещё крутится на Rails 1.0 (был переписан с Access) — и заказчик вполне доволен до сих пор (прошло уже почти 10 лет). Изучать новые технологии необходимо, но и понимать, что в конечном итоге надо решать бизнес задачи.
А автору спасибо за DataMapper — использовал (совместно с Sinatra) в нескольких проектах.
И если вы пытаетесь сделать какой-то проект на инструменте, который для этого проекта не предназначен, например, магазин на Wordpress или веб-приложение, архитектурно не похожее на Basecamp, на Rails, то вы будете страдать. Однако, он забывает, что когда Rails только набирал обороты, многие говорили «Зачем нужен фреймворк, для большинства проектов достаточно CMS», «Зачем нужны Ruby и Python, большинство крупных проектов написаны на PHP». Так что текущая ситуация — просто очередной виток истории.
Также он отмечает, что слишком сильная дефрагментация сообщества, как у PHP и JS, — это ещё хуже, чем монополия. С этим я тоже согласен.
Важно принять для себя принцип разумной достаточности, а не тратить время на поиски святого грааля — той библиотеки, того инструмента, где все будет ну прям все-все-все идеально, все будет чудесным образом реализовано на все случаи жизни! Не трать свою жизнь на это! Есть базис, который тебя устраивает, вот и пользуйся им! Есть множество механизмов, реализованных за тебя — пользуйся ими! Все остальное можно реализовать самому. Я вообще не лезу глубоко в дебри Rails, использую базовые механизмы, и, знаете, меня все устраивает и прекрасно все работает! А Ruby — это вообще идеальный язык из тех, с которыми мне довелось познакомиться за время своей карьеры.
Сообщество Ruby и Ruby on Rails как раз и отличается тем, что без лишних разговоров, пафоса, споров, холиваров просто делают свою работу, занимаются своим любимым делом, и делают это грамотно и хорошо — видимо, менталитет такой. Ну а если кто-то решил уйти, вот так шумно хлопнув дверью, то не велика потеря.
У любой технологии есть свой цикл развития:
Rails сейчас очевидно находится на этапе «Late Majority». И вполне объяснимо, что Пётр, как один из лидеров Ruby-сообщества, чувствует социальную ответственность и соответственно потребность описать свою точку зрения.
Автор 9 лет программировал на Ruby — в каком месте тут «постоянные метания»?
И говорить о каком-то закате инструментария разработчика совершенно неуместно, пока этот инструмент востребован и прекрасно выполняет свои функцииРечь не о закате, а о насыщении. Все, кто хотел использовать Rails, — уже используют. Теперь добавляться будут только начинающие программисты. А профессионалы будут постепенно уходить в категории «Innovators» и «Early Adopters» других технологий. И это не тенденция последнего времени, так было всегда.
Если тот же Hanami наберёт популярность, то для Ruby никакого заката не будет, даже наоборот.
Автор программировал на Ruby 9 лет. И что с того? Постоянно пытался изменить Ruby? Так он (Ruby) и так постоянно меняется при чем очень даже в лучшую сторону.
Я бы не стал говорить о каком-то насыщении, если речь идет о притоке все новых начинающих программистов. Какое же тут насыщение? Да и с чего бы профессионалам уходить куда-то, если их все устраивает. Профессионал на то и профессионал, что занимается делом, а не мечется в поисках истины в последней инстанции.
В данном конкретном случае более уместно все же говорить о той массе «профессионалов», которые постоянно мигрируют от одной технологии к другой, в каждой из которых им обязательно что-то не нравится.
По своему опыту скажу, что я менял технологии разработки только по мере того, как возникала необходимость переходить на какой-то новый качественный уровень, а предыдущие инструменты уже ну никак не подходили для реализации. Вот ну не стану я сейчас писать веб-приложение на assembler! Хотя раньше программирование на assembler было очень увлекательным занятием! А так, для общего развития, я достаточно много языков программирования изучил, дабы расширить собственный кругозор и границы мышления, но это совершенно не означает, что я их все собираюсь использовать в своей работе.
А может, да, вместо Ruby и на Rubi попробовать писать :))))) Вдруг он лучше!
Все мои размышления о том, что смена одной технологии на другую вряд ли чем-то значительно облегчит автору жизнь. Устал он от Rails, ну пусть поищет себя в чем-то другом. Только вот проецировать свое видение на весь фреймворк все же не стоит.
Ложь — это один из признаков заблуждения.
> вместо Ruby и на Rubi попробовать писать
Существенное замечание.
>Все мои размышления о том, что смена одной технологии на другую вряд ли чем-то значительно облегчит автору жизнь
Надо же, Вы первый в мире человек, который сказал, что смена технологий не облегчает жизнь.
> Ложь — это один из признаков заблуждения.
Ложь — утверждение, заведомо не соответствующее истине и высказанное в таком виде сознательно.
Заблуждение — ошибочное убеждение, представление о чем-либо.
Вы уж определитесь, пожалуйста, либо это ложное утверждение в виде явного, намеренного и сознательного искажения действительности, либо это заблуждение ввиду ошибочного представления о чем-либо.
Судя по вашему утверждению это взаимоисключающее утверждение. Если я в чем-то заблуждаюсь, то как я осознанно могу говорить ложь об этом, а если явно представляю истину, но при этом лгу, то как я в таком случае могу заблуждаться?
Или это у вас несхождение в голове от того, что я вроде ни к чему не призываю, значит, я обязательно должен в чем-то лгать?
> Надо же, Вы первый в мире человек, который сказал, что смена технологий не облегчает жизнь.
В данном контексте акцент надо сделать на «значительно облегчит». Смена технологии, безусловно, изменит жизнь автора, но станет ли она от этого лучше и проще?
«Везде хорошо, где нас нет». Но мы даже понятия не имеем, как бы нам было там, если бы мы там были. Только квантовые вычисления помогут нам побывать сразу во всех состояниях одновременно, а затем выбрать наилучшее! )))))
Начнем с того, что я не занимаюсь проектированием и разработкой языков программирования, библиотек, фреймворков, а использую их в качестве инструментов. Улучшать их? Какой смысл?Смысл есть, иначе бы развитие технологий совсем остановилось )))
А вот то, что Вы не занимаясь этим и даже не изучив код того же Rails, пытаетесь намекнуть на то, что люди, которые этим занимаются, не являются профессионалами — это как-то странно. Докатились… разработка фреймворков и библиотек — это по-вашему не дело, а метания в поисках истины. Вам самому не смешно?
Автор программировал на Ruby 9 лет. И что с того? Постоянно пытался изменить Ruby?Автор вносил весьма значительный вклад в экосистему Ruby, если не 9 лет, то на протяжении 5 лет точно. Причём весьма активно.
Я бы не стал говорить о каком-то насыщении, если речь идет о притоке все новых начинающих программистов. Какое же тут насыщение?Новички, как правило, просто используют то, что есть, и поэтому не добавляют никакой ценности в сообщество. Конечно, они могут со временем набрать квалификацию, выходя за рамки Rails. Но в целом на этой фазе развития идёт неизбежное понижение квалификации в среднем по сообществу.
Да и с чего бы профессионалам уходить куда-то, если их все устраивает.С чего это Вы решили, что профессионалов всё устраивает?
По своему опыту скажу, что я менял технологии разработки только по мере того, как возникала необходимость переходить на какой-то новый качественный уровень, а предыдущие инструменты уже ну никак не подходили для реализации.Ну вот, автор тоже перешёл на новый качественный уровень — к функциональному программированию.
А они и останавливаются в каком-то смысле. Уповая на чудо-технологии все больше появляется недопрограммистов неспособных самостоятельно писать хорошие программы.
> пытаетесь намекнуть на то, что люди, которые этим занимаются, не являются профессионалами
Не путайте понятия! Те, кто пытаются что-то изменить и улучшить заслуживают уважения, являются двигателями прогресса! Те, же, кто уповают только на смену технологий в надежде на чудесные изменения… в общем, можно долго метаться.
> Но в целом на этой фазе развития идёт неизбежное понижение квалификации в среднем по сообществу.
Благо, что такие просто не осиливают освоение того же Ruby, чем и хорош высокий порог вхождения в подобные системы.
> С чего это Вы решили, что профессионалов всё устраивает?
Преимущественно устраивает. Если человек профессионал, но его что-то не устраивает в готовой системе, то он хотя бы в состоянии собственной реализации недостающих ему механизмов. Я в этом смысле. А в области программирования я вообще не встречал людей, которых бы вообще все устраивало.
А они и останавливаются в каком-то смысле.В каком интересно? Тот же Rails выходит уже в 5-й мажорной версии. IT всё ещё неустоявшаяся отрасль, поэтому тут неизбежно постоянное развитие и изменения на уровне технологий. Стабильными пока остаются только теория и фундаментальные принципы. Назовите хотя бы парочку технологий, которые остановились в развитии, скажем, в 2014 году или раньше и до сих пор актуальны?
Уповая на чудо-технологии все больше появляется недопрограммистов неспособных самостоятельно писать хорошие программы.Статья отчасти и посвящена тому, что появляется много таких Rails-программистов, которые даже на Ruby в отсутствии Rails не могут программировать.
Вообще раньше моветоном было указывать даже язык программирования перед понятием программист, а теперь везде и всюду НазваниеФреймворка-программист (AngularJS Developer, Magento Developer, Rails Developer). Являются ли люди, которые так себя позиционируют вообще программистами? На мой вгляд, нет. Они — пользователи фреймворков и даже гордятся этим. Для них переключиться и сделать новый проект на другом фреймворке — это целая смена Вселенной, хотя по меркам программирования — это пустяковая задача. Это не хорошо и не плохо, это просто факт. К тому же такие люди тоже нужны отрасли, т.к. программистов на все компании тупо не хватит.
Не путайте понятия! Те, кто пытаются что-то изменить и улучшить заслуживают уважения, являются двигателями прогресса! Те, же, кто уповают только на смену технологий в надежде на чудесные изменения…
Похоже Вы сами запутались… Автор статьи совсем не школьник, который не осилил Rails и ищет замену. В его профессионализме сомневаться не приходится, так же как в профессионализме Steve Klabnik, José Valim и многих других. Все они вполне осознанно переходят на другие технологии, потому что пришло время. Профессионалам не нужно надеяться на чудесные изменения, они сами меняют то, что их не устраивает.
P.S. И, кстати, с чего Вы взяли, что у Ruby высокий порог входа?
К вопросу о высоте порога.
Хоть у языка и очень красивый синтаксис (на мой личный вкус), но все равно некоторые штуки могут принести боль на начальных этапах.
Например, последний аргумент-хеш. Я когда очень давно познакомился с руби, на какое-то время завис над чем-то вроде:
object.method { key1: 1, key2: 2 }
Тема с блоками кода вообще достаточно сложная, мне кажется.
Например, у меня есть предположение, что далеко не все начинающие rails-программисты смогут провести разницу между лямбдой и обычным блоком.
Плюс к тому, знаю людей, для которых первое время вызывало некую боль отсутствие Си-подбного синтаксиса. Ну, собственно, такие проблемы будут почти у всех людей, которые слишком долго писали на Java и т.п.
Возможно, сами рельсы и являются фреймворком, очень простым для старта, но язык Ruby — нет.
Разумеется, это сугубо мое личное неавторитетное мнение.
После других языков самое непривычное в Ruby — это необязательность скобок (т.н. poetry mode)
Вообще вопросы синтаксиса — это очень субъективно… кто-то синтаксис Python терпеть не может из-за отсутствия end
или фигурных скобок, кому-то def
в Ruby не нравится. Можно от всего этого абстрагироваться для решения какой-то единичной задачи, но при выборе языков для постоянного использования всё-таки важно, чтобы синтаксис был по душе.
Вроде, главное преимущество рельс в их сложности, которая позволяет, не задумываясь о том, что там внутри, решать задачи.
Да, понятное дело, что порой возникают проблемы, приходится копать глубже, а там уже черная магия. Но не бывает ничего идеального, нужно быть готовым к этому.
Например, думаю, все понимают, что monkey-patching — это плохо. Но ведь это одна из сильнейших фич Руби! Да, ей можно отстрелить себе ногу (или что там обычно отстреливают?), но вы не можете не согласиться с тем, что среди этих патчей есть много хороших решений. Лично мне, например, ну очень нравится простой метод #try(:method). Некоторые вещи из ActiveSupport и вовсе становятся практически неотъемлемой частью жизни разработчиков, это и обуславливает некоторые вопросы на SO, связанные с тем, что вне рельс какие-то методы undefined.
Еще я заметил, что после повального увлечения темой функционального программирования (мне, кстати, она тоже очень интересна), началась повальная критика существующих устоявшихся подходов.
Но ведь все те недостатки, которые перечисляют авторы подобных статей, существовали в нынешних подходах и раньше. Это как «разоблачение», что АНБ следит за людьми.
Нужно задаться вопросом, почему наши подходы имеют такой успех и разделить сферы влияния новых «веяний моды» от «старого доброго».
Piotr Solnica
@solnic
21:30
ie in upcoming hanami-validations you'll be able to do filled(:str?, include?: ".")
that's why I was sad to see this new feature in ruby, as people may not think about proper input validation, if you can make sure that input is in the expected state then lots of complexity in your code won't be needed
Но полбеды само неправильное или неуместное использование, для реализации этого метода AS патчит класс Object, от которого наследуются почти все объекты в руби. Что может пойти не так?
Как я и сказал, за все нужно платить:)
Я им почти не пользуюсь (воспользовался пару раз, когда в чужих костылях нужно было что-то поправить. Собственно, как раз тот случай, который вы описали: непродуманная валидация данных), но сама идея мне нравится. В упомянутом мною случае (правки в костылях) оно сократило количество изменений и при этом в diff все было очень ясно и четко (хоть сам код и говно, прямо скажем).
Подобные удобства, ясное дело, порождают проблемы. Но ведь они все равно остаются удобствами.
Да, я понимаю, что к языкам программирования и технологиям основным требованием является ограждение программиста от возможных ошибок, но нельзя ведь бросаться в крайности.
Упомянутый Haskell, возможно, шикарный язык (не могу оценить его в силу слабого владения ФП и всеми этими математическими штуками в целом), но сомневаюсь, что с его помощью можно быстро обучить команду программистов и делать продукты с той же скоростью и легкостью (до поры до времени), как в Rails.
Мне кажется, что если сейчас провести эксперимент и заставить всех программистов писать на Clojure, то код превратится в императивную кучу скобочек. И это проблема не языка, это проблема программиста.
Камнем преткновения является человеческий фактор. ФП может быть сколько угодно крутым, но оно не становится повсеместно используемым по вполне адекватным и понятным причинам. А подобные статьи — это скорее крик души.
IMHO, естественно
И да, читайте книжки по языкам, не обязательно на них программировать, но это даст вам хорошее понимание сильных и слабых сторон у разных решений.
Я изучаю Clojure в данный момент;)
Вы, очевидно, решили, что я считаю рельсы панацеей. Напротив, я бы с радостью хотел попробовать что-нибудь еще.
Несколько раз сталкивался с тем, что приходилось лезть в код самого фреймворка, чтобы понять, почему что-то работает неправильно. В такие моменты задаешься вопросом: это со мной что-то не так или с фреймворком. Что ж, без лишней скромности считаю, что фреймворк виноват :)
Однако, как Вы сами упомянули, рельсы имеют очень развитую инфраструктуру: множество гемов (и не только rails-специфичных!), множество накопленной информации и, как многие считают, достаточно низкий порог вхождения. И работы по рельсам очень много, что тоже не маловажно.
Мне нравится, что есть такой прекрасный фреймворк (который я иногда называю: "одна большая DSL") и что я с ним работаю (а не с 1С-битрикс, как в начале карьеры, упаси боже). Когда представится возможность, и я с ним распрощаюсь, потому что люблю изучать новые штуки (и мода на ФП меня тоже коснулась). Но распрощаюсь без какой-либо критики:)
Ну а Clojure — это правильно, не забудьте посмотреть выступления Рича Хикки.
Спасибо за продуктивный диалог, оставили мне пищу для ума:)
За сим считаю разговор оконченным.
можно грубо перевести как «Хватит с меня рельсов»По-моему это более эмоциональный перевод, а по сути то же самое. Хотя все по-разному воспринимают… не исключаю, что кто-то мог «Пришло время попрощаться с Rails» воспринять как «Прекратите использовать Rails!», несмотря на то, что в заголовке никакого призыва нет и посыл другой.
Мое мнение, как я уже упомянул, нельзя считать авторитетным:)
Под очевидными причинами я имел в виду:
- приученность к императивной парадигме (если заставить школьника, который писал на паскале, писать на лиспе, то он будет писать на нем точно так же, как на паскале, просто со скобочками)
- сложность обучения (частично вытекает из первого пункта).
- отсутствие (пока что) развитой инфраструктуры. По Rails/Django/etc можно найти ответ практически на любой вопрос на SO, документация в рельсах достаточно неплоха (т.к. проект опенсорсный и при этом популярный, то понятное дело, что она постоянно улучшается), количество плагинов/гемов/модулей просто зашкаливает. Может этим похвастаться Haskell/Elixir? Сомневаюсь. Говоря о плагинах, можно упомянуть JVM, но:
- по тому, что я успел увидеть в Clojure, у меня сложилось мнение, что использование Java-библиотек выглядит не очень естественно.
- а Scala, видимо превращается в Scala-Java, что тоже по сути не ФП. Но это лишь предположение
На Хабре где-то была статья, где автор рассказал, что их компания отказалась от Scala в пользу Go. Всю статью не помню, но запомнил следующие тезисы:
- Код был слишком разношерстный (кто-то писал функционально, кто-то писал в стиле Scala-Java)
- Некоторые конструкции невозможно было гуглить из-за "странных" символов (это не проблема ФП, но все равно интересный факт. Я не в курсе, но, возможно, у Haskell могут быть похожие проблемы)
- Сложно было нанимать новых программистов
Мне кажется, что перечисленные мною причины действительно имеют место быть я являются вполне очевидными. Наверняка, есть множество подводных камней, но, в виду отсутствия опыта в ФП, говорить о них не решусь. Но я вангую, что со временем появится куча статей "разоблачающих" ФП. Кто знает, может быть, в будущем будет популярно логическое программирование?
приученность к императивной парадигме (если заставить школьника, который писал на паскале, писать на лиспе, то он будет писать на нем точно так же, как на паскале, просто со скобочками)Вот в этом основная проблема «моды на ФП», по сути то это просто ещё 1 инструмент и надо понимать как им пользоваться. Вот неплохая статья на эту тему: http://degoes.net/articles/fp-is-not-the-answer
По Rails/Django/etc можно найти ответ практически на любой вопрос на SO, документация в рельсах достаточно неплоха (т.к. проект опенсорсный и при этом популярный, то понятное дело, что она постоянно улучшается), количество плагинов/гемов/модулей просто зашкаливает. Может этим похвастаться Haskell/Elixir?Те, кто помнят экосистему Rails и Django времён 2008-2010 годов, могут оценить, что в том же Elixir ситуация с экосистемой уже гораздо лучше. Конечно по кол-ву пакетов/гемов обогнать Ruby не просто, но нет каких-то прям стоп-факторов от использования. Про экосистему Haskell я не в теме, честно говоря.
Те, кто помнят экосистему Rails и Django времён 2008-2010 годов, могут оценить, что в том же Elixir ситуация с экосистемой уже гораздо лучше.
Возможно, но суть в том, что сейчас уже не 2010 год и многое уже пройдено и установилось. Это не стоп фактор, но в данный момент это одна из причин, почему его не используют повсеместно. Все хотелось использовать слово "сыро", но не поворачивается язык, а словарного запаса для более удачного выражения, увы, не хватает.
А если серьёзно, то всё-таки ситуация получше, каждый первый точно править не надо. В основном в допилке нуждаются не особо популярные гемы типа интеграций со всякими сервисами. Случаи, когда нужно влезть в исходники того же Arel или kaminari, не так уж часто встречаются.
Если честно, без особых объективных причин. Просто захотелось.
За Clojure стоит JVM, за Elixir, если не ошибаюсь, Erlang. Я встречал мнение, что чтобы использовать Erlang, нужно четко знать, в чем его преимущества и нужны ли они вам.
К тому же немаловажным фактором является то, что мне нравится Лисп с его простотой и однородной структурой. Можно сказать, что Clojure — это современный диалект Лиспа. А так работу можно найти и по тому, и по тому (видел таких людей). Тем более, что со временем количество вакансий будет только увеличиваться, имхо, причем в случае Clojure это будет происходить быстрее, поскольку некоторые компании, которые работают с Java начинают все чаще смотреть в сторону Scala, а там и Clojure недалеко.
> ФП может быть сколько угодно крутым, но оно не становится повсеместно используемым по вполне адекватным и понятным причинам.
А можете уточнить, что за причины?
Как на меня основная причина в том, что, по сути, почти все программирование ПО — про сайд-эффекты. Запись в базу, вывод на экран, етс. Потому чистоты не добиться и приходится прибегать к костылям. А в итоге получается иммутабельность ради иммутабельности, абсолютно нечитаемые конструкции и тонны копипасты. И, конечно, никакой декларативности на практике. Потому что обычно программа по своей сути является последовательностью нескольких изменений состояния. Обычно на ФП пишут в императивном стиле и в нечитабельной форме. Пример:
https://habrahabr.ru/post/279715/#comment_8812695
pandoc — просто математическая либа. Функции получают что-то на вход и возвращают. это не программа.
ну да. а что именно ещё нужно?
Емс. Я могу его вот взять и запустить на клиентской машине? Залогиниться, написать сообщение. Принять. Увидеть его в трее.
не, вот этот http://pandoc.org/
Да, я понял. Математическая — неправильно выразился. Суть такой либы в том, чтоб в функцию принять данные и вернуть новые. Но она еще не программа, которую можно поставить на компьютер и пользоваться. Такие либы вообще все-равно на чем писать — особой бизнес сложности они не имеют.
Но она еще не программа, которую можно поставить на компьютер и пользоваться.
Почему? Pandoc — программа для преобразования форматов текстовых файлов. Можно поставить и пользоваться. Для той же windows есть msi-инсталлер.
Я могу его вот взять и запустить на клиентской машине? Залогиниться, написать сообщение. Принять. Увидеть его в трее.
Из коробки — нет. RabbitMQ это не мессенджер и не чат. Это система передачи сообщений между компонентами программного комплекса. У этой системы есть серверная часть (написанная на Erlang) и клиентские библиотеки, которые можно встроить в любую программу.
ну извините
Обьясню. Примеры очень узкие. При чем все — для использования программистами, не конечными юзерами. Феникс — фреймворк, Пандок — либа (хоть и с консольным интерфейсом), Реббит — либа. Интересно увидеть многогранный продукт. Я не сомневаюсь, что для некоторых (довольно узких) целей ФП очень удобен. Когда в бизнес-требованиях есть вход и выход. Но он далек от серебрянной пули и уж точно не замена ООП, как любят покричать. Потому он и «не становится повсеместно используемым по вполне адекватным и понятным причинам». Он банально не рассчитан на большинство задач программирования, а только очень узкий спектр, а на остальные задачи натягивается с треском и костылями. В то время, как другие подходы более приближены к реальности разработки.
1. Использование ФП ограничено довольно узким кругом специфических задач
2. Большинство, в том числе апологеты ФП не умеют его готовить (как, кстати, множество апологетов ООП не умеет его готовить)
Такие выводы у меня из следующих предпосылок:
1. Известные мне программы на ФП довольно узки
2. Большинство примеров ФП в статьях, что лично я видел — обычная императивщина просто записана навыворот.
— Я понимаю, что теоретически ФП круто паралелится (наверное, клево было б шейдеры писать), но как оно будет параллелиться когда у функций будут сайд-эффекты?
— Более того, когда появляется сложный стейт и нетривиальные зависимости, я часто вижу, что в много функций приходится передавать не какие-либо чистые данные, а что-то вроде: `mySmallFn(wholeAppState)`, что, по сути просто использование глобальной переменной, хоть и с притворством, что она локальная — связи очень сложно проследить, особенно ввиду утиной типизации. (а кто вообще может прочитать `id`, который я верну из функции?)
— функция, которая возвращает функцию, которая возвращает функцию, которая зависимо от аргумента возвращает результат. Как такое прокрыть юнит-тестами? В том же ооп все довольно просто. Вызвал метод — должен вернуться результат или измениться состояние. Методы очень атомарны.
— другая проблема — дебагинг. Кто кого вызывает и почему? Путь кода становится абсолютно неконтролируемым и отладка сводится к обычным `print(currentData)`.
Так вот — у меня вопрос. Может, я ошибаюсь? Но если так и ФП действительно очень удобен, то я хочу научиться делать такие проекты. Покажите мне примеры, статьи, научите. Расскажите, как обходите такие принципиальные вопросы? Давайте я приведу контр-примеры. А что с действительно сложными и комплексными проектами? Не обработка текстовых данных, а игры, графические редакторы?
Просто с таким агрессивным пиаром и такой слабой базой через пару лет от ФП все будут плеваться (непонятный, запутанный, невозможно поддерживать, тормозной и так далее, обязывает к копи-пасте) и вполне возможно, что незаслуженно и есть способы на нем программировать легко и кльово. Но люди, которые умеют делать — сидят тихонько и всем говорят, что их ААА-игры написаны на попсовом С++, чтоб не спалиться.
Я просто искренне надеюсь, что как можно больше людей прочитав мои комметарии решат не лезть в то болото, которое сейчас пропагандируется как ФП и не будеть видеть в нем серебрянную пулю и, конечно, что перестануть писать бред из серии «ООП — отстой, все клевые пацаны давно фигачат в ФП», при этом не иметь в своем коде ни декларативности, ни чистоты и пародию на иммутабельность с её минусами, но без её плюсов.
Вот уже получается, что ФП может найти свое применение, и на сервере и на клиенте, и в играх. И это не какие-то редкие случаи, не какой-то специфичный софт, а самые общие вещи: сервера, графический интерфейс, рендеринг, расчет физики.
Но будущее, на мой взгляд, за гибридным подходом. Сплав ООП и ФП, на мой взгляд, наиболее удобен с практической точки зрения.
@Cryvage пишет о том, что можно ОО-язык использовать в функциональном стиле. Т.е. данные о состоянии объекта передавать только конструктору и объявлять на них только геттеры, чтобы даже у методов объекта не было возможности повлиять на его состояние. Тогда получится своеобразное замыкание как в ФП.
Но чтобы так писать на ОО-языке всё равно надо уже расширить своё мышление функциональной парадигмой :-)
Вы во многом правы, но не считаете ли Вы, что функциональные примеси в ООП демонстрируют слабость ОО-парадигмы? По сути даже создатели языков программирования, признают чистое ООП недостаточно удобным. Остался ли хоть один современный ЯП, в котором есть только чистое ООП и ничего больше? Так чтоб никаких лямбд (только Strategy), никаких foreach (только Iterator) и т.д.
Языки программирования добавляют функциональные примеси для того, чтобы сделать язык более универсальным и удобным. Это вполне логично с их стороны. По этой же причине во многих языках высокого уровня можно делать ассемблерные вставки. По этой же причине, в C# можно добавить unsafe код.
Если топор не подходит для того, чтобы копать землю, и человек берет с собой, и топор, и лопату, чтобы сначала срубить дерево, а потом выкопать пень, разве это говорит о слабости топора?
Функциональные примеси, они не в ООП. Они в языках программирования.
Верно, я имел в виду ООП-языки.
Это говорит лишь о том, что ОО-парадигма не является ответом на все вопросы
+1, у любой парадигмы есть свои границы применимости.
И даже там где одна парадигма применима, другая может иметь более удобные средства. Так что по-хорошему программист должен быть знаком с многими парадигмами, чтобы делать осознанный выбор под конкретную задачу, а не просто по привычке.
Но он далек от серебрянной пули и уж точно не замена ООП
Что Вы как ребёнок всё в серебряные пули верите…
ФП — это парадигма программирования и она предоставляет свои инструменты для решения задач. ООП — другая парадигма, в идеале их области применения могли бы не пересекаться, но на практике одну и ту же задачу можно решать в рамках и той и другой парадигмы.
Мы тут обсуждаем конкретно веб-разработку, а не всё подряд. Если вспомнить как ООП попало в веб-разработку, то очевидно, что это было мотивированно больше всего модой на ООП, т.к. весь практический смысл этой парадигмы теряется для программ, которые отрабатывают за долю секунды.
Само по себе ООП — не решение. Важно то, как оно реализовано в конкретном языке.
Насколько я помню, есть всего 3 реализации ООП — на основе классов, на основе прототипов и на основе акторов.
C# ранних версий — это шикарный пример реализации ООП на основе классов, а вот начиная с 3-й версии туда начали добавлять ФП и прочие не ООП-концепции.
Из различий реализаций ООП на основе классов, Вы упомянули только множественное наследование, которое по холиварности не уступает goto, поэтому в большинстве реализаций отсутствует )))
сколько абстракций он держит в той же Джанге, и, наверное, в этих ваших рельсах…
А задумайтесь сколько из этих абстракций реально нужны, чтобы обработать запрос? именно из-за усложнения простых вещей "за долю секунды происходит столько всего, что в голове не удержишь". Вы догадываетесь сколько объектов создаётся для обработки тривиального GET /page/permalink? Хотя по сути Вам нужен 1 объект класса Page и то он сам Вам нафиг не нужен, Вам нужны данные из БД, но как же, без ORM никуда..
Я возможно Вас слегка расстрою, но утиная типизация — это часть парадигмы обобщённого программирования, к ОО-парадигме она никаким боком не относится :-)
Метапрограммирование — это тоже не ООП, строго говоря. Вообще рекомендую ознакомиться со списком парадигм программирования, там много интересной информации.
Что касается ООП, попробуйте хотя бы для себя, абстрагируясь от привычек, ответить на вопрос: при каких условиях неудобно применять ООП?
Я понимаю, хотя списочек там реально заслуживающий внимания, я несколько новых для себя нашёл.
Дело не в обобщении алгоритмов, а в том, как определяется тип объекта.
Дело как раз в том, что можно написать обобщенный метод/функцию, без явного указания типа/интерфейса параметров в сигнатуре метода. В ООП для подобных методов придётся использовать явные интерфейсы.
Как тогда Lisp стал функциональным — не вполне ясно.
Lisp появился ещё до того как все эти парадигмы были сформулированы. Формально, он в первую очередь гомоиконный. Но всё ФП началось именно с него.
В общем, не всё так однозначно, различные парадигмы могут иметь общие техники и подходы.
В принципе, да, остаётся их разделять разве что по обязательности к-л части.
бы не рискнул запилить что-то серьезное, скажем, на Java или том же C#, хоть они и продвинулись значительно
эмс. А на чем бы рискнули?
Но вот по ощущениям пишется как на рельсах ;)
И все равно что там ооп или фп. Конечно, код отличается, для разных языков совсем по разному структурирование программы происходит, если следовать идеологии языка то все замечательно (шутка про программиста на фортране пишущего на фортране на любом языке). Но вот подход «взял и пользуешься» точно такой же как в рельсах.
Собственно кроме phoenix и rails я ничего даже близко подобного не видел, не зависимо от языка
Что Вы как ребёнок всё в серебряные пули верите…
Так я как раз и не верю. Я прекрасно комбинирую, ФП — для мелкой обработки данных, ООП — для глобальной архитектуры. Это адепты ФП пытаются убить ООП и кричат, что ФП — серебрянная пуля, что приводит к фейспалму.
весь практический смысл этой парадигмы теряется для программ, которые отрабатывают за долю секунды.
При чем ООП к времени жизни программы? О, о
При чем ООП к времени жизни программы? О, о
При том, что ООП хорош для задач, где нужно управлять глобальным состоянием программы в оперативной памяти. Взять тот же GUI, как его инстанцировали при открытии программы, так он и продолжает существовать пока программу не закроешь, и у каждого контрола свои атрибуты и обработчики событий. Удобно для ООП? Конечно!
Проблема в том, что ООП превратили в культ карго и создают объекты везде где ни попадя, просто потому что так принято.
но если забыть на секундочку ФП, то без ООП становится совсем сложно
Это от масштаба проекта зависит на самом деле. 80% сайтов вообще просты до безобразия… просто мы тут их не обсуждаем :-)
ООП успешно дает доступ к долгоживущему глобальному состоянию, такому, как база данных, такими средствами, как ORM
По факту, ORM — это ещё одно следствие моды на ООП. Данные в реляционной БД — это данные, а не объекты. Как следствие OR impedance mismatch и разнообразные статьи типа "ORM is an anti-pattern".
За эти миллисекунды веб-приложение успевает пропустить запрос по конвейеру прослоек различных предварительных обработчиков...
И вот Вы перечислили больше десятка действий и ни одного объекта. Когда задача описывается через действия — это как раз признак того, что она больше подходит для ФП, чем для ООП. В случае обработки веб-запросов объекты создаются только чтобы вызвать какие-то их методы, а потом напрячь GC. Советую Вам книгу Programming Phoenix, чтобы посмотреть как эта задача решается без объектов.
ООП здесь помогает упаковать все в удобный объект.
точнее вместо того, чтобы функцию поставить в очередь, требует сначала обернуть её в класс
А если закрыться в своей коморке и ни с кем не общаться, то да, можно не использовать никаких абстракций и каждый проект писать с нуля.
Абстракции и повторное использование — это вещи, слабо связанные с ЯП и с парадигмами программирования. И возможны они везде, было бы желание. А если нет желания, то и в ООП их не будет.
ООП не решает проблем, а просто является модой.
Я этого и не говорил. Я говорил про то, что веб-разработка пошла сначала по пути ООП, а не сразу по ФП, и это во многом было именно веяние моды. Сейчас мода поутихла и появляются более уместные решения. Ну не является обработка потока изолированных входящих запросов задачей, подходящей для ООП, т.к. у них тупо нет никакого shared state в памяти.
Ну, как ни странно, ООП начала активно пробираться в веб как раз через PHP 5, ещё 12 лет назад. А потом уже Ruby и Python подтянулись )))
ООП действительно появилось гораздо раньше и на момент, когда веб-сайты стали превращаться в веб-приложения и им стал нужен нормальный бэкенд в ходу были C++, Delphi, Java, C#. Все ООЯП.
И по сути был двусторонний процесс, с одной стороны разработчики популярных языков для обычных приложений заметили веб. А с другой стороны веб стал усложняться и требовать подходов для борьбы с этой сложностью. Поэтому недолго думая решили, что и для web ООП пойдёт не хуже, чем для desktop. Ну и экономический фактор тоже сыграл роль, дело даже не в пороге входа, а в том, что ОО-языки уже много кто знал по работе с desktop-приложениями.
Да, реализация там была действительно неважная. Хотя говорят, что сейчас уже лучше.
Вы больше говорите о программистах, которые сразу начали с PHP, мой опыт не сильно репрезентативен, но я таких почти не встречал. Разве что видел их по вопросам на форумах.
Когда ООП добавили в PHP, это была уже знакомая для многих парадигма. Поэтому наверно и добавили.
Даже фреймворки типа CodeIgniter стали появляться. Хотя он тоже отличался весьма оригинальным видением ООП.
По поводу вопросов, специалистов по ООП в начале 00-х было на порядки больше, чем специалистов по ФП. Опять же благодаря моде, т.к. именно ООП преподавали во всех ВУЗах, а ФП касались на редких факультетах. Да и до сих пор ФП в виду непопулярности остаётся тем конкурентным преимуществом, про которое писал Пол Грэм. Инертность мышления ещё долго будет останавливать людей от изучения чего-то кроме ООП.
Только вот теперь непонятно, зачем такое громкое название было давать — ФП, когда большинство улучшений (по сравнению с ООП) можно было бы реализовать в рамках несколько видоизмененного ООП, применяя например объекты с явным указанием вроде «с сайд-эффектами» / «без сайд-эффектов»?
Есть ли какие-то вещи, которые принципально не вписываются в ООП?
В чем ФП-парадигма не могла быть интегрирована в существующие ОО-ЯП? Да, они бы не были уже чисто оопешными, ну и что, какая разница, если такие «фичи» бы появились?
Только вот теперь непонятно, зачем такое громкое название было давать — ФП, когда большинство улучшений (по сравнению с ООП) можно было бы реализовать в рамках несколько видоизмененного ООП
1) ФП появилось лет на 10-15 раньше, чем ООП
2) то, что на ОО-ЯП можно писать в функциональном стиле не меняет ОО-парадигму, просто код перестаёт ей следовать
3) Интеграция обеих парадигм в рамках одного языка и так уже идёт, причём давно уже
Интересно, что в Вики Ruby не сильно отстает по внедрению функциональности от например Common Lisp / Erlang / F# / Scala. А вот по Вашим словам разница существенная.
И еще вопрос в том, насколько чистые Ф-языки приспособлены для выполнения разных задач (как это уже здесь обсуждалось), не будет ли универсальность принесена в ущерб мощи.
Почему я и вопрос задал — не проще ли «допилить» уже существующие ОО-языки, сфера применения которых известна и отработана, привнеся в них Ф-парадигмы.
Ну это наверное холивар уже с моей стороны ))
Как я успел осознать, неизменяемое состояние в ФП — это миф. Без изменения состояния невозможно что-либо "напрограммировать" (я не математик, поэтому не возьмусь доказывать это свое утверждение, а просто с умным видом поставлю восклицательный знак) !
Просто состояние сохраняется не так, как мы привыкли (в переменных), а с помощью использования лямба функций, замыканий и т.п.
Как минимум, думаю, Вы не будете спорить, если я скажу, что даже в императивной программе, чем меньше мутабельности, тем проще и, возможно, лучше.
Любая функция, если она что-то делает изменяет состояние, это вроде очевидный факт касаемо ФП.
Даже чисто математические функции изменяют состояние:
y(x) = x*x
y(5) => 25 // было состояние: 5, стало: 25.
Разница в том, что в ФП это состояние передаётся в качестве аргумента функции, а в ООП состояние — это отдельная «сущность», на которую 2 метода могут влиять параллельно.
Возможно, я что-то не то подразумеваю под состоянием.
Давайте разберемся. Я предполагаю, что в данном контексте состоянием является некоторый переменный(upd.) набор данных, принадлеащий системе.
Например, при добавлении значения в стек мы меняем его состояние, а именно:
- количество элементов в нем
- "верхний" элемент*
- и т.д.
- и т.п.
Функция-квадрат сама по себе никакого состояния не меняет. Функция — просто правило, по которому элементы одного множества сопоставляются другому. О каком состоянии может быть речь?
Теперь касательно ФП.
Когда мы говорим о том, что данные неизменяемые, мы, по моей логике, немного лукавим, поскольку в нашей системе есть только одна вещь — вычисляемое значение. А вот сам процесс его вычисления — уже имеет некоторое состояние в разном виде. Например, в изменяющихся аргументах при хвостовой рекурсии (как-то странно я ее назвал, но Вы меня поняли) либо в изменении функции (правила сопоставления одного элемента другому) с помощью замыканий и пр.
Поэтому данные все же меняются, просто не те, к которым мы привыкли. Лично я привык к тому, что состояние системы зависит от ее переменных, которые являются хранилищем данных, к которому мы имеем прямой доступ (привет, оператор присваивания). В случае ФП мы не имеем такого прямого доступа, но достигаем нужного результата, воздействуя на него косвенно способами, которые я уже частично перечислил.
Примерно так выглядит мое понимание такого явления как функциональное программирование. Как же выглядит Ваше? Буду признателен, если поделитесь или укажите, где я не прав.
Я предполагаю, что в данном контексте состоянием является некоторый переменный(upd.) набор данных, принадлеащий системе.В таком определении у Вас состояние — это вся база данных + redis + ещё что-то. Слишком глобально и внешне к самому приложению.
Давайте возьмём для примера веб-приложение, оно обрабатывает входящие HTTP-запросы. Задача приложения обработать запрос и выдать HTTP-ответ. Для простоты рассмотрим один поток выполнения. Получив запрос, приложение создаёт некоторую структуру данных, описывающую запрос. Теперь эта структура данных и есть состояние. Дальше оно передаётся от функции к функции, сначала проходит через middleware-функции, потом в роутинг-функцию, потом в action-функцию контролера и т.д. пока эта структура-состояние не станет ответом.
Пришло время попрощаться с Rails