LINUX.ORG.RU

[Python][Функциональщина] Медленный не пайтон, а функциональщина

 


0

0

Разгребаю код на пайтоне, джанго. Писал один интересный человек, который верил в функциональщину. Почти тру лиспотролль.
Что хочу сказать. Его функциональные фишки отжирают овер 90% времени обработки запроса и рендера.
Оптимизировал самое очевидное и получил не хилый профит.
Опыт кодинга на C и D помог не мало.
Пайтон не медленный(а даже если и медленный, то не так уж как говорят), его замедляют люди, юзающие функциональщину без раздумий о том что «находится за сценой».
Когда код, в котором 7 раз создаются новые лиспы с помощью генераторов и вызывается 5+N раз конструкторы, можно написать не менее элегантно не используя принципы и функционал функциональщины.
Вообще, конечно, важно умение использовать инструменты, но с функциональщиной оно наиболее опасно и менее всего очевидно. Увы.
Вот такой вот возгляд с другой стороны на вашу функицональщину. А я пошёл спать.


Ответ на: комментарий от anonymous

>Нет. Хороший тон - использовать макры для определения eDSL.

Знаешь, в руби вот тоже была мода делать eDSL на каждый чих. Ну там, define_method, хуки разные, method_missing, непонятные и ненужные добавления в базовые объекты, для сахарку.. Дебажить такие штуки - милое дело, даже если и без переопределения каких-нибудь базовых объектов. Ты наверное скажешь что да руби, да он говно и не сравнится с всеочищающим богоугодным CL, и т.д. и т.п.

Вобщем спорить не хочу, хочу какую-нибудь статейку по поводу дебага макров в CL, лучше всего наверное в каком-нибудь Slime, но не суть. Есть ли какие-нибудь тонкости, сложности, почему где как и т.п.

volh ★★
()
Ответ на: комментарий от anonymous

> В том же C.L.L тоже совсем не много реальных практиков. Практики в такие гадюшники не ходят и во флеймах не участвуют.

Ага, а на ЛОРе нам является элита.

tailgunner ★★★★★
()
Ответ на: комментарий от tia

>Зачем? Я хеллоуворды посмотрел, почитал

угагагаг.. С этого и надо было начинать. Хеллоу ворлды посмотрел >.<

Waterlaz ★★★★★
()
Ответ на: комментарий от volh

> Знаешь, в руби вот тоже была мода делать eDSL на каждый чих.

В Руби для этого никаких средств нет.

Вобщем спорить не хочу, хочу какую-нибудь статейку по поводу дебага макров в CL, лучше всего наверное в каком-нибудь Slime, но не суть. Есть ли какие-нибудь тонкости, сложности, почему где как и т.п.

Какую тебе статейку? Для дебага хватает функции expand.

anonymous
()
Ответ на: комментарий от volh

>Вот тут вопрос как раз по теме: как в питоне сделать произвольный объект неизменяемым?

Замыкание только на чтение?

def const(c):x=c;return lambda:x

SV0L0CH
()
Ответ на: комментарий от anonymous

>Между eval и макрами нет абсолютно ничего общего.

Это не мешает мне в некоторых случаях использовать eval для возмещения отсуцтвия макросов.

SV0L0CH
()
Ответ на: комментарий от SV0L0CH

Не выйдет. В питоне все значения таскают by-reference

In [1]: x = [1,2,3]

In [3]: x
Out[3]: [1, 2, 3]

In [5]: const(x)()
Out[5]: [1, 2, 3]

In [6]: const(x)()[0]='a'

In [7]: x
Out[7]: ['a', 2, 3]

Shimuuar
()
Ответ на: комментарий от anonymous

> читать надо не флеймы, а код.

Ну как бы z прочитал много кода и утверждаю, что в хороших проектах использование макросов обычно достаточно невелико. Правда, не понятно, что значит 60% макросов. Имеется ввиду, что 60% всего кода это код макросов? Или, что в 60% кода встречаются макросы? Первое, естественно, не так. Второе, очевидно тоже, ибо в таком случае надо говорить об 95% или типа того.

archimag ★★★
()
Ответ на: комментарий от Shimuuar

>Не выйдет. В питоне все значения таскают by-reference

Да, забыл про copy

SV0L0CH
()

Где-же love5an?

Реквестирую величайшую битву: упоротейшего (лиспо)клоуна ЛОРа VS упоротейшего (антилисп)клоуна ЛОРа.

Waterlaz ★★★★★
()
Ответ на: комментарий от anonymous

>В Руби для этого никаких средств нет.

Если нет макр, не значит что нет средств метапрограммирования. В руби оно крутое, не такое крутое как в Smalltalk или CL, но простым смертным хватает за глаза.

http://rake.rubyforge.org/ , http://www.sinatrarb.com/ , http://api.rubyonrails.org/classes/ActiveRecord/Base.html - примеры eDSL. Может быть ты имеешь в виду что-нибудь другое? embedded DSL - это те, которые не меняют семантику, ты имел в виду external?

volh ★★
()
Ответ на: комментарий от anonymous

>Какую тебе статейку? Для дебага хватает функции expand.

Я имел в виду раскрытие каких-нибудь поинтов «Although extremely powerful and useful, macros are also significantly harder to design and debug than normal Lisp functions, and are normally considered a topic for the advanced Lisp developer» ( http://www.apl.jhu.edu/~hall/Lisp-Notes/Macros.html ). Я постоянно натыкался на утверждения «макры сложно дебажить», вот и хочу знать почему.

volh ★★
()
Ответ на: комментарий от volh

> макры сложно дебажить

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

archimag ★★★
()
Ответ на: комментарий от SV0L0CH

Вот код из моего проекта:

(define-interface rasterizer-state (device-child iid-rasterizer-state)
        (description ()
          "Get the properties of a rasterizer-state object."
          (%with-value (p-desc rasterizer-desc)
            (method-funcall
                :pointer p-desc
                :void)
            (%get-value p-desc rasterizer-desc))))
Тут define-interface, %with-value, method-funcall и %get-value - макросы. Суть в том, вобщем, что определяется CLOS-класс, враппер над COM-интерфейсом. Тот наследуется от device-child и имеет своим IID структуру типа IID, хранящуюся в слоте значения символа iid-rasterizer-state.

Своих методов у этого интерфейса один - description. В примере можно увидеть строчку документации и собственно тело метода. Сам метод этот, естественно, реализован в d3d10.dll, а на стороне лиспа происходит просто маршалинг данных из лиспа(с помощью макросов %with-value(подготавливает на сишном стеке место для структуры типа rasterizer-desc) и method-funcall, в данном случае), вызов метода интерфейса по оффсету в табличке виртуальных функций(за это отвечает method-funcall, как понятно) и маршалинг обратно в лисп(это делает %get-value).

Макросы в теле метода раскрываются в зело большое количество низкоуровневого кода, оперирующего как сишными данными на сишном стеке, так и лисповскими структурами(и оперирующего, кстати, довольно быстро, потому как везде проставляются декларации типов, ну и потому, что код низкоуровневый), и вызывающего методы COM-интерфейсов из динамических библиотек, частей direct3d, через FFI конкретной лисп-системы.

Сам собственно макрос определения интерфейса раскрывается тоже в немаленькое количество кода, определяющего CLOS-класс, обобщенную функцию, если нужно(description, в данном случае)(и когда методов не один - несколько функций, соответственно), соответствующий метод к ней, расставляющего локальные макросы, необходимые для вычисления оффсета в таблице виртуальных функций при компиляции, генерирующего методы у обобщенных функций, ответственных за работу с IID(uuid-of etc.), заполняющего разные глобальные хеш-таблички информацией о новом типе, необходимой для работы других макросов и функций с этим интерфейсом, и т.д. и т.п.

Как это все делать функциями, и зачем - я не знаю и мне лень думать об этом.

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

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

Такие дела.

Love5an
()
Ответ на: комментарий от Waterlaz

Да уж, посидишь на ЛОРе - почувствуешь себя клоуном у пидарасов.
Такое сборище идиотов, что /c/, /s/ и c.l.l. вместе взятые стынут.

Love5an
()
Ответ на: комментарий от SV0L0CH

> Это не мешает мне в некоторых случаях использовать eval для возмещения отсуцтвия макросов.

Боюсь даже представить себе, чем ты возмещаешь отсутствие подруги.

Eval выполняется в рантайме. Макросы раскрываются во время компиляции. Всё ещё не видишь разницы?

anonymous
()
Ответ на: комментарий от volh

> Если нет макр, не значит что нет средств метапрограммирования. В руби оно крутое, не такое крутое как в Smalltalk или CL, но простым смертным хватает за глаза.

В Руби - runtime metaprogramming. Это не имеет ничего общего с compilation time staged metaprogramming.

anonymous
()
Ответ на: комментарий от volh

> Я постоянно натыкался на утверждения «макры сложно дебажить», вот и хочу знать почему.

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

Да, конечно же, макры и дизайнить надо правильно, чтоб их можно было дебажить. Но это всё на самом деле очень просто.

anonymous
()
Ответ на: комментарий от archimag

> Но, правда, я макросов типа loop и не писал никогда (и не думаю, что буду).

А зря не думаешь. Попробуй для упражнения написать: pattern matching в стиле ML, компилятор регулярных выражений, компилятор R5RS-макр для CL, компилятор BNF. Исключительно на макрах. Обязательно делать это в несколько этапов - каждая макра должна быть очень простой и очевидной.

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

anonymous
()
Ответ на: комментарий от Waterlaz

>> Сравниваем интерпретированный или компилированный хаскелл с питоном? Алгоритм хорошо разрешимый в ФЯ или просто, что под руку попало?

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

Если ты сравниваешь скомпилированный код на хаскеле с интерпретируемым кодом питона то ты пожалуй малообразованный лох. И продолжать с тобой дискас бессмысленно.

А где было заявлено, что питон функциональный? С элементами функциональности-же. И то Гвидо видимо первоначально их фор фан воткнул ;)

Иди распарсь еще раз свой же пост и мой ответ.

Это похоже ты не распарсил мой вопрос. Твой коммент: «Функциональное программирование на питоне реализовано не очень хорошо. это тоже факт». Еще раз для тупых: Питон не функциональный язык, он язык универсальный ))) Если ты вчера начитавшись на ЛОРе про кайфы хаскеля, сеголня прочитал про него статью в википедии, это не дает тебе право срать на питон от имени мирового сообщества.) Подумай над этим перед сном сегодня!)

Alesh
()
Ответ на: комментарий от anonymous

> А зря не думаешь. Попробуй для упражнения написать

Я никогда не пишу упражнений

pattern matching в стиле ML


Ну и при чём здесь макросы, если ключ к решению это унификацию? Да и сделано уже, см. cl-unification.

компилятор регулярных выражений

компилятор BNF



Я что, похож на извращенца? Зачем это делать на макросах?

компилятор R5RS-макр


Не знаю, что это такое.

Тогда и поймешь, что LOOP - это примитивно, и что любой,

сколь угодно сложный язык можно легко реализовать на макрах.



Да, говорят что и шаблоны в С++ являются Тьюринг-полными (на них даже интерпретатор лиспа времени компиляции смогли сделать). Только ключевой вопрос: зачем? Ну зачем это так делать? Если всё это можно сделать с помощью обычных функций, которые, вот же фокус, будут выполняться во время компиляции. Макросы в CL это по сути просто синтаксический сахар. Тоже самое можно сделать с помощью обычного кода, выполняемого на этапе компиляции, просто выглядеть это будет не очень, вот и всё. Для примера смотрим реализацию cl-ppcre или cl-who на худой конец (там есть макросы, но основная работа выполняется обычными функциями).

archimag ★★★
()
Ответ на: комментарий от archimag

>Тоже самое можно сделать с помощью обычного кода, выполняемого на этапе компиляции

Это немного неправильно так говорить, потому что макросы в CL это оно самое и есть.

Love5an
()
Ответ на: комментарий от tia

ТИА ты был в моих глазах более вминаемым парнем до этого, ты перед кем бисер мечешь, это же троль тупой и конкретный, к томуже ананимус! )))

Alesh
()
Ответ на: комментарий от Love5an

то немного неправильно так говорить,
потому что макросы в CL это оно самое и есть.

(eval-when (:load-toplevel :compile-toplevel :execute)
  (defun hello-macro (name)
    (eval `(defun ,(intern (format nil "HELLO-~A" (string-upcase name))) ()
             (print ,name))))

  (hello-macro "Love5an"))

(hello-love5an)

Это я что, макрос оказывается написал?

archimag ★★★
()
Ответ на: комментарий от Alesh

>Если ты сравниваешь скомпилированный код на хаскеле с интерпретируемым кодом питона то ты пожалуй малообразованный лох.

последовательность реплик. «питон медленнее» => «4.2» => «ну как же? реально медленнее» В чем проблема? Мне как-то пох на причины, почему? Инетрпретируемый/компилируемый? Важно то, какие у этого последствия.

Еще раз для тупых: Питон не функциональный язык, он язык универсальный )))

Сышишь, Вася. Может быть ты не будешь тупить и прочитаешь тред? А то гон от теб я такой, что пи***ц.

Если ты вчера начитавшись на ЛОРе про кайфы хаскеля, сеголня прочитал про него статью в википедии, это не дает тебе право срать на питон от имени мирового сообщества.

Засунь свой баттхерт куда подальше. Я на питон не срал.

Waterlaz ★★★★★
()
Ответ на: комментарий от tia

>> пистон - это бэйсик для ниасыляторов типа тебя

А лисп для тех кто не осилил asm. Вы пишете на лиспе? Значит вы неосилятор!

Блин, ну чё ты за хрень пишешь? Питонщекам потом перед липсерами не отмыться будет!)

Alesh
()
Ответ на: комментарий от archimag

> Я никогда не пишу упражнений

Зря. У тебя был бы шанс стать хорошим программистом. И вообще - тебе в натуре не нужен pattern matching?

Ну и при чём здесь макросы, если ключ к решению это унификацию? Да и сделано уже, см. cl-unification.

Ты с какого дерева упал? При чём тут унификация? Ты не понимаешь, что такое pattern matching?

Например: (defun f (x) (match x with ((«plus» a b) (add (f a) (f b))) ((«minus» a b) (sub (f a) (f b)))

И тогда (f '(plus (plus 2 (minus 3 1)) 1)) дал бы 5.

Я что, похож на извращенца? Зачем это делать на макросах?

Как это зачем? Чтоб во время компиляции BNF разворачивалось бы в конечный автомат.

Не знаю, что это такое.

Почитай R5RS. Удобная штука.

Для примера смотрим реализацию cl-ppcre или cl-who на худой конец (там есть макросы, но основная работа выполняется обычными функциями).

Это и есть макры. Зачем так тупишь?

Только вот - в cl-ppcre криво сделано, там однопроходный компилятор. Такие макры дебажить сложно. Я тебе предлагаю попробовать более грамотный подход - компиляцию в несколько проходов.

Как так получилось, что ты до сих пор так и не понял Лиспа?

anonymous
()
Ответ на: комментарий от Love5an

> фактически, да

defmacro это сахар над eval-when


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

archimag ★★★
()
Ответ на: комментарий от Waterlaz

>> Если ты вчера начитавшись на ЛОРе про кайфы хаскеля, сеголня прочитал про него статью в википедии, это не дает тебе право срать на питон от имени мирового сообщества.

Засунь свой баттхерт куда подальше. Я на питон не срал.

Батхерт у тебя начался))) И эта реплика: «Я на питон не срал.» тому подтверждение. Иди нах уже ложись спать что что ли )))

Alesh
()
Ответ на: комментарий от anonymous

> Ты с какого дерева упал? При чём тут унификация?

Ты не понимаешь, что такое pattern matching?


Здрасьте, на чём основан pattern matching в ML?

Как это зачем? Чтоб во время компиляции BNF разворачивалось

бы в конечный автомат.



Как я написал выше для этого не нужны макросы.

Почитай R5RS. Удобная штука.


Scheme не люблю.

Это и есть макры. Зачем так тупишь?


Открой реализацию и посмотри кто тупит.

Как так получилось, что ты до сих пор так и не понял Лиспа?


У тебя я полагаю спрашивать это бесполезно.

archimag ★★★
()
Ответ на: комментарий от anonymous

> Да. Только криво.

Приехали, тогда макросы есть и в Python, и в JavaScript и вообще в любом динамическом языке.

archimag ★★★
()
Ответ на: комментарий от tia

>> мда, ты получается вообще общелисп не видел, а мнение имеешь. Смешно. Я видел лисп и кодил на нём некоторые простые задачи, что делал на пайтоне. После этого я лисп не видел? Его от меня спрятали, ...

Харе уже липсоидов веселить ...

Alesh
()
Ответ на: комментарий от Alesh

>Батхерт у тебя начался))) И эта реплика: «Я на питон не срал.» тому подтверждение. Иди нах уже ложись спать что что ли )))

Я написал, что питон как функциональный язык плох да и сам по себе медленный. От этого у тебя пена изо рта пошла. Дык у кого баттхерт? По моему у того, кто на стуле нормально усидеть не может, прочитав, что их язычок ВНЕЗАПНО не самый лучший на свете.

Waterlaz ★★★★★
()
Ответ на: комментарий от Waterlaz

> «питон медленнее» => «4.2» => «ну как же? реально медленнее» В чем проблема?

Ты когда пишешь, конкретнее пиши))) Сравнивать код скомпилированного хаскеля с кодои интерпретируемого питона может тока троль со стажем. Но ты таким не являешься, поэтому ход твоих мыслей туп и банален.

Сышишь, Вася. Может быть ты не будешь тупить и прочитаешь тред ...

Тебе Петя не помешает тред перечитать )

Засунь свой баттхерт куда подальше. Я на питон не срал.

А на чё ты счас срешь? На Яву?) Твой баттхерд на лицо, смирись, да и спать тебе уже пора.

Alesh
()
Ответ на: комментарий от archimag

> Здрасьте, на чём основан pattern matching в ML?

До свидания, на 1st order unification в ML основан вывод типов. Компиляция pattern matching - это совсем другая история. Почитай, например, книгу S.P.Jones, там алгоритм хорошо описан.

Как я написал выше для этого не нужны макросы.

Нужны, как минимум один:

(define-bnf calculator бла-бла-бла)

Scheme не люблю.

Я тоже. Но макры там иногда удобно описывать по шаблонам.

У тебя я полагаю спрашивать это бесполезно.

Ты заблуждаешься.

anonymous
()
Ответ на: комментарий от Waterlaz

> Я написал, что питон как функциональный язык плох да и сам по себе медленный.

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

Alesh
()
Ответ на: комментарий от Alesh

>Сравнивать код скомпилированного хаскеля с кодои интерпретируемого питона может тока троль со стажем.

А я код и не сравниваю, троллоло ты наше.

А на чё ты счас срешь? На Яву?)

Ну вот. Опять бессвязный бред

Waterlaz ★★★★★
()
Ответ на: комментарий от Alesh

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

С этим утверждением не спорю, но ты такого не писал. По крайней мере отвечал я не тебе. У тебя же правда сразу инстинкт сработал «Пистон обижают»

Waterlaz ★★★★★
()
Ответ на: комментарий от Waterlaz

> ппц... школие думает, что если человека лохом назовет, то это уже троллинг.

Это не тролинг, это РЛ! Если человек лох, то лучше если он узнает об этом как можно раньше в кругу друзей (ну ты понял, я про ЛОР), чем от быдла в своем подъезде.

Alesh
()
Ответ на: комментарий от anonymous

> До свидания, на 1st order unification в ML основан вывод типов.

Компиляция pattern matching - это совсем другая история.


Как это другая? И как же это тогда работает?

Нужны, как минимум один:

(define-bnf calculator бла-бла-бла)



Можно и без него. Можно для удобства использовать макрос «верхнего уровня», для интерфейса, но он всё равно будет вызывать функцию для выполнения основной работы (можно и без этого, но это будет извращение). Хороший и простой пример на эту тему: cl-who - на поверхности макрос, но под копотом всю работу делает обычная функция tree-to-command.

Ты заблуждаешься.


Насчёт чего?

archimag ★★★
()
Ответ на: комментарий от Alesh

Блин. Харе свои пустые оскорбления писать.

На всякий случай. Последовательность сообщений(знаешь есть такая «кнопочка» Ответ на:комментарий. Читай иногда):

http://www.linux.org.ru/view-message.jsp?msgid=4467501&lastmod=1264195318025#...

http://www.linux.org.ru/view-message.jsp?msgid=4467501&lastmod=1264195318025#...

http://www.linux.org.ru/view-message.jsp?msgid=4467501&lastmod=1264195318025#...

Почитай и пойми, что ты тут не в тему звездишь.

Waterlaz ★★★★★
()
Ответ на: комментарий от archimag

> Как это другая? И как же это тогда работает?

Почитай spj. Статическая типизация тут совершенно не обязательна - см. мой пример.

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

Можно и без него. Можно для удобства использовать макрос «верхнего уровня», для интерфейса, но он всё равно будет вызывать функцию для выполнения основной работы

Если эта функция создаст полностью готовый низкоуровневый код на Лиспе - то как раз такую макру отлаживать будет непросто. Проще будет сделать несколько этапов преобразования - например, промежуточная макра раскрутит EBNF в набор trie, следующая макра сделает автомат (всё ещё декларативный), следующая уже скомпилирует автомат в код.

Насчёт чего?

Насчёт того, что не мне судить.

anonymous
()
Ответ на: комментарий от Waterlaz

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

С этим утверждением не спорю, но ты такого не писал.

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

Alesh
()
Ответ на: комментарий от anonymous

> Почитай spj. Статическая типизация тут совершенно

не обязательна - см. мой пример.


При чём тут статическая типизация? cl-unification реализует pattern matching в стиле ML для динамического CL.

Если эта функция создаст полностью готовый низкоуровневый код

на Лиспе - то как раз такую макру отлаживать будет непросто.



А функцию нельзя разбить на несколько? И отлажить каждую по отдельности? Это религия запрещает? У меня в cl-closure-template текстовые шаблоны компилируются в лисп код (при желании - на этапе компиляции) без всяких макросов (скажем так, их там немного). Для каждого этапа обработки написаны тесты и никаких проблем с отладкой нет.

Насчёт того, что не мне судить.


Без ссылки на ваши проекты принимать на веру затруднительно.

archimag ★★★
()
Ответ на: комментарий от Alesh

>Вкури еще раз последний абзац этого поста, я как раз там об этом и писал. Ты хотя бы ознакомся с мнением опонента прежде: чем кидаться какашками.

Ясно. Ты или невменяем или троль...

Waterlaz ★★★★★
()
Ответ на: комментарий от Waterlaz

> Блин. Харе свои пустые оскорбления писать.

Ладно, может я и переборщил. Но надо обоснованно в дискасе тпосты класть, а не как те на душу легло.

Alesh
()
Ответ на: комментарий от archimag

> При чём тут статическая типизация? cl-unification реализует pattern matching в стиле ML для динамического CL.

Нет, он реализует унификацию. Pattern matching в ML работает намного проще и тупее.

А функцию нельзя разбить на несколько? И отлажить каждую по отдельности?

Можно, но тогда отладка будет сложнее. Не будет универсальной пошаговой отладки для любых макр. Ну и, главное - за каким хреном это делать? Зачем себе жизнь усложнять?

Мейл давай - покажу на примере.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.