alexey_rom: (Default)
alexey_rom ([personal profile] alexey_rom) wrote2010-03-11 02:57 pm

Откровения Guido van Rossum о функциональных языках

Цитата из Masterminds of Programming:
Python probably has the reputation of supporting functional programming based on the inclusion of lambda, map, filter and reduce in the language, but in my eyes these are just syntactic sugar, and not the fundamental building blocks that they are in functional languages. The more fundamental property that Python shares with Lisp (not a functional language either!) is that functions are first-class objects, and can be passed around like any other object. This, combined with nested scopes and a generally Lisp-like approach to function state, makes it possible to easily implement concepts that superficially resemble concepts from functional languages, like currying, map, and reduce. The primitive operators that are necessary to implement those concepts are built into Python, where in functional languages, those concepts are the primitive operations. You can write reduce() in a few lines of Python. Not so in a functional language.

Перевод:
Считается, что Python поддерживает функциональное программирование, скорее всего из-за включения lambda, map, filter и reduce в язык. Но с моей точки зрения это просто синтаксический сахар, а не основные строительные блоки, которыми они являются в функциональных языках. Куда более фундаментальным свойством, общим для Python и Lisp (который тоже не функциональный язык!), является то, что функции — объекты первого класса, и могут передаваться так же, как и любой другой объект. Это, в сочетании с вложенными областями видимости и в общем близким к Lisp'у подходом к состоянию функций, позволяет легко реализовать возможности, поверхностно напоминающие о таких возможностях функциональных языков, как карринг, map, и reduce. В Python встроены примитивные конструкции, необходимые для реализации этих понятий; а вот в функциональных языках они сами и являются примитивными конструкциями. В Python достаточно нескольких строк, чтобы написать reduce(). В функциональных языках это не так.

[identity profile] rmihael.livejournal.com 2010-03-11 12:07 pm (UTC)(link)
"В Python достаточно нескольких строк, чтобы написать reduce(). В функциональных языках это невозможно".
Он что, прикалывается?

[identity profile] alexey-rom.livejournal.com 2010-03-11 12:10 pm (UTC)(link)

Учитывая остальное, что он говорит про ФП — похоже, что нет :(


[identity profile] alexey-rom.livejournal.com 2010-03-11 12:15 pm (UTC)(link)
Впрочем, привёл перевод чуть ближе к буквальному, поскольку кто-то утверждает, что понял эту фразу как "в функциональных языках нет необходимости писать reduce". По-моему, неправильно, но оставлю этот вариант.

[identity profile] sdfgh153.livejournal.com 2010-03-11 12:39 pm (UTC)(link)
Ну я всегда подозревал, что от него ничего хорошего не дождешься.

[identity profile] archimag-dev.blogspot.com (from livejournal.com) 2010-03-11 01:05 pm (UTC)(link)
О, отлично, теперь буду на него ссылаться, доказывая неверующим, что Common Lisp не является функциональным языком ;)

[identity profile] jtootf.livejournal.com 2010-03-11 01:08 pm (UTC)(link)
в свете данного абзаца это, пожалуй, не лучшая идея :)

[identity profile] archimag-dev.blogspot.com (from livejournal.com) 2010-03-11 01:15 pm (UTC)(link)
А я буду опускать последние три предложения. Принципиально то его рассуждения верны.

[identity profile] lionet.livejournal.com 2010-03-11 01:18 pm (UTC)(link)
Currying — это можно считать "примитивной операцией" в функциональных языках, действительно. Но не map и не reduce. Так что он way out of line.

[identity profile] dsorokin.blogspot.com (from livejournal.com) 2010-03-11 03:23 pm (UTC)(link)
Да, вообще, нелучшая идея доказывать отрицание. Позитива в этом мало :)

[identity profile] lionet.livejournal.com 2010-03-11 01:14 pm (UTC)(link)
Да хоть на http://fprog.ru/ можно ссылаться. Там на первой же странице об этом написано.

[identity profile] archimag-dev.blogspot.com (from livejournal.com) 2010-03-11 01:17 pm (UTC)(link)
Хм, на первой странице такого не вижу :( Кажется, в первом журнале было что-то на тему того, что он остался в прошлом (с позиций ФП), хотя на самом деле он просто свернул в другую сторону ;)

[identity profile] lionet.livejournal.com 2010-03-11 01:19 pm (UTC)(link)
Во втором номере журнала была провокация, чтобы получить лисперов в четвёртый. А на сайте во второй же строке заголовка это написано.

[identity profile] archimag-dev.blogspot.com (from livejournal.com) 2010-03-11 01:22 pm (UTC)(link)
А!!! В упор не замечал :)))

[identity profile] alexey-rom.livejournal.com 2010-03-11 01:31 pm (UTC)(link)
Если посмотреть ещё на предыдущий абзац: "functional languages are all about doing as much as possible at the compile time" -- то Common Lisp (приличная часть использования макросов) и C++ (шаблоны) получаются куда более функциональные чем, например, Erlang.

[identity profile] archimag-dev.blogspot.com (from livejournal.com) 2010-03-11 01:40 pm (UTC)(link)
Шаблоны в С++ это действительно отдельный функциональный язык ;) А в Common Lisp термин "compile time" вообще нельзя употреблять, ибо есть только :COPMILE-TOPLEVEL, :LOAD-TOPLEVEL и :EXECUTE (а термин компиляции означает просто процесс раскрытие макросов).

[identity profile] alexey-rom.livejournal.com 2010-03-11 01:46 pm (UTC)(link)
А в Common Lisp термин "compile time" вообще нельзя употреблять
Если HyperSpec и CLtL употребляют, то мне тоже можно :)

[identity profile] archimag-dev.blogspot.com (from livejournal.com) 2010-03-11 01:57 pm (UTC)(link)
Ну только если понимать, что "compile time" в CL очень далеко от аналогичного понятия в том же C++. С точки зрения CL компиляция - это процесс раскрытия макросов. SBCL, например, выражение, введённое в REPL по-умолчанию сначала компилирует в машинный код, а только потом исполняет, но это не то же самое, что раскрытие макросов. Но, даже процесс раскрытия макросов (compile time) происходит во время исполнения и, вообще говоря, зависит от текущего состояния образа, и может иметь произвольные сайд-эффекты.

[identity profile] alexey-rom.livejournal.com 2010-03-11 02:53 pm (UTC)(link)
Да, так я и понимаю.

[identity profile] ivan-gandhi.livejournal.com 2010-03-11 01:50 pm (UTC)(link)
Он сделал свой язык, вполне компактный, юзабельный, и, при определённой сноровке, пригодный на вполне хорошие проекты. Но будущего нет ни у Питона, ни у Гвидо. Спросите его про монаду. Он не знает и не хочет знать про монаду. Ну и т.д. Так что язык, как бы он ни был хорош, останется набором хороших штучек, соответствующих передовым понятиям примерно 2000-го года.

(Anonymous) 2010-03-11 01:59 pm (UTC)(link)
> Но будущего нет ни у Питона, ни у Гвидо.

Размер Python-community, а также размер банковского счёта самого Гвидо свидельствует об обратном ;)

[identity profile] zevlg.livejournal.com 2010-03-11 01:52 pm (UTC)(link)
всё нормально старикан сказал. Я вон для geo задачи (с fprog.ru) накатал парсер файлов с полигонами в три строчки! на питоне - сомневаюсь, что такое возможно на любом ФП:
def contours(f):
    def notEND(): return takewhile(lambda x: x[:3] != "END", f)
    def contour(): return [map(float, l.split()) for l in notEND()]       
    return [(contour(), l[0] == "!") for l in notEND()]

[identity profile] lionet.livejournal.com 2010-03-11 03:15 pm (UTC)(link)
Круто, да. Лаконично. В функциональном стиле. Но мутабельные итераторы подсирают чуток понимание кода. Вот хаскельный вариант:
countours = map excl . filter ((/=) ["END"]) . groupBy notEND . words
excl (h:t) = (map read t :: [Double], head h == '!')
notEND x y = x /= "END" && y /= "END"

[identity profile] alexey-rom.livejournal.com 2010-03-11 03:20 pm (UTC)(link)
Серьёзно сомневаетесь?


contours f = [ (contour p, head (head p) == '!') | p <- map lines (endBy "END" f)]
               where contour p = map (read :: String -> Double) (words p)


endBy из Data.List.Split, а не из стандартной библиотеки, но в одну строчку пишется.

[identity profile] alexey-rom.livejournal.com 2010-03-11 03:25 pm (UTC)(link)
Чуть ошибся в contour, здесь ведь p -- список строк:

contour p = map (map (read :: String -> Double) . words) (tail p)

[identity profile] zevlg.livejournal.com 2010-03-11 03:42 pm (UTC)(link)
не пробовал, но кажется, что на завершающем файл ENDе обломается и выдаст неправильный контур

если серьёзно, то конечно не сомневался, но хотелось чтобы кто-нибудь *подоказывал* :)

[identity profile] alexey-rom.livejournal.com 2010-03-11 03:49 pm (UTC)(link)
не пробовал, но кажется, что на завершающем файл ENDе обломается и выдаст неправильный контур
Ну тогда (init $ endBy "END" f).

[identity profile] alexey-rom.livejournal.com 2010-03-11 03:50 pm (UTC)(link)
но хотелось чтобы кто-нибудь *подоказывал* :)
:)

[identity profile] zevlg.livejournal.com 2010-03-11 03:44 pm (UTC)(link)
там ещё на реальных файлах в конце END бывает \r, поэтому у меня x[:3]

[identity profile] lionet.livejournal.com 2010-03-11 03:26 pm (UTC)(link)
Вот блин. Спасибо за Data.List.Split. В хугле его нет, кстати.

[identity profile] lionet.livejournal.com 2010-03-12 02:06 pm (UTC)(link)
Считай, что нет:

http://holumbus.fh-wedel.de/hayoo/hayoo.html#0:%5Ba%5D%20-%3E%20%5Ba%5D%20-%3E%20%5B%5Ba%5D%5D

Как можно найти endBy, если знаешь только примерную сигнатуру?

[identity profile] palm-mute.livejournal.com 2010-03-12 02:09 pm (UTC)(link)
Никак, hayoo по типам не ищет.

[identity profile] palm-mute.livejournal.com 2010-03-12 02:12 pm (UTC)(link)
С последним заявлением я поторопился

[identity profile] b-al-u.livejournal.com 2010-03-11 02:13 pm (UTC)(link)
Но нельзя в несколькострок сделть лямбду :)

[identity profile] ulysses4ever.livejournal.com 2010-03-11 05:06 pm (UTC)(link)
> В Python встроены примитивные конструкции, необходимые для реализации этих понятий; а вот в функциональных языках они сами и являются примитивными конструкциями. В Python достаточно нескольких строк, чтобы написать reduce(). В функциональных языках это не так.
Одному мне кажется, что в первом предложении он утверждает, что Пайтон более низкоуровневый, чем «функциональные языки», а во вторых двух — что он более высокоуровневый — сиречь противоречит себе?

[identity profile] alexey-rom.livejournal.com 2010-03-11 05:15 pm (UTC)(link)
Нет, по-моему, во вторых двух предложениях он утверждает, что ФЯ слишком высокоуровневые, чтобы внутри них реализовать reduce().

[identity profile] archimag-dev.blogspot.com (from livejournal.com) 2010-03-11 08:01 pm (UTC)(link)
На самом деле он просто утверждает, что Python не является ФЯП (есть такое поверье), и что map/reduce не являются признаком ФЯП (и такое поверье тоже есть). Вряд ли стоит выискивать здесь что-либо ещё.

[identity profile] alexey-rom.livejournal.com 2010-03-11 08:19 pm (UTC)(link)
Да нет, он всё же утверждает, что reduce (т.е. foldl) нельзя написать в несколько строчек на функциональных языках. Что, собственно, людей (включая меня) и впечатлило :)

[identity profile] zevlg.livejournal.com 2010-03-11 10:45 pm (UTC)(link)
да ладно, основная идея мне кажется в словах Гвиды, что динамическая суть строения языка важнее функциональной части -- в этом возможно есть смысл. Нужен симбиоз -- может быть бумеранг спасение, хотя хз

[identity profile] ivan-gandhi.livejournal.com 2010-04-07 01:23 am (UTC)(link)
Гвидо хороший человек, но образования у него не хватает, и это, конечно, ставит крест на будущем питона.