Re[7]: Python: s/callback/generator/
От: palm mute  
Дата: 16.07.09 07:21
Оценка: +1
Здравствуйте, c-smile, Вы писали:

CS>Или вообще практически в одну строку:

CS>
CS>function linesOfResponse( cmd ) { var lines = []; 
CS>                                  retrlines(cmd, :line: lines.push(line) ); 
CS>                                  return lines; }

CS>for( var line in linesOfResponse( "LIST" ) )
CS>  stdout.printf("%s\n", line);
CS>


Буферизовать и отдавать по одной строке не проблема. Мне почему-то кажется, что автору темы не хотелось качать с ФТП-сервера больше, чем нужно.
Re[4]: Python: s/callback/generator/
От: neFormal Россия  
Дата: 16.07.09 10:13
Оценка: +1
Здравствуйте, c-smile, Вы писали:

CS>Сугубо для сравнения вот функция в TIScript которая итерирует все строки в файле path удовлетворяющих template


совсем не та задача..
читай из файла с колбэком.. чтобы каждая итерация дёргала кусок данных..
...coding for chaos...
Re[8]: Python: s/callback/generator/
От: c-smile Канада http://terrainformatica.com
Дата: 17.07.09 17:43
Оценка:
Здравствуйте, palm mute, Вы писали:

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


CS>>Или вообще практически в одну строку:

CS>>
CS>>function linesOfResponse( cmd ) { var lines = []; 
CS>>                                  retrlines(cmd, :line: lines.push(line) ); 
CS>>                                  return lines; }

CS>>for( var line in linesOfResponse( "LIST" ) )
CS>>  stdout.printf("%s\n", line);
CS>>


PM>Буферизовать и отдавать по одной строке не проблема. Мне почему-то кажется, что автору темы не хотелось качать с ФТП-сервера больше, чем нужно.


Ну во первых retrlines() по своей спецификации и так читает всё. Т.е. callback будет вызван для каждой
line. А во вторых если уже говорить про суть дела то я не вижу особой разницы в написании скажем так:

retrlines("LIST", :line:{  .... = line;...  });


и так

for( var line in responselines("LIST")) {  .... = line;...  }


Разница в основном сугубо синтаксическая.

А кстати интересно бы придумать синтаксис котрый бы позволил "разворачивать" такие вызовы....

Как-то так что-ли:

for(var line in retrlines("LIST",@)) 
   { ... = line;... }


что должно спродуцировать
retrlines("LIST", 
   function(line) { .... = line;...  }
);


Правда не ясно что делать с break; внутри такого цикла ...

Хммм... что-то в этом наверное есть... или нет?
Re[9]: Python: s/callback/generator/
От: Mr.Cat  
Дата: 17.07.09 18:49
Оценка:
Здравствуйте, c-smile, Вы писали:
CS>Разница в основном сугубо синтаксическая.
Т.е. ты предлагаешь прочитать все строки в список, а потом по нему пройтись? Это очевидное решение, но оно не подходит, если строк очень много.
Re[10]: Python: s/callback/generator/
От: c-smile Канада http://terrainformatica.com
Дата: 17.07.09 19:10
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

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

CS>>Разница в основном сугубо синтаксическая.
MC>Т.е. ты предлагаешь прочитать все строки в список, а потом по нему пройтись? Это очевидное решение, но оно не подходит, если строк очень много.

Ты ошибаешься.

Конструкция

retrlines("LIST", :line:{  .... = line;...  });


переводится на JS как

retrlines("LIST", function(line){  .... = line;...  } );


Т.е. строки читаются функцией retrlines() и отдаются в callback одна за одной.
Что есть штатный режим использования retrlines (в Python):

retrlines(self, cmd, callback=None) unbound ftplib.FTP method
Retrieve data in line mode. A new port is created for you.

Args:
cmd: A RETR, LIST, NLST, or MLSD command.
callback: An optional single parameter callable that is called
for each line with the trailing CRLF stripped.
[default: print_line()]

Returns:
The response code.


Я же просто предлагаю доработать как-то синтаксис чтобы вызов с использованием inline callback function declaration:
retrlines("LIST", 
     function(line)
     {  .... = line;...  } 
  );


*выглядел* как скажем:
for( var line in retrlines("LIST", @ ))
  {  .... = line;...  }


что сути в общем-то не меняет — сугубый синтаксический сахар. Но приятного вкуса.
Re[9]: Python: s/callback/generator/
От: palm mute  
Дата: 18.07.09 11:46
Оценка:
Здравствуйте, c-smile, Вы писали:

PM>>Буферизовать и отдавать по одной строке не проблема. Мне почему-то кажется, что автору темы не хотелось качать с ФТП-сервера больше, чем нужно.


CS>Ну во первых retrlines() по своей спецификации и так читает всё. Т.е. callback будет вызван для каждой

CS>line.

Так в том и фокус, что нормальные продолжения или корутины позволяют взять обычную функцию и превратить ее в генератор при помощи соответствующего callback'а. См. пример z00n, он решает поставленную задачу на Lua.
Re[11]: Python: s/callback/generator/
От: . Великобритания  
Дата: 18.07.09 13:24
Оценка:
c-smile wrote:

> переводится на JS как

> retrlines("LIST", function(line){ .... = line;... } );
Это всё не то. Код "for( var line in retrlines...)" привели для примера. Суть в том, что нам нужна самостоятельная сущность iterator, c которой удобнее работать.
Если код несколько сложнее, скажем что-то типа
iter = retrlines(ftp...)
l1 = iter.next()
if(l1 == 'a'):
  l2 = iter.next()
  l3 = iter.next()
  doSomething(l2, l3, iter)
else
  doSomething2(iter.next())

switch(iter.next())
...

Т.е. если нужно не просто перебирать строки, а читать их по порядку, и это происходит изнутри какого-то хитрого сложного алгоритма, то тупо переиначить код на использование callback не выйдет. А уж если нужно читать строки из нескольких итераторов сразу... брр:
iter1 = ...
iter2 = ...
try:
   doSomething(iter1.next(), iter2.next())
except StopIteration, e:
  ...

Как ты предлагаешь использовать тут callbacks?
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[10]: Python: s/callback/generator/
От: c-smile Канада http://terrainformatica.com
Дата: 18.07.09 18:05
Оценка:
Здравствуйте, palm mute, Вы писали:

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


PM>>>Буферизовать и отдавать по одной строке не проблема. Мне почему-то кажется, что автору темы не хотелось качать с ФТП-сервера больше, чем нужно.


CS>>Ну во первых retrlines() по своей спецификации и так читает всё. Т.е. callback будет вызван для каждой

CS>>line.

PM>Так в том и фокус, что нормальные продолжения или корутины позволяют взять обычную функцию и превратить ее в генератор при помощи соответствующего callback'а. См. пример z00n, он решает поставленную задачу на Lua.


Ну как сказать... использовать coroutine для перебора элементов некоего stream это себя не любить.

corouitine это отдельный stack. Имплементация оных (corroutines) и в Lua и в Python (generators/yield) выполнена как т.н. называемые "green" thread (a.k.a. cooperative threads, a.k.a. fibers).

В принципе green thread значительно легче чем OS thread но тем не менее это не самая простая операция.
Re[12]: Python: s/callback/generator/
От: c-smile Канада http://terrainformatica.com
Дата: 18.07.09 19:30
Оценка:
Здравствуйте, ., Вы писали:

.>c-smile wrote:


>> переводится на JS как

>> retrlines("LIST", function(line){ .... = line;... } );
.>Это всё не то. Код "for( var line in retrlines...)" привели для примера. Суть в том, что нам нужна самостоятельная сущность iterator, c которой удобнее работать.

Роман задал конкретный вопрос который можно сформулировать след. образом:

Как трансформировать delegated-iteration в inline-iteration.

Пусть iB это блок кода который нужно выполнить на каждой итерации.
Тогда логику итерации для delegated-iteration можно описать как F(iB(el))
а inline-iteration соответственно вот это (el=F(),iB(el)).

Разница между этими двумя логически эквивалентными способами итерации
состоит в структуре стека (ну или последовательности вызовов):

F(iB(el)) на стеке лежит F frame а затем iB frame.
el=F(),iB(el) — F и iB frames появляются на стеке попеременно.

.>Если код несколько сложнее, скажем что-то типа

.>
.>iter = retrlines(ftp...)
.>l1 = iter.next()
.>if(l1 == 'a'):
.>  l2 = iter.next()
.>  l3 = iter.next()
.>  doSomething(l2, l3, iter)
.>else
.>  doSomething2(iter.next())

Есть два способа:
1) переделать саму функцию retrlines чтобы действительно можно было писать вот так:
[code]
 iter = retrlines()
 l1 = iter.next()

т.е. она должна возвращать итератор (т.е. ссылку на функцию getNextValue())
а не делать итерацию на своем стеке.

либо при сохранении текущей сигнатуры retrlines использовать способ brute force (2):
загоняем retrlines в отдельный thread и подсовываем в качестве callback функцию делающую
context switch на каждой итерации. Это то что делает coroutine.wrap в LUA.
Очевидно что это не есть самый эффективный способ рвать зубы.

Что-то мне говорит что есть еще пара способов такой трансформации ... думать надо короче.


















.>switch(iter.next())

.>...
.>[/code]
.>Т.е. если нужно не просто перебирать строки, а читать их по порядку, и это происходит изнутри какого-то хитрого сложного алгоритма, то тупо переиначить код на использование callback не выйдет. А уж если нужно читать строки из нескольких итераторов сразу... брр:
.>
.>iter1 = ...
.>iter2 = ...
.>try:
.>   doSomething(iter1.next(), iter2.next())
.>except StopIteration, e:
.>  ...
.>

.>Как ты предлагаешь использовать тут callbacks?
Re[11]: Python: s/callback/generator/
От: z00n  
Дата: 18.07.09 21:41
Оценка: 54 (3)
Здравствуйте, c-smile, Вы писали:

CS>Ну как сказать... использовать coroutine для перебора элементов некоего stream это себя не любить.

Здесь начинается ваше заблуждение.

CS>corouitine это отдельный stack. Имплементация оных (corroutines) и в Lua и в Python (generators/yield) выполнена как т.н. называемые "green" thread (a.k.a. cooperative threads, a.k.a. fibers).

CS>В принципе green thread значительно легче чем OS thread но тем не менее это не самая простая операция.
Еrlang, Lua, Stackless Python, Limbo и.т.д используют VM threads — они очень дешевые ~600-1000 байт на поток, а скорость переключения контекста соизмерима со скоростью вызова функции. Хорошая реализация продолжений (как в Chez) будет не хуже.
Т.е. для луа цена вопроса: создание потока — ~300 ns, переключение ~100ns + 1K на стек (ns — это 10e-9 sec). Stackless по моим замерам аналогичен по скорости. Limbo в пару раз быстрее, но он статически типизирован.

По поводу структурирования программ посредством микропотоков и передачи сообщений — есть интересная лекция того самого Роба Пайка. Сейчас он работает в Google — разрабатывает для них секретный язык Sawzall. Речь там идет о предтече Limbo, языке Newsqueak.

Video: Advanced Topics in Programming Languages: Concurrency/message passing Newsqueak by Pob Pike

PDF: The Implementation of Newsqueak
Re[13]: Python: s/callback/generator/
От: . Великобритания  
Дата: 18.07.09 22:49
Оценка:
c-smile wrote:

> Роман задал конкретный вопрос который можно сформулировать след. образом:

>
> Как трансформировать delegated-iteration в inline-iteration.
Ладно, может я не так понял. Но если это правда об этом, т.е. синтаксическое "преобразование", то неинтересно. А вот когда кто-то упомянул корутины — стало интересней.

> загоняем retrlines в отдельный thread и подсовываем в качестве callback

> функцию делающую
> context switch на каждой итерации. Это то что делает coroutine.wrap в LUA.
> Очевидно что это не есть самый эффективный способ рвать зубы.
Как я понимаю, в LUA корутины использую cooperative threads, что сильно упрощает жизнь — не надо использовать локи, нет никакого параллельного выполнения, системных вызовов. Просто переключаются стеки, context не такой страшный — если я правильно понимаю — указатель на текущий стек. А в более других языках это делается ещё проще.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[12]: Python: s/callback/generator/
От: c-smile Канада http://terrainformatica.com
Дата: 19.07.09 06:55
Оценка:
Здравствуйте, z00n, Вы писали:

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


CS>>Ну как сказать... использовать coroutine для перебора элементов некоего stream это себя не любить.

Z>Здесь начинается ваше заблуждение.

Вполне возможно. Я просто сам в поисках оптимального решения поэтому может и смотрю "искоса низко голову наклоня".

CS>>corouitine это отдельный stack. Имплементация оных (corroutines) и в Lua и в Python (generators/yield) выполнена как т.н. называемые "green" thread (a.k.a. cooperative threads, a.k.a. fibers).

CS>>В принципе green thread значительно легче чем OS thread но тем не менее это не самая простая операция.
Z>Еrlang, Lua, Stackless Python, Limbo и.т.д используют VM threads — они очень дешевые ~600-1000 байт на поток, а скорость переключения контекста соизмерима со скоростью вызова функции. Хорошая реализация продолжений (как в Chez) будет не хуже.

Память и количество опреаций на переключение это не единственные ограничения.
Есть еще косвенная доп. нагрузка на GC например.

Z>Т.е. для луа цена вопроса: создание потока — ~300 ns, переключение ~100ns + 1K на стек (ns — это 10e-9 sec). Stackless по моим замерам аналогичен по скорости. Limbo в пару раз быстрее, но он статически типизирован.


Времена в абсолютном значении мало что говорят. Нужны относительные цифири.

Переключение кстати может быть вообще нулевым — вернее равным вызову функции в C.
coroutine (или generator в терминах Python) должна получить stack некоего размера в начале исполнения — 1k это хорошо, но
может потребоваться dynamic resize оного в runtime. Тоже что-то стоит.

Возвращаясь к исходной задаче идеальным наверное является рефакторинг самого метода retrlines
или использование оной как есть т.е. без ненужной for-in beautification.

Z>По поводу структурирования программ посредством микропотоков и передачи сообщений — есть интересная лекция того самого Роба Пайка. Сейчас он работает в Google — разрабатывает для них секретный язык Sawzall. Речь там идет о предтече Limbo, языке Newsqueak.


Z>Video: Advanced Topics in Programming Languages: Concurrency/message passing Newsqueak by Pob Pike


Это действительно интересно. Странно, как-то раньше это прошло мимо меня. Спасибо.
Но кстати как я понимаю эффективной имплементации этого дела так и нет.
Интерпретация UI модели конечно интересная, но в реалии требуется concurrent multitasking что в общем-то
так на так выходит. Ну и в принципе messaging используемый в GUI это и есть те самые channels.
Отказ от примитивов синхронизации в пользу messages — в этом действительно что-то есть как представляется.
Re[13]: Python: s/callback/generator/
От: z00n  
Дата: 19.07.09 09:45
Оценка: 8 (1)
Здравствуйте, c-smile, Вы писали:

CS>Память и количество опреаций на переключение это не единственные ограничения.

CS>Есть еще косвенная доп. нагрузка на GC например.

Z>>Т.е. для луа цена вопроса: создание потока — ~300 ns, переключение ~100ns + 1K на стек (ns — это 10e-9 sec). Stackless по моим замерам аналогичен по скорости. Limbo в пару раз быстрее, но он статически типизирован.


CS>Времена в абсолютном значении мало что говорят. Нужны относительные цифири.


CS>Переключение кстати может быть вообще нулевым — вернее равным вызову функции в C.

CS>coroutine (или generator в терминах Python) должна получить stack некоего размера в начале исполнения — 1k это хорошо, но
CS>может потребоваться dynamic resize оного в runtime. Тоже что-то стоит.

Можно потестировать что-то конктретное.


Z>>По поводу структурирования программ посредством микропотоков и передачи сообщений — есть интересная лекция того самого Роба Пайка.

CS>Это действительно интересно. Странно, как-то раньше это прошло мимо меня. Спасибо.
CS>Но кстати как я понимаю эффективной имплементации этого дела так и нет.

Это встроенные системные фичи обеих post-UNIX операционных систем от Bell Labs — Plan 9 и Inferno. В Plan 9 это библиотека libthreads (ее можно покрутить под линуксом в составе plan9port). На ней, в частности написан оконный менеджер.
Inferno — это OS постоенная поверх виртуальной машины Limbo — работает на голом железе или поверх эмулятора на полудюжине архитектур. Я ее в режиме эмуляции гонял под XP — у нее jit и работает очень шустро.
исходники: http://code.google.com/p/inferno-os/
урезанная Inferno c интерфейсом из Acme: http://code.google.com/p/acme-sac/
бинарники: http://www.vitanuova.com/inferno/net_download4T.html
русские фанаты http://habrahabr.ru/blogs/os_inferno/

CS>Интерпретация UI модели конечно интересная, но в реалии требуется concurrent multitasking что в общем-то так на так выходит.

Ну, в вышепреведенном списке языков потоки кооперативные только у Lua, у Stackless можно и так и этак, у Limbo и Erlang — concurrent. На скорость это практически не влияет.
Re[5]: Python: s/callback/generator/
От: achmed Удмуртия https://www.linkedin.com/in/nail-achmedzhanov-9907188/
Дата: 28.07.09 20:53
Оценка:
Здравствуйте, palm mute, Вы писали:

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


SH>>Это всё-таки не вполне полноценные корутины, насколько я понимаю. Питоновская корутина должна возвращать итератор, т.е. объект с предопределённым интерфейсом, у него потом можно вызывать функцию next, а в конце он выбросит исключение. Для возвращаемого значения тут места нет.

PM>Неполноценность питоновских генераторов в другом — ограниченность контекста одной процедурой, тем хорошо раскрыта в Lua wiki.

Интересная ссылка. Всегда обделял Lua вниманием, видимо зря .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.