Comments 27
Перевод не полностью локализован. Много англо-штампов " Почему бы вместо забвения JavaScript и его удивительной экосистемы" вот это вот.
Есть понятие "Функции первого класса" но в контексте статьи было б лучше ф-ции первого порядка. Потому что автор хочет показать отличие от декларативных яп. Где нет high order func
Есть понятие "Функции первого класса" но в контексте статьи было б лучше ф-ции первого порядка.
Есть устоявшиеся термины, и, мне кажется, нет нужды придумывать свои, потому что это только добавит неразберихи. Ну а функции первого порядка показывают отличие императивных языков, в которых объекты первичны, а функции вторичны, от декларативных, в которых функции как раз первичны (речь идет о способах работы с объектами и функциями).
Потому что автор хочет показать отличие от декларативных яп. Где нет high order func
Википедия с вами несогласна: Функция_высшего_порядка
Ok+.
Для понимания того, что хочет автор прилагал усилия, и перестарался. :)
Отдельно хочу плюс за то, что узнал об отсутствии оптимизаций хвостовой рекурсии. Теперь только for и foreach — наше все.
Оптимизация хвостовой рекурсии — сильно разрекламированная фича. По факту любая линейная рекурсия, а не только хвостовая, легко и непринужденно вручную переписывается на цикл, без усложнения кода.
Любая рекурсия на цикл переписывается, только может понадобиться вручную управлять стеком в куче.
Это понятно, только код получается слегка упоротым.
Мой поинт вот о чем: хвостовая рекурсия реально нужна, только если в язык по каким-то причинам не завезли нормальный цикл. Например, это ФП. Тогда программисту приходится вместо цикла делать хвостовую рекурсию. Которую потом компилятор разматывает обратно в цикл. И вот это преподносится как фича!
Эта самая оптимизация в JavaScript даже была когда то, но потом ее безжалостно выпилили из V8. А вот в Safari она живет по сей день.
Картинка забавная (кстати, почему ее внутри статьи не видно?): код красивый, можно смотреть, медитировать, философствовать. Но вот куда поставить брекпоинт, если что-то работает не так?
Имхо, ФП хорош в малых дозах. Всякие там частичные применения, array.map и т.д. Сильно не увлекаться, в общем.
Я, в общем-то, с вами согласен, потому что магия теории категорий весьма сложна для чтения, а вот базовые вещи весьма полезно знать и применять даже и внутри обычных приложений. Собственно автор об этом откровенно говорит — не стоит рассматривать ФП или ООП, они не враждуют, а, скорее, дополняют друг друга.
Не получил ответ на главный вопрос — что мне даст переход на ФП. Допустим все мое приложение написано чистыми функциями, ок. Профит какой?
Я, наверное, мог бы начать вас убеждать что профита ну просто воз и маленькая тележка, но не стану, потому что не считаю нужным "переходить" на ФП. На мой взгляд, достаточно знать что такой путь существует и может быть применен не только в полностью ФП-шных приложениях.
Например "чистые функции" дают вам отличную тестируемость, функции высшего порядка — путь построения абстракций вне парадигмы ООП (ну и тестируемость тоже, они же тоже чистые).
Я понимаю, что аргумент "тестируемость" весьма шаткий, потому что даже из абсолютно одинаковых кирпичей можно построить дом, который развалится при первом же хлопке дверью :) Но лучше уж иметь набор конструктов, которые можно проверить, чем не иметь совсем ничего.
А еще улучшается читаемость, потому что код содержит указания что делать, а не как. Например, частенько при решении задачи об обработке списка (когда нужно выполнить какое-то действие с каждым элементом) применяется цикл, тогда как сама задача заключается в трансформации одного списка в другой, что можно сделать используя .map()
И тут я ворвусь со своим тредом о ФП: https://twitter.com/_jin_nin_/status/1356967512462753793
А как реализовать к примеру задачу: надо в цикле на 10000 итераций инкрементировать поле какого-то обьекта?
Ну, если нужно в цикле инкрементировать поле, то и используйте цикл, кто вам мешает?
Это я к тому, что постановка задачи в вашем изложении выглядит не как "сделать что-то", а "сделать так-то". Можно, к примеру, поставить задачу "посчитать среднее значение для заданного массива", а можно "в цикле сложить все элементы массива и поделить результат на размер массива". В первом случае вы, как программист, можете принять решение как именно вы будете решать задачу. Во-втором случае у вас нет выбора, сама формулировка задает путь решения.
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Control.Lens hiding (element)
import Control.Lens.TH
data MyObject = MyObject { _field :: Int } deriving (Show)
$(makeLenses ''MyObject)
generate :: MyObject -> [Int] -> [MyObject]
generate obj numbers = foldl go [] numbers
where go l n = l ++ [ set field (n + view field obj) obj ]
main :: IO ()
main = putStrLn . show $ generate obj [1..99]
where obj = MyObject 123
Не знаю, насколько это хорошее решение. На самом деле, я до конца не понимаю, как это всё работает. Либо я какой-то не такой, либо высокий порог входа.
Наверное, надо лучше покопаться в теории категорий, чтобы было полное понимание всех этих монад, функторов…
Такое чувство, будто первый день программирую!
Даже не знаю… неужели мысли ценятся по месту рождения? Если мысль родилась в голове гения, она всегда гениальна? И не может ли случиться так, что самый последний дурак вдруг изречет мудрость, которую потомки увековечат в камне?
Ну и да, вы не поделитесь списком авторов, которых стоит переводить?
У Эрика есть определенный талант объяснять сложные вещи простыми словами. Код в постах оказывается не всегда верным, но так даже интереснее.
Жду продолжения...
Сочиняя ПО: Почему стоит изучать ФП на JavaScript?