Re: NRE committed: PLEASE TEST



Fredderic wrote:
On Wed, 03 Sep 2008 20:19:33 +0100, Neil Madden <nem@xxxxxxxxxxxxx> wrote:

Fredderic wrote:
miguel <msofer@xxxxxxxxxxxx> wrote:
Fredderic wrote:
[yield] would be a handy way to allow a [proc] to do some
initialisation on first run.
Oh - now I understood what you mean. This would make procs a bit
heavier than coroutines (see below).
I kind of figured that, and pretty much wiped that idea myself.
My wish here would be served by the [coroutine] command being able
to displace an existing proc or command until it completes. Having
[coroutine] displace the current proc with an inline [apply]
invocation (as DKF mentioned is possible), would allow exactly the
semantics I was rather hoping would be possible. A proc could then
trivially be built that can [yield] without having to be explicitly
invoked through [coroutine].
A limitation of this approach is that you couldn't have 2 or more simultaneous coroutine instances based on the same command.

Not at all... The musings I muttered on coroutines ages ago over on
the wiki were along these lines (with the unenlightened assumption that
[yield] would only effect the proc it was invoked from).

Link?

In those
musings a [coroutine] command would be used to explicitly create a
simultaneous instance until a new name, where the original command
would simply resume the default one. No reason the same couldn't be
applied here.

If the original command has been replaced by a default coroutine, how do you construct other coroutines based on it?

Another difficulty is that the original proc may take different
arguments than the resume command.

Actually that came out rather cleanly in the wash. The original proc
takes initialisation arguments, while the resumed coroutine gets any
arguments via the return value from [yield]. Unless it takes specific
action, those arguments will be ignored in the resuming case anyhow.

Two cases:

1. resume only takes a single argument, whereas the original proc takes >1, in which case anybody trying to call the original will get an error.
2. resume takes multiple arguments and the coroutine expects >1, whereas the original proc takes only 1 argument, will again result in an error for callers of the original proc.

The point is that the original proc and the coroutine resume command can have wildly different signatures and expectations. Dynamically replacing one with the other is likely to create incompatibilities in most cases. What does it achieve?



As currently implemented, it would also prevent the second and
later calls to take more than one argument.
Dare I ask, why? ;)
If you think about how the mechanism works, a coroutine suspends from
a yield, and is later resumed from that place. Any arguments to the
resume become the result of the yield as far as the coroutine is
concerned: set next [yield $val]

I believe I just said that as the answer to your prior question. ;)


Therefore, if the resume command could take multiple arguments then
it would be impossible to distinguish between multiple separate
arguments and a list. You could maybe extend yield, something like:

No. You simply ALWAYS return a list, ala [proc]s special "args"
argument. It might be slightly inconvenient, but it's an awful lot
more convenient than not being able to do it at all. There are other
possibilities also, such as allowing [yield] to take an arguments list
after the return value. A bit odd, but it's an idea if you're
desperate. ;)

The alternative is to leave things as they are and pass a list when you want to pass multiple values. That has the benefit of symmetry.


My focus on this issue, btw, is mostly in the interest of allowing
coroutines to be used as an implementation detail in the
construction of a proc, rather than a project-wide design decision
from the outset. I think _if_ it can be done without too much
effort, it would be a fantastically handy way to do the first-run
initialisation thing.
Coroutines should be possible to use as an implementation detail, as
in my worked example converting a simple synchronous program to use
the event loop: http://wiki.tcl.tk/21532

It gets a little more complicated when you're not writing the entire
application from scratch. When you're trying to retro-fit new ideas
into old code (which I tend to do a lot of), things get a little more
interesting.

Did you read the page? The entire point of the example is that you can rewrite the implementation without touching the main logic. I.e., using coroutines makes it *easier* to "retrofit new ideas into old code".

-- Neil
.



Relevant Pages

  • Re: NRE committed: PLEASE TEST
    ... command and the underlying mechanics of the coroutine mechanism, ... if the coroutine command itself can do something useful with its ... whereas the original proc takes only 1 argument, ...
    (comp.lang.tcl)
  • Re: NRE committed: PLEASE TEST
    ... to displace an existing proc or command until it completes. ... that [yield] would only effect the proc it was invoked from). ... If the original command has been replaced by a default coroutine, ...
    (comp.lang.tcl)
  • Re: NRE committed: PLEASE TEST
    ... My wish here would be served by the command being able to ... displace an existing proc or command until it completes. ... A limitation of this approach is that you couldn't have 2 or more simultaneous coroutine instances based on the same command. ... If you think about how the mechanism works, a coroutine suspends from a yield, and is later resumed from that place. ...
    (comp.lang.tcl)
  • Re: NRE committed: PLEASE TEST
    ... Symmetry between the way the coroutine is called and the way yield returns ... data -- i.e. you pass a single value to the resume command, and a single value is returned from [yield]. ... Just because TCL doesn't have a more obvious multiple variable assignment syntax, doesn't make it any less useful. ... That value may be interpreted as a list or a dict, sometimes a file handle, sometimes a command name. ...
    (comp.lang.tcl)
  • Re: NRE committed: PLEASE TEST
    ... resume only takes a single argument, whereas the original proc ... Creation of a coroutine takes inital arguments - fair enough - and resuming a coroutine also takes an argument. ... From the Tcl script level it is indeed a command, and it does take an optional argument. ...
    (comp.lang.tcl)