3

I've been told in Java that I should avoid modifying the original parameters such as

public int doStuff(int begin, int end) {
  /* loop or something */
  begin++; //bad
  end--; //also bad
  /* end loop */
  return
}

instead, I should do something like

public int doStuff(int begin, int end) {
  int myBegin = begin; //something like this
  int myEnd = end;
  /* stuff */
  return
}

So, I've been doing this in lua

function do_stuff(begin, last)
  local my_begin = begin
  local my_last = last
  --stuff
  my_begin = my_begin + 1
  my_last = my_last - 1
  --stuff
end

But, I'm wondering if

function do_stuff(begin, last)
  --stuff
  begin = begin + 1
  last = last - 1
  --stuff
end

is also discouraged, or is it nice and concise?

Blubber
  • 1,375
  • 1
  • 15
  • 32

3 Answers3

6

There are no rules. Let taste, clarity, and need decide.

Nevetheless, a common idiom is to provide default values for parameters as in

function log(x,b)
   b = b or 10
   ...
end
lhf
  • 70,581
  • 9
  • 108
  • 149
2

If you were told not to modify the parameters of functions, then there was probably a reasoning associated with that. Whatever that reasoning is would apply as much to Lua as to Java, since they have similar function argument semantics. Those reasons could be one or more of (but not limited to):

  • If you modify a parameter... you don't have it anymore. If you suddenly have a need for the original value you were passed, it's gone now.

  • Creating confusion, depending on how the parameters are named. The word "begin" suggests the beginning of something. If you change it, it isn't necessarily the beginning anymore, but merely the current element you're operating on.

  • Creating potential errors, if dealing with reference types (non-basic types in Java, tables and such in Lua). When you modify an object, you're changing it for everyone. Whereas incrementing an integer is just changing your local value. So if you're frequently modifying parameters, you still need to think about which ones you ought to be poking at and which ones you shouldn't be.

To put it another way, if you agreed with the suggestion for doing so in Java, then it applies just as much to Lua. If you didn't agree with the suggestion in Java, then you have no more reason to follow it under Lua.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • "If you change it, it isn't necessarily the beginning anymore": Indeed! I eschew the concept of vary-ables almost everywhere. If you change the value of a variable, its name should become a lie if it was named properly to begin with. However, for parameters, immediate, short, sensible "fix ups" such as defaults as @lhf suggests can be useful. – Tom Blodget Apr 01 '16 at 00:02
1

In Lua functions, threads, tables and userdata types are passed by reference. So unless you have one of those you are working with a local copy anyway.

So in your example:

function do_stuff(begin, last)
  --stuff
  begin = begin + 1
  last = last - 1
  --stuff
end

begin and last are local non-reference variables in do_stuff's scope.

The only reason to make a copy of them is that you might want to store there initial value for later use. For that purpose you can either create a backup copy of the initial value or you create a working copy of it. Whatever you prefer.

Only make sure you know what is passed by reference and what by value so you avoid changing things you don't want to change and the other way around.

Piglet
  • 27,501
  • 3
  • 20
  • 43
  • In historical CS terms, all Lua parameters are passed "[by value](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value)." On [SO](http://stackoverflow.com/a/40523/2226988). Variables cannot be referenced by being actual arguments. (Syntactically, actual arguments are always expressions, regardless of how simple, and expressions cannot be given a new value.) – Tom Blodget Apr 02 '16 at 02:48