moonscript icon indicating copy to clipboard operation
moonscript copied to clipboard

[Feature Request] MoonScript VarArg Naming

Open Idyllei opened this issue 9 years ago • 6 comments

In some of my code, I find myself using the extra arguments in a packed (named) table. For example:

stringify = (obj, ...) ->
    opt = {...}
    -- Do stuff with opt

In other programming languages, one is allowed to give a name to the variable arguments. In MoonScript, I would LOVE to be able to do it like so (and I think it still looks nice):

stringify = (obj, ...opt) ->
    -- Do stuff with opt

Which may (or may not) translate to:

stringify = (obj, ...)
    opt = {...}
    -- Do stuff with opt

This could make some code snippets smaller in the long run. And I believe this would be a valuable addition to the MoonScript language (in terms of readability and succinctness).

Idyllei avatar Jun 14 '15 20:06 Idyllei

+1 to this. Seems like a fairly small thing, but it would look pretty nice. Parallels with coffeescript as well.

ghost avatar Jun 15 '15 05:06 ghost

+1

evandro-costa avatar Jun 17 '15 22:06 evandro-costa

+1

deathbeam avatar Jun 17 '15 22:06 deathbeam

@leafo Do you have any input on this?

Idyllei avatar Dec 28 '15 21:12 Idyllei

:+1:

RyanSquared avatar Apr 05 '16 13:04 RyanSquared

Some thoughts:

  1. It should use table.pack(...) rather than {...} so that one gets a chance to use a for i=1, opt.n loop so as to both keep track of the indices and handle nil arguments gracefully. With for x in *opt you can do the latter but not the former.

  2. Wouldn't it be a good idea to use the Python-like * operator:

    foo = (bar, *opt) ->
    

    MoonScript already uses *foo to mean "unpack and iterate foo" and extending it to in a signature mean "pack remaining/var args into foo" kind of makes sense, while ...foo is two more chars to type/fit into the line.

  3. I pretty much always want the options to be either a map table or the value of some default key, so I do this:

    foo = (required, opt={}) ->
      unless 'table' == type opt
        opt = { default: opt }
      -- Do something with opt
    

    making the first two of the following equivalent, but also allowing the third:

    foo 'bar', 'baz'
    
    foo 'bar', {default: 'baz'}
    
    foo 'bar', {default: 'baz', other: 'quux'}
    

    I'm so addicted to this pattern that I wish there was a syntax for it, like

    foo = (req, *opt:default) ->
      -- do stuff
    

    which would compile into something like this

    local foo
    do
      foo = function (req, opt)
        if nil == opt then
          opt = {}
        elseif 'table' ~= type(opt) then
          opt = { default = opt }
        end
        -- do stuff
      end
    end
    

bpj avatar Jun 11 '20 10:06 bpj