Re: NRE committed: PLEASE TEST



On Fri, 22 Aug 2008 09:52:18 -0300,
miguel <msofer@xxxxxxxxxxxx> wrote:

Fredderic wrote:
Personally, I think it would make more sense if [yield] would
function regardless of whether the proc was evaluated via
[coroutine] or not, rather than throwing an error. You could still
use [coroutine] to create simultaneous invocations, and unlike a
[coroutine] invocation, the original proc it would essentially
"reset" when it completes. Basically acting exactly as though it
was storing internal state in a private global variable between
runs.
Not sure about that ... when [yield] fails to accomplish what it is
designed to do, I think it is better for it to error out rather than
do something else.

How is it not doing what it's designed to do? If it fails because of
an impure stack, then by all means error out. But [yield] would be a
handy way to allow a [proc] to do some initialisation on first run.


The only issue I'm aware of, is how they would mix. [yield] would end
up yielding the current [coroutine] instead of creating a new one. (I
presume in your implementation, you can [yield] from any TCL call
depth.) It would need a [yield -local] switch (or its converse) to
function the way I would like to see it, I guess. I'd like to know
which most people think is the sanest default behaviour if both were
available; yield back to the inner-most [coroutine] and error if there
isn't one, or yield the current proc only which is more what the term
co-routine implies to me. (In either case there would be an option to
perform the other.)

Something that would at least let me fudge what I would like to see, is
the ability for [coroutine] to push the current proc out of the way and
bring it back later. So you'd end up with something like this:

proc something {args} {
coroutine something {{abc def} {
{ ... the real body goes here ... }
}} {*}$args
}

I'll certainly be adding a -coroutine switch to my standard [proc]
wrapper, I think, though it's going to be ugly and flakey without that
kind of capability.

I presume there'll be an [info] sub-command to tell us whether we're in
a [coroutine] or not...?


Failing that, I think [coroutine] should work exclusively on
lambda's and not [proc]s at all, to highlight the fact that you
seemingly can't really use them in interchanged contexts; a proc
with [yield]s won't work too wekk when invoked directly rather than
via construction by [coroutine], and a proc without [yield]s
doesn't make much sense to invoke through [coroutine]. So you'd
take a lambda style function-in-a-variable, and use [coroutine] to
create a command out of it, which would then be used instead of
invoking the lambda via apply.
Conceptually (and very much in code too), what
coroutine foo cmd arg1 arg2 arg3
does is:
1. create a new execution environment

Could you elaborate on this part, please? What is different in this
new execution environment compared to the regular one, and how heavy is
this new environment. Would it be feasible to do this as part of the
regular proc invocation process?

By my understanding this basically entails starting a fresh TCL stack,
and pre-loading it with a small hook to regain control later on, within
which you evaluate the subject code.

I suppose my question, is whether there's anything within the TCL stack
that will stop you from basically taking the current TCL call level
with you to this new environment. As I understood it (which may well
be utterly wrong here ;) ), the TCL stack portions were relocatable, it
was (and still is) the C chunks that got in the way, which is what the
NRE eval deals with by allowing the C stack to unwind before performing
the eval.


2. create a new command foo that resumes running this execEnv
3. swap in the new execEnv as the current execution environment,
insuring that the caller execEnv is swapped back in when this
one exits (return or yield)
4. run (in the new env) uplevel #0 [list cmd arg1 arg2 arg3]
5. if the execEnv returned, delete it together with the associated
command foo

Steps 2-5 sound like standard library-based task-swapping mechanics.


Yield just checks that the current environment is not the main one,
ie, that we are executing within an execEnv that can be suspended. It
does not know about procs, lambdas nor anything else.

It was the fact that [yield] will work from any level that had slipped
my attention. Still, having [coroutine] take a lambda instead of a
proc would make it nestable within a proc, as in the example up top,
and I do still think it makes a whole lot more sense, as I said, with
[yield] not working from the main environment, even though [yield] can
still occur within other procs.

I wonder whether it would be sane to add an [info lambda] command that
will compile and return a proc as a lambda expression...?


The other thing it checks is that the C stack is currently at the
same level it was when the execEnv was last resumed. This means for
instance that you can't [*] yield from within an [eval]ed or
[source]d script.

I presume these two can be fixed, though...? Which leaves just
old-style non-NRE-aware extensions.


--
Fredderic

Elephant = mouse built to government specs

Debian/unstable (LC#384816) on i686 2.6.23-z2 2007 (up 51 days, 22:22)

.



Relevant Pages

  • Re: NRE committed: PLEASE TEST
    ... You could still use [coroutine] to ... create simultaneous invocations, and unlike a invocation, ... the original proc it would essentially "reset" when it completes. ... swap in the new execEnv as the current execution environment, insuring that the caller execEnv is swapped back in when this one exits ...
    (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
    ... function regardless of whether the proc was evaluated via ... use [coroutine] to create simultaneous invocations, ... IOW, your proposal may look like "let us change [yield], but ir really is "let us change ". ... is whether there's anything within the TCL stack ...
    (comp.lang.tcl)
  • Re: NRE committed: PLEASE TEST
    ... be a proc, and hence you could pass in arguments and have them update ... so you give an argument to the coroutine and it pops out as the ... that a design decision, or a practical limitation? ... foreach arg [info args $proc] { ...
    (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)