[vienna.pm] Coroutines

Marcel Grunauer marcel at codewerk.com
Wed Jul 4 10:23:22 CDT 2001


* * * vienna-pm-list * * *


On Wednesday, July 4, 2001, at 04:32  PM, Stefan Heinecke wrote:

>>> Marc Lehmann hat ja gerade das Coro-Modul auf CPAN gestellt, das
>>> Coroutines bereitstellt (oder zumindest emuliert; hab die
>>> print "in main, switching to coroutine\n";
>>> doit;
>>> print "back in main, switch to coroutine again\n";
>>> doit;
>>> print "back in main\n";
>
>> Wow. Klingt spacig. Und wozu kann man das praktisch einsetzten?
>
> *aufdembodenroll* hab ich mich auch gefragt.
>
> The same old topic:
>
> Teaching computer science vs. creating programming drones for the 
> software
> industry.

In dem Fall beides. Die besten Interfaces sind meines Erachtens die,
die computer sciene-level stuff nehmen und sie so praesentieren, dass
sie jeder einsetzen kann. Z.B. sort(), das Dir Quicksort abnimmt. Oder
closures.

So auch mit Coroutines. Das Prinzip ist, dass yield() wie ein return
ist, nur dass nach dem naechsten Aufruf der coroutine die Abarbeitung
nicht am Anfang beginnt, sondern nach dem yield. D.h. der ganze Stack
samt lexicals bleibt erhalten, Du brauchst also etwa bei event loops
nicht den Status ewig speichern und wieder abrufen.

Sieh Dir mal http://www.yetanother.org/damian/Perl5+i/coroutines.html
an. (Perl 5+i ist Damian's Entwurf von Perl 6; der ist aber schon
wieder ueberholt.). Interessant sind da coroutines etwa beim
Traverse von Baumstrukturen:

-----citation-----------------------
    Coroutines make it very easy to implement generic parameteric closures
    and iterators:

         package Tree;

         sub next_inorder ($self) {
                 yield $self->{left}->next_inorder if $self->{left};
                 yield $self;
                 yield $self->{right}->next_inorder if $self->{right};
                 return undef;
         }

         # and later...

                 while (my $node = $root->next_inorder()) {
                         print $node->{data};
                 }

    Note that the above example implies (correctly) that yielding a result
    which itself was yielded leaves the suspended execution of the
    subroutine within the same nested yield statement (not the following
    statement).
-----citation-----------------------

oder:

-----citation-----------------------
         sub every_second ( @vals ) {
                 yield (splice @vals, 0, 2)  while @vals;
                 return;
         }
-----citation-----------------------

oder, wenn Du eine Funktion auf jeden Key eines hashes anwenden
willst, und eine andere auf jede value eines hashes, musst Du im Moment
schreiben:

         @newhash{map {transform_key($_)} keys %oldhash} =
                 map {transform_val($_)} values %oldhash;

Mit coroutines wird daraus:

         %newhash = map {yield transform_key($_); transform_val($_)} 
%oldhash;

Mit anderen Worten: Coroutines machen nichts moeglich, was schon
vorher nicht moeglich war, aber das trifft auf viele Konstrukte
von high-level Languages zu. Aber es vereinfacht manche Dinge, die
bislang umstaendlich oder kompliziert waren, und das ist ja eines
der Mottos von Perl:

	Keep simple things simple, make hard things possible.

Marcel

--
Marcel Grunauer          | $ perl -we time
Codewerk Perl Services   | Useless use of time in void context at -e 
line 1.
http://www.codewerk.com  |
Perl 6 proof-of-concepts |
###
You are subscribed to vienna-pm-list as Marcel Grunauer <marcel at codewerk.com>
http://www.fff.at/fff/vienna.pm/



More information about the Vienna-pm mailing list