Pull to refresh

Comments 42

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

то есть это программирование для тех кто сомневается что сложение коммутативно, и таких становится все больше. Когда 2+2=5 спасают только все новые и новые парадигмы, потому что там где получилось 5 может получиться и 6 и 7 и даже 3 с половиной.

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

Спасибо.

Возможно стоит упомянуть и ООП в смысле Алана Кэя - что это подход к организации программы через создание обособленных объектов (включающих как данные так и их обработку) и отправку сообщений между ними.

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

В этом смысле агенто-ориентированное программирование (Которое акторное) или, например, микросервисы - это хрестоматийное следование идеям ООП на разных уровнях.

Еще можно упомянуть связи между подходами - почти все современные ЯП используют императивное и структурное программирование как базу, имеют инструменты для метапрограммирования, опираются на системы типов разной мощности.
Часть подходов являются подразделами друг друга - например data-flow подход это в каком то смысле простая идея, что "процесс - это тоже объект"

А вообще спасибо, хорошая обзорная статья

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

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

Именно по функциональному программированию не соглашусь. Там идея в том, что функция может принимать всё, что угодно, в том числе и другие функции, а это уже далеко от императива. Плюс, довольно важным является понятие чистоты функции и отсутствия побочных эффектов. А вот поток данных является частным случаем функционального программирования.

Там идея в том, что функция может принимать всё, что угодно, в том числе и другие функции, а это уже далеко от императива.

А разве в каком-то языке программирования этого нет, что функция может принимать как параметр другую функцию? Даже в чистом Си это изначально было разрешено! В любую функцию можно передать указатель (фактически ссылку) на другую функцию, ядро Линукса как раз на этом построено. Получается ядро Линукса написано в функциональном стиле?

Парадигма программирования - это про то, как мы воспринимаем программу, думаем про неё. Язык тут вторичен. Изначально императив - набор инструкций, функции - обработка мат. объектов (в т.ч. и других функций). И если мы говорим не о языке программирования, а о парадигме, то да, процедура может не уметь принимать другие процедуры. Ну и никакой рекурсии, как следствие.

Ну и если уж придираться, то разница между ссылкой на объект и самим объектом принципиальная. Именно на уровне восприятия кода.

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

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

При чем тут рекурсия? Вроде для рекурсии достаточно иметь возможность из тела функции вызвать эту же функцию, при чем здесь не уметь принимать другие процедуры?

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

тот же Паскаль не умел в рекурсию

Шутить изволите? Конечно же паскаль умел в рекурсию. У него вызовы и параметры на стеке, хотя и не в том порядке, что у си. И алголы из которых вырос паскаль, умели в рекурсию.

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

Современные фортраны умеют в рекурсию из коробки. Если явно пометить функцию как рекурсивную.

Спасибо за уточнение. Было давно и неправда, как говорится. Я это к тому, что вещи, которые кажутся нам сейчас очевидными, тогда очевидными не были.

Я это к тому, что вещи, которые кажутся нам сейчас очевидными, тогда очевидными не были.

Я всё же полагаю, что отсутствие поддержки рекурсии в ранних фортранах это не от неочевидности идеи, а сознательное решение с целью предельной оптимизации. Так-то к тому времени уже несколько лет существовал Лисп из которого очевидность идеи рекурсии торчит из всех скобочек )). И примерно в эти годы появился алгол и другие с передачей параметров через стек.

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

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

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

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

Когда-нибудь, автор узнает в чём смысл заголовков и они начнут отображать суть написанного.

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

Из интернета:

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

И по мнению автора, даже если вы пишите прошивки под МК, то должны знать некие 5 парадигм, иначе увы.

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

И по мнению автора, даже если вы пишите прошивки под МК, то должны знать некие 5 парадигм, иначе увы.

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

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

Ну так тогда это статья для таких людей, поясняет названия.

Но чаще подобные комментарии идут подобно "высшее образование бесполезно, патамуша я итак магу"

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

Если разработчик претендует на лычку мидл+, но не чувствует себя свободно хотя бы в основных пяти парадигмах, — это напыщенный дурак, гоните его в шею.

Есть ли ситуации, где этот совет полезен? Очевидно да, даже не вспоминая про сломанные часы. А вот на сколько это верно - совсем другой вопрос. Ну чувствует человек себя свободно в основных пяти парадигмах (кстати, спиок не приведён) - и что? А ведь ничего...

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

Претензия формулировалась так:

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

Тогда решение не в знании парадигм, а в умении не пользоваться неподходящей парадигмой. А тем, чего не знаешь, и не воспользуешься (just saying). В просторечии - и последние станут первыми, типа.

А как можно получить свободу в пяти парадигмах? Проще всего - заниматься разными задачами. Чтобы быстрее позаниматься разными задачами, удобно побыстрее потерпеть неудачу в каждой. По этой причине в своё время потерпела крах серебрянная пуля "бригада ведущего программиста", примерно современницв бума ООП, предъявлявшая к ведущему программисту требования идентичные знанию пяти парадигм.

Следующий тезис я пересказываю в собственном переводе по памяти о речениях наших западных партнёров.

Если есть три способа, значит ни одного хорошего нет.

Повеселившись, перейдём к инструментам. Автор сам пишет

Но попытка написать на Prolog веб-сервер будет выглядеть как попытка заколотить крота микроскопом.

но, к счастью,

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

Что приводит к мысли, что владние парадигмами эквивалентно полному владению языком программирования, ключевое слово - полному. В мире, где существуют курсы по основам, антониму полноты, Python - пропаганда и того и другого бессмысленна.

Если кто вместо броска к парадигмам потратит часть остатка праздников на то, чтобы просто перечитать доки по своему языку программирования от начала и до конца сосредоточившись на "почему" и "зачем", комментировать стоило. Если язык программирования Go, Dart или Rust - и перечитать проще не бывает, и вообще, Вы уже на правильном пути.

перечитать доки по своему языку программирования

Что значит «своему языку»? Если речь не про стажера, 1 активный язык — это приговор на «давай, до свидания». Что в принципе полезного может сделать человек, который не может написать внятный код хотя бы на Java/.NET + Ruby/Python + JS/TS + Haskell/Idris + LISP?

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

Ценность пишущего на "Java/.NET + Ruby/Python + JS/TS + Haskell/Idris + LISP" тем выше, чем больше накоплено дурно написанного разномастного кода. Но только при условии, что явно или неявно принято решение (пока) оставить всё как есть, ибо в ином случае стек унифицируют и от лишних языков избавляются. Стремиться в эту среду... добровольно...

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

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

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

И тут происходят события, представляющиеся мне знаковыми. Например, Dart, якобы специализированный язык для Flutter. И на него только что портировали с Go библиотеки Bubbletea (Charmbracelet) в виде пакета Artisanal... так что у (действительно) выучившего Dart на одну причину учить Go меньше.

Что значит «своему языку»?

Ну, типа совет выбрать язык который будете действительно знать. Если такой уже есть, то давать какие-то советы уже не нужно...

А если такого нет, то я неявно рекомендовал что-то типа Dart, Go, Python или Rust потому, что у них есть связная и полная официальная документация которую искать не нужно и можно просто последовательно прочитать. В отличии от С++ или JavaScript, где документация тоже есть, но...

Dart, Go, Python или Rust

Ох, ну и списочек.

Давайте я сразу на личности перейду: у вас много коммитов в корку любимого языка? — А у меня сразу в два, и — если не заленюсь — скоро будет в три. У вас много библиотек, которые используются сообществом в опенсорсе? — А у меня больше десятка (и я даже на богопротивном Расте оскоромился написать нормальную акторную модель, потому что существующие — ни в какие ворота). Вас знают в англоязычных сообществах вашего любимого языка? — А меня знают, причем в двух.

Понимаете, эрудиция пока еще никому не вредила. А знать Dart… Невеликое достижение, прям скажем. Мне потребовалось приложульку тут написать — я сел и написал за неделю. Знаете, почему это было так несложно? Потому что после первых десяти — все остальные языки на одно лицо.

UFO landed and left these words here

Архитектура Фон Неймана, наборы команд процессора, микрокоды, ассемблеры пожалуй таки императивны по сути... Мы всё же сильно привязаны к железу. Наверное можно сказать что вычисления на GPU и квантовых прототипах привносят что то новое.

Забыто автоматное программирование, и экзотика типа Ladder logic.

Ну и куда нибудь Dragon категоризовать.

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

Императив, функционал, тро-ло-ло... Низко летаем, ну или мелко плаваем...

Смысл такой: можно назвать это метапарадигмой, она сводится к элементарному, просто обращаем внимание на слой исполнения. И всё. Кто понял, тот уже оценил. А кто не понял, ну..., автор вот за мидл+ вас не считает.

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

Пример:

sum = foldl (+) 0 [0..9]

Это функциональщина от автора. Далее:

sum = foldl(p, 0, 0, 9);

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

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

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

Первый раз встречаю термин "Слой исполнения". Это про что?

Вы как будто Шрека не смотрели.

— Огры — они как лук!
— Воняют?
— Нет, они слоистые! В ограх много слоёв!

Это (аллюзия на Greenspun's Tenth Rule) — заново написанная, неспецифицированная, глючная и медленная реализацию половины акторной модели.

Не сказал бы, прекрасная идея прекрасно работает, избавляет от многих проблем

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

Ещё можно представить что так могли бы общаться классы в python, было бы интересно

По моему это логичное продолжение развития асинхронного програмирования

Раньше у нас у функций было async await и мы руками описывали всё поведение

А в классах у нас скрытая реализация

Вы бы, хотя бы ради собственной эрудиции, поинтересовались для начала, что такое акторная модель. Алана Кая можно почитать, Смолток поковырять...

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

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

И вместе эти оба момента делают изучение хорошего спектра парадигм достаточно трудоёмким. Возможно я не прав, но банально по времени, желательно учить языки изолировано - то есть, вынь да положь пол года или год на парадигму. И, хотя время в ВУЗе позволяет, я нигде ничего подобного не видел.

Угу.

Так век живи - век учись!

Специалистом станешь

Или не станешь :)

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

А чо такого сделал Алан Кей? ;-) Smalltalk? Ну вот вам цитата из старой статьи о несомненно специалистах, настоящих программистах, про этот самый Smalltalk:

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

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

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

Sign up to leave a comment.

Articles