Главная страница
    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, при этом она вызывается как раз непосредственно когда надо. Вижу только одну проблему ее реализации, когда хочется хранить значения неких перменных от вызова к вызову этой функции - вот и все. Но и эта проблема - легко решаема более или менее изящно.

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



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

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

Наверх





Память: 0.58 MB
Время: 0.057 c
15-1192793813
DevilDevil
2007-10-19 15:36
2007.11.25
Визуальные компоненты на TDataModule


15-1193278614
Slider007
2007-10-25 06:16
2007.11.25
С днем рождения ! 25 октября 2007 четверг


2-1194089436
timekiller
2007-11-03 14:30
2007.11.25
Делим строку на символы, практически..


2-1193305028
Basic
2007-10-25 13:37
2007.11.25
Установка нового компонента


11-1178208197
Даддитс
2007-05-03 20:03
2007.11.25
Оптимизация





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский