lua-users home
lua-l archive

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


First note that my previous bit of code contained a transcription error. It should have read:

			elseif s == iterate then
				return f, state, key

Arguably, mapping is common enough that one might optimize for it syntactically by insisting that sequence transformers -- i.e., functions operating on sequences -- get explicitly declared.

	local transformers = setmetatable( { }, { __mode = 'kv' } )

	function transformer( fn )
		transformers[ fn ] = fn
		return fn
	end

	function iterate( seq )
		return seq
	end

	function iterate( seq )
		return seq
	end

	function seq( f, state, key )
		local self, apply
		apply = function( ff, ... )
			if ff == 'done' then
				return ...
			end
			if ff then
				f = ff
			end
			return self, state, key
		end
		self = function( s, k, ... )
			if s == state then
				return f( s, k )
			elseif s == iterate then
				return f, state, key
			elseif transformers[ s ] ~= nil then
				return apply( s( self, f, k, ... ) )
			else
				return apply( map( self, f, s, k, ... ) )
			end
		end
		return self, state, key
	end

Where map is defined appropriately.

This would then able things like:

	seq.gmatch( text, "%a" )( string.lower )( seq.collect_set )

Mark

On Jan 1, 2010, at 10:09 PM, Mark Hamburg wrote:

> Okay, how about this:
> 
> 	function iterate( seq )
> 		return seq
> 	end
> 
> 	function seq( f, state, key )
> 		local self, apply
> 		apply = function( ff, ... )
> 			if ff == 'done' then
> 				return ...
> 			end
> 			if ff then
> 				f = ff
> 			end
> 			return self, state, key
> 		end
> 		self = function( s, k, ... )
> 			if s == state then
> 				return f( s, k )
> 			elseif s == iterate then
> 				return f, s, k
> 			else
> 				return apply( s( self, f, k, ... ) )
> 			end
> 		end
> 		return self, state, key
> 	end
> 
> Which then enables us to write things like:
> 
> 	function collect( seq )
> 		local r = { }
> 		for k, v in seq( iterate ) do
> 			r[ k ] = v
> 		end
> 		return 'done', r
> 	end
> 
> This shows that iterate can pay off in other ways besides simply performance. (And if I understand LuaJIT's tracing behavior, the performance win for iterate may not even be relevant since state will be a constant in the loop and hence the tests on state will get optimized away even without the use of iterate.)
> 
> This is beginning to feel like it could turn into a very useful library...
> 
> Mark
> 
>