Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.11.25;
Скачать: [xml.tar.bz2];

Вниз

Yield средствами Delphi. За и против.   Найти похожие ветки 

 
oxffff ©   (2007-10-15 20:14) [0]

В C# есть такая конструкия Yield.
Я подумал, а почему бы нам собственно не реализовать тоже самое в Delphi.  
Итак сейчас например если вам необходимо формировать набор по запросу, то это вполне реально и синтаксис аналогичен yield C#.
Что это из себя представляет. Небольшой ASM код

Что есть сейчас

Корректное финализация локальных параметров
Сохранение и восстановление контекста последнего вызова.
Подстраивание регистра EBP при смене положения в стеке.

Чего пока нет

Осталось доделать подстраивание SEH фрейма при Yield, естественно с подстройкой при смене положения. Чтобы при исключении вызывался не внутренний финализатор.

Пример использования.

number,exponent,counter,Res:integer;
begin
for i := 1 to 10 do Yield(i);
Yield(11);
Yield(24);
for i := 1 to 10 do Yield(trunc(sin(i)));
Yield(15);
g:=1;
for i := 1 to 10 do
  begin
  g:=trunc(sin(i));
  Yield(trunc(g*cos(i*2)));
  end;
Yield(g+10);
number:=2;
exponent:=8;
counter:= 1;
Res:=1;
while counter<exponent do
begin
Res:=Res*number;
Yield(Res);
inc(counter);
end;
end;


 
aesma   (2007-10-15 20:16) [1]

А что это за yeld, объясни пожалуйста.


 
oxffff ©   (2007-10-15 20:18) [2]

Упрощенный пример. Самое главное посмотри на последовательность вывода сообщения.

 public static IEnumerable Power(int number, int exponent)
  {
     yield return 1;
     Console.Write("We are here ", i);
     yield return 2;
    Console.Write("We are here Again", i);
     yield return 3;
 }

  static void Main()
  {
      // Display powers of 2 up to the exponent 8:
      foreach (int i in Power(2, 8))
      {
          Console.Write("{0} ", i);
      }
  }

На экране будет следующая последовательность
1                         <- Это выводиться из Main
We are here         <- Это выводиться из Power!!!!!!!!
2                         <- Это выводиться из Main
We are here Again <- Это выводиться из Power!!!!!!!!
3                          <- Это выводиться из Main


 
oxffff ©   (2007-10-15 20:21) [3]

Чтобы особо не понятливые не задавали вопросы по типу
"Зачем? Все можно сделать и так".

Сразу контр пример для них

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

procedure TYieldObject.YieldUseProc;
var i,g:integer;
  number,exponent,counter,Res:integer;
begin
for i := 1 to 10 do Yield(i);
Yield(11);
Yield(24);
for i := 1 to 10 do Yield(trunc(sin(i)));
Yield(15);
g:=1;
for i := 1 to 10 do
  begin
  g:=trunc(sin(i));
  Yield(trunc(g*cos(i*2)));
  end;
Yield(g+10);
number:=2;
exponent:=8;
counter:= 1;
Res:=1;
while counter<exponent do
begin
Res:=Res*number;
Yield(Res);
inc(counter);
end;
end;


 
Prohodil Mimo ©   (2007-10-15 20:25) [4]

повторите пожалуйста, я не успел записать.


 
oxffff ©   (2007-10-15 20:28) [5]

Прошу высказывать свое мнение аргументированно.
Аргументы здесь:
-размер кода
-скорость его исполнения.


 
vpbar ©   (2007-10-15 20:34) [6]

Очень любопытно было бы код посмотреть. Или это комерческая тайна?


 
oxffff ©   (2007-10-15 20:36) [7]


> Очень любопытно было бы код посмотреть. Или это комерческая
> тайна?


Он есть. Это секрет. Черновой вариант.
http://delphimaster.net/view/15-1192221654/
[47]


 
aesma   (2007-10-15 20:37) [8]

На мой взгляд, так несколько красивее.


(define return-several-numbers
..(lambda ()
.....(values 1 2 3 4)))

(define main
..(lambda x
....(for-each (lambda (a)    
.................(printf "~A~%" a)) x)))

(call-with-values return-several-numbers main)


Как считаете?


 
oxffff ©   (2007-10-15 20:38) [9]


> Как считаете?


oxffff ©   (15.10.07 20:21) [3]


 
oxffff ©   (2007-10-15 20:41) [10]


> Он есть. Это секрет. Черновой вариант.

Не секрет конечно. :)


 
vpbar ©   (2007-10-15 20:42) [11]

oxffff ©   (15.10.07 20:36) [7]
хм. Интересная идея. Надо попробовать


 
aesma   (2007-10-15 20:46) [12]

oxffff ©   (15.10.07 20:21) [3]

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


 
oxffff ©   (2007-10-15 20:49) [13]


> aesma   (15.10.07 20:46) [12]


Все элементы формируются по запросу.
Функция не возвращает набор сразу. А каждый следующий элемент динамически вычисляется при запросе. :)


 
aesma   (2007-10-15 20:50) [14]

>Все элементы формируются по запросу.

Это как?


 
oxffff ©   (2007-10-15 20:53) [15]


> Это как?


Надо еще раз посмотреть oxffff ©   (15.10.07 20:18) [2].
Посмотреть внимательно комментарии, когда, что и откуда выводится


 
aesma   (2007-10-15 21:26) [16]

а, ну это известная проблема

(define-macro coroutine
 (lambda (x . body)
   `(letrec ((+local-control-state
              (lambda (,x) ,@body))
             (resume
              (lambda (c v)
                (call/cc
                 (lambda (k)
                   (set! +local-control-state k)
                   (c v))))))
      (lambda (v)
        (+local-control-state v)))))

(define main
 (coroutine prtr
   (resume prtr 1)
   (printf "We are here~%")
   (resume prtr 2)
   (printf "Being there~%")
   (resume prtr 3)))

(main (lambda (a)
         (printf "~A~%" a)))


 
tesseract ©   (2007-10-15 21:39) [17]


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


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


 
oxffff ©   (2007-10-15 22:24) [18]


> aesma   (15.10.07 21:26) [16]
> а, ну это известная проблема
>
> (define-macro coroutine
>  (lambda (x . body)
>    `(letrec ((+local-control-state
>               (lambda (,x) ,@body))
>              (resume
>               (lambda (c v)
>                 (call/cc
>                  (lambda (k)
>                    (set! +local-control-state k)
>                    (c v))))))
>       (lambda (v)
>         (+local-control-state v)))))
>
> (define main
>  (coroutine prtr
>    (resume prtr 1)
>    (printf "We are here~%")
>    (resume prtr 2)
>    (printf "Being there~%")
>    (resume prtr 3)))
>
> (main (lambda (a)
>          (printf "~A~%" a)))


А теперь все это привяжи к for-each.
И сделай полный пример  [3].


 
oxffff ©   (2007-10-15 22:28) [19]


> tesseract ©   (15.10.07 21:39) [17]
>
> > Посмотреть внимательно комментарии, когда, что и откуда
>
> > выводится
>
>
> Чем не нравиться те же абстрактные классы - управляемый
> код это круто, но вот его применение больше проблем вызывает.
>


Во первых где ты увидел управляемый код?

Во вторых, чем тебе помогут абстрактные классы, чтобы код который ты будешь писать с помощью абстрактные классов был короче чем в oxffff ©   (15.10.07 20:21) [3].
И делал бы тоже самое.

Ждем от тебя примера хотя бы части реализации [3]

procedure TYieldObject.YieldUseProc;
var i,g:integer;
 number,exponent,counter,Res:integer;
begin
for i := 1 to 10 do Yield(i);
Yield(11);
Yield(24);
for i := 1 to 10 do Yield(trunc(sin(i)));
Yield(15);
g:=1;
for i := 1 to 10 do
 begin
 g:=trunc(sin(i));
 Yield(trunc(g*cos(i*2)));
 end;
Yield(g+10);
end;


 
alex_*** ©   (2007-10-15 22:47) [20]

типа наш ответ Чемберлену?


 
aesma   (2007-10-16 09:17) [21]

oxffff ©   (15.10.07 22:24) [18]


> А теперь все это привяжи к for-each.
> И сделай полный пример  [3].


Мне лень, но если вы поищите, то можете найти реализацию yeld и на ленивых потоках (чем в сущности является функция для ее пользователя) и на континуациях (что происходит внутри).


 
Игорь Шевченко ©   (2007-10-16 09:26) [22]

"На углу двое юношей возились с каким-то
механическим устройством. Один убежденно говорил: "Конструкторская мысль
не может стоять на месте. Это закон развития общества. Мы изобретем его.
Обязательно изобретем. Вопреки бюрократам вроде Чинушина и консерваторам
вроде  Твердолобова".  Другой  юноша нес свое:  "Я нашел,  как применить
здесь нестирающиеся шины  из  полиструктурного  волокна  с  вырожденными
аминными  связями и неполными кислородными группами.  Но я не знаю пока,
как использовать регенерирующий реактор на субтепловых нейтронах.  Миша, Мишок!  Как быть с реактором?""

(с) Понедельник начинается в субботу


 
Суслик   (2007-10-16 10:50) [23]

Сергей, я все же выступаю за то, что yield вполне можно заменить штатными средствами. Не первой необходимости данная фича. ИМХО.


 
Dmitry S ©   (2007-10-16 14:21) [24]

Фииигня какая-то. Особенно после прочтения http://rsdn.ru/?Info/Howtoask.xml .


 
Сусл ©   (2007-10-16 14:40) [25]


> Фииигня какая-то. Особенно после прочтения http://rsdn.ru/?Info/Howtoask.xml
> .

это то здесь при чем, уважаемый.


 
KSergey ©   (2007-10-16 14:49) [26]

> oxffff ©   (15.10.07 20:18) [2]

Вот снова смотрю на этот пример  и та же мысль меня посещает: странное все же мышление у индусов.
Взяли, вывернули цикл и вызываемый из него callback ровно наизнанку, приумали под это дело конструкцию языка - и тихо тащятся... Зачем?
ну да ладно, видимо мое мышление слишком костное (впрочем, уже убеждался в этом в попытках понять boost"овское метапрограммирование)


 
Dmitry S ©   (2007-10-16 14:50) [27]


> Сусл ©   (16.10.07 14:40) [25]

Почему что ни смысла ни сути.
Не все имели дело с C#, и не все знают что такое Yield. Если автор хочет обсудить проблему создания этого самого в Delphi, почему бы ему не объяснить, что такое это самое?


 
atruhin ©   (2007-10-16 15:56) [28]

В принципе может быть удобно при синтаксическом анализе. По сравнению с callack,
не нужно запоминать текущее состояние в одной из процедур.


 
KSergey ©   (2007-10-16 16:05) [29]

> Dmitry S ©   (16.10.07 14:50) [27]
> Если автор хочет обсудить проблему создания этого самого
> в Delphi, почему бы ему не объяснить, что такое это самое?

Пост номер два внимательно прочитан?


 
KSergey ©   (2007-10-16 16:09) [30]

> atruhin ©   (16.10.07 15:56) [28]
> В принципе может быть удобно при синтаксическом анализе.
>  По сравнению с callack,
> не нужно запоминать текущее состояние в одной из процедур.

Хм, мне виделось, что это происходит автоматически, на стеке...
Или имеется в виду сохранение некоего состояния callback между вызовами?
К стати, может в этом и есть фишка сего действа - в отпадании необходимоси передавать некие данные в нутрь callback сквозь вызывающую callback функцию?
Надо будет какой-нибудь реальный пример попробовать завернуть в это дело.


 
DiamondShark ©   (2007-10-16 16:54) [31]

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

Как говорил Пузатый Пасюк: "Коли нужно чорта, то и ступай к чорту".

Если нужно вычислять элементы на лету по запросу, то и вычисляй их внутри IEnumerator.MoveNext().


 
oxffff ©   (2007-10-16 19:14) [32]


> KSergey ©   (16.10.07 16:09) [30]
> > atruhin ©   (16.10.07 15:56) [28]
> > В принципе может быть удобно при синтаксическом анализе.
>
> >  По сравнению с callack,
> > не нужно запоминать текущее состояние в одной из процедур.
>
>
> Хм, мне виделось, что это происходит автоматически, на стеке.
> ..
> Или имеется в виду сохранение некоего состояния callback
> между вызовами?
> К стати, может в этом и есть фишка сего действа - в отпадании
> необходимоси передавать некие данные в нутрь callback сквозь
> вызывающую callback функцию?
> Надо будет какой-нибудь реальный пример попробовать завернуть
> в это дело.


Здесь есть ссылка на мой черновой, но рабочий исходник.
Быть может попробовать реализовать [3] обычном способом на лету. И тогда наконец оценить назначение конструкции.

:)


 
tesseract ©   (2007-10-16 21:19) [33]


>  Быть может попробовать реализовать [3] обычном способом
> на лету. И тогда наконец оценить назначение конструкции.
>


Ты нормальный пример проведи -  в этом копаться лень. От всяких хитропоставленных с-шных штучек и так тошнит. Я вот сам на измену подсел - этот твой елд-метр кроме счётчика входа в функцию другую нагрузку несёт ?


 
oxffff ©   (2007-10-16 21:48) [34]


> Ты нормальный пример проведи -  в этом копаться лень. От
> всяких хитропоставленных с-шных штучек и так тошнит. Я вот
> сам на измену подсел - этот твой елд-метр кроме счётчика
> входа в функцию другую нагрузку несёт ?


В твоем вопросе есть ответ.

>в этом копаться лень

Вот если ты будешь использовать как ты сказал абстрактные классы, то усилий ты затратишь больше, при той же функциональности.

> Я вот сам на измену подсел - этот твой елд-метр кроме счётчика входа в >функцию другую нагрузку несёт ?

Я ссылку на исходники дал, может тебе стоит глянуть.

Ты кстати не ответил на oxffff ©   (15.10.07 22:28) [19]


 
tesseract ©   (2007-10-16 21:58) [35]


> Ты кстати не ответил на oxffff ©   (15.10.07 22:28) [19]


Ты говоришь, что это быстрее  Напиши мне как мне быстрее внести в код класс обработки, ну например поля в  БД decimal 5.4 без переписывания пары тысяч строк кода ?


 
oxffff ©   (2007-10-16 22:44) [36]


> tesseract ©   (16.10.07 21:58) [35]
>
> > Ты кстати не ответил на oxffff ©   (15.10.07 22:28) [19]
>
>
> Ты говоришь, что это быстрее  Напиши мне как мне быстрее
> внести в код класс обработки, ну например поля в  БД decimal
> 5.4 без переписывания пары тысяч строк кода ?


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

поэтому давай свои абстрактные классы в студию.

Причем здесь базы данных.
Ты что хочешь переписать СУБД. Зачем?
Есть реляционная алгебра. Там не нужен Yield.
Во-первых субд возвращает готовый, конечный набор данных, кол-во в наборе известно, и элемент данных вычисляется по законам реляционной алгебры, т.е. фактически он один (способ вычисления).


 
tesseract ©   (2007-10-16 23:00) [37]


> поэтому давай свои абстрактные классы в студию.


Смотрим иерархию Tfield  с потомками, и то что его запросы запросто выясняться на этапе компиляции тоже.


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


Гм, c SQL работал  ? там ссылочная целостность частенько разваливаеться. И вот как раз Tfield при грамотном использовании - сильно нервы сбережёт. А я вот в классе написанном за три года до AV - могу предсказать результат твоего елд ? (ну так и хочеться дописать до общенародного).


 
oxffff ©   (2007-10-16 23:20) [38]


> tesseract ©   (16.10.07 23:00) [37]


Читать еще раз тему до просветвления.
Каким боком обертка для типа поля относиться к самому способу извлечения данных СУБД.
Может все таки тебе обратиться и перечитать Дейта?

Tfield - что формирует элемент данных? Это всего лишь обертка.

>Гм, c SQL работал ?

А что это такое? Марка автомобиля? Нет наверно фирма по производству утюгов. Точно это она.

У меня лично сложилось впечатление что тебе нужно еще раз перечитать Дейта

>там ссылочная целостность частенько разваливаеться.  

особенно после этих слов.
Вообщем тебе срочно читать про НФБК и выше и срочно править кривые тригеры.

Вообщем теперь по теме.
Пока ты не пересмотришь свой способ мышления, ты не поймешь преимущества и недостатки yield.

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


 
pasha_golub ©   (2007-10-17 11:12) [39]


> oxffff ©   (16.10.07 23:20) [38]


> Читать еще раз тему до просветвления.

Не надо сыпать такими фразами. Они только отталкивают. Пример реальный и нужный у вас есть? Или только вычисление, хрен пойми с какого бодуна, косинусов с ShowMessage"ами?

А также что по поводу сказанного:

> DiamondShark ©   (16.10.07 16:54) [31]
> Если нужно вычислять элементы на лету по запросу, то и вычисляй
> их внутри IEnumerator.MoveNext().


 
KSergey ©   (2007-10-17 11:36) [40]

> oxffff ©   (16.10.07 19:14) [32]
> Быть может попробовать реализовать [3] обычном способом
> на лету. И тогда наконец оценить назначение конструкции.

Я посмотрел oxffff ©   (15.10.07 20:18) [2]
Решил, что понимаю как работает эта конструкция (к стати, нафиг тама столько неиспользуемых аргументов?? может при их использовании было бы немного понятнее про бонусы?).
Посмотрел на [3]. Вижу что, по сути, есть некая функция, которая вызывает из себя некую другую функцию Yield() (да да, именно такую реализацию этого геморроя я вижу!). В эту самую Yield() вполне можно перенести тело  foreach, при этом она вызывается как раз непосредственно когда надо. Вижу только одну проблему ее реализации, когда хочется хранить значения неких перменных от вызова к вызову этой функции - вот и все. Но и эта проблема - легко решаема более или менее изящно.

Так нафига по большому счету?


 
Сусл ©   (2007-10-17 12:02) [41]


>  [39] pasha_golub ©   (17.10.07 11:12)
> > oxffff ©   (16.10.07 23:20) [38]
> > Читать еще раз тему до просветвления.
> Не надо сыпать такими фразами. Они только отталкивают


+3 (т.е. сильно поддерживаю).


 
oxffff ©   (2007-10-17 12:06) [42]

pasha_golub ©   (17.10.07 11:12) [39]
KSergey ©   (17.10.07 11:36) [40]

А если например для расчета используетяс не один, а два алгоритма или 10 алгоритмов. А алгоритмы могут сочетаться.
Поэтому я привожу пример имеено не тривиально алгоритма элементов.

В случае реализации вычисление в MoveNext стандартными способами
самое главное вам придется "разобрать алгоритм" вычленив оттуда состояние и указатель на следующий алгоритм вычисления и сохранив все это полях объекта. Повторяю, что это можно сделать.
Но это будет трудоемко при разном способе вычислениии алгоритма. Представьте если эти способы могут сочетаться.

В С# ввели эту конструкцию на уровне компилятора в IL.

Скоро от меня будет более менее детальное описание работы. Правда на английском. :)


 
KSergey ©   (2007-10-17 12:28) [43]

Я все же не понимаю как соотносится oxffff ©   (17.10.07 12:06) [42] и

> KSergey ©   (17.10.07 11:36) [40]
> Вижу что, по сути, есть некая функция,
>  которая вызывает из себя некую другую функцию Yield() (я про реализацю стандарными средствами тут говорю, а не о том, что пример написан для иллюстрации имеющего инструментария)

так о чем приседания


 
oxffff ©   (2007-10-17 13:32) [44]


> KSergey ©   (17.10.07 12:28) [43]


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

:)


 
Игорь Шевченко ©   (2007-10-17 14:00) [45]

oxffff ©   (17.10.07 13:32) [44]


> А еще подуйте и сделайте ее такой,
> чтобы она была универсальна, то есть сама запоминала состояния
> между передачей значения для любых случаев


Тоже мне, бином Ньютона.


 
pasha_golub ©   (2007-10-17 15:58) [46]


> oxffff ©   (17.10.07 13:32) [44]


> то есть сама запоминала состояния между передачей значения
> для любых случаев.

А как это, пардон, сама? Программист тут уже нафиг не нужен шоли?

Был бы изящный живой пример, авось и взаправду вещь нужная. А так я ее лично просто не понимаю.


 
Virgo_Style ©   (2007-10-17 18:15) [47]

А я-то уж начал тихо подозревать, что я дурак... оказывается, не один я не понимаю, что это и зачем оно надо %-)


 
oxffff ©   (2007-10-17 19:34) [48]


> pasha_golub ©   (17.10.07 15:58) [46]
>
> > oxffff ©   (17.10.07 13:32) [44]
>
>
> > то есть сама запоминала состояния между передачей значения
>
> > для любых случаев.
>
> А как это, пардон, сама? Программист тут уже нафиг не нужен
> шоли?
>
> Был бы изящный живой пример, авось и взаправду вещь нужная.
>  А так я ее лично просто не понимаю.

>Virgo_Style ©   (17.10.07 18:15) [47]
>А я-то уж начал тихо подозревать, что я дурак... оказывается, не один я >не понимаю, что это и зачем оно надо %-)

Вы oxffff ©   (15.10.07 20:18) [2] внимательно смотрели?

Повторю еще раз

public static IEnumerable Power(int number, int exponent)
 {
    yield return 1;
    Console.Write("We are here ", i);
    yield return 2;
   Console.Write("We are here Again", i);
    yield return 3;
}

После вызова  yield return 1 управление перейдет во внешнюю процедуру, то есть тому кто вызвал MoveNext.
После следующего вызова MoveNext управление будет передано сразу на
Console.Write("We are here ", i) и передано обратно после yield return 2.
А состояние всех переменных объявленных внутри будет сохранено автоматически (во всяком случае вам не надо прилагать для этого усилий).

Если вам и теперь не понятно.
Тогда либо ждите статью (стаья правда на английском), либо смотрите код на ASM. Ссылка в первой странице.

Кстати сейчас я его уже усовершенстовал, для того, чтобы Yield работал для любого типа.

Либо напишите пример на C# и смотрите под отладчиком.

По


 
oxffff ©   (2007-10-17 19:39) [49]


> А состояние всех переменных объявленных внутри будет сохранено
> автоматически (во всяком случае вам не надо прилагать для
> этого усилий).


В данном примере в Power не объявлены переменные, но если были объявлены то их состояние оставалось бы прежним между передачей управления yield.
То есть от yield до yield состояние переменных объявленных внутри сохраняется.


 
Virgo_Style ©   (2007-10-17 21:32) [50]

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

Быть может, для этого нужен специфический опыт, но из [2] могу только предположить, что для запутывания кода и головной боли у программиста (


 
oxffff ©   (2007-10-17 22:22) [51]


>
> Быть может, для этого нужен специфический опыт, но из [2]
> могу только предположить, что для запутывания кода и головной
> боли у программиста (


oxffff ©   (17.10.07 12:06) [42]


 
Virgo_Style ©   (2007-10-17 23:43) [52]

oxffff ©   (17.10.07 22:22) [51]
oxffff ©   (17.10.07 12:06) [42]


Virgo_Style ©   (17.10.07 21:32) [50]

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

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

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

Сказал бы - есть такая-то конструкция, работает так-то, можно применять в такой-то задаче. Достоинства следующие. И все, начинается диалог. А так - разговор ни о чем с явно "религиозным" оттенком(


 
oxffff ©   (2007-10-18 00:33) [53]


> Virgo_Style ©   (17.10.07 23:43) [52]


Собственно как можно вести диалог с людьми, которые не только не хотят читать тему с начала, но даже вдуматься в предмет разговора.
Бывают даже такие, которые дают оценки всему и вся.
Где аргументы?
Приводите аргументы господа.
Но в большинстве никто ни хочет ни читать, ни тем более открыть C# проект, открыть отладчик и посмотреть ход исполнения.
Хотя я уже неоднократно уже повторил, смотреть [0],[2],[3] или исходники.

Кто привел хоть одну демострацию кода?
Одна болтовня - из разряда "Зачем? Это можно и так сделать?".
Я согласен, конечно, но какой ценной для тех алгоритмов со множеством состояний и алгоритмов расчетов.
Поэтому в якобы религиозности это скорее к вам.
Мы признаем только одну свою веру.
В этой теме я уже неоднократно озвучил назначение этой конструкции и ее удобство.

Если кому это станет интересно, то я буду вести диалог и обсуждение только с вашими аргументами  в виде кода.


 
FeiFei   (2007-10-18 09:06) [54]

oxffff ©   (18.10.07 00:33) [53]

>Одна болтовня - из разряда "Зачем? Это можно и так сделать?".
>Я согласен, конечно, но какой ценной для тех алгоритмов со множеством состояний и алгоритмов расчетов.

А зачем для таких алгоритмов использовать Delphi?


 
Игорь Шевченко ©   (2007-10-18 09:07) [55]


> В этой теме я уже неоднократно озвучил назначение этой конструкции
> и ее удобство.


Вот честно читал, но удобства не увидел. Плохо смотрел ?


 
KSergey ©   (2007-10-18 10:04) [56]

> oxffff ©   (18.10.07 00:33) [53]
> Собственно как можно вести диалог с людьми, которые не только
> не хотят читать тему с начала, но даже вдуматься в предмет
> разговора.

Ты бы спесь-то сбавил, а? Примеры привел кривейшие с кучей каких-то неиспользуемых переменных (а потому совершенно не понятно нужны они там или нет). Это я про [2]. Как работает конструкция - понятно из [2]. И все кто желал это давно поняли.

Однако пример в [19] и проч. - не убедителен нифига, т.к. не понятно что снаружи этой функции, т.е. внутри foreach (или, говоря иначе, внутри Yeld).
Вот когда это будет видно - тогда и будет предметный разговор по поводу "как это написать традиционными средствами и проще ли это". Пока же - в общем случае - просто вызов некоего метода/функции Yeld полностью решит данную задачу. Без "АСМ вставок".


 
Virgo_Style ©   (2007-10-18 10:28) [57]

oxffff ©   (18.10.07 0:33) [53]

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

Замечу в скобках, что здесь форум по Delphi. Лично моя квалификация не позволяет мне выяснять достоинства секретной конструкции под отладчиком в неизвестной мне среде (которую качать еще через gprs) на неизвестном мне языке. Я уж не говорю про желание этим заниматься.

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


 
vpbar ©   (2007-10-18 10:53) [58]

>>oxffff
Ты крут, ты супер крут. (Может не надо этим так гордится, но это мелочи)
Продолжай. Эта конструкция иногда пригождается.

>>other
А примеры - ну у меня гдето была книга по дискретной математике, так вот там автор на абстрактном языке (похож на паскаль :) ) с использованием yeld приводил примеры построения множеств и чтото еще. Если найду напечатаю тут.
Еще я тут применяю поиск файлов и их обработку, так мне былобы удобнее делать так

foreach (string filename in NextFile(Root, Mask))
      {
          //Console.Write(FileName);
      }

А не через калбаки или возвращение списка.

ЗЫ
Сергей, если ты еще сделаешь в Delphi аналог return, то я тебе лично вышлю пива (или аналог). :)


 
oxffff ©   (2007-10-18 10:57) [59]


> KSergey ©   (18.10.07 10:04) [56]
> > oxffff ©   (18.10.07 00:33) [53]
> > Собственно как можно вести диалог с людьми, которые не
> только
> > не хотят читать тему с начала, но даже вдуматься в предмет
>
> > разговора.
>
> Ты бы спесь-то сбавил, а? Примеры привел кривейшие с кучей
> каких-то неиспользуемых переменных (а потому совершенно
> не понятно нужны они там или нет). Это я про [2]. Как работает
> конструкция - понятно из [2]. И все кто желал это давно
> поняли.


Ты бы вел себя корретно, уважаемый.
А то я тоже могу зубы показать.

Теперь по порядку.
Ты выдрал [19] не указав контекст. Полный пример в [3].

Далее я 5 раз тебе говорил реализуй [3] обычным способом.
Тогда тебе станет понятно
Он специально подобран таким образом, чтобы алгоритм вычисления
элемента менялся, вместе с большим количеством состояний
Чтобы вызвать неудоство и трудности при реализации обычным способом.
Ввиде "вычленения" состояния вычисления следующего элемента ( включая параметры этого алгоритма и сам алгоритм).

Если ты утвержаешь, что понял алгоритм. И все внимательно читал.
То это не так. Ничего ты не понял.

См. [48]. В нем ключевая фраза

А состояние всех переменных объявленных внутри будет сохранено автоматически (во всяком случае вам не надо прилагать для этого усилий).


 
euru ©   (2007-10-18 11:02) [60]

Попрбую помочь oxffff. А то он как-то зациклился (наверно, yield-ы у себя неверно расставил).
Программа на С#, т.к. там имеется штатная реализация yield. В ней реализованы итерации как с применением yield, так и без него.

using System;
using System.Collections;

namespace Test
{
class Program
{
 public static void Main(string[] args)
 {
  int count = 4;
  foreach (int i in YieldFunc(count))
  {
   Console.Write("{0}", i);
  }
 
  foreach (int i in new Yield(count))
  {
   Console.Write("{0}", i);
  }

  Console.WriteLine("\nPress any key...");
  Console.ReadKey();
 }
 
 public static IEnumerable YieldFunc(int count)
 {
  Console.Write("Значения квадратов от 1 до ");
  yield return count;
  int s = 0;
  for (int i = 1; i <= count; i++)
  {
   Console.WriteLine();
   yield return i;
   Console.Write(" * ");
   yield return i;
   Console.Write(" = ");
   yield return i * i;
   s += i * i;
  }
  Console.Write("\nСумма квадратов равна ");
  yield return s;
 }
 
 private class Yield : IEnumerable, IEnumerator
 {
  private int count;
  private int current;
  private int state;
  private int s;
 
  public Yield(int count)
  {
   this.count = count;
  }
 
  public IEnumerator GetEnumerator()
  {
   return this;
  }
 
  public Object Current
  {
   get
   {
    switch (state)
    {
     case 0:
      Console.Write("Значения квадратов от 1 до ");
      state = 1;
      return count;
     case 1:
      Console.WriteLine();
      state = 2;
      return current;
     case 2:
      Console.Write(" * ");
      state = 3;
      return current;
     case 3:
      Console.Write(" = ");
      state = 1;
      s += current * current;
      return current * current;
     default:
      Console.Write("\nСумма квадратов равна ");
      return s;
    }
   }
  }
 
  public bool MoveNext()
  {
   if (state == 1) current++;
   if (state == 4) return false;
   
   if (current > count) state = 4;
   return true;
  }
 
  public void Reset()
  {
   current = 0;
   state = 0;
   s = 0;
  }
 }
}
}


 
Игорь Шевченко ©   (2007-10-18 11:09) [61]

"Страшно далеки они от народа" (с)


 
oxffff ©   (2007-10-18 11:12) [62]


> vpbar ©   (18.10.07 10:53) [58]
> >>oxffff
> Ты крут, ты супер крут. (Может не надо этим так гордится,
>  но это мелочи)
> Продолжай. Эта конструкция иногда пригождается.
>
> >>other
> А примеры - ну у меня гдето была книга по дискретной математике,
>  так вот там автор на абстрактном языке (похож на паскаль
> :) ) с использованием yeld приводил примеры построения множеств
> и чтото еще. Если найду напечатаю тут.
> Еще я тут применяю поиск файлов и их обработку, так мне
> былобы удобнее делать так
>
> foreach (string filename in NextFile(Root, Mask))
>       {
>           //Console.Write(FileName);
>       }
>
> А не через калбаки или возвращение списка.
>
> ЗЫ
> Сергей, если ты еще сделаешь в Delphi аналог return, то
> я тебе лично вышлю пива (или аналог). :)


Когда звездит, то это очень плохо.
У меня не зведит. :(

Если вводить это конструкцию на уровне языка, то надо вводить на компилятора языка, и надо сделать реализацию так же как и в С#.
Поскольку я своей реализации вынужден манипулировать стеком.

Можно даже рассмотреть мое предложение по улучшению этой конструкции (лучше чем в C#, поскольку там есть ограничения на try catch)
А именно о раскрутке SEH. Но здесь нужно исходить из скорости.
Статью я написал вчера, попросил проверить западного коллегу.


 
oxffff ©   (2007-10-18 11:19) [63]


> euru ©   (18.10.07 11:02) [60]
> Попрбую помочь oxffff. А то он как-то зациклился (наверно,
>  yield-ы у себя неверно расставил).


Спасибо за пример.
Я хотел, чтобы они до этого сами дошли.

P.S.
Yield я расставил правильно. Сделал это намеренно.
Алгоритмы бывают еще сложнее.
И вычленить состояние и тем более алгоритм бывает не просто.
Представь вложенность одного алгоритма в другом.
Или их сочетание для произвольных элементов.
Тогда сложность еще более возрастет.

А вычленить в плоский case будет достаточно сложно.

Но ключевое здесь есть способ перенести это на компилятор с помощью Yield


 
oxffff ©   (2007-10-18 11:19) [64]


> euru ©   (18.10.07 11:02) [60]
> Попрбую помочь oxffff. А то он как-то зациклился (наверно,
>  yield-ы у себя неверно расставил).


Спасибо за пример.
Я хотел, чтобы они до этого сами дошли.

P.S.
Yield я расставил правильно. Сделал это намеренно.
Алгоритмы бывают еще сложнее.
И вычленить состояние и тем более алгоритм бывает не просто.
Представь вложенность одного алгоритма в другом.
Или их сочетание для произвольных элементов.
Тогда сложность еще более возрастет.

А вычленить в плоский case будет достаточно сложно.

Но ключевое здесь есть способ перенести это на компилятор с помощью Yield


 
KSergey ©   (2007-10-18 11:57) [65]

Это звездец, дорогая редакция...

> oxffff ©   (18.10.07 10:57) [59]
> Ты бы вел себя корретно, уважаемый.
> А то я тоже могу зубы показать.

Да сколько угодно! Не я хамить всем начинал (в этой ветке :) ).

> Теперь по порядку.
> Ты выдрал [19] не указав контекст. Полный пример в [3].

Да не полный тама пример, блин, можешь ты это понять??
Либо я что-то не вижу (что опять же не мне претензия), либо тама все же нет главного: того foreach где это используется.

А если предположить, что тама foreach (гипотетический, т.е. не на дельфи, понятно) например такой:

foreach (integer ii in YieldUseProc())
begin
  Writeln("ii=" + IntToStr(ii));
end;


то все решается в рамках существующего компилятора простым добавлением в коду в [3] функции

procedure Yield(ii: Integer);
begin
  Writeln("ii=" + IntToStr(ii));
end;


Так понятно тебе наконец, что нет полного кода??!!

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


 
oxffff ©   (2007-10-18 12:10) [66]


> KSergey ©   (18.10.07 11:57) [65]


Я не думаю, что если бы я использовал форматирование тебе бы стало понятнее.
Вообщем придет время и ты все поймешь.

>procedure Yield(ii: Integer);
>begin
>  Writeln("ii=" + IntToStr(ii));
>end;

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

я кстати могу улучшить твой код.
Сделай так вместо вызова Yield вставь сразу вызов Writeln.


 
oxffff ©   (2007-10-18 12:19) [67]


> Так понятно тебе наконец, что нет полного кода??!!

А как у нас дела с ASM?
Ты что его не смотрел?
Может тебе его посмотреть все же. Ссылку я дал.


 
Игорь Шевченко ©   (2007-10-18 12:26) [68]

Дети Ивана Кулибина. Сколько ж можно-то ? :)


 
KSergey ©   (2007-10-18 12:32) [69]

> oxffff ©   (18.10.07 12:10) [66]
> Вообщем придет время и ты все поймешь.

И в самом деле - чего я гоячусь?
Мне и имеющихся средст вполне хватает для решения моих задач.
На прочее отвечать не вижу смысла.


 
oxffff ©   (2007-10-18 12:40) [70]


> Игорь Шевченко ©   (18.10.07 12:26) [68]
> Дети Ивана Кулибина. Сколько ж можно-то ? :)


Так мы же ваши дети (в смысле кто нам пример подает).
:)


 
oxffff ©   (2007-10-18 13:36) [71]

Вот часть статьи.

C# Yield  implementation in Delphi.

C# yield keyword is used to provide a value to the enumerator object or to signal the end of iteration. The main idea of yield construction is generate a collection item on request and return one to enumerator consumer immediately. You may find it useful in some cases.

As you know the Enumerator has two methods MoveNext и GetCurrent.
But how yield works?

Technical details of implementation

As I first time had seen this construction I asked myself where is MoveNext и GetCurrent?
The function returns the enumerator object or interface, but enumerator is nowhere explicitly constructed. So there is some secret mechanism that makes it possible.
And how it really works?
After spending some time for debugger and answers appear.

In short the compiler generate some special form of object that of course
have some magic MoveNext и GetCurrent.

And because this construction may be useful for our Delphi community,  I Asked myself, what can I do for yield supporting by Delphi with no special methods calling with saving the form of using like in С#.
I want to retain yield C# syntax, but later I changed syntax for a little and delegate implementation to external procedure almost like in C# but with additional parameter yield wrapper object. First time it was a virtual procedure.

But of course I have to generalize implementation for all types.

And of course additional question to myself.
Сan I improve С# yield implementation? May be.

I start from programmer’s viewpoint.
Something like this

var  
number, exponent, counter, Res:integer;
begin

…..
Res:=1;
while counter<exponent do
begin
Res:=Res*number;
Yield(Res);
inc(counter);
end;
end;

I had to implement some class that implements magic MoveNext и GetCurrent.
And If I(you) use local vars (that is placed on stack) I had to implement some mechanism that guarantee no memory leaks for finalized types and some mechanism that guarantees that I use
the valid local vars when the actual place of local vars has been changed after last yield calling due for external reasons (e.g. enumerator  passed as parameter to other procedure, so the place in stack becomes an other).

So after each yield calling I have to preserve the state of local vars and processor registers,
clean up stack and return to enumerator consumer,
And after next call to MoveNext I must alloc stack, restore  state of local vars and processor registers, i.e. emulate that nothing is happened.  
And of course I must provide a normal procedure exiting at the end.


 
pasha_golub ©   (2007-10-18 14:38) [72]

euru ©   (18.10.07 11:02) [60]

А что-нибудь посложней можно в функцию для примера засунуть? Ну, например объекты разных классов что-ли. Ибо пример-то в целом ясен, но как иллюстрация. А хотелось бы нечто такого, что развернуть без Йелда ну никак в разумных усилиях.


 
Zeqfreed ©   (2007-10-18 15:21) [73]

#!/usr/bin/python

def odd_powers(n):
m = n
while True:
 yield m
 m = m * n * n

def factorials():
n = 6 #start with 3!
c = 3
while True:
 yield n
 c = c + 1
 n = n * c

def signs():
s = -1
while True:
 yield s
 s = s * (-1)

def sine(x):
p = odd_powers(x)
p.next()    #skip first power
f = factorials()
s = signs()

while True:
 yield x
 a = p.next()
 b = f.next()
 f.next()   #skip even factorials
 c = s.next()
 x = x + c * a / b

s = sine(3.14 / 2)
while True:
try:
 print str(s.next())
except:
 break  


В качестве примера :)


 
Zeqfreed ©   (2007-10-18 15:24) [74]

Ну как обычно все отступы съедены. Попытка номер два.

#!/usr/bin/python

def odd_powers(n):
  m = n
  while True:
     yield m
     m = m * n * n

def factorials():
  n = 6 #start with 3!
  c = 3
  while True:
     yield n
     c = c + 1
     n = n * c

def signs():
  s = -1
  while True:
     yield s
     s = s * (-1)

def sine(x):
  p = odd_powers(x)
  p.next()    #skip first power
  f = factorials()
  s = signs()

  while True:
     yield x
     a = p.next()
     b = f.next()
     f.next()   #skip even factorials
     c = s.next()
     x = x + c * a / b

s = sine(3.14 / 2)
while True:
  try:
     print str(s.next())
  except:
     break
 


 
tesseract ©   (2007-10-18 22:05) [75]


> Zeqfreed ©   (18.10.07 15:24) [74]


Знания по питону не ахти, но понял больше. В 1с полезная штука - в delphi раком лебедю щукой.


 
oxffff ©   (2007-10-19 02:54) [76]

Добавил динамическую сборку/разборку всех SEH фреймов  локальной процедуры и их подстройку в случае смещению локальных данных.


 
ZeroDivide ©   (2007-10-24 08:39) [77]

http://hallvards.blogspot.com/2007/10/sergey-antonov-implements-yield-for.html

:)


 
KSergey ©   (2007-10-24 09:30) [78]

По статье, ссылку на которую любезно нашел ZeroDivide ©

А что, вот это и правда работает??

procedure TForm1.Button1Click(Sender: TObject);
var   a:string;
begin
  for a in self do
     Memo1.Lines.Add(a);end;


Мне лень проверять, сорри.
И еще.

> oxffff ©   (18.10.07 13:36) [71]

Нельзя ли все же привести полный пример использования? Т.е. и точ то"внутри" и то, что снаружи? (я не имею в виду реализацию).


 
KSergey ©   (2007-10-24 09:33) [79]

> pasha_golub ©   (18.10.07 14:38) [72]
> А хотелось бы нечто
> такого, что развернуть без Йелда ну никак в разумных усилиях.
>

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

Правда, использовать все равно не буду, т.к. только моя часть на дельфи, прочее - на вражьем :)


 
ЗапомниСынок ©   (2007-10-24 16:56) [80]

На королевстве Delphi статья по реализации Yield на Delphi лежит с начала 2006 г. Интересно, автор тот же?


 
Сусл ©   (2007-10-24 17:01) [81]

http://hallvards.blogspot.com/2007/10/sergey-antonov-implements-yield-for.html


 
oxffff ©   (2007-10-24 19:14) [82]


> ЗапомниСынок ©   (24.10.07 16:56) [80]
> На королевстве Delphi статья по реализации Yield на Delphi
> лежит с начала 2006 г. Интересно, автор тот же?


Ссылку в студию.


 
oxffff ©   (2007-10-24 19:20) [83]


> ЗапомниСынок ©   (24.10.07 16:56) [80]
> На королевстве Delphi статья по реализации Yield на Delphi
> лежит с начала 2006 г. Интересно, автор тот же?


http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=1191 ?
Автор не я. Реализация другая.  

Предлагаю сравнить самому ЗапомниСынок © .


 
ЗапомниСынок ©   (2007-10-25 10:08) [84]

ага, делать мне больше нечего...



Страницы: 1 2 3 вся ветка

Форум: "Прочее";
Текущий архив: 2007.11.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.75 MB
Время: 0.044 c
2-1193740709
BATTLE_MAX
2007-10-30 13:38
2007.11.25
TListView без родителя


2-1194007977
BATTLE_MAX
2007-11-02 15:52
2007.11.25
Сохранение TImageList


15-1193108125
Slider007
2007-10-23 06:55
2007.11.25
С днем рождения ! 23 октября 2007 вторник


10-1140499983
rosl
2006-02-21 08:33
2007.11.25
excel


2-1193965529
ореол
2007-11-02 04:05
2007.11.25
Загрузка содержимого *.doc файла в своем приложении





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский