lua-users home
lua-l archive

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


Hi,

This carries on the discussion of the "source for functions" thread:

Playing around some more with function source, bytecode, argument declarations
etc. it appears to me, that the most flexible solution is not far away:

I was down to a function "deffun" that takes as arguments a function name,
a list of arguments and a string containing the source. It is now fully in
the responsibility of this function not only to store source and compiled
function together in one tagged table (that is accessible as function aswell)-
also different styles of argument handling are now possible, eg. the
argumentlist could be a table of <name>=<type> pairs, and the "function"
tagmethod could per option decide to type check the arguments or not. 
Then I stumbled over a syntax which is not really pleasing, 
function definitions would now look like this:

deffun("myPrint", "a", "print(\"myprint says:\",a)")

-- or

deffun("anotherFunc", {a1="string", a2="number"}, 
"print('anotherFunction says:')\
print(a1,a2)"
)

Now instead of puzzling about newlines in strings etc. I really like to
suggest no new syntax but A NEW TAGMETHOD: 

-- with:
function deffun(name, arguments, body)
  ...
end
-- do:
settagmethod(tag(nil), "definefunction" definefunction)
-- such that a simple ...
function myPrint (a) 
    print("myPrint says:", a)
end
-- ... would invoke a function call similar to the above "deffun" lines.

This way we would be free to assign any semantics to a function definition
in our usual syntax. First this entails a builtin function "rawdefinefunction"
which is needed to really generate a function object which is returned
from the builtin function and can be assigned to any global or local variable.
I haven't checked all implications, on how this blends with local
functions and closures; first it appears, that a function name will now
be optional; is the name a part of the function altogether? or is it two
basic operations: defining a function (argument_list, body) and assigning
the result to some variable, table field whatsoever. So maybe it would be:

function deffun (arguments, body)
   -- build my_arguments from arguments
   local fun={source=body, func=rawdefinefunction(my_arguments, body)}
   settag(fun, funcTag)
   return fun
end
-- the "function" tagmethod (f,a) for funcTag would simply call(f.func,a)

Assignment to the global name would then be outside the scope of this 
tagmethod. For anonymous functions the parser probably uses something 
similar to "rawdefinefunction" anyway, replacing a function definition
by the function object in place.

Main applications of such a technique would probably be, to store additional
information with functions, such as:
  -- the source code
  -- argument type information
  -- modifiers? think of :

	private()
	function dontcallme () ... end

	-- which could set a flag in the function's table, that prevents
	-- calls from outside this "module"

I know, the matter is not as simple, as I advertised it. Firstly the
parser may have to be completely re-written :-). More seriously the
syntax of <argument_list> might have to be reconsidered: let 
   function a (a,b,c) body end
produce a call of the tagmethod with arguments ({a,b,c}, body). 
Wouldn't it be neat to let
   function checked {a=string, b=number} body end
invoke it with ({a="string", b="number"}, body) ???
How about evaluation of names "string", "number" in the example? Would we need:
{a="string", b="number"} 
etc.pp.

Ok, I will stop for now. Maybe this looks all too esoteric to you?

I'm eagerly awaiting comments

Stephan
--------------------------------------------------------------------------
 Stephan Herrmann
 ----------------
 Technical University Berlin
 Software Engineering Research Group
 http://swt.cs.tu-berlin.de/~stephan
 phone: ++49 30 314 73174         
--------------------------------------------------------------------------