Pull to refresh

Comments 35

интересно. присматриваюсь к питону. хотя сам тоже пишу на императивных языках.
Python является императивным языком.
Скорее все-же мультипарадигменным.
Уж очень стало популярно использовать это слово — «мультипарадигменный».

Императивный и функциональный стили — это не набор фич. Это филисофия решения задачи.
Вернее, не функциональный, а декларативный. Но из-за непопулярности логических языков, в данное время эти понятия практически слились.
Это Python-то декларативный? С чего бы это?
Питон — императивный язык.

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

то, что в python называется поддержкой ФП, в реальности является лишь синтаксическим сахаром, имитацией этой самой парадигмы. например, вот такой ФП-подобный код на «мультипарадигменном» python выглядит вполне органично:
>>> f = lambda (x, y): x + y
>>> a = (1, 2)
>>> f(a)
3

но по сути, он чужеродный, ведь работает очень не эффективно. в процессе выполнения такой программы, в самом деле, создаются переменные, а лямбда распаковывает кортеж в пару локальных объектов. в «настоящих» функциональных языках картина совсем иная, т.к. там нет переменных.
Императивность ортогональна функциональности. Сколько, блин, можно путать?! Ещё раз:
1) императивный <-> декларативный (речь идёт о задании явной последовательности действий либо о декларировании желаемого результата)
2) процедурный <-> функциональный (результат достигается либо путём последовательных изменений состояния машины (машина Тьюринга), либо вычислением некоего выражения (лямбда-счисление). для последнего, например, не важен порядок вычисления аргументов функции)
3) возможны любые сочетания — императивный функциональный, например.
и что же такое «императивный функциональный» — можно ссылки на терминологию?
> (let* ([a 1] [b (+ a 1)]) (+ a b))
3

например. императивно? да, тут явно задана последовательность действий. функционально? да, тут вычисляется значение выражения.
g(f(x)) — проще говоря? =) тут явно задана последовательность действий: сначала f(), затем g(), и тут вычисляется значение выражения.
Во-первых, let* раскрывается вот так:
(let* ([a 1] 
          [b (+a 1)]) 
  (+ a b)) 

(let ([a 1]) 
  (let ([b (+a 1)]) 
     (+ a b)))

(let ([a 1]) 
  (let ([b (+a 1)]) 
     (+ a b)))

((lambda (a) 
   ((lambda (b) (+ a b)) 
    (+ a 1))) 
 1)
</source
Да, в данном случае это эквивалентно g(f(x)) (в конце концов, в лямбда-счислении всё есть вложенные функции), но в общем случае так говорить не совсем корректно.
Во-вторых, let* и есть императивное последовательное вычисление значений и биндинг их к переменным, сравните:
<source>
(let* ([a 1]
       [b 2]
       [c (a . + . b)]
       [d (b . - . a)]) 
  (c . + . d))

int a = 1;
int b = 2;
int c = a + b;
int d = b - a;
return c + d;

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

последний пример (на си?) тоже императивный функциональный?
Нет, последнее скорее императивный процедурный. Потому как в примере кода на схеме 3 является значением выражения, а в коде на псевдо-Си мы явно задаём возврат откуда-то (с тем же успехом там мог быть какой-нибудь вывод на консоль, вся эта штука целиком не является выражением).
Товарищ автор статьи, скажите пожалуйста, а чем так привлекателен «функциональный стиль»? Я не силен в Python, но на Matlab есть очень даже элегантное решение вышеупомянутой проблеммы — операторы с точкой(".+" ".*" ....), которые позволяют применять некую операцию к каждому элементу массива(думаю, в Python тоже есть что-нибудь подобное)(обычно сих операторов много не нужно, иначе теряется структура и смысл записи, что заставляет задуматься в нужности подобного оформления). ИМХО люди, прогающие на функциональных языках сами усложняют себе жизнь, т.к. структурирование у последних просто скверное. В этом плане Python очень силен, т.к. он не станет работать, если код неструктурирован(если неправильно расставлены отступы по крайней мере), т.е. он приучавает человека к порядку, а не наоборот. Так как это личное субьективное мнение, критиковать не буду, но все же, задумайтесь на написанным.
Автор статьи — Гвидо ван Россум, создатель Python.

Эта статья — экскурс в историю.
Тогда прошу простить. Не заметил.
> на Matlab есть очень даже элегантное решение вышеупомянутой проблеммы — операторы с точкой(".+" ".*" ....), которые позволяют применять некую операцию к каждому элементу массива
Такое нужно только в numpy и оно там есть (перегрузкой обычных операторов). В языке общего назначения это не требуется, а требуется несколько другое.
Гвидо обязательно задумается над написанным :-D
Тут проблемы, как принято говорить, не в языках, а в головах.
Если у человека проблемы с организацией — то они будут проявляться независимо от языка.
А структурирование делает любая человеческая IDE — раз уж речь о ФП, тот же SLIME по C-M-\ переформатирует блок, чтобы легко читалось…
> обычно сих операторов много не нужно
вот именно, вы мыслите операторами, а тут речь про целые функции. Простейший пример:

найдет максимальный элемент в списке элементов, причем сделает это по конкретному полю:
max(obj_list, key=lambda x: x.param)

вернет список нечетных элементов содержащихся в списке lst:
filter(lambda x: x % 2, lst)

Можно конечно написать это в цикле, но так красивее, короче а главное понятней.
Попытаюсь показать решение на своем любимом языке(на С++):
#define filter(list,filter,new_list) \
{ \
new_list.clear(); \
for (typeof(list)::iterator it=list.begin(); it!=list.end(); ++it) \
if (filter(*it)) \
new_list.push_back(*it); \
}
вот приблизительно так.
На С++ это вот так

copy_if(list.begin(), list.end(), back_inserter(new_list), boost::lambda::....)

где лямбды вполне себе юзабельны.
А вы то на С накатали, не нужно позорить плюсы.
А вы мне copy_if распишите, и желаельно не задевайте буст, это отдельная тема с отдельной концепцией.
Мейерс достаточно написал, зачем плодить сущности? А буст это чистые плюсы, в чем проблема? В tr1 вошли некоторые вещи из буста, лямбды стали стандартом.
люди, прогающие на функциональных языках сами усложняют себе жизнь, т.к. структурирование у последних просто скверное. В этом плане Python очень силен, т.к. он не станет работать, если код неструктурирован
О блин, как структурированность с функциональной парадигмой связана вообще?
Вот только тишина там аж с августа. Гвидо, пиши ещё!
Спасибо за перевод и ссылку на интересный блог.
Sign up to leave a comment.

Articles