Обновить

Комментарии 23

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

Так в 1979 язык Си был дополнен классами.

Чем чем? Структуры (не классы) появились раньше, а c++ - это другой язык и появился позже.

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

В 1991-ом.

Так открылась эра функционального программирования в языках общего назначения (анонимные функции были добавлены в C# в 2007, а в Java в 2014).

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

Аспектно-ориентированное программирование появилось в Python в 2008 вместе с языковой конструкцией декоратор.

PEP-318 принят в 2003-2004.

Я правильно понимаю, что в статье проблемы только с датами? Все остальное по делу?

Если накидано рандомных дат - может и другая информация тоже рандомная? С какой целью в корректную (возможно) информацию вставлены некорректные цифры?

Спасибо за поправки к датам. Я торопился и искал их в гугл. Возможно, он мне неверно даты посоветовал. В 1979 началась разработка «C with Classes» Бьярном Страуструпом. В 1983 язык получает название С++. Что касается Си и С++. Структуры Си - это уже начало объектного-ориентированного программирования, но изначально наследования между структурами не было. Так что это ООП в урезанном виде. Добавление в Си классов порождает новый язык - С++. Считать ли его совсем новым? Знаю людей, которые писали код Си, но на С++.

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

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

Ну ладно, положим.
Про парадигмы. Я вижу, что вы делаете свой язык, но самостоятельно - выдают "три уровня интеграции" (хотя термины устоялись - внешний и внутренний dsl) и другие похожие моменты. А тема богатая, интересная, и сложная конечно. В отрыве от сообщества или не прочитав хотя бы пары книг (база - SICP, конечно же) можно нагородить всякого разного.

Я подумаю, как можно поменять терминологию, прочитав SICP. Это, действительно, классика. Там правда LISP. Я его когда-то немного преподавал и сейчас, по правде говоря, вспоминаю как страшный сон. Например, карринг на Lisp и карринг на C# или Python для студенческого восприятия - это совершенно разные вещи. Насчет терминологии - это вообще большая проблема. Что, например, выбрать в качестве терминологии - кортежи или факты? В одном случае обидятся поклонники Prolog, в другом - SQL. А если эти языки назвать dsl, то обидятся и те и другие. Причем обзовут меня дилетантом, сказав, что их языки полные по Тьюрингу, и на них можно написать любой алгоритм. Из терминологических неточностей даже в самом пайтоне, например, большая проблема, как перевести list comprehension. Генератор списков? А если генерируется множество или словарь? И как тогда различить с конструкцией yield? В общем, с единой терминологией - проблема. Но со своей стороны, обязуюсь не порождать дополнительную путаницу.

В целом согласен, по отдельным терминам хочу заметить:

карринг на Lisp и карринг на C# или Python

Честно говоря, тоже на Лиспе плотно не работал, зато много работал на Хаскелле. Мне кажется, вы путаете карринг и частичное применение функции. Второе - забава для узкого класса задач, первое - одна из основ функциональных языков, упрощает компиляторы и естественно ложится в парадигму. Карринг в Питоне можно сделать, но как библиотеку с неясным назначением.

факты

Забавно, поизучаю Пролог на досуге.

пайтоне, например, большая проблема, как перевести list comprehension

Я хоть и сам питонист, но мнение питонщиков тут неважно, потому что это урезанная реализация monad comprehension, что вы справедливо сами отметили. В Хаскелле и функционал богаче и для любой монады работае (и мб ограниченно для аппликаторов, через ApplicativeDo?). Списки тут частный случай.

Представьте, я замучился студентам объяснять разницу между каррингом и частичным применением функции! Когда-то делал её на С# - там разница в коде - буквально в пару пустых скобок. Кстати, автор книги "C# для профессионалов", кажется, не делает разницы между этими приемами программирования. На Python теперь рассказываю о частичном применении функции и карринге на разных лекциях.

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

print(sum(t for t in Table if t>50))

Не декларативный. Ну, просто для меня, он выглядит как запись всё той же функции с циклом и условием (if-else) просто в одну строку.
Можете объяснить, чем он стал декларативным?

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

вполне себе декларативный стиль, или может вы считаете что SELECT * FROM users WHERE age > 25 это тоже императивный подход?

я конечно могу где-то ошибаться в своих суждениях, но генераторы в python ближе к чему-то функциональному, а оно в свою очередь подмножество чего-то декларативного

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

t for t in Table if t>50
for t in Table:
  if t> 50:
    some_list.append(t)
    

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

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

та же конструкция

нет, не та же, первый вариант это генератор, то есть объект, а второй инструкция, в первом варианте мы описали новое представление коллекции, не проходя по ней в момент создания генератора, а во втором описали последовательность действий при обходе коллекции, которые будут сразу выполнены при выполнении инструкции for

В том-то и дело, что это - декларативное программирование! Когда я познакомился с этой языковой конструкцией, я тоже думал, что это просто синтаксический сахар - короткая удобная запись в одну строчку. И так её почти все и воспринимают - это совершенно нормально. Очень уж она не похожа на SQL. Но сделаем мысленную замену на аналогичные операторы: if заменим на where, in на from, а for на select - и вы получите код, очень похожий на SQL

Вы конечно, простите, но кто вам дал право менять конструкции языка на другие, которые работают по другому принципу?
Когда мы пишем запрос в СУБД на SELECT — мы не указываем каким образом СУБД должна получить значение. В коде python мы явно указываем, что значения должны перебираться последовательно циклом FOR.

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

извините но, это не так в общем случае, и работает только в случае поиндексного обхода

Извините, но Вы буквально указываете способ перебора значений циклом FOR. В СУБД перебор данных запросом SELECT может организовываться множествами способами. В этом и отличие декларативного подхода от императивного: мы не указываем каким образом будет происходить перебор данных. А из ваших утверждений это выглядит так, будто разница в количестве строк.

из ваших утверждений это выглядит так, будто разница в количестве строк.

где вы такое увидели?

Вы буквально указываете способ перебора значений циклом FOR

я так понимаю для вас любая инструкция for это сишное for(i=k;i<n;i++){..} и по другому не применяется данная конструкция, а итераторы, генераторы вышли из чата

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

На тему известных декларативных языков ещё добавлю XPath и RegExp, хоть к классу самостоятельных ЯП и не относятся.

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

А тестирование и отладка программы на прологе - как отдельный вид искусства...

Спасибо, отлично разложили по полочкам. Будет удобно использовать такой взгляд для преподавания.
Либу DecPy (фактически один модуль) интересно поизучать.

Пока изучил либу поверхностно. Восторг!
Теперь буду мечтать, чтобы
- Либо такое встроили в штатный itertools.
- Либо кто-то сделал низкоуровневую реализацию, как для numpy.
Тогда скорость операций вырастет на порядки.

Мне очень хочется своей библиотекой подтолкнуть процесс развития языка пайтона. Пока я не думал о быстродействии, а хотел убедиться, что в принципе можно соединить три вида декларативного программирования вместе, сделать рекурсивные запросы, добавить логическое программирование. И главное при этом остаться в рамках обычных пайтоновских операторов. Я был счастлив, когда у меня получилось! А вот далее трудная и долгая работа - то ли делать низкоуровневую реализацию с привлечением С++, набирая коллектив разработчиков. То ли как-то пиарить библиотеку, показывая всем - смотрите, какая забавная языковая игрушка получилась! Так сделайте то же самое в штатных библиотеках. Я рад, что вам понравилась моя разработка!

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации