lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Oct 04, 2002 at 05:15 +0200, Benoit Germain wrote:
> Hi,
> 
> I have setup a system in which several tasks are run as coroutines so that
> they can interrupt their processing when they want. All tasks share the same
> function, but of course there is one coroutine instance per task. Now, here
> comes my problem: The function being used as a coroutine needs arguments,
> whose values change each time the coroutine is called (typically, a system
> date, that must be the same for all tasks)
> Unfortunately, the following sample will not work as (I would have)
> expected:
> 
> function f(n)
> 	while true
> 	do
> 		print ( n )
> 		coroutine . yield ( )
> 	end
> end
> 
> c = coroutine . create ( f )
> 
> f(1)
> f(2)

I think you meant "c(1)" "c(2)" on the above two lines?

> -->
> nil
> nil
> 
> 
> Seeing, I got a closer look at the manual. From what I have seen,
> arguments can be only provided at the coroutine creation. Calling a
> coroutine with any arguments will always end up with the function
> using the initial argument, those provided when calling the
> coroutine being ignored. Therefore, what I want to do can be
> achieved by providing a table at coroutine creation, and modifying
> its contents each time I call the coroutine:
> 
> function f(t)
> 	while true
> 	do
> 		print ( t[1] )
> 		coroutine . yield ( )
> 	end
> end
> 
> args={}
> c = coroutine . create ( f ,args)
> 
> args[1] = 33
> f()
> args[1] = 44
> f()
> 
> -->
> 33
> 44
> 
> However,  it is not very elegant, and prevents usage of coroutines as normal
> functions.
> Isn't it possible instead, each time the coroutine resumes, to store its
> current arguments in the argument slots of the function being coroutined ?
> In the event it is possible, is there a way, given a function, to know how
> many arguments it is expecting, in order to adjust what is provided to the
> coroutine to what the function is expecting ?

I think, rather than needing a language change, you can get the effect
you want with some wrapper code:

function make_c_caller()
	local t = {}
	local function f()
		while true do
			print(t[1]);
			coroutine.yield()
		end
	end

	local c = coroutine.create(f)

	local function c_caller(arg)
		t[1] = arg;
		c()
	end

	return c_caller
end

c = make_c_caller()

c(1)
c(2)

Hopefully that gives you some ideas.

-- 
Thatcher Ulrich
http://tulrich.com