Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Python: Общие вопросы > О функциональном программировании на Python


Автор: Artemios 24.8.2006, 00:38
P.S. А вообще, http://www.citforum.ru/programming/python/python7.shtml интересная статейка о функциональном программировании на Python (если знаком с лиспом - должно понравиться smile )

Автор: pythonwin 24.8.2006, 06:33
Цитата(Artemios @  24.8.2006,  07:38 Найти цитируемый пост)
P.S. А вообще, вот интересная статейка о функциональном программировании на Python (если знаком с лиспом - должно понравиться smile

За ссылку спасибо! smile
С лиспом не знаком. smile

Автор: albertn 24.8.2006, 09:01
Цитата(Artemios @ 24.8.2006,  00:38)
P.S. А вообще, http://www.citforum.ru/programming/python/python7.shtml интересная статейка о функциональном программировании на Python (если знаком с лиспом - должно понравиться smile )

Но по моему они зря сравнивают свои Короткозамкнутые функции с функцией COND. На сколько я понимаю, 
Код

x=1
y=-1
print x==0 and y or x==1 and y+1 or x==2 and y+2 or y+3

Вернет совсем не 0, а 2. А для обхода этой ситуации придется толи менять условия, толи менять возвращаемое значение.
А лисп это вещь, если конечно не это бесконечное количество скобок  smile

Добавлено @ 09:03 
Цитата(Artemios @ 23.8.2006,  23:59)
Код

ll = map(lambda x: (x.s1, x.s2), l) or [(-1, '-1')]


или

Код

ll = [(x.s1, x.s2) for x in l] or [(-1, '-1')]


 smile ну да, изврат. smile короткозамкнутое логическое выражение.

Че-то я забыл, что пустой список это тоже False

Автор: pythonwin 24.8.2006, 14:41
Цитата(albertn @  24.8.2006,  16:01 Найти цитируемый пост)
Че-то я забыл, что пустой список это тоже False 

Код

[] or [1] == [1]


Спасибо, - пригодилось!

Автор: Artemios 24.8.2006, 18:01
Цитата(albertn @ 24.8.2006,  09:01)
Но по моему они зря сравнивают свои Короткозамкнутые функции с функцией COND. На сколько я понимаю, 
Код

x=1
y=-1
print x==0 and y or x==1 and y+1 or x==2 and y+2 or y+3

Вернет совсем не 0, а 2. 


Полной аналогии с COND наверно не получится:
Код

(x==0 and y) or (x==1 and y+1) or (x==2 and y+2) or y+3

будет 2, так как
Код

(x==0 and y) == False
(x==1 and y+1)==0 # короткого замыкания для or нет и цепочка вычисляется дальше:
(x==2 and y+2) == False
(y+3) ==2


Цитата(albertn @ 24.8.2006,  09:01)
А для обхода этой ситуации придется толи менять условия, толи менять возвращаемое значение.

Да, для аналогии с COND нужно, чтобы в мультиселекте в паре (a and b) второй элемент (возвращаемое значение b) никогда не был нулевым/пустым/ложным/etc, например:
Код

(x==0 and [y]) or (x==1 and [y+1]) or (x==2 and [y+2]) or [y+3]

вернет [0]. А это уже извращение smile , но я думаю, у нас нет задачи полностью повторять лисп smile 

Автор: albertn 25.8.2006, 08:41
Цитата(Artemios @  24.8.2006,  18:01 Найти цитируемый пост)
Да, для аналогии с COND нужно, чтобы в мультиселекте в паре (a and b) второй элемент (возвращаемое значение b) никогда не был нулевым/пустым/ложным/etc

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

print x==0 and y or x==1 and y+1 or x==2 and y+2 or (x<0 or x>2) and y+3

Но это тоже не всегда удобно.
Кстати, в случае чего можно написать свою функцию типа сишного ?:, как сделали в Zope, или даже  саму функцию COND. Возможно даже это будет иметь смысл.

Автор: Artemios 25.8.2006, 13:12
Цитата(albertn @  25.8.2006,  08:41 Найти цитируемый пост)
Кстати, в случае чего можно написать свою функцию типа сишного ?:, как сделали в Zope, или даже  саму функцию COND. Возможно даже это будет иметь смысл. 

Можно и весь лисп прикрутить в качестве расширяемого модуля smile Есть же его сишные исходники smile 

Автор: albertn 25.8.2006, 13:31
Цитата(Artemios @ 25.8.2006,  13:12)
Можно и весь лисп прикрутить в качестве расширяемого модуля smile Есть же его сишные исходники smile

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

Автор: pythonwin 25.8.2006, 13:56
тогда лучше создать отдельную тему в форуме.


Цитата(albertn @  25.8.2006,  20:31 Найти цитируемый пост)
Ну че, организуем проект? 

я  - за! Но знаний по лиспу нет.

Автор: Artemios 25.8.2006, 19:40
Эх, оффтопик, но для отдельной темы наверно это пока будет излишне...
Цитата(Artemios @  25.8.2006,  13:12 Найти цитируемый пост)
Можно и весь лисп прикрутить в качестве расширяемого модуля

Цитата(albertn @  25.8.2006,  13:31 Найти цитируемый пост)
Ну если так посмотреть, то в питоне есть почти все, что необходимо для лиспа.
Ну че, организуем проект? 

Цитата(pythonwin @  25.8.2006,  13:56 Найти цитируемый пост)
я  - за! Но знаний по лиспу нет. 


У меня по лиспу тоже мало знаний. Есть такие соображения.
Если нам нужен чистый функциональный лисп (без ОО), то здесь вообще проблем не должно быть. Единственное, что потребуется - реализовать на си преобразование:
питоновский список <--> лисповский список.

Другой вопрос: а нужно ли это? То же самое со списками мы можем и питоном делать. 
Как в лиспе программа - это такой же список, как и данные, - так и в питоне программа - это такой же объект, как и другие объекты. То есть, если нам нужны не только преобразования списочных данных, но и динамическая генерация/модификация программного кода - то это позволяет и питон (функции высших порядков, метаклассы).
Такое вот ИМХО smile 

Автор: pythonwin 27.8.2006, 15:48
Цитата(Artemios @  26.8.2006,  02:40 Найти цитируемый пост)

Другой вопрос: а нужно ли это? То же самое со списками мы можем и питоном делать. 
Как в лиспе программа - это такой же список, как и данные, - так и в питоне программа - это такой же объект, как и другие объекты. То есть, если нам нужны не только преобразования списочных данных, но и динамическая генерация/модификация программного кода - то это позволяет и питон (функции высших порядков, метаклассы).
Такое вот ИМХО smile  


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

Автор: Cr@$h 27.8.2006, 18:28

M
Cr@$h
Выделил из темы "инструкция "if" для проверки длины списка, записать это решение в одну строку".

Автор: Void 27.8.2006, 23:21
Почти в тему smile
Набрёл случайно по ссылкам на следующий ASPN Cookbook recipe: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/439361.
Отрывок кода:
Код
class Infix:
  def __init__(self, function):
      self.function = function
  def __ror__(self, other):
      return Infix(lambda x, self=self, other=other: self.function(other, x))
  def __or__(self, other):
      return self.function(other)
  def __call__(self, value1, value2):
      return self.function(value1, value2)

...

@Infix
def mplus(g1, g2):
    return chain(g1, g2)

...
parser = hexParser |mplus| digitParser |mplus| wordParser

Отдавая должное изобретательности автора этого кода, лично у меня возникают ассоциации с шаблонным метапрограммированием в С++: выглядит круто, но на практике проще пользоваться языками и инструментами, изначально ориентированными на такой род задач. Могу ошибаться smile

Автор: setq 27.8.2006, 23:58
Цитата(Void @  27.8.2006,  23:21 Найти цитируемый пост)
выглядит круто


+1

Автор: pythonwin 28.8.2006, 07:18
Cr@$h, спасибо!

Автор: Cr@$h 28.8.2006, 15:25
Цитата(pythonwin @  28.8.2006,  08:18 Найти цитируемый пост)
Cr@$h, спасибо! 

Развлекайтесь. Мне самому первая статья понравилась очень.

Автор: Artemios 28.8.2006, 20:41
Цитата(Cr@$h @  28.8.2006,  15:25 Найти цитируемый пост)
Развлекайтесь. Мне самому первая статья понравилась очень. 


Ну тогда вот продолжения того же автора:

http://www.citforum.ru/programming/python/python8.shtml

http://www.citforum.ru/programming/python/python9.shtml

В этих двух статьях он рассматривает специфический модуль для ФП. Модуль достаточно древний, 2001 г., но интересный, наверно не потребуется и этого:
Цитата(pythonwin @  27.8.2006,  15:48 Найти цитируемый пост)
предлагаю написать функции, которые эмулировали работу со списками или написать класс потомок списка и класс потомок словаря, у которых были бы специфические методы и свойства.



http://www.citforum.ru/programming/python/python10.shtml

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

Автор: Cr@$h 28.8.2006, 21:11
Цитата(Artemios @  28.8.2006,  21:41 Найти цитируемый пост)
В этих двух статьях он рассматривает специфический модуль для ФП. Модуль достаточно древний, 2001 г.

Возможно, с Python 2.5+ некоторые средства модуля ФП уже являются родными для языка и реализовывать их руками нет смысла. Спасибо за ссылки, почитаю. ++

Автор: Artemios 28.8.2006, 21:14
Цитата(albertn @ 25.8.2006,  08:41)
А также можно сделать, чтобы условия не пересикались, тогда результат будет аналогичным
Код

print x==0 and y or x==1 and y+1 or x==2 and y+2 or (x<0 or x>2) and y+3

Но это тоже не всегда удобно.

albertn, прости, сразу невнимательно смотрел, пропустил.
Твой пример возвращает False по первому элементу последней пары, а по логике COND первые элементы вообще невозвращаются, нам был нужен 0 по второму элементу второй пары.

Автор: setq 28.8.2006, 23:49
Artemios, генераторные включения есть в 2.4

Код

>>> (x for x in [1,2,3]).next()
1
>>> 


Автор: Artemios 29.8.2006, 00:51
Цитата(setq @ 28.8.2006,  23:49)
Artemios, генераторные включения есть в 2.4

Код

>>> (x for x in [1,2,3]).next()
1
>>> 

О как! Спасибо огромнейшее, не забуду. Или кто-нибудь плз ++setq.

Автор: Cr@$h 29.8.2006, 01:38
Цитата(Artemios @  29.8.2006,  01:51 Найти цитируемый пост)
О как! Спасибо огромнейшее, не забуду. Или кто-нибудь плз ++setq. 


M
Cr@$h
Ну, конечно ++.

Автор: Artemios 1.9.2006, 01:04
из: http://forum.vingrad.ru/index.php?showtopic=109973&view=findpost&p=838866
Цитата(albertn @ 31.8.2006, 08:57)
Но если присмотреться, то есть функции чисто императивные, я подчеркну, что это именно функции (операторы простительно), такие как sort, reverse, и другие, которые не возвращают результат, а все операции производят над исходным списком.

Так это вроде бы и не функции - методы класса list ... 

Автор: albertn 1.9.2006, 08:36
Цитата(Artemios @ 1.9.2006,  01:04)
Так это вроде бы и не функции - методы класса list ...

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

Автор: Artemios 1.9.2006, 11:36
albertn, прости пожалуста, я наверно тебя не очень понимаю, так как не очень хорошо знаком с ФП.

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

А в ООП - нечто противоположное - методы объекта - для работы с данными объекта и их изменения, то есть все и завязано на побочных эффектах методов, если их рассматривать как функции от объектов.

То есть, для достижения функциональности, как мне кажется, должна быть некоторая внутренне императивная обертка вроде:
Код

def fp_sort(lst,cmp=None):
        lst1 = lst[:]
        return lst1.sort(cmp=cmp) or lst1

Автор: albertn 1.9.2006, 12:10
Цитата(Artemios @ 1.9.2006,  11:36)
albertn, прости пожалуста, я наверно тебя не очень понимаю, так как не очень хорошо знаком с ФП.

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

А в ООП - нечто противоположное - методы объекта - для работы с данными объекта и их изменения, то есть все и завязано на побочных эффектах методов, если их рассматривать как функции от объектов.

То есть, для достижения функциональности, как мне кажется, должна быть некоторая внутренне императивная обертка вроде:
Код

def fp_sort(lst,cmp=None):
        lst1 = lst[:]
        return lst1.sort(cmp=cmp) or lst1

Ты все верно понимаешь. Если бы в Python эти функции были реализованы, то тогда о нем можно было-бы говорить как о  ФП. А так в нем есть только включения, упрощающие функционального программирования.

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

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

Автор: Void 1.9.2006, 17:07
Цитата(albertn @  1.9.2006,  14:10 Найти цитируемый пост)
Там скорее не про побочные действия, а про то, что никакая функция не должна изменять переданные ей аргументы, а возвращать новый измененный аргумент.

Второе есть необходимое, но не достаточное условие первого.

Давайте разделять понятия: Питон позволяет писать в функциональном стиле, поскольку функции в нём являются первоклассными объектами, есть замыкания и функции высшего порядка. Питон не является чисто функциональным языком, поскольку не только позволяет побочные эффекты, но и не препятствует им. До звания функционального языка он, на мой взгляд, не дотягивает из-за отсутствия оптимизации хвостовой рекурсии (я тут приводил пример, как её реализовать с помощью декораторов, но это хак и притом медленный хак).

Автор: Artemios 2.9.2006, 00:45
Цитата(Void @  1.9.2006,  17:07 Найти цитируемый пост)
До звания функционального языка он, на мой взгляд, не дотягивает из-за отсутствия оптимизации хвостовой рекурсии (я тут приводил пример, как её реализовать с помощью декораторов, но это хак и притом медленный хак). 

Нашел там же еще примерчики:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/474088

Автор: Artemios 2.9.2006, 01:19
А вот еще карринг:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/222061
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549

Автор: Artemios 4.9.2006, 16:28
Цитата(Artemios @  1.9.2006,  01:04 Найти цитируемый пост)
Но если присмотреться, то есть функции чисто императивные, я подчеркну, что это именно функции (операторы простительно), такие как sort, reverse


Цитата(Artemios @  1.9.2006,  11:36 Найти цитируемый пост)
для достижения функциональности, как мне кажется, должна быть некоторая внутренне императивная обертка вроде:


С питона 2.4, оказывается есть и функциональные аналоги: sorted, reversed:
Цитата

class reversed(object)
 |  reversed(sequence) -> reverse iterator over values of the sequence

sorted(...)
    sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list



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

Автор: Cr@$h 4.9.2006, 17:40
Здорово. Я же говорил очевидную вещь
Цитата(Cr@$h @  28.8.2006,  22:11 Найти цитируемый пост)
Возможно, с Python 2.5+ некоторые средства модуля ФП уже являются родными для языка и реализовывать их руками нет смысла. 


Так что теперь
Цитата(Artemios @  4.9.2006,  17:28 Найти цитируемый пост)
С питона 2.4, оказывается есть и функциональные аналоги: sorted, reversed:

а
Цитата(albertn @  1.9.2006,  13:10 Найти цитируемый пост)
Если бы в Python эти функции были реализованы, то тогда о нем можно было-бы говорить как о  ФП. 

Ну, по этим двум зачот. А что осталось собственно? Tail recursion и чистота функций, как минимум.
Кстати, про хвостовую рекурсию. Компилятор/интерпретатор делает оптимизацию прозрачно, да? В некоторых языках давно есть, посмотрите в Python.

Artemios, а сам с собой говорить не стоит -- первый признак шизофрении.  smile Да просто мы читаем да обдумываем, что ты тут выложил. На вот посмотри http://gnosis.cx/publish/programming/charming_python_b1.html, пока сюда никто не отвечает  smile .

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)