Proposal: Function Definition Named/Default Argument Syntax Sugar

6 messages
Open this post in threaded view
|

Proposal: Function Definition Named/Default Argument Syntax Sugar

Open this post in threaded view
|

Re: Proposal: Function Definition Named/Default Argument Syntax Sugar

 2012/6/13 Andrew Starks <[hidden email]>: > I like named arguments much more so than positional ones. In fact, I > hate positional arguments and refuse to use them. It depends on the number of arguments. One argument: daft to make a whole table just for it. Ten arguments: daft to depend only on position. > Therefore, all of my functions look like this: > > local myfunc = function(args) >  local name = args.name or nil >  local age = args.age or error("You have to pass me an age, dimwit.") > There is also the possibility of a mixture.  For example, only today I wrote a function that can be called this way:    subst { expr, x=1, y=2, z=3 } The great thing about the fact that this is legal in Lua is that the number and the names of the extra parameters may vary.  It's way more powerful than the named parameters of Python etc, in which the names have to be predictable. > I'm just looking for a way to express what I expect within a table > argument and to do so in the same spirit as the sugar that we get with > a function call that has a single table as the argument. Of course, I > only propose this if it contributes to Lua's simplicity. Having sugar in the same spirit sounds very attractive, especially in the southern hemisphere where it is very cold right now :-) But seriously, the simplicity of Lua would be well served by this aspect of your proposal: the syntax of a valid call sequence should be valid definition syntax too.  How about the following:    1. Defining a function with {...} instead of (...) means that it takes a single table-valued argument, with the specified fields initialized.    2. The implicit name for that argument should clearly be `self`.    3. Which combines nicely with object-oriented programming. Example:    function fct {expr, x=1, y=2, z=3}       ...    end has the same semantics as (_proto being invisible to the user)    function fct(self)       local _proto = {expr, x=1, y=2, z=3}       for k,v in pairs(_proto) do self[k] = self[k] or v end       ...    end At a later call, `fct(tbl)` would ensure that tbl[1], tbl.x, tbl.y and tbl.z are defined on return.  And if `fct` is assigned to `obj.init`, then merely `obj:init()` would initialize those fields.
Open this post in threaded view
|

Re: Proposal: Function Definition Named/Default Argument Syntax Sugar

 With a metatable and some helper functions, you can have almost what you need : local function required(msg)   return function(value) return value or error(msg, 2) end end local function check_type(...)   local types = {...}   return function(value)     local t = type(value)     for i=1,#types do       if t == types[i] then return value end     end     error("Expected value of type "..table.concat(types, " or ")..", got "..t)   end end function get_args(args, canvas)   return setmetatable({}, {__index=function(t, k)     local v = rawget(canvas, k)     if type(v) == 'function' then return v(args[k]) end     return args[v] or v   end}) end Function get_args must be called at the beginning of all named parameters functions. Local functions required and check_type are just example of validating functions. With that above code, you can then write something like this: function person(args)   args = get_args(args, {     name = required "Please provide a name", -- your name     age = check_type("number"), -- your age     address = "(no street address)", -- your street address    })    print(args.name, args.age, args.address) end person{name = "John Doo", age=56} --> John Doo 56  (no street address) person{} -- Error: Please provide a name
Open this post in threaded view
|