lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Mon, Jul 23, 2018 at 11:48 AM, Dirk Laurie wrote:
Oh, I have three other favorite tricks.


I'm glad you disclosed them.
 

I call it first one "semi-global variables". All upvalues that are intended to
have scope of the entire file are collected near the top of the program
with no initializer. They tend to have fairly long, descriptive names,
not just 'x'.

Declaring all "pseudo-global" variables at the beginning of a program isn't a good idea, IMO.
(Even in Pascal you can declare a global variable anywhere in the code.)
More convenient approach is to define a variable at the line where the variable is really starting to be needed.
 

I call the second one "local closures". All my functions that use upvalues
needed only by themselves sit inside a do..end block in which those upvalues
are declared.


That's useful and natural.

 
I call the third one "logical blocks". If half a page of code deserves a
comment describing what it does, one might as well put that comment
on the rest of a line starting with "do".

The result is that seeing 'local' at a place where I can't see the start of its
scope makes my eyes hurt.


So, all your variables (except "semi-global") must have small enough scope to fit inside one screen?
That's not good.
It means you don't allow yourself to use full power of upvalues.
 
IMO, upvalues are "long-range devices" in Lua.
One of their strong sides is "shooting" over several big "do...end" blocks.
Typical situation:
You have four chunks of code, they are big enough,
and you have a variable "var23" which must be shared between chunks 2 and 3, while it's undesired to expose "var23" to chunks 1 and 4.
 
   do chunk 1 end
   do
      local var23
      do chunk 2 end
      do chunk 3 end
   end
   do chunk 4 end
 
What are your options here?
Making "var23" a "semi-global" is a bad idea (its usage is limited to chunks 2 and 3, so why should we expose it to the code which doesn't need it?).
Making chunks 2 and 3 small enough (to fit one screen) is unreachable: in Lua local/upvalue can't be passed by reference to some external code (dofile/require); would you create getter and setter functions to pass them to external code?  Please no.
 

I realize that these habits betray my Algol/Pascal programming past,
but at least they cost nothing.


Your habits cost you pretty much.
Your "three other favorite tricks" are actually a workaround describing "how to survive in global-by-default Lua".
The reason is: you are afraid of a global been accidentally shadowed out by a local/upvalue, that's why you are refusing to use upvalues wherever/whenever they are useful.
To unleash full power of upvalues (to make them work at long ranges without problems), you need some kind of safety; one possible source of such safety is separation of namespaces of locals and globals.
A new syntax and a new habit could make your fears gone away.