vicisdev Posted August 12, 2021 Share Posted August 12, 2021 (edited) Often times more complex function which do a lot to the user requires a lot of required and optional parameters. Think about InterpolateBetween function. Is it a best practice to instead of countless parameters passed in to a function to pass in a single table which keys matches those parameters? If not can we turn this into a best practice? A thing such as passing an options table makes the code auto documented so when you look at it you know exaclty what that "false" value means. Bad way The code below shows how clueless it can be when you have a lot of parameters to a function. To be honest, it could be even worst if written all in a sigle line. interpolateBetween( 0, 0, 0, 10, 10, 10, 0.5, "Linear" ) Good way This seems more interesting, doesn't it? You know exactly what all those values means. What do you think? interpolateBetween({ from = { 0, 0, 0 }, to = { 10, 10, 10 }, progress = 0.5, easing = "Linear" }) This also makes it easier to work with optional parameters Edited August 12, 2021 by vicisdev fixing indentation & typos Link to comment
CastiaL Posted August 12, 2021 Share Posted August 12, 2021 (edited) _interpolateBetween = interpolateBetween function interpolateBetween(from, to, progress, easing) return _interpolateBetween(unpack(from), unpack(to), progress, easing) end -- example interpolateBetween( from = { 0, 0, 0 }, to = { 10, 10, 10 }, progress = 0.5, easing = "Linear" ) or _interpolateBetween = interpolateBetween function interpolateBetween(table) return _interpolateBetween(unpack(table.from), unpack(table.to), table.progress, table.easing) end -- example interpolateBetween({ from = { 0, 0, 0 }, to = { 10, 10, 10 }, progress = 0.5, easing = "Linear" }) Edited August 12, 2021 by CastiaL Link to comment
vicisdev Posted August 12, 2021 Author Share Posted August 12, 2021 (edited) 23 minutes ago, CastiaL said: _interpolateBetween = interpolateBetween function interpolateBetween(from, to, progress, easing) return _interpolateBetween(unpack(from), unpack(to), progress, easing) end -- example interpolateBetween( from = { 0, 0, 0 }, to = { 10, 10, 10 }, progress = 0.5, easing = "Linear" ) or _interpolateBetween = interpolateBetween function interpolateBetween(table) return _interpolateBetween(unpack(table.from), unpack(table.to), table.progress, table.easing) end -- example interpolateBetween({ from = { 0, 0, 0 }, to = { 10, 10, 10 }, progress = 0.5, easing = "Linear" }) Ok, I know I could create a workaround to it but this is just a discussion. Also, you wouldn't want to call two unpacks on a function like interpolateBetween which run on every frame. Your first example is quite interesting and made me search for "Lua named argument". It turns out Lua already have named arguments built in, but it's not how you wrote it. It would be something like this: local function coolFunction(args) -- ... end coolFunction { param1 = "val1", param2 = "val2", param3 = "val3" } I've already used it but I totally forgot about it lol. Anyway the discussion remains the same. Edited August 12, 2021 by vicisdev Link to comment
CastiaL Posted August 12, 2021 Share Posted August 12, 2021 Unfortunately, only these solutions are available to me at the moment. Link to comment
vicisdev Posted August 12, 2021 Author Share Posted August 12, 2021 (edited) 9 minutes ago, CastiaL said: Unfortunately, only these solutions are available to me at the moment. Please read the edited version of my answer if you have not already Edited August 12, 2021 by vicisdev Link to comment
Moderators IIYAMA Posted August 15, 2021 Moderators Share Posted August 15, 2021 On 12/08/2021 at 19:38, vicisdev said: You know exactly what all those values means. What do you think? It does have some benefits. Some very good ones. But I could also find a few cons, how would you address the following? 1. You have to write more code. (More than double in some cases) 2. You need to know the exact table keys. For some functions those are obvious, for other that might become complicated based on the context and requires more wiki info: x, x1, x2, text, message, speed, velocity, time, duration. This is a language as well as a logic issue. It needs some clear rules in order to function. 3. Somebody has to update the wiki with a 3e syntax. 4. A lot of object instance creation and disposal on onClientRender is a combination I rather not recommend. Link to comment
The_GTA Posted August 15, 2021 Share Posted August 15, 2021 (edited) This sounds like you do not agree with the Lua language design. The idea of named parameters could be nice if the Lua function call were extended to be a key-value map for parameters in general. Right now the parameters to a function are an integer-map. By adding a new opcode "LUA_CALL_MAPPED" each parameter could first pass the ID and then the value. This would prevent the creation of a table for each function call (IIYAMA made an excellent point why creation of a table would be a bad idea). I disagre with your syntax though, so here is mine: function named_args map( one, two : two, three : 1 ) -- one = 1 -- two = 2 -- three = 3 end named_args( "one" = 1, two : 2, 3 ) This syntax is backwards compatible with the old way of calling Lua functions. Edited August 15, 2021 by The_GTA 1 Link to comment
vicisdev Posted August 20, 2021 Author Share Posted August 20, 2021 (edited) On 15/08/2021 at 11:19, IIYAMA said: It does have some benefits. Some very good ones. But I could also find a few cons, how would you address the following? 1. You have to write more code. (More than double in some cases) 2. You need to know the exact table keys. For some functions those are obvious, for other that might become complicated based on the context and requires more wiki info: x, x1, x2, text, message, speed, velocity, time, duration. This is a language as well as a logic issue. It needs some clear rules in order to function. 3. Somebody has to update the wiki with a 3e syntax. 4. A lot of object instance creation and disposal on onClientRender is a combination I rather not recommend. I tested 4 and for 10000 iterations on every frame it would increase the frame drawn time by about 4ms (on my PC). I don't know if someone would get a UI with more than 10000 function calls per render, but creating tables does decrese performance. About the third point, I'm not asking to rewrite the MTA API, this practice could be good for later community created libraries. The second point the first sentence I think it's not a problem since you have to know what every parameter means anyway. The first one, I don't fear writing more in order to get better readability. I see a lot of people writing a function call in a single line +100 characters long specially when using DX because they think less lines is better or even naming variables on character long. From the perspective of the interpreter just minify your files and you're good. On 15/08/2021 at 15:59, The_GTA said: This sounds like you do not agree with the Lua language design. The idea of named parameters could be nice if the Lua function call were extended to be a key-value map for parameters in general. Right now the parameters to a function are an integer-map. By adding a new opcode "LUA_CALL_MAPPED" each parameter could first pass the ID and then the value. This would prevent the creation of a table for each function call (IIYAMA made an excellent point why creation of a table would be a bad idea). I disagre with your syntax though, so here is mine: function named_args map( one, two : two, three : 1 ) -- one = 1 -- two = 2 -- three = 3 end named_args( "one" = 1, two : 2, 3 ) This syntax is backwards compatible with the old way of calling Lua functions. This is very specialized. I'm not a Lua expert, I had no clue about this opcode, I have no idea what's happening here but it's cool. But this opcode would need to be added in the MTA's Lua library, wouldn't it? It's not a configuration you can toggle in your server config files. Edited August 20, 2021 by vicisdev Link to comment
The_GTA Posted August 20, 2021 Share Posted August 20, 2021 (edited) 5 hours ago, vicisdev said: This is very specialized. I'm not a Lua expert, I had no clue about this opcode, I have no idea what's happening here but it's cool. But this opcode would need to be added in the MTA's Lua library, wouldn't it? It's not a configuration you can toggle in your server config files. Once this opcode is available any resource could enable it inside of their own meta.xml file. <script src="advanced.lua" type="client" extended_syntax="true" /> We are talking about a possible feature in the future. I could implement it inside of the Lua compiler that I have started working on this month. Then it would be merged into MTA after QA. Edited August 20, 2021 by The_GTA Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now