Implementation of named function parameters

193 views
Skip to first unread message

Patrick Kurth

unread,
Sep 10, 2025, 5:37:46 AMSep 10
to lu...@googlegroups.com
Hello,

I would like to have proper support for named parameters (different
from the typical way using tables). My preferred syntax would be as
shown in the following example. Named parameters are introduced by '@'
and then resolved/used in the function call with '?' (these are only
rough ideas of course, if there is a good reason not to do it like
that, that's also fine):


-- default of 'extra' is nil
-- default of 'option' is 1
function foo(a, b, @key extra, @key option = 1)
if option ~= 1 or option ~= 2 then
error(string.format("foo: expected 1 or 2 as option, got
'%s'", option))
end
if extra then
print(string.format("extra: %s", extra))
end
print(a, b)
end

foo(1, 2)
foo(1, 2, ?extra "additional string")
foo(1, 2, ?option 2)


My idea for implementing this is to store named parameters and their
default values as upvalues for the function. Additionally, the named
parameter are internally turned into positional regular parameters.
During the call the additional parameters are either filled by their
default values from the upvalues or the values given in the code.
The compiler perhaps could emit a special instruction handling this
value-fetching, which is only done when named parameters are used
(which is known at compile time).

Is something like this possible without changing a large amount of
things? I'm comfortable with changing the parser, adding a few
instructions, but ideally this addition would work with the existing
architecture, using the internal API.

I am happy to read your opinions on this.

Kind regards,
Patrick

Martin Eden

unread,
Sep 10, 2025, 10:35:21 AMSep 10
to lu...@googlegroups.com
Hello Patrick,

Okay, we have several unused keyboard characters: @ $ ?.
Let's create additional constructions with them!

  function foo(a, b, @key extra, @key option = 1)
    if option ~= 1 or option ~= 2 then
      error(string.format("foo: expected 1 or 2 as option, got '%s'",
option))
    end
    if extra then
      print(string.format("extra: %s", extra))
    end
    print(a, b)
  end

  function do_job()
    foo(1, 2, ?extra "additional string")
    foo(1, 2, ?option 2)
  end

* Note that that caller of foo() now depends of parameter names.
  If you change "extra" to "extra_string", all dependent code
  needs to be adjusted.

* Argument list is no longer a sequence

  How to do generic call?

    function do_job(worker, worker_args)
      worker(table.unpack(worker_args))
    end

    do_job(foo, { 1, 2 })

-- Martin

Patrick Kurth

unread,
Sep 10, 2025, 2:26:46 PMSep 10
to lu...@googlegroups.com
Hello Martin,

>
>
> * Note that that caller of foo() now depends of parameter names.
>    If you change "extra" to "extra_string", all dependent code
>    needs to be adjusted.

Yes, obviously. Just as code needs to change when you change the name
of a function.

> * Argument list is no longer a sequence
>
>    How to do generic call?
>
>      function do_job(worker, worker_args)
>        worker(table.unpack(worker_args))
>      end
>
>      do_job(foo, { 1, 2 })
>

You don't. Not every function needs to support this.

I'm confused with your message, as it did not answer any of my question
but point out unnecessary things. Sorry for the slight rudeness, but I
find it odd. This is not about standard lua, it's about how to modify
the lua implementation in a project embedding its own lua interpreter
in order to support something like this.

Kind regards,
Patrick

Sainan

unread,
Sep 10, 2025, 2:33:19 PMSep 10
to lu...@googlegroups.com
Pluto[1] has named arguments[2], but it's implemented entirely in the parser so the coverage is somewhat limited by what the type system can see. The latest release might make this a bit less painful with $declare and $include. Definitely a different approach to what you had in mind.

[1] https://github.com/PlutoLang/Pluto
[2] https://pluto-lang.org/docs/New%20Features/Named%20Arguments

-- Sainan

eugeny gladkih

unread,
Sep 11, 2025, 4:20:51 AMSep 11
to lu...@googlegroups.com


> On 10 Sep 2025, at 17:35, 'Martin Eden' via lua-l <lu...@googlegroups.com> wrote:
>

...

> * Note that that caller of foo() now depends of parameter names.
> If you change "extra" to "extra_string", all dependent code
> needs to be adjusted.


like it was

>
> * Argument list is no longer a sequence
>

no, it is. all parameters have the position number which is the same as it was

--
Yours sincerely, Eugeny.


Rett Berg

unread,
Sep 11, 2025, 11:08:04 AMSep 11
to lua-l
I feel like this feature is unnecessary in lua since you can accept a table as your only argument. If you want your function to behave with named arguments you can just do:

function myfn(t)
  local a, b = t[1] or t.a, t[2] or t.b
  print('a', a, 'b', b)
end

myfn{'this is a', b='this is b'}

Philippe Verdy

unread,
Sep 11, 2025, 12:22:42 PMSep 11
to lu...@googlegroups.com
Passing a table has a cost because you need to construct it.

What the user proposes is an extension for giving explicit names to *numbered* parameters, and so allow calls without needing to pass intermediate "nil" values. This makes sense for me. Nothing is changes in the generated bytecode (except possibly with additional meta-data for retrospection of functions. The compiler would just do the trick to pass enough nil values in the call stack, but should then detect possible duplicate parameter (for example for the "function f(@a, @b)", we still have parameters 1 and 2, taking a nil value by default, but if we call "f(10,$a=20)" there's a collision on parameter 1: you should not call the function with two values for the same parameter 1).

I like the ability to give explicit names to positional parameters. (For now the retrospection gives fake info about these names, or can only refer them by their integer position).

Note that the user proposes a second independant extension to pass other default values than nil: in Lua, all missing parameters are all nil, and the internal code of the function has to check these nil values to treat them with a different value). Externally, the compiled function does not expose these other default values (and does not even expose if these parameters cannot be null: this is something considered bad in many projects, and thatr the compiler should be fixed by being aware of such constraints; however the Lua language does not expose any constraint to functions, so you can still call "math.sin(nil)" or just "math.sin()" even if it makes no sense, and the function has to perform parameter validation all the time, and this has a runtime cost that could be avoided if the check was performed at compile-time: this is a similar problem in Java and many languages that have "nil"/"null" values or "any" in Python: this complicates the QA in the development/debugging cycle, with frequent missing value checks; notice that the caller may not even be completely aware of these usage constraints when he calls a function: there's a missing "contract", and Lua is not designed to support contracts, so in large projects, you need to look at documentation, which is often defective or not fully available; as well Lua does not make any inference on those unspecified contracts; that's what Java solved cleanly using "annotations" and why they are now standard in all large Java projects).


--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/lua-l/db9f0360-79d2-45b8-b8a6-86121985a619n%40googlegroups.com.

Andrey Dobrovolsky

unread,
Sep 11, 2025, 12:23:25 PMSep 11
to lu...@googlegroups.com
Quote from https://hisham.hm/papers/talks/hisham-lap-luaconf2017.pdf :

Programming languages and their mottos
● Perl – maximalist: n ways to do it – “There’s More Than One Way To Do It”
● Python – opinionated: 1 way to do it – “There should be one—an
preferrably only one—obvious way to do it” - Zen of Python
● Lua – minimalist: 0 ways to do it – “Mechanisms, not policies” --
Corollary: “There’s More Than One Way To Do It”

Regards,
Andrew

чт, 11 вер. 2025 р. о 18:08 Rett Berg <goog...@gmail.com> пише:

Rett Berg

unread,
Sep 11, 2025, 12:27:16 PMSep 11
to lu...@googlegroups.com
Nothing is changes in the generated bytecode (except possibly with additional meta-data for retrospection of functions. The compiler would just do the trick to pass enough nil values in the call stack, but should then detect possible duplicate parameter...

This would require the compiler to be tracking types, which I'm pretty sure would require a complete overhaul of the lua compiler. The lua compiler currently knows nothing about what function you are calling, only that it is a local or global.

This seems like it could be a useful feature in a lua extension language like teal. I'd say keep it out of lua core as it would add way too much complexity to the compiler.

You received this message because you are subscribed to a topic in the Google Groups "lua-l" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/lua-l/BgNg4MkCOg0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to lua-l+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/lua-l/CAN5FJ7cN3_Av-3jAHF%2BW4-2%3DGX0ij8ucpu3ypcXogRsr9%3DMqOg%40mail.gmail.com.

Patrick Kurth

unread,
Sep 11, 2025, 1:23:21 PMSep 11
to lu...@googlegroups.com
Dear list,

Apparently I have to clarify a few things:
* This is not about standard lua, so a discussion of whether it
should be kept out of the lua core is unnecessary
* I am aware of the method of using tables to mimic named parameters.
I explicitly do not want this
* The question was about how to implement this, not whether I should
(and I have good reasons IMHO, see below)
* I am willing the modify the VM, the compiler etc.

Why I want this:
I use an embedded lua interpreter in a larger project where internal
structures are controlled via lua, much like a game engine (it is about
integrated circuits, not games, but the usage of lua is similar). There
are API functions that require many parameters. Function calls with 13
parameters are ugly, this can be enhanced by named parameters.
Furthermore, named parameters allow addition to extend API functions
without changing existing code (to some extent at least).
So yes, I have good reasons to look for a feature like this and since I
maintain my own lua interpreter within this project anyway it makes
sense to me to think about implementing something like this.
Hence I would like to talk about the technicalities of this and whether
I might run into unforseen roadblocks.

Let's not talk about the 'if', let's talk about 'how' ;)

Kind regards,
Patrick

Rett Berg

unread,
Sep 11, 2025, 2:10:24 PMSep 11
to lu...@googlegroups.com
Okay, so this is intentionally a new language.

On the topic of *how*, I want to make sure you've explored all possibilities. Mainly, you could write a separate language which compiles to lua that implements this, and reduces all named-arg calls to the ugly code you want to avoid. This would keep the fork from lua as minimal as possible.

For instance your language could parse:

foo(1, 2, f='something')

And output the following for the lua interpreter (possibly as lua bytecode instead of literal source code)
foo(--[[a]]1, --[[b]]2, --[[c]]nil, --[[d]]nil, --[[e]]nil, --[[f]]'something')

You could use a different extension than '.lua' for files written in your language and handle files with that extension by overriding how `require` works.

Hope that helps!

Scott Morgan

unread,
Sep 11, 2025, 2:13:29 PMSep 11
to lu...@googlegroups.com
On 11/09/2025 17:22, Philippe Verdy wrote:
> Passing a table has a cost because you need to construct it.

Have you profiled that cost? How big is it?

Seen lots of people trying to avoid tables in Lua, but considering Lua
is like 90% tables - getting, setting, creating, collecting, _G, _ENV,
strings, std libs, userdata, etc. etc. - does it really make that much
difference to performance in the real world?

If you do have a particularly hot area of code, sure strip out as much
table use (and strings) as possible (would such a section of code need
named params?). But in general? Not convinced.

Scott

Sainan

unread,
Sep 11, 2025, 2:19:48 PMSep 11
to lu...@googlegroups.com
> Seen lots of people trying to avoid tables in Lua

Usually I would share your sentiment, and, yes, using tables is relatively cheap, but creating them... oh boy. And that is what is asked here: Creating a table for every function call to be made. It's a terrible idea, and will lead to a massive performance drops.

-- Sainan

Roberto Ierusalimschy

unread,
Sep 11, 2025, 2:41:34 PMSep 11
to 'Sainan' via lua-l
> > Seen lots of people trying to avoid tables in Lua
>
> Usually I would share your sentiment, and, yes, using tables is relatively cheap, but creating them... oh boy. And that is what is asked here: Creating a table for every function call to be made. It's a terrible idea, and will lead to a massive performance drops.

I don't think the point is "Creating a table for every function call
to be made", but creating a table for every function call to be made
THAT USES NAMED ARGUMENTS. More ofthen than not, named arguments
are used for functions that are somewhat complex.

-- Roberto

Philippe Verdy

unread,
Sep 11, 2025, 4:21:06 PMSep 11
to lu...@googlegroups.com
Le jeu. 11 sept. 2025 à 18:27, Rett Berg <goog...@gmail.com> a écrit :
Nothing is changes in the generated bytecode (except possibly with additional meta-data for retrospection of functions. The compiler would just do the trick to pass enough nil values in the call stack, but should then detect possible duplicate parameter...

This would require the compiler to be tracking types,

Absolutely NO. missing parameters in Lua are ALREADY not passed at end and take the value NIL. And you can already pass more parameters than what is exposed by the function Lua source definition, where local variables that are named are invisible from the caller. The caller can then freely pass the number of parameters they want (without knowing if the function will use them as named parameters or not), as long they can fit on the call stack. No type information is necessary.
However if one wants to call that function used named parameters instead, the compiled code of the function should expose in metadata a mapping from names to parameters number (this mapping can be generated by the Lua compiler, or can be exposed by the interface of a natice C implementation, using for example its metatable).

Rett Berg

unread,
Sep 11, 2025, 4:38:45 PMSep 11
to lu...@googlegroups.com
This would require the compiler to be tracking types,
Absolutely NO.
... the compiled code of the function should expose in metadata a mapping from names to parameters number 

But this would have a runtime cost -- at which point you're barely better off than passing a table (If you're better off at all).

--
You received this message because you are subscribed to a topic in the Google Groups "lua-l" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/lua-l/BgNg4MkCOg0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to lua-l+un...@googlegroups.com.

Andrey Dobrovolsky

unread,
Sep 11, 2025, 4:48:28 PMSep 11
to lu...@googlegroups.com
An example of using closure's locals for arguments. Demands putters ((

Creating the job:

local make_job = function()
local a, b, c -- arguments
local clean = function(A, B, C) -- positional
a, b, c = A or 1, B or 2, C or 3
end
clean() -- defaults
local put_a, put_b, put_c = -- putters
function(x) a = x end,
function(x) b = x end,
function(x) c = x end
local job = function() -- very complex job
print(a + b + c, "--", a, b, c)
end
return job, put_a, put_b, put_c, clean
end

Usage:

print("first dataset")

local job1, put_first1, put_second1, put_third1, clean1 = make_job()

job1()
put_first1(5) job1()
put_second1(10) job1()

print("second dataset")

local job2, put_first2, put_second2, put_third2 = make_job()

put_first2(4) job2()
put_second2(11) job2()

print("let's return to the first dataset")

put_third1(1) job1()
clean1(100, 200) print("clean1(100,200)") job1()

Output:

first dataset
6 -- 1 2 3
10 -- 5 2 3
18 -- 5 10 3
second dataset
9 -- 4 2 3
18 -- 4 11 3
let's return to the first dataset
16 -- 5 10 1
clean1(100,200)
303 -- 100 200 3

Is usage of closure more expensive than table?

-- Andrew

чт, 11 вер. 2025 р. о 23:38 Rett Berg <goog...@gmail.com> пише:
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/CALW7ahymYzJwV_7vs43QPZHoT2yCytQvVhD_VkG4QWAc0XjvyA%40mail.gmail.com.

Sean Conner

unread,
Sep 11, 2025, 5:20:35 PMSep 11
to lu...@googlegroups.com

I've read the follow-up clarifications from Patrick, so I know this isn't
for Lua proper, but for a private branch of Lua.

It was thus said that the Great Patrick Kurth once stated:
> Hello,

Hi.

> I would like to have proper support for named parameters (different
> from the typical way using tables). My preferred syntax would be as
> shown in the following example. Named parameters are introduced by '@'
> and then resolved/used in the function call with '?' (these are only
> rough ideas of course, if there is a good reason not to do it like
> that, that's also fine):
>
>
> -- default of 'extra' is nil
> -- default of 'option' is 1
> function foo(a, b, @key extra, @key option = 1)

Why mark certain parameters as named? I would think that having a
function with both positional and named parameters might be confusing. Why
not just allow all the parameters to be used either positionally or named?
I also don't think you need the extra '@' or '?' for syntax. For example:

function foo(a,b,extra=nil,option=1)
...
end

foo(1,2) -- foo(1,2,nil,1)
foo(1,2,"...") -- foo(1,2,"...",1)
foo(1,2,,2) -- NOTE, missing extra as positional
-- maybe not allow?
-- foo(1,2,nil,2)

foo(a=1,extra="...") -- foo(1,nil,"...",1)
foo(extra="...") -- foo(nil,nil,"...",1)
foo(extra="...",1,2) -- maybe foo(1,2,"...",1)?

This is similar syntax to how tables can be constructed:

x = { field1 = a , field2 = b , 3 , 4 }
y = { 3 , 4 , field1 = a , field2 = b }

This is not to say you need to use tables for the implementation, just
that the idea of mixing positional and named fields isn't totally alien to
Lua. Ohe down side is how to handle this:

foo(1,2,"...",2,extra="!!!",option=42,a=5)

> My idea for implementing this is to store named parameters and their
> default values as upvalues for the function. Additionally, the named
> parameter are internally turned into positional regular parameters.
> During the call the additional parameters are either filled by their
> default values from the upvalues or the values given in the code.
> The compiler perhaps could emit a special instruction handling this
> value-fetching, which is only done when named parameters are used
> (which is known at compile time).
>
> Is something like this possible without changing a large amount of
> things? I'm comfortable with changing the parser, adding a few
> instructions, but ideally this addition would work with the existing
> architecture, using the internal API.

I think it could. Your idea of using upvalues for named parameters is
nice, but if you do allow my idea, you will have an upvalue per parameter
(which, now that I think about it, might have been the reason you wanted to
separate position from named values---to cut down on upvalues). Lua already
tracks names, making them availble to the debug routines, but if you do go
this route, be aware that such information can be stripped.

-spc

Sean Conner

unread,
Sep 11, 2025, 5:57:00 PMSep 11
to lu...@googlegroups.com
It was thus said that the Great Patrick Kurth once stated:
>
> Why I want this:

> I use an embedded lua interpreter in a larger project where internal
> structures are controlled via lua, much like a game engine (it is about
> integrated circuits, not games, but the usage of lua is similar). There
> are API functions that require many parameters. Function calls with 13
> parameters are ugly, this can be enhanced by named parameters.

I'm just curious, but how often are these large parameter functions
called? If it's just a few times, then using a table for the parameters
might be good enough.

Another question: are any of the parameters tables themselves? If not,
why not? [1] Speed concern over table construction? Poor API design? In my
experience, functions with a large number of paramters is a ... for lack of
a better term, a design smell (maybe not bad, but definitely not good). But
if you're stuck with it, you're stuck with it.

-spc


[1] Thinking of things like commonly passed paremters that don't change
too often, could be grouped into a table and passed as a single
parameter.

Patrick Kurth

unread,
Sep 11, 2025, 6:25:06 PMSep 11
to lu...@googlegroups.com
Hi Sean,

I'm still writing an answer to your previous message, but writing it
down I found some errors in my thinking :)
So that has to wait. Meanwhile, an answer to your last message:

On Thu, 2025-09-11 at 17:56 -0400, Sean Conner wrote:

>  I'm just curious, but how often are these large parameter functions
> called?  If it's just a few times, then using a table for the
> parameters
> might be good enough.

Definitely not a performance issue, as any heavy-lifting is happening
in C. So yes, I could probably also just turn that into a table, with
support of the compiler. Internally that would be... ok (not ideal, but
ok), but I don't want user-facing code to use tables. I want a concise
syntax, I even removed support for foo{} and foo"" calls. I never use
those.

>
>   Another question:  are any of the parameters tables themselves?  If
> not,
> why not? [1] Speed concern over table construction?  Poor API
> design?  In my
> experience, functions with a large number of paramters is a ... for
> lack of
> a better term, a design smell (maybe not bad, but definitely not
> good).  But
> if you're stuck with it, you're stuck with it.

Sometimes the parameters are tables, sometimes they are not. I agree
mostly about this being a design smell, but I have yet to find a better
solution. In my opinion, there are two choices: a large number of
parameters or split the task up in multiple functions. The former is
ugly, the latter can be weird from a semantic perspective and requires
passing a state around. Both are not ideal, but in the end I (mostly)
prefer a larger number of parameters.

As a specific example/use case: I'm developing a layout generator for
layouts of integrated circuits:
https://github.com/patrickschulz/openPCells

There are functions that perform certain tasks of placing objects in
layouts, for instance a rectangular metal fill in an area, guided by
exclude regions. For this the current interface is:

geometry.rectangle_fill_in_boundary(cell, layer, width, height,
xpitch, ypitch, xstartshift, ystartshift, boundary, excludes)

This function has 10 parameters and I (having wrote it myself)
constantly have to look up the parameters. In a call this looks not
very nice and only really makes sense with comments. However, grouping
these things in a table also does not really feel right, as there are
very different objects involved: A 'cell' is a C structure with a full
userdate layer in between, 'layer' is light userdata (layers are unique
and can simply be identified by their address). 'width', 'height',
'xpitch', 'ypitch', 'xstartshift' and 'ystartshift' are all numbers.
The boundary is a polygon (represented simply by a table) and excludes
is a table of polygons (again a table). Sure, I could just put these in
a table like this:

geometry.rectangle_fill_in_boundary({
cell = cell,
layer = layer,
-- and so on
})

but this does not feel right, as I have many of these functions, often
they have fewer parameters so regular parameters are fine. But now the
interface for one function is different. Not very nice, in my opinion.
So I could do something like this:

geometry.rectangle_fill_in_boundary( -- no table here
cell ,
layer,
{
width = width,
height = height,
-- and so on
},
boundary,
excludes
)

but this does not feel right as well, for me at least. The table
constructor within the function call is just not right.

geometry.rectangle_fill_in_boundary( -- no table here
cell ,
layer,
?width = width,
?height = height,
-- and so on
?boundary = boundary,
?excludes = excludes
)

looks nicer, again at least for me. The intended use and target
audience might also be relevant for these thoughts, as design tools for
integrated layout (mostly for digital circuits, if the difference
matters) typically are programmable via tcl, so you get a shell-like
interface. This also depends a lot on optional and named parameters.
You might have something like this forum example (sorry, it is hard to
find better examples as the documentation of these tools is mostly not
accessible for the public):
https://community.cadence.com/cadence_technology_forums/f/digital-implementation/38588/addstripe-command-for-multiple-power-domains

Ok, sorry for the wall of text. That all being said: I'm open for
suggestions regarding making API functions more concise and perhaps use
fewer parameters :)
*That* being said, I also don't mind diving into the lua internals and
hacking the compiler/interpreter, I still would like to try and
implement named parameters.

Kind regards,
Patrick

Luiz Henrique de Figueiredo

unread,
Sep 11, 2025, 10:29:37 PMSep 11
to lu...@googlegroups.com
> I'm open for suggestions regarding making API functions more concise
> and perhaps use fewer parameters :)

One approach is to use parameters for essential values only and add
one last table parameter with optional values that can have defaults.
This approach is used in LED [1] using attribute lists and in PDFlib
using strings [2].

[1] https://dx.doi.org/10.1002/(SICI)1097-024X(199607)26:7%3C737::AID-SPE31%3E3.0.CO;2-W
[2] https://www.pdflib.com/products/pdflib-family/

Rett Berg

unread,
Sep 12, 2025, 11:28:19 AMSep 12
to lu...@googlegroups.com
If the functions are not called in any tight loops then I would again recommend taking a single table as the input, that way you can freely use either named or positional arguments. You could pretty easily make a small library which converts a table with positional arguments into their associated named args -- actually I might do just this in my https://lua.civboot.org#Package_metaty library.

- Rett

--
You received this message because you are subscribed to a topic in the Google Groups "lua-l" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/lua-l/BgNg4MkCOg0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to lua-l+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/lua-l/CAD55k3r0FGD0vjpXwDkvApkey7dDnOH1QE5s-%2B6nZvzd29DdrQ%40mail.gmail.com.

Lars Müller

unread,
Sep 12, 2025, 4:13:03 PMSep 12
to lu...@googlegroups.com

I strongly agree with the sentiment.

Lua does not need "named parameters". If you want named parameters, use a table.
There is no need to introduce another language concept which is just a crippled form of tables.
What I love about Lua is that it avoids such unnecessary language complexities.
(And if a case was to be made for fragmenting "table-like" concepts, the most important distinction would probably be lists vs maps; and after that probably maps vs structs with a fixed set of members.)

There are many advantages to passing a table. To name just one, you can easily and cheaply pass it on to another function.
Probably quite a few scripting languages that have named parameters eventually ended up using some kind of hash map to be able to satisfy the demand for a variable number of them.

The assertion that "passing a table needs to have significant cost" has been proven wrong by LuaJIT's allocation sinking optimization [1].
I strongly encourage you to give it a shot. For a very simple example, I get the exact same performance and machine code.

And as others have said already, if you want peak performance on a hot path, might have to just use normal parameters after profiling.

Such is the nature of a scripting language: You can not expect abstractions to be zero cost - at least not in a relatively simple interpreted implementation.

On the plus side, everything can be wonderfully simple, reflectable and flexible.


Kind regards,
Lars

[1]: https://github.com/tarantool/tarantool/wiki/LuaJIT-Allocation-Sinking-Optimization

Reply all
Reply to author
Forward
0 new messages