Re: Декораторы?
От: dmz Россия  
Дата: 21.12.08 06:53
Оценка: 34 (1)
CS>В принципе все типичные use cases для чего они были введены в Питон у меня как бы перекрыты и так.
CS>Есть встроенные virtual property и статические методы/свойства класса.

CS>А расскажите кто и как их полезно использует?


AOP. Типичный кейс — ест веб-метод, нужно его обвесить декодированием значений, проверкой валидности, сгенерить данные, добавить общие для контекста данные, выплюнуть все XML и наложить XSL:

    @render('trip-edit.xsl')
    @permission('View trip')
    @global_view()
    @conf_info()
    @common_trip_info()
    def edit_trip(self, id):
        trips = Trips()
        the_trip = trips.get_trip_info(id)
        return dict(trip=the_trip)

...

    class update_route_rq(object):
        route_name = not_empty()&not_space()&has_len(max=200, min=0)&trunc(200)

    @render(raw=True)
    @permission('Edit geo')
    @validate_form(update_route_rq)
    def update_route(self):
        fd = Form_Data(self.request.form)
        fe =  Form_Errors(self.form_errors)

        (откушено)
...
Re: Декораторы?
От: targeted Россия http://www.targeted.org/
Дата: 04.01.09 15:06
Оценка: 17 (1)
CS>А расскажите кто и как их полезно использует?

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

Пример:

@typecheck
def bar(a: int, b: int) -> int:

@typecheck
def bar(self, filename: os_path.isfile, f: optional(callable) = None) -> list_of(str):

@typecheck
def str2int(x: by_regex("^[0-9]+$")) -> int:

@typecheck
def serialize(stream: with_attr("write", "flush") -> bool:

и т.д.

Реализация для Python 3.0 тут:
http://code.activestate.com/recipes/572161/
менее красивая версия для Python 2.x тут:
http://code.activestate.com/recipes/426123/
Re[10]: Декораторы?
От: z00n  
Дата: 23.12.08 02:52
Оценка: 3 (1)
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 — а так по фичам все остальные выглядят довольно бледно.
Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 20.12.08 22:38
Оценка:
Подумываю о том чтобы добавить в tiscript декораторы в стиле Питон'а
http://www.python.org/dev/peps/pep-0318/

В принципе все типичные use cases для чего они были введены в Питон у меня как бы перекрыты и так.
Есть встроенные virtual property и статические методы/свойства класса.

А расскажите кто и как их полезно использует?
Re: Декораторы?
От: z00n  
Дата: 21.12.08 04:56
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Подумываю о том чтобы добавить в tiscript декораторы в стиле Питон'а

CS>http://www.python.org/dev/peps/pep-0318/

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>А расскажите кто и как их полезно использует?

Хаскелисты повсеместно используют для композиции функций, у них это обозначается точкой: '.'
-- псевдокод:
foo = decorator1 . decorator2 . decorator3 $ foo

-- или в 'столбик'
foo = decorator1
    . decorator2
    . decorator3
    $ foo
Re[2]: Декораторы?
От: dmz Россия  
Дата: 21.12.08 06:55
Оценка:
Z>Python Way: вместо того, чтобы дать людям инфиксный оператор композиции функций (или вообще возможность определять операторы как в ML, Haskell, Scala etc.), давайте изобретем новое понятие и новый синтаксис.

Ну все таки питоне не ФЯ и никогда не будет, поэтому врядли их стоит этим попрекать. Декораторы реализованы
чрезвычаной ракообразно и непрозрачно; детали трудно помнить, но в процессе разбирательств понимаешь, что это ничего общего
с композицией функций не имеет.


CS>>А расскажите кто и как их полезно использует?

Z>Хаскелисты повсеместно используют для композиции функций, у них это обозначается точкой: '.'

А вот в эрланге есть что-то, чем можно заменить композицию функций?
Re[3]: Декораторы?
От: z00n  
Дата: 21.12.08 07:42
Оценка:
Здравствуйте, dmz, Вы писали:

dmz> ... но в процессе разбирательств понимаешь, что это ничего общего

dmz>с композицией функций не имеет.

Нет никакой приципиальной разницы, только минорные синтаксические различия и вот это:

The decorator statement is limited in what it can accept -- arbitrary expressions will not work. Guido preferred this because of a gut feeling .



dmz>А вот в эрланге есть что-то, чем можно заменить композицию функций?

Синтаксически — не знаю. Саму функцию 'compose' легко написать:
Compose = fun(F,G) -> fun(X) -> F(G(X)) end end.
Re[2]: Декораторы?
От: z00n  
Дата: 21.12.08 08:06
Оценка:
Здравствуйте, dmz, Вы писали:


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
Re[4]: Декораторы?
От: dmz Россия  
Дата: 21.12.08 08:16
Оценка:
dmz>>А вот в эрланге есть что-то, чем можно заменить композицию функций?
Z>Синтаксически — не знаю. Саму функцию 'compose' легко написать:
Z>
Z>Compose = fun(F,G) -> fun(X) -> F(G(X)) end end.
Z>


Кстати, вполне нормальная конструкция. В контексте сервера можно где-то написать:

map_url( Url, { {validator, Validate}, {permission, Permission}, {handler, urlHandler}})


и получим вполне разумный аналог декораторам — т.е. map_url вполне может породить функцию с заданными контекстами без синтаксического оверхеда.

Интересно не это, а то, что это все можно точно также сделать и на питоне — не бодаясь с передачей параметров, неявным порядком вызовов и т.п.
Причем и структуру аспектов можно сделать нелинейной:

map_url( Url, { {{validate, validate_form},{validate_fuckup, invalid_form}, 
                 {{permission, some_permission},{permission_fuckup, access_denied}} 
                 {handler, some_url_handler}} )


Более того, если не писать декораторы над веб-методами, а вместо этого написать код, который пробежится по приведенной структуре данных и построит описанные композиции, то можно вообще выкинуть слой веб-методов, который у нас между вебом и бизнес-логикой — оставить только хелперы (валидаторы, проверки пермиссий) и методы бизнес-логики.

Но это и в голову никому не пришло! Прямо по Оруэллу — язык сужает горизонты мышления. Когда в голове один питон, то и вместо текста получается питоновский речекряк.

А напоследок, покажу почему я считаю декораторы гимороем.

class generic_decorator(object):
    def __init__(self):#, orig_self, *args, **kwargs):
        pass
        
    def get_origrun(self, args=None, kwargs=None):
        if args == None:
            args = self.func_args
        if kwargs == None:
            kwargs = self.func_kwargs

        #return decorated function object
        return lambda:self.orig_func(self.func_self, *args, **kwargs)

    #setter for decorated function object attr
    def set_function_attr(self, name, val):
        setattr(self.orig_func, name, val)

    def __new__(typ, *attr_args, **attr_kwargs):  # argument values of decorator

        def decorator(orig_func): # original function name
            self = object.__new__(typ)
            self.orig_func = orig_func
            self.__init__()

            attr_args
            attr_kwargs
           
            args, varargs, varkw, defaults = inspect.getargspec(orig_func)
            parameters = inspect.formatargspec(args, varargs, varkw, defaults)[1:-1]
    
            wrapper_func_str = """
def %s(%s):
    args, varargs, varkw, defaults = inspect.getargspec(%s)
    kw_args = dict.fromkeys(args)
    f_vals = []
    for key in args:
        kw_args[key] = locals()[key]
        f_vals.append(locals()[key])
    orig_self = f_vals[0]
    caller.func_self   = orig_self
    caller.func_args   = []
    caller.func_kwargs = kw_args
    return caller.__call__(*attr_args, **attr_kwargs)
"""%(orig_func.__name__, parameters, orig_func.__name__)

            exec_dict = locals()
            exec_dict.update(globals())
            exec_dict[orig_func.__name__] = orig_func
            exec_dict['orig_func'] = orig_func
            exec_dict['caller'] = self
            
            exec wrapper_func_str in exec_dict
            wrapper_func = locals()[orig_func.__name__]
            wrapper_func.__doc__ = orig_func.__doc__
            wrapper_func.__dict__ = orig_func.__dict__.copy()
            return wrapper_func
                                                        
        return decorator
Re[2]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 22.12.08 07:50
Оценка:
Здравствуйте, dmz, Вы писали:

dmz>
dmz>    @render('trip-edit.xsl')
dmz>    @permission('View trip')
dmz>    @global_view()
dmz>    @conf_info()
dmz>    @common_trip_info()
dmz>    def edit_trip(self, id):
dmz>        trips = Trips()
dmz>        the_trip = trips.get_trip_info(id)
dmz>        return dict(trip=the_trip)
dmz>


Интересно. А вот для UI?
Пока думаю полезность будет в описании событий:

@when_click("#myId1")
function onMyId1Click()
{
  ...
}
@when_selection_changed("#myId2")
function doSomething()
{
  ...
}
Re[3]: Декораторы?
От: dmz Россия  
Дата: 22.12.08 13:16
Оценка:
CS>Интересно. А вот для UI?
CS>Пока думаю полезность будет в описании событий:

Биндинг обработчиков? Вполне. Но. Тут есть неудобство — по крайней мере в питоне — обработчики же должны быть зарегистрированы где-то? У какого-то объекта или чего-то подобного. Вот это вот что-то должно существовать на момент инстанциации модуля, и его надо протаскивать в декоратор или оно должно быть глобальным. И то и другое — не айс. Что бы этого избежать, например в TurboGear они в декораторе устанавливают атрибуты метода (т.е. метод — объект, к нему можно привесить любые атрибуты), а потом путем интроспекции перечисляют все методы с атрибутами и в этот момент привязывают их к запросам — как-то так:

@exposed(всякая хрень) # тут только устанавливается атрибут метода, а привязка обработчика осуществляется позже 
def web_method(еще какая-то хрень)
   pass
Re[4]: Декораторы?
От: Andrey_Pilya  
Дата: 22.12.08 16:12
Оценка:
Здравствуйте, dmz, Вы писали:


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(хрень)"

а то идут какие-то статически вписанные в вычислитель полу-модели, и синтаксические корчи.

ведь всего-то навсего захотелось аспектировать код. тоесть, что бы вместо прямого мызова метода,
вызывался еще какой-то код, который, возможно, имеет в своем замыкании какое-то состояние (возможно
то, какой код будет вызван, зависит от контекста, где вызван метод).
Re[5]: Декораторы?
От: dmz Россия  
Дата: 22.12.08 16:19
Оценка:
A_P>... вот мне интересно, когда люди начнут наконец придумывать "макросы" и "generic-function"
A_P>ну честное слово — детям на смех.
...
A_P>ведь всего-то навсего захотелось аспектировать код. тоесть, что бы вместо прямого мызова метода,

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

Декораторы придумал не я, если чо.
Re[6]: Декораторы?
От: Andrey_Pilya  
Дата: 22.12.08 17:14
Оценка:
Здравствуйте, 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...
но ведь все это уже давно изобретено, опробовано и работает

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

    Message =
    {
    constructor: function( text ) {  this.text = text;  },
        say: function(  )      {  stdout.println( this.text );  }
    }


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?
Re[7]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 22.12.08 18:35
Оценка:
Здравствуйте, 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.

Лично мне декораторы представляются вполне себе полезным сахаром.

Т.е. вместо вот такой вот закорюки:

(self.onControlEvent || (self.onControlEvent = [])) += function(evt)
{
  if( evt.type == Event.BUTTON_CLICK && evt.target.match("bytton#my") )
    //doSomething usefull
}


Вот такое вот

@event_click("bytton#my")
  function doSomething()
  {
    usefull
  }


представляется записью более ясно отражающей суть.
Re[8]: Декораторы?
От: z00n  
Дата: 23.12.08 00:31
Оценка:
Здравствуйте, 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).
Re[9]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 23.12.08 00:34
Оценка:
Здравствуйте, 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 были выкинуты за для эффективности.
Re[11]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 23.12.08 07:10
Оценка:
Здравствуйте, z00n, Вы писали:

Z>>>У вас есть хотя-бы каналы? send-receive?

CS>>В Stackless Python есть microthreads которые известны также как green threads.
Z>Они много где есть и что? А вот это куда более редкая вещь: http://www.stackless.com/wiki/Channels

Вот это спецификация из семейства технологий HTML5
http://www.whatwg.org/specs/web-workers/current-work/

Вот в частности про 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 лучше, для чего-то хуже.
Просто чудес не бывает к сожалению. Чем-то приходится жертвовать в угоду скорости.

А мой вопрос был про декораторы. Стоят они овчинки или нет.
Re[12]: Декораторы?
От: z00n  
Дата: 23.12.08 08:52
Оценка:
Здравствуйте, 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.

— то нет Если не согласны — зависит.
Re[12]: Декораторы?
От: FR  
Дата: 23.12.08 09:10
Оценка:
Здравствуйте, c-smile, Вы писали:


CS>Я не буду вдаваться в механику этого дела ибо она очевидна, просто скажу что наличие этой фичи "сажает" эффективность JS, Python, Ruby.

CS>И за этим много языковых возможностей стоит на самом деле.

Мы кажется уже беседовали на эту тему, так что питон вычеркни
Re[7]: Декораторы?
От: FR  
Дата: 23.12.08 09:18
Оценка:
Здравствуйте, Andrey_Pilya, Вы писали:

A_P>просто нужно понимать, что динамика появляется не в момент выполнения кода, а в момент его

A_P>"загрузки" (бутстрапа)...

Вообще-то питоновские декораторы как раз и отрабатывают в момент "загрузки" и тогда же происходит инстанцирование классов и ссответственно выполнение кода метаклассов.
Re[6]: Декораторы?
От: FR  
Дата: 23.12.08 09:28
Оценка:
Здравствуйте, dmz, Вы писали:

dmz>Честно говоря, не очень понял, что вы хотели сказать, но если это о том, декораторы — это неконсистентный изврат, и в плане метапрограммирования и фунцкионального подхода питон сливает — то да, сливает.


Смотря с чем сравнивать, по моему в плане метапрограммирования питон вполне хорош. Синтаксис менять конечно не умеет, но метаклассы штука очень мощная.
Re[12]: Декораторы?
От: z00n  
Дата: 23.12.08 10:51
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Одна из основных фич которая есть во всех остальных языках этой группы (JS, Python, Ruby) но нет в Lua это наличие virtual properties.


CS>Вот код на TIScript:

CS>
CS>class Foo {
CS>  property bar(v)
CS>  {
CS>    get { return this._bar || 0; }
CS>    set { this._bar = v; }
CS>  }
CS>}

CS>var foo = new Foo();
CS>foo.bar = 28;
CS>


CS>это в принципе не реализуемо в Lua в силу ейной архитектуры.


Ладно, не дожидаясь уточнений, вот совершенный аналог на луа:
local Proto = {}
Proto.__index = Proto

function Proto:get() return self._bar or 0 end
function Proto:set(v) self._bar = v end

local function new() return setmetatable({},Proto) end

-- TEST:
local obj1 = new()
local obj2 = new()
obj1:set(42)

print(obj1:get()) ---> 42
print(obj2:get()) ---> 0


Ваш ход
Re[13]: Декораторы?
От: z00n  
Дата: 23.12.08 11:13
Оценка:
В ответ на возможные претензии, что мало сахара, можно например так:
local Proto = {}
Proto.__index    = fun (self,prop)   -> rawget(self,prop) or 0 end
Proto.__newindex = fun (self,prop,v) -> rawset(self,prop,"decorated:"..v)  end

local fun new() ->
  setmetatable({},Proto)
end

-- TEST:
local obj1 = new()
local obj2 = new()

obj1.bar = 42

print(obj1.bar) --> decorated:42
print(obj2.bar) --> 0


Люди удивительные вещи делают на метатаблицах — я даже не берусь.
Re[8]: Декораторы?
От: Andrey_Pilya  
Дата: 23.12.08 13:28
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, Andrey_Pilya, Вы писали:

A_P>>тут скоре посыл к c-Smile,
A_P>>ведь TIScript — это его детище, которое совсем даже не питон.
A_P>>просто он основан на "стереотипах" и синтаксисе, который ни коим образом не гнется
A_P>>(тоесть, отсутствует настраиваемый meta-протокол, нет макросов и слегка завуалирован процесс бутстрапа)

CS>По архитектуре TIScript это практически Stackless Python. Т.е. стереотипы те же.

CS>А вот синтаксис, да, другой — от Java/JavaScript. Я бы не сказал что он(синтаксис) как-то гнется меньше или больше по сравнению
CS>со всеми остальными языками этой группы: ruby, python, lua, perl, php.

CS>Лично мне декораторы представляются вполне себе полезным сахаром.


...в обсуждении выделилось 2 линии:
1. сравнение базовых концепций "вычислителя" (я не говорю "языка", потому как обсуждаются именно вопросы, связанные с
организацией вычислений, а не с формой записи в виде синтаксиса).

2. обсуждение собственно декораторов как синтаксического сахара.

я предложил, раз уж обсуждаем, взглянуть не на сами декораторы, а на те задачи, откуда они появились.
добавлять сахар в язык — помоему это примерно как напаривать лотерею среди жильцов дома: "не будут брать — газ отключим"
Язык хотелось бы иметь таким, что бы программист мог добавить себе сахар сам, по-вкусу и исходя из своих
задач, ибо далеко не всегда тот сахар, который встраивается сразу, оказывается сладким...

касательно первого пункта — вопрос может затрагивать много чего и процесс этот длинный.
(в принципе, большинство вопросов сводится к Closure + MessagePassing)
А вот при хорошем решении второго — фичи будут появляться без нарушения синтаксиса языка и красиво в него впишутся.
Проблема синтаксиса JS/Python/VB/C# и т.п. -- их синтаксис плохо гнется под что-либо новое. и У разработчиков платформ
постоянно вылазят проблемы: им не так сложно дописать новую концептуальную фичу в вычислитель,
сколько сложно дописать нотацию этой фичи в язык, поскольку в одном "текстовом потоке" совмещаются директивы,
которые должны интерпретироваться на разных стадиях жизненного цикла программы.
(компиллирование, интерпретировани, виртуальная машина — это уже не имеет значения)

так вот, возвращаясь к теме:
у нас есть, как минимум: CSSS, TIScript, Html, CSS, JSON, D/C++/C#/etc

и есть идея: размечать GUI на Html + писать несложные обработчики/behaviors на каком-то всем понятном языке.

имея опыт Web-разработки на Html+ JS + Php/Perl/Python/Ruby/C#/etc... можем попробовать проследить некоторые тенденции:
(не претендую на новости, просто, что бы упорядочит мысль)
1. общение с сервером производится через Message (пакет послал/пакет принял)
сервером, в данном случае, может выступать "приложение", для которого мы пишем GUI.
можно сказать, нас это вопрос мало волнует, кроме пункта асинхронности (что бы не залипал GUI).
2. картинку можно рисовать как на одном из серверов, так и на клиенте — причем второе вошло в моду
этот пункт больше относится к вопросу "кто как генерит HTML" — его лучше не вносить в язык.
3. поскольку картинка клеится из "кубиков", то inline-код не желателен.
но наличие такого inline-кода, так же как и кода в CSSS поднимает вопрос связи с тем контекстом,
в котором этот код написан. без такой связи, пользы от него будет мало.
Тоесть, это скорее закидка в пограничную область: связь языка (например TIScript) с объектами DOM/CSS,
а возможно, и с объектами предметной области прикладного программиста.
В языке хотелось бы увидеть удобный механизм взаимодействия с внешним миром.
4. кубикам нужно как-то дружить друг с другом — появляется среда типа оконной системы в OS и EventDriven програмирование
но хуже того! появляется сложный этап загрузки модулей и их инициализации. Некий "файл проекта" или
"файл загрузки". При этом, какие-то модули могут дозагружаться походу.
Собственно отсюда начинаются вопросы языка, как средства организации кода, ведь модули могут быть написаны разными
людьми в разное время.

Собственно для разделения логики программы и нужны всякие Meta-уровни.

CS>Вот такое вот


CS>
CS>@event_click("bytton#my")
CS>  function doSomething()
CS>  {
CS>    usefull
CS>  }
CS>


так вот. представим себе ситуацию, где "bytton#my" — результат динамического формирование HTML в процессе работы программы,
и узнать какой ID будет у кнопки, не представляется возможным на момент написания кода.
стало быть, это фича всего лишь для небольшого набора статических юзкейсов.
...

можно придумать еще пяток синтаксических упрощений.
Но каждое из них усложнит и без того не простой синтаксис (прибавим к этому кучу особенностей в восприятии Html и CSS в HtmlLayout)
после 5 таких упрощений — уже будет не совсем ясно, что проще: вычитывать, как себя ведет данная конструкция в текущей версии, какие еще есть способы записи этого дейсвия, какие у действия есть побочные эффекты, или написать по-старинке.

так что я еще раз предлагаю взглянуть не на саму фичу, а на способ и причину добавления фич в язык.
Если язык хорош — то нужные мне фичи я добавлю сам,
а если фича хороша — она войдет в стандартный набор фич, но не обязательно в язык.
Re[9]: Декораторы?
От: Andrey_Pilya  
Дата: 23.12.08 15:57
Оценка:
Здравствуйте, Andrey_Pilya, Вы писали:

A_P>Здравствуйте, c-smile, Вы писали:

CS>>Лично мне декораторы представляются вполне себе полезным сахаром.

A_P>...в обсуждении выделилось 2 линии:

A_P>1. сравнение базовых концепций "вычислителя" (я не говорю "языка", потому как обсуждаются именно вопросы, связанные с
A_P>организацией вычислений, а не с формой записи в виде синтаксиса).

A_P>2. обсуждение собственно декораторов как синтаксического сахара.


[..бла-бла-бла...]

A_P>так что я еще раз предлагаю взглянуть не на саму фичу, а на способ и причину добавления фич в язык.

A_P>Если язык хорош — то нужные мне фичи я добавлю сам,
A_P>а если фича хороша — она войдет в стандартный набор фич, но не обязательно в язык.

Конкретизирую.

что бы можно было "мета-программировать фичи" нужно иметь:
1. операторы разметки базовых примитивов языка (функции, классы, методы) должны быть командами этого языка,
либо для них должны быть рефлексивные интерфейсы и структуры

2. Нужен Code-Dom, что бы можно было вызывать операторы рефлексии и формировать код по мета-данным.
в т.ч. нужен доступ к актуальной мета-информации языка/виртуальной машины/рабочего пространства
(тут могут быть нюансы типа версионирования мета-информации)

3. Нужны хуки на вызовы методов и на внутренние процессы вычислителя (виртуальной машины)

4. нужен людский синтаксис, который бы позволял эскейпить "синтаксические слои".
в том числе, не следует забывать, что где есть 2, там есть и 3, и 33...
(раз уж мы начали писать мета-код, то появится и мета-мета-мета код.
в lisp, например, это макросы, которые используют макросы, которые используют макросы...
поскольку код имеет такую же структуру, что и данные, то с эскейпингом и синтаксическим деревом проблем нет)

5. нужна детерменированая процедура бутстрапа: когда исполняется мета код, когда можно
его менять, что доступно мета-коду.
Важно не думать о мета коде как о чем-то "узком" и "маленьком". мета код — это такой же
полноценный код, которому нужно полноценно работать с данными, с уже загруженным мета-кодом/кодом
и возможно понадобится даже "сходить на сервер"

6. понятие "контекст декларации" — связь с тем объектом "над системы", откуда производится декларативный вызов.
это частный случай контекста вызова, но предназначеный для "мета-слоев".
замыкание (функция/метод/делегат), которое будет создано в этом контексте, может поймать его в себе,
так что прийдется следить за временем жизни подобных "контекстов".
(например, это может быть HtmlTag или CSS-декларация, возможно какой-то другой контекст, значимый для бизнес-логики)
с контекстом, скорее всего, будет связан специфический DSL.

больше всего зависит от синтаксиса, потому как именно за удобство кодо-писания мы боремся

может показаться, что я преувеличиваю значение Meta-программирования, но это всего лишь
вопрос наличия средств и привычки: нет средств — нет и мета-программирования.


ЗЫ
можно, конечно, продолжать сравнивать decorator-ы с питоновскими и искать изъяны у lua,
но встроенному языку для HTMLayout это не многим поможет.
Re[14]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 23.12.08 21:52
Оценка:
Здравствуйте, z00n, Вы писали:

Z>В ответ на возможные претензии, что мало сахара, можно например так:

Z>
Z>local Proto = {}
Z>Proto.__index    = fun (self,prop)   -> rawget(self,prop) or 0 end
Z>Proto.__newindex = fun (self,prop,v) -> rawset(self,prop,"decorated:"..v)  end

Z>local fun new() ->
Z>  setmetatable({},Proto)
Z>end
Z>


Это далеко не то же самое что вот это вот:

class Foo {
  property bar(v)
  {
    get { return this._bar || 0; }
    set { this._bar = v; }
  }
}
var foo = new Foo();
foo.bar = 28;


Для полного воспроизводсва этой функциональности тебе надо не просто делать rawget/rawset,
а организовывать нечто типа

if (name == 'bar') then ...
elseif (name == 'baz') then ...
elseif (name == 'bor') then ...
else
end

что в результате выйдет еще хуже чем в JS/Ruby. И все это делать для __index и для __newindex
Ну и не забывать про вещи типа super и наследование по цепочке prototypes.

Это и есть то что я имею ввиду когда говорю про "выкинутые фичи".
Если быть точным то это фичи которые изначально в язык не закладывались.

Z>Люди удивительные вещи делают на метатаблицах — я даже не берусь.


Не сомневаюсь. На С тоже можно написать свою систему повторяющую классы из C++.
Это не значит что C хуже или лучше C++. Просто языки исповедуют несколько разные парадигмы — сиречь оптимальны для несколько разных domains.
Re[10]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 23.12.08 22:42
Оценка:
Здравствуйте, Andrey_Pilya, Вы писали:

A_P>>так что я еще раз предлагаю взглянуть не на саму фичу, а на способ и причину добавления фич в язык.

A_P>>Если язык хорош — то нужные мне фичи я добавлю сам,
A_P>>а если фича хороша — она войдет в стандартный набор фич, но не обязательно в язык.

A_P>Конкретизирую.


A_P>что бы можно было "мета-программировать фичи" нужно иметь:

A_P>1. операторы разметки базовых примитивов языка (функции, классы, методы) должны быть командами этого языка,
A_P> либо для них должны быть рефлексивные интерфейсы и структуры

Ну собсвенно так оно и есть.
class Foo {  }

это не что иное как
const Foo = new Class();


Может не настолько атомарно как хотелось но тем не менее.


A_P>2. Нужен Code-Dom, что бы можно было вызывать операторы рефлексии и формировать код по мета-данным.

A_P> в т.ч. нужен доступ к актуальной мета-информации языка/виртуальной машины/рабочего пространства
A_P> (тут могут быть нюансы типа версионирования мета-информации)

С Code-Dom проблемы. Языки этой группы чаще всего используются в режиме eval (например JS).
Т.е. скорость компиляциии критична. Вводить AST это вводить доп. фазу компиляции.
Без компромиса не обойтись. Собственно @decorator и есть такой компромис.

A_P>3. Нужны хуки на вызовы методов и на внутренние процессы вычислителя (виртуальной машины)


Ну наверное. Пока не возникало необходимости.

A_P>4. нужен людский синтаксис, который бы позволял эскейпить "синтаксические слои".

A_P> в том числе, не следует забывать, что где есть 2, там есть и 3, и 33...
A_P> (раз уж мы начали писать мета-код, то появится и мета-мета-мета код.
A_P> в lisp, например, это макросы, которые используют макросы, которые используют макросы...
A_P> поскольку код имеет такую же структуру, что и данные, то с эскейпингом и синтаксическим деревом проблем нет)

Это как "напишите систему которой сможет пользоваться дурак. И только дурак сможет ею пользоваться".
Вместо "дурак" подставляем "гик" и получаем опять же верное утверждение.

Это я к тому что обычные люди типа меня могут испытавать просто физиологические проблемы работая с синтаксисом
в стиле lisp. Не каждому дано.

A_P>5. нужна детерменированая процедура бутстрапа: когда исполняется мета код, когда можно

A_P> его менять, что доступно мета-коду.
A_P> Важно не думать о мета коде как о чем-то "узком" и "маленьком". мета код — это такой же
A_P> полноценный код, которому нужно полноценно работать с данными, с уже загруженным мета-кодом/кодом
A_P> и возможно понадобится даже "сходить на сервер"

Разные design goals. У Nemerle неможливо "детерминированная структура бутстрапа" но в реалии процент прикладных
программеров которые в состоянии писать язык под себя оперируя понятиями AST/code-dom всего ничего.
В болшинстве же случаев расширяемость языка на уровне новых синтаксических конструкций это наоборот зло.
Требования к валидности и отсутствии side-effects в таком коде неизмеримо выше чем для "рабочее место тети Маши".

A_P>может показаться, что я преувеличиваю значение Meta-программирования, но это всего лишь

A_P>вопрос наличия средств и привычки: нет средств — нет и мета-программирования.

Я думаю что практическая истина где-то посредине. Метапрограммизм возведенный в самоцель ...
...ну короче только метапрограммисты и будут им пользоваться.

A_P>ЗЫ

A_P> можно, конечно, продолжать сравнивать decorator-ы с питоновскими и искать изъяны у lua,
A_P> но встроенному языку для HTMLayout это не многим поможет.

Если это про меня то изъяны в lua я не ищу. Как бы даже наоборот, в свое время расковырял архитектуру lua чтобы понять
почему она быстрее чем скажем тот же python или ruby. Даже у меня был компайлер который строил байткоды lua но использовал
\r\n free grammar в стиле JS. Которая (grammar используящая \r\n\t в качестве значимых лексем ) кстати плохо работает в случае embedded языков.
Ну там всякие варианты с <a href="#" onclick="some code"> сразу исключают Lua/Ruby/Python из рассмотрения.
Re[15]: Декораторы?
От: z00n  
Дата: 24.12.08 02:57
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Это далеко не то же самое что вот это вот:

CS>
CS> ...
CS>  property bar(v)
CS>  {
CS>    get { return this._bar || 0; }
CS> ...
CS>

Это тоже самое, только диспатчинг в другом месте. И это даже лучше, в контексте предыдущей беседы, я могу навесить "декоратор" сразу на все геттеры или на все сеттеры.


CS>Для полного воспроизводсва этой функциональности тебе надо не просто делать rawget/rawset,

CS>а организовывать нечто типа

CS>if (name == 'bar') then ...

CS>elseif (name == 'baz') then ...
CS>elseif (name == 'bor') then ...
CS>else
CS>end

Для этого есть паттерн матчинг.
case name of
  | "bar" -> ...
  | "baz" -> ...
  | "bor" -> ...
end


Потом это удобно — писанины меньше, можно выделить, например, все поля, которые начинаются c "OnMouse...". И о метапрограмировании не забывайте
local (\) = tostring

local Proto = {}
Proto.__index    = fun (self,prop)   -> rawget(self,prop) or 0 end


fun Proto.__newindex (self,prop,v) ->
  case v of
    | v if prop:match("^OnMouse") -> rawset(self,prop,"OnMouseMethod:"..\v)
    | v -> rawset(self,prop,v)
  end
end

local fun new() -> setmetatable({},Proto) end

-- TEST:
local obj1 = new()

obj1.OnMouseMove = fun()->end
print(obj1.OnMouseMove)     ---> OnMouseMethod:function: 0039D1A0


CS>что в результате выйдет еще хуже чем в JS/Ruby. И все это делать для __index и для __newindex

CS>Ну и не забывать про вещи типа super и наследование по цепочке prototypes.

Для справки: полноценная объектная система с одиночным наследованием занимает 22 строки. Prototype-based занимает 1 функцию.

CS>Это и есть то что я имею ввиду когда говорю про "выкинутые фичи".

CS>Если быть точным то это фичи которые изначально в язык не закладывались.
Метатаблицы закладывались в язык изначально и представляют собой, помимо прочего, прототипную объекную систему на стероидах (например работают для С++ обектов, дают намного больше контроля над происходящим). Используются в языке повсеместно включая стандартную библиотеку. Но я не просто спрашивал о выкинутых фичах, я просил раскрыть мне глаза на:
CS> ... наличие virtual properties
CS>Я не буду вдаваться в механику этого дела ибо она очевидна, просто скажу что наличие этой фичи "сажает" эффективность JS, Python, Ruby.
CS>И за этим много языковых возможностей стоит на самом деле.
Я, честно, вообще не понимаю, о чем сыр-бор. Я лично, когда мне нужен сеттер напишу set_bar и буду вызывать его как функцию. Ответьте прямо — какие возможности от этого зависят и чего в них такого важного, что их даже нельзя выключить при том, что они замедляют (это ваша версия) язык в разы.

CS>Не сомневаюсь. На С тоже можно написать свою систему повторяющую классы из C++.

Вот уже и аналогии пошли в ход. А по существу?
CS>Это не значит что C хуже или лучше C++. Просто языки исповедуют несколько разные парадигмы — сиречь оптимальны для несколько разных domains.
Для протокола я ни разу во всей ветке не сказал "лучше" или "хуже".
Re[11]: Декораторы?
От: z00n  
Дата: 24.12.08 03:31
Оценка:
Здравствуйте, c-smile, Вы писали:

CS> Даже у меня был компайлер который строил байткоды lua но использовал

CS>\r\n free grammar в стиле JS. Которая (grammar используящая \r\n\t в качестве значимых лексем ) кстати плохо работает в случае embedded языков.
CS>Ну там всякие варианты с <a href="#" onclick="some code"> сразу исключают Lua/Ruby/Python из рассмотрения.

Либо вы перепутали луа и питон, либо сильно заблуждаетесь. Грамматика lua whitespace free.
Re[11]: Декораторы?
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 24.12.08 03:47
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Если это про меня то изъяны в lua я не ищу. Как бы даже наоборот, в свое время расковырял архитектуру lua чтобы понять

CS>почему она быстрее чем скажем тот же python или ruby. Даже у меня был компайлер который строил байткоды lua но использовал
CS>\r\n free grammar в стиле JS. Которая (grammar используящая \r\n\t в качестве значимых лексем ) кстати плохо работает в случае embedded языков.
CS>Ну там всякие варианты с <a href="#" onclick="some code"> сразу исключают Lua/Ruby/Python из рассмотрения.

Хм. А какие конструкции в Руби нельзя написать в одну строку? Мне казалось, везде, где значим \n, есть альтернативный синтаксис без него (;, then, :, etc.).
Re[11]: Декораторы?
От: FR  
Дата: 24.12.08 04:44
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Ну там всякие варианты с <a href="#" onclick="some code"> сразу исключают Lua/Ruby/Python из рассмотрения.


Даже питон не исключают, теги <script> </script> никто ни отменял, плюс даже на питоне много чего можно в одну строчку сделать.
Питон от ActiveState кстати умеет встраиватся в html как клиентский язык.
Re[12]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 24.12.08 07:03
Оценка:
Здравствуйте, z00n, Вы писали:

Z>Либо вы перепутали луа и питон, либо сильно заблуждаетесь. Грамматика lua whitespace free.


Дико извиняюсь, но что точно такое whitespace free grammar?

Если я правильно понял то вот это есть синтаксически валидная последовательность:
a = 1 b = 2 a = b + 1 c d()

?
Re[12]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 24.12.08 07:10
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Хм. А какие конструкции в Руби нельзя написать в одну строку? Мне казалось, везде, где значим \n, есть альтернативный синтаксис без него (;, then, :, etc.).


Собственно в том и проблема что требуется альтернативный синтаксис.
Требования к языкам встраиваемым inline в markup как раз и состоит в том чтобы им не требовался доп. синтаксис.
Более того есть ситуации когда \r или \n вообще могут быть заменены пробелами или вообще удалены.
По этому принципу работают компрессоры JS кода. Там вообще все whitespace выкидываются.
Re[12]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 24.12.08 07:13
Оценка:
Здравствуйте, FR, Вы писали:

FR>Даже питон не исключают, теги <script> </script> никто ни отменял, плюс даже на питоне много чего можно в одну строчку сделать.

См. мой ответ выше по дереву.
FR>Питон от ActiveState кстати умеет встраиватся в html как клиентский язык.
Завтра как раз у них в гостях буду. Будет повод авторам этого безобразия прррыстально в глаза смотреть.
Re[13]: Декораторы?
От: z00n  
Дата: 24.12.08 07:40
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, z00n, Вы писали:


Z>>Либо вы перепутали луа и питон, либо сильно заблуждаетесь. Грамматика lua whitespace free.

CS>Дико извиняюсь, но что точно такое whitespace free grammar?
Это когда лексер выкидывает не глядя весь whitespace: [ \n\r\t] и комментарии. Другими словами, никаких значащих для программы пробелов, переводов строк и комментариев в луа нет. Разделителем стейтментов в луа является ';' — и он опционален во всех случаях с одним исключением.

CS>Если я правильно понял то вот это есть синтаксически валидная последовательность:

CS>
CS>a = 1 b = 2 a = b + 1 c d()
CS>

CS>?

Нет — у вас 'c' — expression стоит лишнее
a = 1 b = 2 a = b + 1 c= d() -- valid
a = 1 b = 2 a = b + 1 d()    -- valid
Re[13]: Декораторы?
От: z00n  
Дата: 24.12.08 07:47
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Собственно в том и проблема что требуется альтернативный синтаксис.

CS>По этому принципу работают компрессоры JS кода. Там вообще все whitespace выкидываются.
Справедливости ради, компрессоры — это простые компиляторы — им нечего не стоит еше и синтаксис менять на альтернативный. Хорошие компрессоры еще и длинные имена переименовывают в короткие — значит они и так довольно сильно семантику анализируют.
Re[16]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 24.12.08 08:32
Оценка:
Здравствуйте, z00n, Вы писали:

CS>>Это далеко не то же самое что вот это вот:

CS>>
CS>> ...
CS>>  property bar(v)
CS>>  {
CS>>    get { return this._bar || 0; }
CS>> ...
CS>>

Z>Это тоже самое, только диспатчинг в другом месте. И это даже лучше, в контексте предыдущей беседы, я могу навесить "декоратор" сразу на все геттеры или на все сеттеры.

Я не понял что именно "тоже самое"?

Z>Для этого есть паттерн матчинг.

Z>
Z>case name of
Z>  | "bar" -> ...
Z>  | "baz" -> ...
Z>  | "bor" -> ...
Z>end
Z>


О как! А причем здесь pattern matching (ты это имел ввиду)?
И это на Lua вообще или на чем? Чего-то я не помню в ней такой красоты.

Z>Потом это удобно — писанины меньше, можно выделить, например, все поля, которые начинаются c "OnMouse...". И о метапрограмировании не забывайте

Z>
Z>local (\) = tostring

Z>local Proto = {}
Z>Proto.__index    = fun (self,prop)   -> rawget(self,prop) or 0 end

Z>fun Proto.__newindex (self,prop,v) ->
Z>  case v of
Z>    | v if prop:match("^OnMouse") -> rawset(self,prop,"OnMouseMethod:"..\v)
Z>    | v -> rawset(self,prop,v)
Z>  end
Z>end

Z>local fun new() -> setmetatable({},Proto) end

Z>-- TEST:
Z>local obj1 = new()

Z>obj1.OnMouseMove = fun()->end
Z>print(obj1.OnMouseMove)     ---> OnMouseMethod:function: 0039D1A0
Z>


Круто. Т.е. любое обращение к property типа obj1.foo будет проходить через regexp по строке имени?
И предполагается что это будет быстро работать?
Мы вообще про программирование в этой ветке говорим?

CS>>что в результате выйдет еще хуже чем в JS/Ruby. И все это делать для __index и для __newindex

CS>>Ну и не забывать про вещи типа super и наследование по цепочке prototypes.

Z>Для справки: полноценная объектная система с одиночным наследованием занимает 22 строки. Prototype-based занимает 1 функцию.


Перефразирую тебя слегка: "Вот уже и сантиметры пошли в ход. А по существу?"
В том смысле что 22 попугая это круто. Надеюсь что это не regexp'ы?

Z>Я, честно, вообще не понимаю, о чем сыр-бор. Я лично, когда мне нужен сеттер напишу set_bar и буду вызывать его как функцию. Ответьте прямо — какие возможности от этого зависят и чего в них такого важного, что их даже нельзя выключить при том, что они замедляют (это ваша версия) язык в разы.


http://en.wikipedia.org/wiki/Uniform_access_principle
http://en.wikipedia.org/wiki/Property_(programming)
Re[11]: Декораторы?
От: Andrey_Pilya  
Дата: 24.12.08 11:17
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, Andrey_Pilya, Вы писали:


A_P>>>так что я еще раз предлагаю взглянуть не на саму фичу, а на способ и причину добавления фич в язык.

A_P>>>Если язык хорош — то нужные мне фичи я добавлю сам,
A_P>>>а если фича хороша — она войдет в стандартный набор фич, но не обязательно в язык.

A_P>>Конкретизирую.


A_P>>что бы можно было "мета-программировать фичи" нужно иметь:

A_P>>1. операторы разметки базовых примитивов языка (функции, классы, методы) должны быть командами этого языка,
A_P>> либо для них должны быть рефлексивные интерфейсы и структуры

CS>Ну собсвенно так оно и есть.

CS>
CS>class Foo {  } 
CS>

CS>это не что иное как
CS>
CS>const Foo = new Class();
CS>


CS>Может не настолько атомарно как хотелось но тем не менее.

ок, с этим как правило просто
думаю не стоит разводить канитель про всякие GetClasses, GetMembers, AddMember, и т.м.

далее, полагаю, вопрос становит так: можно ли с классом/методом/virtualproperty ассоциировать
дополнительный набор всякой хрени, которую бы мог интерпретировать мой код на этом же языке,
но уже в режиме "мета-кода". Скажем, выбирать методы, которые делать Event-Handler-ами,
навешивать Before и After обработчики и т.п.

в C# для этого придумали такую хрень: ICustomAttributeProvider (думаю понятно, что это за интерфейс)
используется так:
[MyAttribute(1,2,3)]
[MyAttribute1("хо-хо")]
public class MyClass {
     [MyAttribute2]
     public void MyMethod( [OneModeAttribute]int xx) {
     }
     
     [I_Tut_Attribute]
     public int MyProperty {
        get { return InnerField; }
        set { InnerFiled = value; }
     }
}


это похоже на

@event_click("bytton#my")
  function doSomething()
  {
    usefull
  }
[code]

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

далее - Code-Dom.

A_P>>2. Нужен Code-Dom, что бы можно было вызывать операторы рефлексии и формировать код по мета-данным.
A_P>>   в т.ч. нужен доступ к актуальной мета-информации языка/виртуальной машины/рабочего пространства
A_P>>   (тут могут быть нюансы типа версионирования мета-информации)   

CS>С Code-Dom проблемы. Языки этой группы чаще всего используются в режиме eval (например JS).
CS>Т.е. скорость компиляциии критична. Вводить AST это вводить доп. фазу компиляции. 
CS>Без компромиса не обойтись. Собственно @decorator и есть такой компромис.

:-) главная задача инженера - искать и находить компромисы,
в них же и вся красота решений.

предлагаю рассмотреть такую конструкцию :
[code]
class MyClass (c1, c2, c3) {
    method Method1 (a, b, c) {
    }
    
    decorate (MyDecorator1, MyDecorator2) {
       method Method2 (a, b) {
       }
    }
}

decorate (MyDecorator3) {
    get-Method(MyClass, "Method2")
}


синтаксис условный и очень рагульный, ввиду общей рагульности синтаксисов типа "key Name(name){}".
но! я сейчас не о синтаксисе, а о его семантике:
слова "class", "method", "decorate" — это функции, которые создают соответствующие объекты,
в вот то, что идет после них — это их параметры.
рагульность какраз растет из того, что параметры разбиты на 3 группы: до скобок, в скобках, в фигруных скобках.
что резко отличает их от остальных функций, и мешает видеть простоту: это таки функция, и то, что в фигурных скобках — это таки параметры. точнее, это макрос который отличается от функции тем, что его параметры не вычисляются (не eval-ятся)
при передаче, а передаются в "первозданном" виде (Code-dom, а не строка, естественно).

мета-коду не сильно нужно анализировать Code-dom, в основном, ему нужно уметь подменить или настроить
контекст вызова/декларации для внутреннего кода!

Как могла бы работать такая конструкция:
function формирует функцию (возможно безимянную — тело функции)
method будучи вызван в рамках класса (тоесть, в специальном контексте), формирует meta-запись о методе (только формируе!),
формирует функцию — тело метода и возвращает meta-запись в контекст вызова.
decorate — вызывает method, а так же вызывает для него MyDecorator1, MyDecorator2 и т.п. а потом возвращает
полученую в итоге meta-запись о методе (а возможно и несколько мета-записей!)

class, формирует контекст вызова и вызывает все, что у него в "{" "}", потом полученые мета-записи раскладывает у себя.

class, method, decorate, for, if — это могут быть, для начала, мапинга на базовые функции вычислителя.
но желательно иметь возможность их переопределять, скажем, для определенных контекстов вызова.
типа:

with-my-oo {
   class MyClass {
       super-method M1 (x,y,z) { ... }
   }
}


with-my-oo — это функция (точнее макрос), который переопределяет функцию (точнее name to value binding) для class...

осталось только научиться декларировать макросы, или при декларации функции, задавать какие параметры
должны вычисляться, а какие — нет
ну и базовые функции — apply и eval, которые бы позволяли вычислять/вызывать параметры.
(возможно прийдется немного разобраться с замыканиями и с такими корчами как "if(){}else{}", "try{}catch{}finally{}", "do{}while()")

A_P>>3. Нужны хуки на вызовы методов и на внутренние процессы вычислителя (виртуальной машины)

функции "class", "function", "method", "new" и т.п. и возможность их подмены как раз и будут такими хуками.

CS>Ну наверное. Пока не возникало необходимости.

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

A_P>>4. нужен людский синтаксис, который бы позволял эскейпить "синтаксические слои".

A_P>> в том числе, не следует забывать, что где есть 2, там есть и 3, и 33...
A_P>> (раз уж мы начали писать мета-код, то появится и мета-мета-мета код.
A_P>> в lisp, например, это макросы, которые используют макросы, которые используют макросы...
A_P>> поскольку код имеет такую же структуру, что и данные, то с эскейпингом и синтаксическим деревом проблем нет)

CS>Это как "напишите систему которой сможет пользоваться дурак. И только дурак сможет ею пользоваться".

CS>Вместо "дурак" подставляем "гик" и получаем опять же верное утверждение.


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

беда JS и ему подобных в том, что родившись динамическими (интерпретируемыми), они взяли себе скелет от
статического языка, который был изначально небольшой надстройкой над ассемблером. они потеряли доступ к тому,
что находится в "{}"...


A_P>>5. нужна детерменированая процедура бутстрапа: когда исполняется мета код, когда можно

A_P>> его менять, что доступно мета-коду.
A_P>> Важно не думать о мета коде как о чем-то "узком" и "маленьком". мета код — это такой же
A_P>> полноценный код, которому нужно полноценно работать с данными, с уже загруженным мета-кодом/кодом
A_P>> и возможно понадобится даже "сходить на сервер"

CS>Разные design goals. У Nemerle неможливо "детерминированная структура бутстрапа" но в реалии процент прикладных

CS>программеров которые в состоянии писать язык под себя оперируя понятиями AST/code-dom всего ничего.
CS>В болшинстве же случаев расширяемость языка на уровне новых синтаксических конструкций это наоборот зло.
CS>Требования к валидности и отсутствии side-effects в таком коде неизмеримо выше чем для "рабочее место тети Маши".

A_P>>может показаться, что я преувеличиваю значение Meta-программирования, но это всего лишь

A_P>>вопрос наличия средств и привычки: нет средств — нет и мета-программирования.

CS>Я думаю что практическая истина где-то посредине. Метапрограммизм возведенный в самоцель ...

CS>...ну короче только метапрограммисты и будут им пользоваться.

вот ты автомобили изобретаешь? бензин там? процессоры? электростанции?
но ведь пользуешся?
кто-то напишет декораторы, кто-то — множественное наследование, кто-то DSL для бизнес логики...

хотя с другой стороны: если мы говорим о языке достаточно широкого и тем более прикладного использования,
мы должны понимать, что у прикладного программиста могут быть свои задачи, и не все ему удобно писать
через class+method... иногда короче описать другие сущности, которые бы нагенерили бы 10 классов и 100 методов.

meta-программирование не цель, а такой же полноценный прием в программировании, как функциональный вызов, маршалинг, паттерны...
просто программист настраивает свой вычислитель для решения своей задачи. он может взять чужую библиотеку настройки и т.п.
"meta" его называют только там, где его как такового нет. потому, то там различается "meta" и "не meta",
а когда оно есть — то различий уже нету. есть просто "программирование"
так что, "нет никакой ложки"


PS
предлагаю так же взять на рассмотрение концепцию "symbol-value".

в .NET непример, строки immutable, и есть "глобальный индакс строк", что позволяет их быстро сравнивать,
и если где-то в коде в виде констант заданы две одинаковые строки — то это 2 ссылки на одну и ту же строку.
но это порождает большой геморой с манипуляциями над строками — это делать не сложно, но порождает кучи мусора,
что просаживает систему.
идея была благородная, только не доузнали парадигму. реально, там где нужны строковые константы и ключи — нужно
использовать понятие "символа" — фактически идентификатор, а с ним можно уже связывать дальше что-то.
пускай среда не дает возможности менять какие-то value-binding-и для идентификатора, но зато не нужно
передавать имена классов/методов и т.п. строками.
символ можно присвоить в переменную, передать в функцию, получить значение или превратить в строку...

Развитая система рефлексии/meta-программирования нуждается в такой концепции
Re[12]: Декораторы?
От: FR  
Дата: 24.12.08 12:19
Оценка:
Здравствуйте, Andrey_Pilya, Вы писали:

A_P>ок, с этим как правило просто

A_P>думаю не стоит разводить канитель про всякие GetClasses, GetMembers, AddMember, и т.м.

A_P>далее, полагаю, вопрос становит так: можно ли с классом/методом/virtualproperty ассоциировать

A_P>дополнительный набор всякой хрени, которую бы мог интерпретировать мой код на этом же языке,
A_P>но уже в режиме "мета-кода". Скажем, выбирать методы, которые делать Event-Handler-ами,
A_P>навешивать Before и After обработчики и т.п.

A_P>в C# для этого придумали такую хрень: ICustomAttributeProvider (думаю понятно, что это за интерфейс)


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

http://www.iso.ru/journal/articles/print/253.html
Re[12]: Декораторы?
От: Andrey_Pilya  
Дата: 24.12.08 12:24
Оценка:
A_P>meta-программирование не цель, а такой же полноценный прием в программировании, как функциональный вызов, маршалинг, паттерны...
A_P>просто программист настраивает свой вычислитель для решения своей задачи. он может взять чужую библиотеку настройки и т.п.
A_P>"meta" его называют только там, где его как такового нет. потому, то там различается "meta" и "не meta",
A_P>а когда оно есть — то различий уже нету. есть просто "программирование"
A_P>так что, "нет никакой ложки"

чем плохо поиметь возможность писать:

def-behavior MyBehavior (MyClass1, MyClass2) {

    for-css-selector ("#pushbutton1") {
        def-click-handler MyHandler1(tag, event) {
            di-ti;
        }

        def-style {
            width: 100;
            height: 20;
        }

        def-popup {
            // слово return не обязательно, пускай функция всегда возвращает последнее выражение.
            // "return" может оставаться в качестве flow-control-элемента, по-сути, это то же что и goto
            return get-popup();
        }
    }

    method get-popup() {
        //взять где-то запазухой...
    }
}

MyBehavior.method get-popup () {
   // вот так переопределим метод снаружи
}


причем "def-behavior", "for-css-selector", "def-click-handler", "def-style", "def-popup" — это синтаксический сахар, который не вшит в язык, я является обыкновенной надстройкой.

не думаю, что compile-time тут очень сильно увеличится.
если писать без такой надстройки — то получатся горы тупого дублирующегося кода, который и парситься и компилиться будет дольше,
и работать будет не быстрее...

... тонкий лед возле разбора содержимого "{" "}", например в def-style
при декларации этого макроса, можно было бы указать "парсать его или нет" и если парсать — то как...
Re[13]: Декораторы?
От: Andrey_Pilya  
Дата: 24.12.08 13:13
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Andrey_Pilya, Вы писали:


A_P>>ок, с этим как правило просто

A_P>>думаю не стоит разводить канитель про всякие GetClasses, GetMembers, AddMember, и т.м.

A_P>>далее, полагаю, вопрос становит так: можно ли с классом/методом/virtualproperty ассоциировать

A_P>>дополнительный набор всякой хрени, которую бы мог интерпретировать мой код на этом же языке,
A_P>>но уже в режиме "мета-кода". Скажем, выбирать методы, которые делать Event-Handler-ами,
A_P>>навешивать Before и After обработчики и т.п.

A_P>>в C# для этого придумали такую хрень: ICustomAttributeProvider (думаю понятно, что это за интерфейс)


FR>Тут я думаю что ты учишь рыбу плавать, но в том же питоне (и в руби вроде тоже) есть метаклассы которые

FR>намного мощнее атрибутов из шарпа и которые позволяют получить полный контроль над конструированием и
FR>инициацией классов, в том числе и делать то что ты описал выше.

я ни кого не учу.

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

...кроме комментариев о Могучем и великом удаве, тоесть питоне, может будут какие-то мысли,
как обустроить TIScript?
Re[13]: Декораторы?
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 24.12.08 14:21
Оценка:
Здравствуйте, c-smile, Вы писали:

DM>>Хм. А какие конструкции в Руби нельзя написать в одну строку? Мне казалось, везде, где значим \n, есть альтернативный синтаксис без него (;, then, :, etc.).


CS>Собственно в том и проблема что требуется альтернативный синтаксис.

CS>Требования к языкам встраиваемым inline в markup как раз и состоит в том чтобы им не требовался доп. синтаксис.

Что значит требуется альтернативный? Это самый настоящий исходный синтаксис Руби и есть: хочешь пиши if A\n B end, а хочешь — if A then B end или if A: B end. Хочешь пиши while A \n B end, а хочешь — while A do B end или while A: B end. И так везде, насколько я помню.
Re[14]: Декораторы?
От: FR  
Дата: 24.12.08 15:19
Оценка:
Здравствуйте, Andrey_Pilya, Вы писали:


A_P>я ни кого не учу.


A_P>скажем так, просто что бы не упустить.

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

В руби с питоном более удобный.

A_P>...кроме комментариев о Могучем и великом удаве, тоесть питоне, может будут какие-то мысли,

A_P>как обустроить TIScript?

Так зависит от автора, он похоже вообще не горит желанием вводить метапрограммирование.
А если он его хочет, то логично посмотреть как это сделано в родственных языках,
то есть в том же питоне и руби, ну и плюс в прородителе жанра Smalltalk.
Re[17]: Декораторы?
От: z00n  
Дата: 24.12.08 15:43
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Я не понял что именно "тоже самое"?

OK. Несколько выше вы утвердили что "это в принципе не реализуемо в Lua в силу ейной архитектуры". Я вам показал, что в луа есть встроенный механизм управляющий тем, как происходит обращение к "неопределенным" полям, который вы при желании (у меня его нет) можете употребить для реализации того, что вы считаете нереализуемым. А вы начинаете придираться к неинтересным деталям реализации

Z>>Для этого есть паттерн матчинг.

CS>О как! А причем здесь pattern matching (ты это имел ввиду)?
CS>И это на Lua вообще или на чем? Чего-то я не помню в ней такой красоты.
На луа — это не проблема. Посмотрите http://metalua.luaforge.net/ — а у меня есть даже лучше Да и в данном случае это практически сахар — тут компилировать то нечего.


Z>> | v if prop:match("^OnMouse") -> rawset(self,prop,"OnMouseMethod:"..\v)


CS>Круто. Т.е. любое обращение к property типа obj1.foo будет проходить через regexp по строке имени?

CS>И предполагается что это будет быстро работать?
CS>Мы вообще про программирование в этой ветке говорим?

Это будет работать примерно со скоростью TScript без регэкспов — померяйте (хотя я тоже такого не люблю).

Z>>Я, честно, вообще не понимаю, о чем сыр-бор ...

CS>http://en.wikipedia.org/wiki/Uniform_access_principle
CS>http://en.wikipedia.org/wiki/Property_(programming)

Т.е. Property — это и есть та супер-пупер-мега фича ради которой все тормозят? Я правильно вас понял? А что-нибудь более полезное реализовано на этой базе?
Re[15]: Декораторы?
От: Andrey_Pilya  
Дата: 24.12.08 16:11
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Andrey_Pilya, Вы писали:


A_P>>...кроме комментариев о Могучем и великом удаве, тоесть питоне, может будут какие-то мысли,

A_P>>как обустроить TIScript?

FR>Так зависит от автора, он похоже вообще не горит желанием вводить метапрограммирование.

FR>А если он его хочет, то логично посмотреть как это сделано в родственных языках,
FR>то есть в том же питоне и руби, ну и плюс в прородителе жанра Smalltalk.

Я как раз предлагаю кинуть оком в сторону "не родственных" языков, если кто не заметил.
еще раз: мета программирования не существует. есть просто ограниченные системы и ущербные синтаксисы,
в которых много суеты вокруг 4 "ключевых слов", из которых построена башенка "ООП"...

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

в своем длинном посте, который Вам было, вероятно, леньки читать (там не про питон и не про руби),
я предложил рассмотреть синтаксическую и семантическую конструкцию, которая бы позволила
прикладнику строить свои DSL (Domain Specific Language) и на них писать, не сильно выбиваясь из
родного синтаксиса языка.

не исключаю, что в питоно-руби-луа этот вопрос красиво решен, и тогда хотелось бы это красиво обсудить.

мы помним, что язык наш, предполагается использовать в Html+CSSS, для обработки событий в GUI,
небольших модификаций в DOM и для вычисления значений в CSS (http://rsdn.ru/forum/message/3215850.1.aspx
Автор: c-smile
Дата: 16.12.08
)...
но возможно, и для написания средней руки бизнес-логики в sciter (http://www.terrainformatica.com/sciter/main.whtm)
Re[16]: Декораторы?
От: FR  
Дата: 25.12.08 04:27
Оценка:
Здравствуйте, Andrey_Pilya, Вы писали:


A_P>Я как раз предлагаю кинуть оком в сторону "не родственных" языков, если кто не заметил.

A_P>еще раз: мета программирования не существует. есть просто ограниченные системы и ущербные синтаксисы,
A_P>в которых много суеты вокруг 4 "ключевых слов", из которых построена башенка "ООП"...

A_P>если заглянуть под крышечку — то окажется, что программистам не нужны объекты, классы..

A_P>и даже функции им не нужны. им нужен язык, на котором они коротко и ясно скажут машине что делать.
A_P>(сказать машине не сложно, но вот коротко и ясно — это не все до сих пор умеют)

Угу поэтому сейчас лисп является самым популярным языком програмирования, хотя конечно его сильно
потеснил сначала Forth а потом Dylan, и оглушительный успех Немерли только подтверждает триумф
метаязыков

A_P>в своем длинном посте, который Вам было, вероятно, леньки читать (там не про питон и не про руби),

A_P>я предложил рассмотреть синтаксическую и семантическую конструкцию, которая бы позволила
A_P>прикладнику строить свои DSL (Domain Specific Language) и на них писать, не сильно выбиваясь из
A_P>родного синтаксиса языка.

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

A_P>не исключаю, что в питоно-руби-луа этот вопрос красиво решен, и тогда хотелось бы это красиво обсудить.


В любом динамическом языке этот вопрос решен, обычно кривовато, но вполне достаточно.
Насчет обсуждения я уже давал ссылки на метаклассы в питоне.
Есть и некривые решения с очень мощным метапрограммированием например для питона http://www.fiber-space.de/EasyExtend/doc/EE.html
Re[8]: Декораторы?
От: Гест Украина https://zverok.github.io
Дата: 26.12.08 16:42
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>
CS>(self.onControlEvent || (self.onControlEvent = [])) += function(evt)
CS>{
CS>  if( evt.type == Event.BUTTON_CLICK && evt.target.match("bytton#my") )
CS>    //doSomething usefull
CS>}
CS>


CS>Вот такое вот


CS>
CS>@event_click("bytton#my")
CS>  function doSomething()
CS>  {
CS>    usefull
CS>  }
CS>


CS>представляется записью более ясно отражающей суть.



Непонятно.
А просто
self.addClickListener(function(){doSomething useful})


— это ваще некруто? Безо всякого доп.синтаксиса.
Re[9]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 04.01.09 00:14
Оценка:
Здравствуйте, Гест, Вы писали:

Г>Здравствуйте, c-smile, Вы писали:


Г>Непонятно.

Г>А просто
Г>
Г>self.addClickListener(function(){doSomething useful})
Г>


Г>- это ваще некруто? Безо всякого доп.синтаксиса.


Это работает если в твоей системе есть predefined set событий. В h-smile core набор событий расширяемый — behaviors могут генерировать свои собственные события. Т.е. все возможные случаи просто неизвестны. И во вторых события есть bubbling сущность — контейнер получает скажем Event.BUTTON_CLICK события от всех кнопок которые у него внутри. Типичный обработчик выглядит так:

self.onControlEvent = function(evt) 
{
  if( evt.type == Event.BUTTON_CLICK )
  {
     if( evt.target.match("button#up") )
     {
       stdout << "Up!" << "\n";
     }
     else if( evt.target.match("button#down") )
     {
       stdout << "Down!" << "\n";
     }
  }
}

Такая конструкция слишком многословна. Очень желательно чтобы все это можно было описать более декларативно / table driven.

Скажем вот так:
    @when Event.BUTTON_CLICK @on "button#up" :
    {
      stdout << "Up!" << "\n";
    }

    @when Event.BUTTON_CLICK @on "button#down" :
    {
      stdout << "Down!" << "\n";
    }

что как бы более human readable что ли.

При наличии поддержки декораторов в tiscript имплементация таких event handlers получается простой аки двери:

<html>
<head>
  <script type="text/tiscript">

    // decorator '@when' - filters event type and establishes chain of event handlers
    function @when(evtType, func)
    {
      function t(evt)
      {
        var r = false;
        if( evt.type == evtType) 
          r = func.call(this,evt);
        return t.next? t.next.call(this,evt):r; // even handlers chaining 
      }
      // note 'this' in decorators is current namespace - class or global (ns)
      var principal = this instanceof Behavior? this : self;
      t.next = principal.onControlEvent; 
      return principal.onControlEvent = t;
    }

    // decorator '@on' - filters evt.target by selector
    function @on(selector, func)
    {
      return function(evt)
      {
        if( evt.target.match(selector) )
          return func(evt);
      }
    }

    // tests of these two decorators:

    class Corpus:Behavior
    {
      @when Event.BUTTON_CLICK @on "button#up" :  
      {
        stdout << "Woohoo!" << "\n";
      }
    }

    @when Event.BUTTON_CLICK @on "button#up"
    function onUpClick()  
    {
      stdout << "Up!" << "\n";
    }

    @when Event.BUTTON_CLICK @on "button#down":
    {
      stdout << "Down!" << "\n";
    }
    
  </script>
  <style>
    body { prototype: Corpus; }
  </style>
</head>
<body>
  <button #up>Up</button>
  <button #down>Down</button>
</body>
</html>


По-моему получилось достаточно недурственно. Или нет?
Re[10]: Декораторы?
От: Аноним  
Дата: 04.01.09 01:15
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, Гест, Вы писали:


Г>>Здравствуйте, c-smile, Вы писали:


Г>>Непонятно.

Г>>А просто
Г>>
Г>>self.addClickListener(function(){doSomething useful})
Г>>


Г>>- это ваще некруто? Безо всякого доп.синтаксиса.


CS>Это работает если в твоей системе есть predefined set событий. В h-smile core набор событий расширяемый — behaviors могут генерировать свои собственные события. Т.е. все возможные случаи просто неизвестны. И во вторых события есть bubbling сущность — контейнер получает скажем Event.BUTTON_CLICK события от всех кнопок которые у него внутри. Типичный обработчик выглядит так:


[зверьковыгрызено]

Делаю так:

element.on_button_click do ... #predefined событие

element.on_behavior_event(:mycoolevent) do ... #не predefined событие :mycoolevent

#делаем так:
Hipster::Dom::Element.define_event(:mycoolevent, :cool_event)

#после этого работает такое:
element.on_cool_event do ... #TADA!

#а равно и:
element.on_cool_event('button#coolid') do ... #TADA!


Ни одной дополнительной конструкции в язык Никаких вопросов "а почему @when ... @on ...? а @when ... @where ... @then ... можно?"

Декораторы — это хорошая штука именно для АОП (типа, "а теперь вызов всех методов этого класса логгировать в файл"). Зачем они тут сдались —

//ЗХ
Re[11]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 04.01.09 02:17
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ни одной дополнительной конструкции в язык Никаких вопросов "а почему @when ... @on ...? а @when ... @where ... @then ... можно?"


А>Декораторы — это хорошая штука именно для АОП (типа, "а теперь вызов всех методов этого класса логгировать в файл"). Зачем они тут сдались —


А>//ЗХ


Декораторы расширяют синтаксис JavaScript добавляя chained flat calls фичу, объявление:

@decor1 p11 p12 ... p1N @decor2 p21 p22 ... p2N @decor3 p31 p32 ... p3N function Foo(fp1 ... fpN ) { ... }


фактически транслируется в такую последовательность:

var Foo = @decor1 (p11, p12, ..., p1N, 
 @decor2 (p21, p22, ..., p2N, 
   @decor3 (p31, p32, ..., p3N, 
     function(fp1 ... fpN)
     {
       ... 
     }
)));


Т.е. декораторы не меняют идеологии/runtime языка, а являются сугубо syntax sugar.
Собственно декораторы это syntax islands в которых работает то что я называю flat syntax который используют
например Ruby. Имея в языке две системы можно получить преимущества двух систем.
Скажем можно встраивать в язык различные DSL имея при этом возможность использования классической С alike нотации.

Собственно пример с описаниями селекторов событий @when/@on и есть пример такого рода DSL — в данном случе event/selector definition mini language.

Да, можно конечно то же самое описать и в терминах чистого JS цепляя function references (или delegates) на controls, и часто это является более подходящим. Но хочется имееть более generic средство позволяющее решать задачи которые плохо описываются в терминах C/Java/JS curly syntax.

Эта самая C/Java/JS grammar удобная, надежная, эффективная(для парсинга) и проверенная конструкция. Есть разные варианты расширений её под декларативные нужды: Objective-C, С++ (templates), С# (attributes). Мне так кажется что мой способ наименнее интрузивный что ли...

В любом случае я эти decorators уже имплементировал. Будем посмотреть как народ воспримет это дело.
Re[12]: Декораторы?
От: Аноним  
Дата: 04.01.09 13:32
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, Аноним, Вы писали:


А>>Ни одной дополнительной конструкции в язык Никаких вопросов "а почему @when ... @on ...? а @when ... @where ... @then ... можно?"


А>>Декораторы — это хорошая штука именно для АОП (типа, "а теперь вызов всех методов этого класса логгировать в файл"). Зачем они тут сдались —


А>>//ЗХ


CS>Декораторы расширяют синтаксис JavaScript добавляя chained flat calls фичу, объявление:


[з.выгрызено]

CS>Т.е. декораторы не меняют идеологии/runtime языка, а являются сугубо syntax sugar.


Я знаю. А зачем они в описанной задаче — не знаю.

CS>Собственно декораторы это syntax islands в которых работает то что я называю flat syntax который используют

CS>например Ruby. Имея в языке две системы можно получить преимущества двух систем.
CS>Скажем можно встраивать в язык различные DSL имея при этом возможность использования классической С alike нотации.

Все, здесь я потерялся. Что такое "syntax islands", что ты называешь "flat syntax", какие две системы —

CS>Да, можно конечно то же самое описать и в терминах чистого JS цепляя function references (или delegates) на controls, и часто это является более подходящим. Но хочется имееть более generic средство позволяющее решать задачи которые плохо описываются в терминах C/Java/JS curly syntax.


А почему плохо описывается? То, что я показал на Руби, по-моему на JS переводится 1-в-1. Это плохой вариант? Неудобный или некрасивый?

CS>Эта самая C/Java/JS grammar удобная, надежная, эффективная(для парсинга) и проверенная конструкция. Есть разные варианты расширений её под декларативные нужды: Objective-C, С++ (templates), С# (attributes). Мне так кажется что мой способ наименнее интрузивный что ли...


CS>В любом случае я эти decorators уже имплементировал. Будем посмотреть как народ воспримет это дело.


Честно говоря, пока все это обсуждение мне напоминает легендарных "полупрозрачных изобретателей" ("Я нашел, как применить здесь нестирающиеся шины из полиструктурного волокна с вырожденными аминными связями и неполными кислородными группами. Но я не знаю пока, как использовать регенерирующий реактор на субтепловых нейтронах. Миша, Мишок! Как быть с реактором?"). Т.е. ты сделал в языке фичу, которая тебе просто душевно симпатична, и теперь пытаешься придумать, где она может быть полезна. Пока неубедительно
Re[13]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 04.01.09 18:41
Оценка:
Здравствуйте, Аноним, Вы писали:

CS>>Собственно декораторы это syntax islands в которых работает то что я называю flat syntax который используют

CS>>например Ruby. Имея в языке две системы можно получить преимущества двух систем.
CS>>Скажем можно встраивать в язык различные DSL имея при этом возможность использования классической С alike нотации.

А>Все, здесь я потерялся. Что такое "syntax islands", что ты называешь "flat syntax", какие две системы —


Две грамматики. Я же привел пример выше. Внутри декоратора имеет место быть синтаксис [вызова функций] принципиально отличный от С/Java.

CS>>Да, можно конечно то же самое описать и в терминах чистого JS цепляя function references (или delegates) на controls, и часто это является более подходящим. Но хочется имееть более generic средство позволяющее решать задачи которые плохо описываются в терминах C/Java/JS curly syntax.


А>А почему плохо описывается? То, что я показал на Руби, по-моему на JS переводится 1-в-1. Это плохой вариант? Неудобный или некрасивый?


С декораторами, да — переводится. Без — несколько более коряво.

Простейший случай (element опеределен где-то ещё):
element.on_button_click do ... #predefined событие

практически также
element.onClick = function() { ... } //predefined событие


Но в общем случае когда есть селектор кнопки и код который нужно исполнить получается так:

var element = self.select( selector ); if(!element) throw "element " + selector + " not found";
element.onClick = function() { <код который нужно исполнить> };


что есть несколько более noisy. Вариант:

@when Event.BUTTON_CLICK @on "selector": { <код который нужно исполнить> }


представляется более человеческим, нет?
Re[2]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 04.01.09 22:04
Оценка:
Здравствуйте, targeted, Вы писали:

CS>>А расскажите кто и как их полезно использует?


T>Для проверки сигнатур методов, совпадает ли тип параметра

T>или проходит какая-нибудь другая проверка при фактическом вызове.

T>Пример:


T>@typecheck

T>def bar(a: int, b: int) -> int:

T>@typecheck

T>def bar(self, filename: os_path.isfile, f: optional(callable) = None) -> list_of(str):

T>@typecheck

T>def str2int(x: by_regex("^[0-9]+$")) -> int:

T>@typecheck

T>def serialize(stream: with_attr("write", "flush") -> bool:

T>и т.д.


Однозначно круто.
Я правда не знаю Py до такой степени чтобы понять точно что тут написано. Но догадываюсь.

T>Реализация для Python 3.0 тут:

T>http://code.activestate.com/recipes/572161/
T>менее красивая версия для Python 2.x тут:
T>http://code.activestate.com/recipes/426123/

Вот мой вариант @params декоратора проверяющего тип параметров при вызове функции:

    // decorator '@params' - verification of parameters passed to the function
    function @params(param_types, func)
    {
      return function(params..)
      {
        if(params.length != param_types.length) throw "wrong number of parameters";
        var n = 0; for(var p in params)
          if(typeof p != param_types[n++]) 
            throw String.printf("parameter %d, expected %s but got %s", n, param_types[n-1], typeof p);
        return func.apply(this,params);
      }
    }


Используем так:

    @params [#integer,#integer]
    function SumInt(a,b)
    {
      return a + b;  
    }
    stdout << SumInt(2,2) << "\n"; // should pass
    stdout << SumInt(2,2.0) << "\n"; // should throw an error: "parameter 2, expected integer but got float"


Это конечно не проверка значений параметров как у тебя но добавить поддержку конструкций вида:

@params [#integer, :v: v != 0 ] // lambda function - parameter's value tester
function DivInt(a,b)
{
  return a / b;  
}
Re[14]: Декораторы?
От: Аноним  
Дата: 04.01.09 22:22
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>С декораторами, да — переводится. Без — несколько более коряво.


CS>Простейший случай (element опеределен где-то ещё):

CS>
CS>element.on_button_click do ... #predefined событие
CS>

CS>практически также
CS>
CS>element.onClick = function() { ... } //predefined событие
CS>


CS>Но в общем случае когда есть селектор кнопки и код который нужно исполнить получается так:


CS>
CS>var element = self.select( selector ); if(!element) throw "element " + selector + " not found";
CS>element.onClick = function() { <код который нужно исполнить> };
CS>


CS>что есть несколько более noisy.


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

Hipster.def_behavior('mycoolbehavior') do
  on_button_click do ...
end

#а потом просто <button behavior="~ mycoolbehavior"> в HTML 
#или [selector]{behavior: ~ mycoolbehavior;} в CSS

Т.е. ты же сам (в HTMLayout'е) предоставил вариант (через behaviors) чтобы обработчики событий вешались только тогда, когда нужны. Прекрасный декларативный вариант. Зачем велосипед-то???

CS> Вариант:


CS>
CS>@when Event.BUTTON_CLICK @on "selector": { <код который нужно исполнить> }
CS>


CS>представляется более человеческим, нет?


А чем же он человеческий, если вводится дополнительный новый синтаксис?

//ЗХ
Re[12]: Декораторы?
От: Andrey_Pilya  
Дата: 05.01.09 14:32
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Декораторы расширяют синтаксис JavaScript добавляя chained flat calls фичу, объявление:


CS>
CS>@decor1 p11 p12 ... p1N @decor2 p21 p22 ... p2N @decor3 p31 p32 ... p3N function Foo(fp1 ... fpN ) { ... }
CS>


я бы еще понял, если бы этот синтаксис прятался в комментарии, типа что бы сохранить обратную совместимость.
но раз уж вводятся новые конструкции, то зачем таким боком?
получается слишком много значков, сложный шифр и совсем не видно глазом, как его читать/понимать.
плюс, этот синтаксис крайне упрощен сугубо под одну задачу (как минимум, он декорирует только одну функцию,
а вот для "бутерброда" типа : {обработчик bubbling + обработчик sinking} уже прийдется приумывать...)

CS>фактически транслируется в такую последовательность:


CS>
CS>var Foo = @decor1 (p11, p12, ..., p1N, 
CS> @decor2 (p21, p22, ..., p2N, 
CS>   @decor3 (p31, p32, ..., p3N, 
CS>     function(fp1 ... fpN)
CS>     {
CS>       ... 
CS>     }
CS>)));      
CS>


почему бы так не писать сразу? зачем опускать скобки и делать код ограниченнее и сложнее?
в такой нотации, например, нет причин запрещать многократное появление слова "function"... (другой вопрос, что само по себе
оно уже не нужно, но свой пример нотации я уже приводил)

CS>Т.е. декораторы не меняют идеологии/runtime языка, а являются сугубо syntax sugar.

не runtime, а bottstrap-time. а может ли скрипт догружаться? тогда это будет уже runtime... и к тому же, почему бы не дать программисту инструментарий писать себе такие надстройки? не такие уж они толстые, если действуют только при разборе/компилляции.

CS>Собственно декораторы это syntax islands в которых работает то что я называю flat syntax который используют

CS>например Ruby. Имея в языке две системы можно получить преимущества двух систем.
CS>Скажем можно встраивать в язык различные DSL имея при этом возможность использования классической С alike нотации.

миф. что бы встраивать в язык DSL нужна не вторая нотация, а механизм эскейпинга двух одинаковых нотаций друг от друга (и от всего остального).
да, схем эскейпинга может быть несколько: Html от JS или JS от Html или JS от CSS или Meta-JS от JS....
Re[15]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 05.01.09 22:42
Оценка:
Здравствуйте, Аноним, Вы писали:


А>#а потом просто <button behavior="~ mycoolbehavior"> в HTML

А>#или [selector]{behavior: ~ mycoolbehavior;} в CSS
А>[/rb]
А>Т.е. ты же сам (в HTMLayout'е) предоставил вариант (через behaviors) чтобы обработчики событий вешались только тогда, когда нужны. Прекрасный декларативный вариант. Зачем велосипед-то???

Скажем у тебя есть некий компонент Coo который а) содержит некий DOM внутри и b) должен делать что-то по нажатии кнопки button#up которая является его частью.

Есть два места где можно цеплять обработчики событий: на саму кнопку или на сам компонент. Разница в том чему будет соответсвовать 'this'.
В этом случае:
  this.select("button#up").onClick = function() { this. ...  }


this будет самой кнопкой.

А в этом случае:

  this.onControlEvent = function(evt) 
  { 
    if(evt.target.match("button#up") && evt.type == Event.BUTTON_CLICK )
    {
      this.doFoo();
    } 
    else if(evt.target.match("button#down") && evt.type == Event.BUTTON_CLICK )
    {
      this.doBar();
    } 
  }


'this' будет уже самим контейнером. Ибо события bubble up.

Во втором случае как ты видишь получаем не сильно красивую картину.

Мне кажется что такая запись:

@when Event.BUTTON_CLICK @on "button#up" :: this.doFoo();
@when Event.BUTTON_CLICK @on "button#down" :: this.doBar();


более предпочтительна.

Можно конечно придумать некий dispatch() метод (без decorators):

  this.onControlEvent = function(evt) 
  { 
    this.dispatch
    (
      [
        { when: Event.BUTTON_CLICK, on: "button#up", #doFoo }, 
        { when: Event.BUTTON_CLICK, on: "button#down", #doBar }
      ]
    );
  }


но в этих скобках черт ногу сломит.
Re[16]: Декораторы?
От: Аноним  
Дата: 05.01.09 22:50
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, Аноним, Вы писали:



А>>#а потом просто <button behavior="~ mycoolbehavior"> в HTML

А>>#или [selector]{behavior: ~ mycoolbehavior;} в CSS
А>>[/rb]
А>>Т.е. ты же сам (в HTMLayout'е) предоставил вариант (через behaviors) чтобы обработчики событий вешались только тогда, когда нужны. Прекрасный декларативный вариант. Зачем велосипед-то???

CS>Скажем у тебя есть некий компонент Coo который а) содержит некий DOM внутри и b) должен делать что-то по нажатии кнопки button#up которая является его частью.


CS>Есть два места где можно цеплять обработчики событий: на саму кнопку или на сам компонент. Разница в том чему будет соответсвовать 'this'.

CS>В этом случае:
CS>
CS>  this.select("button#up").onClick = function() { this. ...  }
CS>


CS>this будет самой кнопкой.


CS>А в этом случае:


CS>
CS>  this.onControlEvent = function(evt) 
CS>  { 
CS>    if(evt.target.match("button#up") && evt.type == Event.BUTTON_CLICK )
CS>    {
CS>      this.doFoo();
CS>    } 
CS>    else if(evt.target.match("button#down") && evt.type == Event.BUTTON_CLICK )
CS>    {
CS>      this.doBar();
CS>    } 
CS>  }
CS>


CS>'this' будет уже самим контейнером. Ибо события bubble up.


Ну што за черт...

self.on_click('button#up') do |event|
  #self == контейнер
  #event.target == кнопка
end

self.on_click('button#down') do |event|
  #self == контейнер
  #event.target == другая кнопка
end

#или:
Hipster.def_behavior('coo'){
  on_click('button#up') do ... end
  on_click('button#down') do ... end
}


Ну в чем проблема-то?
Re: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 06.01.09 05:09
Оценка:
Здравствуйте, c-smile, Вы писали:

Вот такая загогулина еще нарисовалась. Объявление member variables в классах:

    class Bar
    {
      // all instances will have at least two fields: 'three' и 'four'
      @this { three:3, four:4 };  // ';' at the end designates an empty decorator
    }


Вот как это реализовано:

    // decorator '@this' - defines ctor that initializes instance by copying fields from proto object.
    //                     see sample below.     
    function @this(func, proto)
    {
      this[#this] = // define ctor in the class - function with name 'this'
        func ? 
          function(params..) { for(var n in proto) this[n] = proto[n]; func.apply(this,params); } 
        : function()         { for(var n in proto) this[n] = proto[n]; }
    }
    
    // testing it:
    
    class Foo
    {
      // Declaration of ctor plus two predefined fields for the instance. 
      // Notation is a bit unusual but works.
      
      @this { one:1, two:2 } :{} 
      // ^  ^                ^ 
      // |  |                | lambda function declaration (empty here) - body of the ctor. 
      // |  |
      // |  | object literal used for instance initialization
      // |
      // | name of our function-decorator (above).
    }

    class Bar
    {
      // Declaration of empty ctor - just predefined fields for the instance. 
      @this { three:3, four:4 };  // ';' at the end designates an empty decorator
    }
    
    var foo = new Foo();
    var bar = new Bar();

    stdout << foo.one << "\n"; // should print '1'
    stdout << foo.two << "\n"; // should print '2'

    //debug;    
    stdout << bar.three << "\n"; // should print '3'
    stdout << bar.four << "\n"; // should print '4'


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

    class Bar
    {
      function this { this.three = 3; this.four = 4; }
    }
Re[17]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 06.01.09 06:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ну што за черт...


А>
А>self.on_click('button#up') do |event|
А>  #self == контейнер
А>  #event.target == кнопка
А>end
А>


А>Ну в чем проблема-то?


Проблема состоит в синтаксисе JS (C,C++). Я уже об этом говорил. Вот имплементация твоего on_click на линейном JS

Element.on_click = function(selector, func) 
{
  var me = this;
  function thunk(evt)
  {
    if( evt.type == Event.BUTTON_CLICK && evt.target.match(selector) )
      func.call(me,evt);
    if( typeof thunk.next == #function ) thunk.next.call(me,evt);
  }
  thunk.next = this.onControlEvent;
  this.onControlEvent = thunk;
}


А вот как это будет использоваться (опять же на линейном JS):

self.on_click("button#up", function(evt) 
 {
   // 'this' here is self
   // evt.target - the button
 });


не так pretty как с Ruby. Как я уже сказал задача состоит в том чтобы дать JS возможность такие
штуки описывать менее curly.

@click : evt { 
  // 'this' here is self
  // evt.target - the button
} 
@click @on $(button#up) :
{   
  // 'this' here is self
}
Re[13]: Декораторы?
От: c-smile Канада http://terrainformatica.com
Дата: 06.01.09 06:57
Оценка:
Здравствуйте, Andrey_Pilya, Вы писали:

A_P>Здравствуйте, c-smile, Вы писали:


CS>>Декораторы расширяют синтаксис JavaScript добавляя chained flat calls фичу, объявление:


CS>>
CS>>@decor1 p11 p12 ... p1N @decor2 p21 p22 ... p2N @decor3 p31 p32 ... p3N function Foo(fp1 ... fpN ) { ... }
CS>>


A_P>я бы еще понял, если бы этот синтаксис прятался в комментарии, типа что бы сохранить обратную совместимость.

A_P>но раз уж вводятся новые конструкции, то зачем таким боком?
A_P>получается слишком много значков, сложный шифр и совсем не видно глазом, как его читать/понимать.
A_P>плюс, этот синтаксис крайне упрощен сугубо под одну задачу (как минимум, он декорирует только одну функцию,
A_P>а вот для "бутерброда" типа : {обработчик bubbling + обработчик sinking} уже прийдется приумывать...)

Ничего не надо придумывать. Вот пример того как на одну функцию (SumInt) цепляется два декоратора (precondition и postcondition):

    @params #integer #integer
    @returns #integer    
    function SumInt(a,b)
    {
      return a + b;  
    }


По-моему достаточно читабельно. Декораторы фактически образуют pipe: функция передается из одного декоратора в другой.
Декоратор может вставить свою прослойку (function call wrapper). Вот как это имплментировано в реале:
    // decorator '@params' - verification of parameters passed to the function
    function @params(func, param_types..)
    {
      return function(params..)
      {
        var n = 0;
        for(var p in params)
          if(typeof p != param_types[n++]) 
            throw String.printf("parameter %d, expected %s but got %s", n, param_types[n-1], typeof p);
        return func.apply(this,params);
      }
    }
    // decorator '@returns' - verification of returned value of the function
    function @returns(func, return_type)
    {
      return function(params..)
      {
        var rv = func.apply(this,params);
        if( typeof rv != return_type )
          throw String.printf("expected to return %s but got %s", return_type, typeof rv);
        return rv;
      }
    }


pipelining декораторов это фактически модель используемая Lisp. Здесь же она работатет в строго отведенном для того месте.


CS>>фактически транслируется в такую последовательность:


CS>>
CS>>var Foo = @decor1 (p11, p12, ..., p1N, 
CS>> @decor2 (p21, p22, ..., p2N, 
CS>>   @decor3 (p31, p32, ..., p3N, 
CS>>     function(fp1 ... fpN)
CS>>     {
CS>>       ... 
CS>>     }
CS>>)));      
CS>>


A_P>почему бы так не писать сразу? зачем опускать скобки и делать код ограниченнее и сложнее?

A_P>в такой нотации, например, нет причин запрещать многократное появление слова "function"... (другой вопрос, что само по себе
A_P>оно уже не нужно, но свой пример нотации я уже приводил)

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

CS>>Собственно декораторы это syntax islands в которых работает то что я называю flat syntax который используют

CS>>например Ruby. Имея в языке две системы можно получить преимущества двух систем.
CS>>Скажем можно встраивать в язык различные DSL имея при этом возможность использования классической С alike нотации.

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


Теоретически — наверное, практически — не ясно зачем встраивать сферческого вакуумного коня в его же но кубического.

A_P>да, схем эскейпинга может быть несколько: Html от JS или JS от Html или JS от CSS или Meta-JS от JS....


К сожалению задача надежного практического решения не имеет. К тому же без кооперации разных нотаций и невозможная в большинстве случаев.
Ну скажем в web/html она так и не решена.

<script>
  <!--
  document.write("</script>");
  -->
</script>


script здесь должен знать про "<!--" и "-->"

В PHP вообще напридумывали чертову силу всяких escapement'ов. Но надежного решения тоже нет.
Вот например такая загогулина:

<?php  // Html safe containers 

$myOutput = <<<MYHTMLSAFEOUTPUT 
<?xml version="1.0"?> 
<html> 
  <title>PHP Example</title> 
  <body> 
   <p>...all sorts goes here...</p> 
  </body> 
</html> 
MYHTMLSAFEOUTPUT; 

echo $myOutput; 
?>
Re[14]: Декораторы?
От: Andrey_Pilya  
Дата: 06.01.09 10:40
Оценка:
Здравствуйте, c-smile, Вы писали:
A_P>>я бы еще понял, если бы этот синтаксис прятался в комментарии, типа что бы сохранить обратную совместимость.
A_P>>но раз уж вводятся новые конструкции, то зачем таким боком?
A_P>>получается слишком много значков, сложный шифр и совсем не видно глазом, как его читать/понимать.
A_P>>плюс, этот синтаксис крайне упрощен сугубо под одну задачу (как минимум, он декорирует только одну функцию,
A_P>>а вот для "бутерброда" типа : {обработчик bubbling + обработчик sinking} уже прийдется приумывать...)

CS>Ничего не надо придумывать. Вот пример того как на одну функцию (SumInt) цепляется два декоратора (precondition и postcondition):


я говорю о декораторе, который декорирует 2 функции в один бутерброд, а не 2 декоратора на одну функцию

CS>По-моему достаточно читабельно. Декораторы фактически образуют pipe: функция передается из одного декоратора в другой.

CS>pipelining декораторов это фактически модель используемая Lisp. Здесь же она работатет в строго отведенном для того месте.

Pipeline — это просто вызов цепочки функций? которые друг дружке передают нечто.... это просто вызов цепочки функций

A_P>>почему бы так не писать сразу? зачем опускать скобки и делать код ограниченнее и сложнее?

A_P>>в такой нотации, например, нет причин запрещать многократное появление слова "function"... (другой вопрос, что само по себе
A_P>>оно уже не нужно, но свой пример нотации я уже приводил)

CS>Не каждый человек в состоянии эту красоту взглядом оценить т.е. понять. А это непонимание — перманентный источник ошибок.

...посмотрим, конечно, но кажется мне, что чем больше неявных вызовов и витиеватостей синтаксиса — тем больше непонимания,
того, что на самом деле происходит. выливается это в "копи-паст" программирование, с аргументацией: "не знаю что это, но вот тут работает". Со временем количество шаманских трюков переваливает за критическое и ошибки лезут фонтаном.

CS>script здесь должен знать про "<!--" и "-->"

потому, что и HTML и JS — это эгоистичные синтаксические извращения.
куда хуже обстоит дело, нужно писать код, который генерит JS, который генерит Html, который....
(и это не сферический конь, это библиотеки контролов и т.п.)

CS>В PHP вообще напридумывали чертову силу всяких escapement'ов. Но надежного решения тоже нет.

CS>Вот например такая загогулина:

CS>
CS><?php  // Html safe containers 

CS>$myOutput = <<<MYHTMLSAFEOUTPUT 
CS><?xml version="1.0"?> 
CS><html> 
CS>  <title>PHP Example</title> 
CS>  <body> 
CS>   <p>...all sorts goes here...</p> 
CS>  </body> 
CS></html> 
CS>MYHTMLSAFEOUTPUT; 

CS>echo $myOutput; 
CS>?> 
CS>


это они не придумали, это они списали (Sh или Perl, уж не знаю, кто там первый..)
а что делать, если хочется в плоский файл засунуть длиннючий кучок стороннего бреда? можно в нем все кавычки эскейпить, но это лениво
вот и придумали когда-то в юниксе "строку-терминатор".

...но сегодня этим пользоваться врядли стоит.
Re[18]: Декораторы?
От: Аноним  
Дата: 06.01.09 14:18
Оценка:
Здравствуйте, c-smile, Вы писали:

А>>Ну што за черт...


А>>
А>>self.on_click('button#up') do |event|
А>>  #self == контейнер
А>>  #event.target == кнопка
А>>end
А>>


CS>А вот как это будет использоваться (опять же на линейном JS):


CS>
CS>self.on_click("button#up", function(evt) 
CS> {
CS>   // 'this' here is self
CS>   // evt.target - the button
CS> });
CS>


CS>не так pretty как с Ruby. Как я уже сказал задача состоит в том чтобы дать JS возможность такие

CS>штуки описывать менее curly.

Дальше, мне кажется, уже чисто вопрос вкуса. По мне, пара лишних скобочков (я так понял, тебе не нравится исключительно "});" в конце), к тому же, привычных для всех жаваскриптеров (см. jQuery и все остальное в том же духе) — вполне приемлемый tradeoff. А новый, ни с чем не совместимый, кусок синтаксиса — не вполне приемлемый. Но это мое личное мнение.
Re[19]: Декораторы?
От: Аноним  
Дата: 06.01.09 14:29
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>Ну што за черт...


А>>>
А>>>self.on_click('button#up') do |event|
А>>>  #self == контейнер
А>>>  #event.target == кнопка
А>>>end
А>>>


CS>>А вот как это будет использоваться (опять же на линейном JS):


CS>>
CS>>self.on_click("button#up", function(evt) 
CS>> {
CS>>   // 'this' here is self
CS>>   // evt.target - the button
CS>> });
CS>>


CS>>не так pretty как с Ruby. Как я уже сказал задача состоит в том чтобы дать JS возможность такие

CS>>штуки описывать менее curly.

А>Дальше, мне кажется, уже чисто вопрос вкуса. По мне, пара лишних скобочков (я так понял, тебе не нравится исключительно "});" в конце), к тому же, привычных для всех жаваскриптеров (см. jQuery и все остальное в том же духе) — вполне приемлемый tradeoff. А новый, ни с чем не совместимый, кусок синтаксиса — не вполне приемлемый. Но это мое личное мнение.


Добавлю к этому, что ситуация вообще характерна. Ты как бы наследуешь TIScript от JS, но последний тебе не нравится, кажется несимпатичным и неизящным, и ты добавляешь в свой язык "нормальные классы" (игнорируя прототипно-ориентированное ООП), декораторы (игнорируя свойственный JS стиль мета-программирования) и т.п.

Результат, возможно, с твоей точки зрения позволяет "всякие прикольные штуки", но изящества и внутренней стройности у нее существенно меньше, чем у JS или же "your-favourite-language", если бы он создавался с нуля. Твоя любимая цитата про коня и трепетную лань кажется здесь вполне уместной
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.