Вот только в C он как был, так и остался, потому что без него невозможно писать компактный код, постоянно дергающий и освобождающий пачками ресурсы, а в других языках есть более ограниченные версии goto все по той же причине (даже в Go при наличии его деферов).
А лисп как был никому не нужен, так и остался. Поправка: никому вне академических интересов и исследований. Продакшн-код на нем никто в здравом уме не пишет.
Естет много фп языков, которые реально используются в проде. К примеру, Scala, F#, Erlang.
Кусками в виде подгружаемых библиотек если только? Кто в здравом уме будет на них что-либо кроме логики писать и то алгоритмов специфических?
Базы данных, сервисы очередей, да и в конце концов Whatsapp - вполне себе реальные примеры.
На функциональщине отлично пишутся самые обычные алгоритмы, а не только специфические.
На Эрланге много чего написано для прода. Хотя бы тот же rabbitmq, который довольно популярен.
Я гуй пишу на js, но в функциональном стиле (React + redux). И это не я такой оригинальный, это такая распространенная практика.
Более того, я считаю, что, если имеется возможность отделения момента сохранения информации от прочей логики, то эту логику следует писать в функциональном стиле.
Там функциональный стиль не от хорошей жизни появился, а из-за общей ущербности языка. Функциональную лапшу на js читать невозможно настолько, что теперь туда даже async/await завезли.
Ерундой не болтайте.
Функциональный подход в React-redux вытекает из его концепции естественным образом.
В JS нет ничего ущербного. Всё те примеры "странного поведения", которые постоянно мусолят в интернет, на практике не встречаются. JS действительно позволяет "выстрелить в ногу" из-за динамической типизации и проглатывания ошибок. Но с эти борются путем использования всяких надстроек над языком типа TypeScript, а никак не функциональным стилем.
Под функциональной лапшой Вы видимо подразумеваете "лапшу из callback'ов" асинхронных вызовов, раз упоминаете в этом же предложении async/await. Это вообще из другой плоскости предмет, и ФП тут не причем! К тому же вовсе не обязательно оформлять код в виде лапши анонимных функций. Всегда можно выписать функции по отдельности и дать им имена.
В действительности функциональный стиль подразумевает:
во-первых, "чистые" функции. Т.е. для одних и тех же параметров функция всегда возвращает одинаковый результат;
во-вторых, все переменные инициализируются единожды. По сути, в ФП нет переменных, это скорее псевдонимы для выражений;
в-третьих, все объекты иммутабельны. Т.е. операция над объектом не модифицирует объект, а возвращает новый объект.
> В JS нет ничего ущербного
> JS действительно позволяет "выстрелить в ногу" из-за динамической типизации и проглатывания ошибок
> путем использования всяких надстроек над языком типа TypeScript
Ты просто на ноль поделил. Если на языке невозможно писать без надстроек - то это как раз таки ущербный язык.
Не надо мне рассказывать про функциональный стиль, пожалуйста. Я прекрасно понимаю, что это такое. Действительно полезная вещь в функциональщине ровно одна - чистые функции. Все остальное крайне ситуативно и способствует созданию неоптимального кода. Что до лапши из каллбеков - это прямое следствие корявой асинхронности и навязанного функционального подхода. Никогда не замечал, что это все подозрительно напоминает лиспы? Вот то-то и оно.
Скажем так, исчезающе мало. Нет никакой технической необходимости писать все в функциональном стиле, потому что прод - это далеко не только алгоритмы. Практика такова, что большая часть современных языков, не являясь чисто функциональными, просто переняли некоторые функциональные конструкции, не перенимая весь подход, и этого оказалось достаточно. Просто потому что когда начинается действительно серьезный прод, эстетические игрища приходится заканчивать и начинать писать эффективный императивный код.
Есть очень занятный пример - сервис по продаже авиабилетов гугла. Они его перекупили у какой-то компании вместе с клиентской базой, и лиспофаги постоянно били себя пяткой в грудь - мол вот, лисп в продакшне, скоро все остальные отправятся дворы мести. На самом деле, как мне поведал один знакомый из гугла, это скобчатое говно поддерживать невозможно и оно тупо тормозит, поэтому когда надо внести какие-то изменения в этот божественный лиспокод, то они просто кусками переписывают его на C++. Дело было много лет назад, так что может быть уже и переписали.
Пример не показателен. На Lisp'е вполне можно писать в императивном стиле. Пример лишь говорит о том, что в первой компании у разрабов ручки кривенькие.
Тормоза программ как правило вызваны не парадигмой программирования или особенностями языка, а неверными архитектурными решениями. Сортировка пузырьком на Python исполняться раз 100 медленней, чем на Си. Но правильным способом ускорения здесь будет не замена языка, а замена алгоритма.
> Пример не показателен.
Еще как показателен. Функциональный подход с его иммутабельностью выглядит красиво, но порождает дичайший оверхед по памяти и использованию процессора.
> Тормоза программ как правило вызваны не парадигмой программирования или особенностями языка
Неудачно спроектированные языки способствуют написанию говнокода. Пуризм и элитизм любителей фп способствуют написанию неподдерживаемого и неэффективного кода.
> На Lisp'е вполне можно писать в императивном стиле.
Тогда вопрос его нужности по сравнению с другими языками встает еще более остро.
Слушай, я вижу, что ты разбираешься в теме, но тебе, наверное, не встречалось еще кода львов толстых, написанного на всяких функциональщинах. Вопрос лично тебе. Ты упоминал про реакт, ты фронтендер, или так, пописываешь иногда? Хочу уточнить не для троллинга, а потому что наши предметные области могут просто не пересекаться.
Последние 5 лет пишу как серверную (на Java), так и клиентскую части (на JS с использованием React). До этого писал серверную часть на Python. Причем та серверная взаимодействовала со всякими промышленным железом. Поэтому писал еще и на Си++. Взаимодействие с железом также добавляло критичности по времени. Поэтому я в достаточной степени представляю, что где уместно использовать, а что нет.
К функциональному программированию пришел не по зову моды, а в ходе профессионального развития. Я не являюсь фанатичным адептом этой парадигмы, однако вижу много областей, где уместно было бы гармонично ее употребить.
Что касается иммутабельности: Она действительно порождает некоторый оверхед. Однако надо понимать следующее:
1. Иммутабельные объекты не копируются полностью. Допустим у нас есть массив на N элементов. Нам нужен такой же массив, но с измененным k-ым элементом. Это не значит, что будут скопированы все N элементов. В действительности будет модифицирован объем памяти размером log N.
2. Иммутабельные структуры не могут образовывать циклические зависимости, поэтому необходимость в сложном сборщике мусора, который может обнаруживать и удалять "подвешенные" острова памяти, отпадает. Достаточно тривиального подсчета ссылок.
3. При правильном использовании сравнение огромных структур данных превращается в простое моментальное сравнение ссылок на эти структуры.
Что касается элитизма любителей ФП: это не проблема ФП, это неизбежный спутник слабо распространенных новшеств.
Когда-то все программисты были "иной кастой", потому что были малочисленны. Просто ФП не мейнстрим, вот ФП-программисты и зазнаются.
Ну вот. А я 10 лет пишу коммерческий код на питонах, сях и прочем не шибко красивом, но железобетонном наборе языков. Хайлоад, железо, все дела. И мой опыт говорит о том, что фп в чистом виде не нужно и вредно, достаточно лишь его отдельных элементов в императивных языках.
Всю жизнь старался держаться подальше от веб-параши, но тут в последний год приспичило написать одну веб-приложуху. И я просто охренел от того говна, которого там понаворотили за последние годы. Сломано и дефективно буквально все, а что не сломано - еще нормально не поддерживается браузерами. Но это платформы. А язык - по факту js без альтернатив, потому что использование js со всякими тайпскриптами и прочими реактами превращает отладку в треш, угар и содомию.
Короче, еще раз. Мой поинт в том, что ФП не нужно в виде отдельного языка и нужно в виде элементов в других языках, поскольку никаких особых задач не решает само по себе, которые нельзя было бы решить на императивных языках.
Правильно ли я понимаю, что сначала все указатели зануляются, потом последовательно требуются ресурсы (если NULL, goto error), потом идёт return и метка error, где указатели сравнивают с NULL (признак либо ошибки, либо того, что код не дошел до требования этого ресурса - тут помогает инициализация NULLами) и в обратном порядке освобождают?
Или можно проще (допустим, не все функции освобождения переваривают NULL)?
Просто делаешь n-меток, на осовбождение ресурсов. И в случае ошибки в коде ты прыгаешь на нужное место в последовательности освобождения. В линух драйверах во всяком случае так
Вот это мне казалось слишком наивным и громоздким (хотя это скорее всего самое быстрое).
Вариант из моего комментария сверху оперирует с одной меткой, хотя после перехода надо проверять несколько условий.
Не все функции освобождения переваривают нулл, конечно же. Хотя free() это делает, все остальные этого делать вообще не обязаны. Например, close() на неоткрытый дескриптор вызовет ошибку. Что-то посложнее, типа ioctl() на возврат в систему какого-нибудь буфера, тоже.
Пример: https://github.com/pi-kvm/ustreamer/blob/master/src/http/static.c
Хороший пример, спасибо! Хотя, жаль, что один ресурс.
Скажем так, goto можно называть и ранний return, так и всякие break/continue штуки. Но в C без goto действительно плохо живется.
Что интересно, в академической среде goto не хейтят совсем. Видел код, написанный не программистами а как раз всякими докторами/академиками - там goto в полный рост. Если считаете, что академики для прода не пишут, ваш любимый mp3 и его реализации как раз они самые и писали.
да нормально живётся на самом деле.
последний раз пользовался лет пятнадцать назад.
Докторами чего? Это вообще не показатель. Физики в CERN'е пишут в основном такой говнокод, что любой программист из индустрии охуеет. Но дешевле оказалось развивать вычислительные мощности, чем переучивать физиков программировать.
Но если "академическая среда" -- это искусственная лингвистика, то да, другое дело. Но там они вообще ничего не хейтят, это не тот уровень отношения к предмету.
Про производительность - это сильносказано. Производительность нужна, чтобы вытащить из измеренных данных то, что нельзя было вытащить без производительности. Раньше в камеру Вильсона глазами смотрели не потому, что в голове всё решали со скоростью ЭВМ.
> любой программист из индустрии охуеет
Программист охуеет прежде всего от предметной области. Сможет только предложить архитектуру, разработать спецфреймворк и обучить физиков необходимым азам, а дальше только отпускать их.
Производительность здесь не при чём.
Проблема в том что этот говнокод нужно поддерживать, сопровождать, использовать повторно. А он годами любовно укладывается слоями в мощные копролитовые напластования.
У меня программирование на первом курсе кафедра математики читала. Тем не менее: "Если увижу в вашей программе goto, то к экзамену вам стоит подготовиться лучше меня" (с). Так что академическая среда очень разная бывает.
Соавторы RFC для сетевых протоколов. Вполне себе академическая среда.
Противники раннего return'а - те ещё извращенцы. Какие же портянки их вложенных if'ов и кучи вспомогательных функций им приходится писать из-за своих предубеждений ;)
Я не против ранних return'ов. Я говорю, что это тот же goto. Как и всякие try/except. Когда запулить можно откуда угодно, а поймать хоть в main()
Я до сих пор не пойму как можно программировать без GOTO.... qbasic.exe научил что НЕЛЬЗЯ!
Картинка потрясающая, а где goto?
>PRINT "Hello there!"
PRINT "General Kenobi..."
10 GOTO 20
15 PROBLEM?
20 GOTO 10
Откройте для себя бесконечные циклы:
While True
Continue While
Problem?
End While
Конечно, можно было не париться с Continue,
но вам видимо хотелось иметь problem в середине текста программы
While True
End While
Problem?
И такой момент, я не уверен, что компилятор не скажет, что код problem не достижим, я это компилировать не буду, а вы проверьтесь у психиатра.
Идите в жопу!
То есть, я хотел сказать go to jopa!
goto видимо наследие асемблеровских jmp, когда пишешь код и такой "нет времени объяснять, пиздуй на 50 строку, там есть дела")
один из самых пожалуй жесткий костылей, но востребованный и по сей день, grpc php например весь напичкан goto и ничо, норм работает
только не надо было ему Роше предавать