> How about the following:
>
> procedure makeLamda(ce)
> return (@ce, ce)
> end
>
> This will perform the initial activation of the coexpression and then
> return the coexpression. You have to write your co-expression with that
> in mind.
>
Meaning it would have to lead with a suspend?
Ultimately I'm just interested in passing anonymous code blocks; it's becoming
quite common out there
- Perl with inline subs:
worker(10, 20, sub { my $x = shift; $x * $x })
- C# with it's
listOfFoo.Where(x => x.Size > 10);
For instance, the code I was working on yesterday said:
l_tmp := list()
if not ident_sequence(l_tmp) then # much-used procedure
tab(0)
else
every buf := ! l_tmp do
if member(qstates, buf) then
error(buf, " already mentioned.")
else
insert(qstates, buf, "required")
However the error( ) method is no longer pointing to the relevant &pos because
the entire sequence of ident is collected before the error checking loop.
A desire arose where I wanted to write (to coin a syntax)
l_tmp := list()
if not ident_sequence(lamba buf => if member(buf...) then error(...)) then
tab(0)
else
every insert(qstates, ! l_tmp, "required")
So the error pointer shown to the user can be correct.
I can pass a little procedure to do the test and insert, but I would have to
add more parameters on ident_sequence just to pass in the target of the test
and insert. In general the parameter count wouldn't necessarily be fixed so
it's all a bit loose and noisy.
I came up with:
global LHA
procedure LambdaCall(cr, args)
local stacked
# gut feeling - LHA needs to be reverted before the suspend happens
suspend 3(stacked <- LHA, LHA <- args, @cr, LHA <- stacked)
end
procedure worker(n, cr)
if LambdaCall(cr, n) then
write("it's a member")
else
write("it's not a member")
end
procedure main()
local hash
hash := table()
worker(10, create member(hash, LHA))
hash[10] := 1
worker(10, create member(hash, LHA))
end
Using LHA as a generic stack to stuff parameters but it means the code is
still clumsy.
Overall I'm coming to the conclusion that coroutines could benefit from some
sort of ability to receive parameters on the first activation. It has always
seemed a bit unfortunate that the first @ discards any transmitted value.
Something like
worker1(x, y, create :a b: codeUsing(a, b))
or
worker{:a b c: codeUsing(a,b,c), :a b: codeUsing(a, b)}
seems to be unambiguous syntactically. I'll reserve judgment on
attractiveness!
However a question arises in
procedure worker(X, Y, C)
x1 @ C
how would x1 be constructed and doled out to a and b? Perhaps the initial
activation could be performed with
C(X, Y)
Once again, a hypothetical discussion of an improvement that brings up several
questions!
It's interesting to note that C# has added a YIELD operator (claiming it to be
"like Python's" the ignorant fools)
// Method that takes an iterable input (possibly an array)
// and returns all even numbers.
public static IEnumerable<int> GetEven(IEnumerable<int> numbers) {
foreach (int i in numbers)
if (i % 2 == 0)
yield return i;
}
I believe it gets crunched into an anonymous iterator class, capturing the
stack and other context which gets restored when the instance of the iterator
has it's next() method called. I guess that's similar to what Icon does at
heart, but whereas Icon uses bytecodes to perform the work, C# seems to spit
out opcodes to emulate it every single time yield is used. Both Python and C#
seem to be completely free of goal-directed evaluation too.
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Unicon-group mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/unicon-group