В принципе все типичные use cases для чего они были введены в Питон у меня как бы перекрыты и так.
Есть встроенные virtual property и статические методы/свойства класса.
composition of functions (g o f)(x) translates to g(f(x)). In Python, @g @f def foo() translates to foo=g(f(foo).
Python Way: вместо того, чтобы дать людям инфиксный оператор композиции функций (или вообще возможность определять операторы как в ML, Haskell, Scala etc.), давайте изобретем новое понятие и новый синтаксис.
CS>А расскажите кто и как их полезно использует?
Хаскелисты повсеместно используют для композиции функций, у них это обозначается точкой: '.'
CS>В принципе все типичные use cases для чего они были введены в Питон у меня как бы перекрыты и так. CS>Есть встроенные virtual property и статические методы/свойства класса.
CS>А расскажите кто и как их полезно использует?
AOP. Типичный кейс — ест веб-метод, нужно его обвесить декодированием значений, проверкой валидности, сгенерить данные, добавить общие для контекста данные, выплюнуть все XML и наложить XSL:
Z>Python Way: вместо того, чтобы дать людям инфиксный оператор композиции функций (или вообще возможность определять операторы как в ML, Haskell, Scala etc.), давайте изобретем новое понятие и новый синтаксис.
Ну все таки питоне не ФЯ и никогда не будет, поэтому врядли их стоит этим попрекать. Декораторы реализованы
чрезвычаной ракообразно и непрозрачно; детали трудно помнить, но в процессе разбирательств понимаешь, что это ничего общего
с композицией функций не имеет.
CS>>А расскажите кто и как их полезно использует? Z>Хаскелисты повсеместно используют для композиции функций, у них это обозначается точкой: '.'
А вот в эрланге есть что-то, чем можно заменить композицию функций?
dmz>AOP. Типичный кейс — ест веб-метод, нужно его обвесить декодированием значений, проверкой валидности, сгенерить данные, добавить общие для контекста данные, выплюнуть все XML и наложить XSL:
А для таких случаев неплохо подходит "монада для бедных", '|>' — оператор популяризованный F#, он должен быть левоассоцитивным с маленькии проритетом:
-- infix left 1
local (!>) = fun(x,f) -> f(x) end
-- TEST:
print $ "hello world"
!> string.upper
!> string.reverse
-- DLROW OLLEH
и получим вполне разумный аналог декораторам — т.е. map_url вполне может породить функцию с заданными контекстами без синтаксического оверхеда.
Интересно не это, а то, что это все можно точно также сделать и на питоне — не бодаясь с передачей параметров, неявным порядком вызовов и т.п.
Причем и структуру аспектов можно сделать нелинейной:
Более того, если не писать декораторы над веб-методами, а вместо этого написать код, который пробежится по приведенной структуре данных и построит описанные композиции, то можно вообще выкинуть слой веб-методов, который у нас между вебом и бизнес-логикой — оставить только хелперы (валидаторы, проверки пермиссий) и методы бизнес-логики.
Но это и в голову никому не пришло! Прямо по Оруэллу — язык сужает горизонты мышления. Когда в голове один питон, то и вместо текста получается питоновский речекряк.
А напоследок, покажу почему я считаю декораторы гимороем.
CS>Интересно. А вот для UI? CS>Пока думаю полезность будет в описании событий:
Биндинг обработчиков? Вполне. Но. Тут есть неудобство — по крайней мере в питоне — обработчики же должны быть зарегистрированы где-то? У какого-то объекта или чего-то подобного. Вот это вот что-то должно существовать на момент инстанциации модуля, и его надо протаскивать в декоратор или оно должно быть глобальным. И то и другое — не айс. Что бы этого избежать, например в TurboGear они в декораторе устанавливают атрибуты метода (т.е. метод — объект, к нему можно привесить любые атрибуты), а потом путем интроспекции перечисляют все методы с атрибутами и в этот момент привязывают их к запросам — как-то так:
@exposed(всякая хрень) # тут только устанавливается атрибут метода, а привязка обработчика осуществляется позже def web_method(еще какая-то хрень)
pass
CS>>Интересно. А вот для UI? CS>>Пока думаю полезность будет в описании событий:
dmz>Биндинг обработчиков? Вполне. Но. Тут есть неудобство — по крайней мере в питоне — обработчики же должны быть зарегистрированы где-то? У какого-то объекта или чего-то подобного. Вот это вот что-то должно существовать на момент инстанциации модуля, и его надо протаскивать в декоратор или оно должно быть глобальным. И то и другое — не айс. Что бы этого избежать, например в TurboGear они в декораторе устанавливают атрибуты метода (т.е. метод — объект, к нему можно привесить любые атрибуты), а потом путем интроспекции перечисляют все методы с атрибутами и в этот момент привязывают их к запросам — как-то так:
dmz>
dmz>@exposed(всякая хрень) # тут только устанавливается атрибут метода, а привязка обработчика осуществляется позже
dmz>def web_method(еще какая-то хрень)
dmz> pass
dmz>
... вот мне интересно, когда люди начнут наконец придумывать "макросы" и "generic-function"
ну честное слово — детям на смех.
Ок. Есть некий "вычислитель", который каким-то образом (но этот вопрос имеет 50% важности) бутстрапит систему.
бутстрап может формировать объекты системы, и потом их же использовать (функции, макросы, в т.ч. можен влиять на бутстрап.)
основной вопрос: дать языку средство, подстройки синтаксиса и процесса бутстрапа, таким образом,
что бы реализовать ту или иную модель организации кода.
Люди называют это Meta-протоколом.
вычислитель оперирует базовыми примитивами и процессом boot-strap-а,
а мета-протокол позволяет задавать что значит "@exposed(хрень) def web_method(хрень)"
а то идут какие-то статически вписанные в вычислитель полу-модели, и синтаксические корчи.
ведь всего-то навсего захотелось аспектировать код. тоесть, что бы вместо прямого мызова метода,
вызывался еще какой-то код, который, возможно, имеет в своем замыкании какое-то состояние (возможно
то, какой код будет вызван, зависит от контекста, где вызван метод).
A_P>... вот мне интересно, когда люди начнут наконец придумывать "макросы" и "generic-function" A_P>ну честное слово — детям на смех.
... A_P>ведь всего-то навсего захотелось аспектировать код. тоесть, что бы вместо прямого мызова метода,
Честно говоря, не очень понял, что вы хотели сказать, но если это о том, декораторы — это неконсистентный изврат, и в плане метапрограммирования и фунцкионального подхода питон сливает — то да, сливает.
Здравствуйте, dmz, Вы писали:
A_P>>... вот мне интересно, когда люди начнут наконец придумывать "макросы" и "generic-function" A_P>>ну честное слово — детям на смех. dmz>... A_P>>ведь всего-то навсего захотелось аспектировать код. тоесть, что бы вместо прямого мызова метода,
dmz>Честно говоря, не очень понял, что вы хотели сказать, но если это о том, декораторы — это неконсистентный изврат, и в плане метапрограммирования и фунцкионального подхода питон сливает — то да, сливает.
dmz>Декораторы придумал не я, если чо.
тут скоре посыл к c-Smile,
ведь TIScript — это его детище, которое совсем даже не питон.
просто он основан на "стереотипах" и синтаксисе, который ни коим образом не гнется
(тоесть, отсутствует настраиваемый meta-протокол, нет макросов и слегка завуалирован процесс бутстрапа)
это полезно для популяризации платформы т.к. много "Кул-хацкеров" которые это едят,
и корпоративные клиенты довольны — т.к. не сложно найти человека, который это осилит.
...но со временем, сам язык уходит на второй план, потому, что для
реальных задач нужны библиотеки, а при их написании всплывают пачки паттернов,
далеко не всегда миниатюрных и оптимальных... просто потому, что концепция синтаксиса
языка — как инструмента организации логики и кода, весьма устарела и не соответствует
современному динамизму.
и вместо того, что бы посмотреть, что не так в консерватории, появляются
небольшие "наросты" для частных случаев...
вот придумали декораторы, потом начнем придумывать MessageQueue, потом мемоизацию,
потом MixIn-ы потом еще что-то....
а в конечном итоге получается синтаксическая и технологическая помойка.
пример такой помойки — это MS Transact SQL.
Возможно я немного повышаю тон — просто "за державу обидно".
понадобится внести в систему еще какие-то "надстройки" — ок, изобретем
"мета-аттрибуты", как с C#... поданобится динамически добавлять аспекты в
чужой код, согласно внешне заданой политике аспектирования для данного контекста —
начнем изобретать аспекторы, рефлекторы и прочую ерунду...
понадобится какой-то Business-специфический DSL — будем лепить горатого либо из JSON или из XML+XXX...
но ведь все это уже давно изобретено, опробовано и работает
просто нужно понимать, что динамика появляется не в момент выполнения кода, а в момент его
"загрузки" (бутстрапа)...
function — это ключевое слово, или базовая функция?
можно ли написать
var x = function;
var y = array[10];
for(i=0; i < 10; i++) {
y[i] = function(null, get_function(i)); // функция без имени
}
var z = get_some_value();
y[z](12,23);
ключевой вопрос тут "get_function", потому, что функция задается не в коде, а где-то снаружи!
(в коде-то написать каждый может)...
что бы это сделать, приходится вводить дополнительную прослойку в виде диспетчера, а по сути — мастерить на коленке свой v-table и т.п.
что такое for?
var msg = new Message("Hello World!");
msg.say(); // will print Hello World!
можно ли переопределить new, что бы вызывалась фабрика, которая могла бы
создавать не Message, а каких-то потомков Message?
Здравствуйте, Andrey_Pilya, Вы писали:
dmz>>Честно говоря, не очень понял, что вы хотели сказать, но если это о том, декораторы — это неконсистентный изврат, и в плане метапрограммирования и фунцкионального подхода питон сливает — то да, сливает.
dmz>>Декораторы придумал не я, если чо.
A_P>тут скоре посыл к c-Smile, A_P>ведь TIScript — это его детище, которое совсем даже не питон. A_P>просто он основан на "стереотипах" и синтаксисе, который ни коим образом не гнется A_P>(тоесть, отсутствует настраиваемый meta-протокол, нет макросов и слегка завуалирован процесс бутстрапа)
По архитектуре TIScript это практически Stackless Python. Т.е. стереотипы те же.
А вот синтаксис, да, другой — от Java/JavaScript. Я бы не сказал что он(синтаксис) как-то гнется меньше или больше по сравнению
со всеми остальными языками этой группы: ruby, python, lua, perl, php.
Лично мне декораторы представляются вполне себе полезным сахаром.
Здравствуйте, c-smile, Вы писали:
CS>По архитектуре TIScript это практически Stackless Python. Т.е. стереотипы те же. CS>А вот синтаксис...
Stackless Python — это "вульгарный" вариант Limbo, по крайней мере автор очень этого хотел.
Есть ли у вас каналы? send-receive?
Генеалогия Stackless Python:
* Hoare породил CSP (1978)
* Из CSP с одной стороны породили OCCAM.
* C другой стороны Ada rendezvous.
* C третьей стороны Pike и Cardelli породили Squeak (все: начало 80-х)
* Потом Pike породил Newsqueak, а Winterbottom породил Alef (системный язык для Plan9)
* Потом Pike и Winterbottom подумали еще и породили Limbo (системный язык для Inferno)
* Потом пришел Tismer, посмотрел на Limbo, все вульгаризовал (выкинул ALT/select) и породил Stackless Python(~ 2002).
Здравствуйте, z00n, Вы писали:
Z>Здравствуйте, c-smile, Вы писали:
CS>>По архитектуре TIScript это практически Stackless Python. Т.е. стереотипы те же. CS>>А вот синтаксис...
Z>Stackless Python — это "вульгарный" вариант Limbo, по крайней мере автор очень этого хотел.
Это очень смелое утверждение.
Z>У вас есть хотя-бы каналы? send-receive?
В Stackless Python есть microthreads которые известны также как green threads.
В принципе несложно добавить, но потребности особой нет в контексте Sciter/TIScript. Что-то типа cooperative multitasking есть и так.
Больший интерес наверное представляет настоящие threads и message ports в смысле Google Gears.
Что исполняется путем создания отдельных (apartment) VMs — т.е. не проблема.
Persistence есть встроенная: http://terrainformatica.com/tiscript/Storage.htm , http://terrainformatica.com/tiscript/Index.htm.
TIScript писался именно в свете HTML UI как продвинутая версия JavaScript. То что получилось фактически близко к Питону так то естественно.
JS и Python вообще близнецы-братья в том что касается понятия что есть объект и класс/прототип. Да собственно как и Ruby. Lua в принципе там-же — просто некоторые фичи в Lua были выкинуты за для эффективности.
Z>>Здравствуйте, c-smile, Вы писали:
Z>>Stackless Python — это "вульгарный" вариант Limbo, по крайней мере автор очень этого хотел.
CS>Это очень смелое утверждение.
Почитайте архив мэйл-листа Stackless Python за 2002 год. Вот кое-что оттуда (там еще много):
Stackless goes Limbo
Christian Tismer tismer@tismer.com
Wed, 24 Apr 2002 17:34:22 +0200
...
after some time of consideration,
I have decided to move the interface to Stackless
Python's multitasking towards the ideas behind
the Limbo Language.
...
Ann: Stackless Limbo Dancing Works Fine!
Christian Tismer tismer@tismer.com
Sat, 18 May 2002 03:30:41 +0200
...
This implementation tries to follow the concepts of the OCCAM/ALEF/LIMBO
languages by supporting the channel concept as the central
communication/blocking/control feature. Tasks do not communicate
directly, but through channels.
You might have guessed it: Stackless will try to implement/support
Hoare's CSP, finally.
...
— There isn't yet an ALT/PRI ALT construct like in OCCAM/ALEF/LIMBO.
This is most sophisticated and very hard to implement correctly!
...
Z>>У вас есть хотя-бы каналы? send-receive? CS>В Stackless Python есть microthreads которые известны также как green threads.
Они много где есть и что? А вот это куда более редкая вещь: http://www.stackless.com/wiki/Channels
CS>В принципе несложно добавить, но потребности особой нет в контексте Sciter/TIScript. Что-то типа cooperative multitasking есть и так.
Концепции, кстати, изначально всплыли для гуя — нажимаешь на кнопку — посылаешь сигнал в некий (заблокированный) канал. Пайк хвастался, что весь менеджер окон в Inferno занял 200-300 строк.
CS>Persistence есть встроенная: ...
В Stackless не просто рersistence — он умеет треды по отдельности сериализовать.
CS>TIScript писался именно в свете HTML UI как продвинутая версия JavaScript. То что получилось фактически близко к Питону так то естественно. CS>JS и Python вообще близнецы-братья в том что касается понятия что есть объект и класс/прототип.
Так и сравнивайте с питоном.
CS>JS и Python вообще близнецы-братья в том что касается понятия что есть объект и класс/прототип. Да собственно как и Ruby. Lua в принципе там-же — просто некоторые фичи в Lua были выкинуты за для эффективности.
Вы не первый раз это говорите. Приведите, пожалуйста, пример фичи викинутой из луа ради эффективности.
Мне кажется у вас превратное представление о луа. Ради эффективности из луа ничего не выкидывали — только ради простоты. Не будь она такой простой — была бы эффективнее скорее всего (взять, например, realloc в качестве аллокатора, или отсутствие простых массивов). С моей же точки зрения луа весьма богатый язык — у нее есть несколько хороших ортогональных фич, которые трудно было бы добавить снаружи: кооперативные треды, метатаблицы, хвостовая рекурсия и очень удобный интерфейс к С. Единственно, у Руби есть настоящие continuations — а так по фичам все остальные выглядят довольно бледно.
Здравствуйте, z00n, Вы писали:
Z>>>У вас есть хотя-бы каналы? send-receive? CS>>В Stackless Python есть microthreads которые известны также как green threads. Z>Они много где есть и что? А вот это куда более редкая вещь: http://www.stackless.com/wiki/Channels
Вот в частности про channels (MessagePorts): http://www.whatwg.org/specs/web-workers/current-work/#the-workers
я не вижу особых проблем с их имплементацией. Тривиальный FIFO с синхронизацией.
Только как бы язык к этому отношения не имеет. В данном случае это вообще для JS.
CS>>В принципе несложно добавить, но потребности особой нет в контексте Sciter/TIScript. Что-то типа cooperative multitasking есть и так.
Z>Концепции, кстати, изначально всплыли для гуя — нажимаешь на кнопку — посылаешь сигнал в некий (заблокированный) канал. Пайк хвастался, что весь менеджер окон в Inferno занял 200-300 строк.
Я к сожаленю не знаю что такое менеджер окон в Inferno. Если рассматривать html/css как менеджер окон (DOM элементы) то у меня получилось 50тыс строк на C++.
Я сомневаюсь что что-то реальное в GUI можно уложить в 200 строк. Можно конечно, но использовать вряди кто-то будет.
CS>>Persistence есть встроенная: ... Z>В Stackless не просто рersistence — он умеет треды по отдельности сериализовать.
Ну наверное им это надо. Только смысла в этом немного. Как например сериализировать состояние https client работающего в потоке?
Сериализировать можно данные. И даже простая сериализация смысла мало имеет. На практике нужно решение гибридное с базой данных.
Т.е. чтобы и индексы были и доставать из базы можно было готовые объекты, а не recordset и все остальные прелести по укладке жизни в реляционные таблицы.
CS>>TIScript писался именно в свете HTML UI как продвинутая версия JavaScript. То что получилось фактически близко к Питону так то естественно. CS>>JS и Python вообще близнецы-братья в том что касается понятия что есть объект и класс/прототип. Z>Так и сравнивайте с питоном.
Ну как скажешь.
CS>>JS и Python вообще близнецы-братья в том что касается понятия что есть объект и класс/прототип. Да собственно как и Ruby. Lua в принципе там-же — просто некоторые фичи в Lua были выкинуты за для эффективности.
Z>Вы не первый раз это говорите. Приведите, пожалуйста, пример фичи викинутой из луа ради эффективности.
Одна из основных фич которая есть во всех остальных языках этой группы (JS, Python, Ruby) но нет в Lua это наличие virtual properties.
Вот код на TIScript:
class Foo {
property bar(v)
{
get { return this._bar || 0; }
set { this._bar = v; }
}
}
var foo = new Foo();
foo.bar = 28;
это в принципе не реализуемо в Lua в силу ейной архитектуры.
Я не буду вдаваться в механику этого дела ибо она очевидна, просто скажу что наличие этой фичи "сажает" эффективность JS, Python, Ruby.
И за этим много языковых возможностей стоит на самом деле.
Z>Мне кажется у вас превратное представление о луа. Ради эффективности из луа ничего не выкидывали — только ради простоты. Не будь она такой простой — была бы эффективнее скорее всего (взять, например, realloc в качестве аллокатора, или отсутствие простых массивов). С моей же точки зрения луа весьма богатый язык — у нее есть несколько хороших ортогональных фич, которые трудно было бы добавить снаружи: кооперативные треды, метатаблицы, хвостовая рекурсия и очень удобный интерфейс к С. Единственно, у Руби есть настоящие continuations — а так по фичам все остальные выглядят довольно бледно.
У меня нет никаких "превратностей" в представлении языков программирования. Это инструменты типа молотка, пассатижей и пр.
Т.е. я не говорю что Lua хуже/лучше. Для чего-то Lua лучше, для чего-то хуже.
Просто чудес не бывает к сожалению. Чем-то приходится жертвовать в угоду скорости.
А мой вопрос был про декораторы. Стоят они овчинки или нет.
Здравствуйте, c-smile, Вы писали:
CS>Здравствуйте, z00n, Вы писали:
Z>>>>У вас есть хотя-бы каналы? send-receive? CS>>>В Stackless Python есть microthreads которые известны также как green threads. Z>>Они много где есть и что? А вот это куда более редкая вещь: http://www.stackless.com/wiki/Channels
CS>Вот это спецификация из семейства технологий HTML5 CS>http://www.whatwg.org/specs/web-workers/current-work/
Обясните как Google Gears относятся к нашему разговору? Каналы — это в первую очередь способ структурирования однопоточной прграммы, как функции или обекты, например. Да, их можно построить поверх корутин, тредов или двже потоков, но тем не менее это совершенно самоценная абстакция.
CS>>>Persistence есть встроенная: ... Z>>В Stackless не просто рersistence — он умеет треды по отдельности сериализовать.
CS>Ну наверное им это надо. Только смысла в этом немного. Как например сериализировать состояние https client работающего в потоке? CS>Сериализировать можно данные. И даже простая сериализация смысла мало имеет. На практике нужно решение гибридное с базой данных. CS>Т.е. чтобы и индексы были и доставать из базы можно было готовые объекты, а не recordset и все остальные прелести по укладке жизни в реляционные таблицы.
Вы видели как работает Smalltalk? Там наверняка можно посмотреть как они справляются.
Z>>Так и сравнивайте с питоном. CS>Ну как скажешь.
Спасибо!
Z>>Вы не первый раз это говорите. Приведите, пожалуйста, пример фичи викинутой из луа ради эффективности.
CS>Одна из основных фич которая есть во всех остальных языках этой группы (JS, Python, Ruby) но нет в Lua это наличие virtual properties. CS>это в принципе не реализуемо в Lua в силу ейной архитектуры.
Это можно сделать даже несколькими способами. Вас что конкретно интересует инкапсуляция или виртуальные функции?
Вообще, для этого, как учит нас SICP, достаточно иметь простые замыкания. Но в луа у нас есть мощнючие метатаблицы.
CS>Я не буду вдаваться в механику этого дела ибо она очевидна, просто скажу что наличие этой фичи "сажает"
эффективность JS, Python, Ruby.
Очень жаль, особенно JS и Ruby (в смысле питон "сажает" сильно меньше). CS>И за этим много языковых возможностей стоит на самом деле.
Приведите, пожалуйста, пример — я не вижу каких .
Z>>Мне кажется у вас превратное представление о луа. Ради эффективности из луа CS>У меня нет никаких "превратностей" в представлении языков программирования. Это инструменты типа молотка, пассатижей и пр.
Я под "превратное" имел в виду "ошибочное". У вас об этом молотке ошибочное представление.
CS>А мой вопрос был про декораторы. Стоят они овчинки или нет.
Это зависит от вашего видения дизайна языка. Если вы согласны с
Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.
CS>Я не буду вдаваться в механику этого дела ибо она очевидна, просто скажу что наличие этой фичи "сажает" эффективность JS, Python, Ruby. CS>И за этим много языковых возможностей стоит на самом деле.
Мы кажется уже беседовали на эту тему, так что питон вычеркни
Здравствуйте, Andrey_Pilya, Вы писали:
A_P>просто нужно понимать, что динамика появляется не в момент выполнения кода, а в момент его A_P>"загрузки" (бутстрапа)...
Вообще-то питоновские декораторы как раз и отрабатывают в момент "загрузки" и тогда же происходит инстанцирование классов и ссответственно выполнение кода метаклассов.