• Subject: Re: Proposal: Function Definition Named/Default Argument Syntax Sugar
• From: Dirk Laurie <dirk.laurie@...>
• Date: Wed, 13 Jun 2012 19:39:40 +0200

2012/6/13 Andrew Starks <andrew.starks@trms.com>:
> 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.

• Follow-Ups:
• References: