lua-users home
lua-l archive

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


Having written the multithreading logic for Lightroom and reading through the luaproc examples, a thought occurs to me about a potentially useful syntactic extension to Lua for these cases. It would be nice to have a way to say essentially "the following portion of the program text should form a syntactically valid Lua chunk which should be encoded as a loadable string". For example, let's look at the example from the luaproc article (http://www.inf.puc-rio.br/~roberto/docs/ry08-05.pdf ):

	luaproc.newproc( [==[
		-- create a new channel
		luaproc.newchannel( "achannel" )
		-- create a new Lua process
		luaproc.newproc( [=[
			-- send a message to the channel
			luaproc.send( "achannel", "hello world" )
		]=] )
		-- create a new Lua process
		luaproc.newproc( [=[
			-- receive a message from the channel
			msg = luaproc.receive( "achannel" )
			-- print the received message
			print( msg )
		]=] )
	]==] )

This requires careful use of the string nesting markers and none of the code can be syntax checked until execution. Furthermore, when we do execute it, we have to compile code for every new Lua process. Presumably we could get around the last point by caching the results of a loadstring somewhere.

We could get around the lack of a syntax check by using special marker characters for the string and having an IDE pull them out and check them separately, but that requires an IDE doing a separate syntax check. We might really prefer to check it all in the initial load. In particular, consider the fact that if the inner calls to newproc are handed invalid code the error happens in the outer process with no good way to communicate with the root environment.

We could get around this by passing functions and dumping them to bytecode strings. That, in fact, is what Lightroom does. However, we have to be careful to ensure that the functions so used do not have any upvalues even as they are being created in the midst of code that values upvalues for performance. One could copy the upvalues over but that requires a more sophisticated copying mechanism and if it can't copy everything we're back to potentially not checking inner process creations until it's awkward to report failure.

But imagine a chunk keyword (anathema I know to add a keyword, but imagine it none the less). This keyword basically works just like "function" but it returns the bytecode for the chunk and does not capture upvalues. Now we write:

	luaproc.newproc( chunk()
		-- create a new channel
		luaproc.newchannel( "achannel" )
		-- create a new Lua process
		luaproc.newproc( chunk()
			-- send a message to the channel
			luaproc.send( "achannel", "hello world" )
		end )
		-- create a new Lua process
		luaproc.newproc( chunk()
			-- receive a message from the channel
			msg = luaproc.receive( "achannel" )
			-- print the received message
			print( msg )
		end )
	end )

The differences are subtle, but the problems cited above are resolved.

Mark