lua-users home
lua-l archive

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


It was thus said that the Great Egor Skriptunoff once stated:
> On Mon, Jul 23, 2018 at 11:48 AM, Dirk Laurie wrote:
> 
> > 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'm not sure what variants of Pascal you are used to, but for the ones I'm
used to, you can only declare new variables at the top of code block, not
anywhere in the code.

  C99 now allows declaring variables at first use instead of the top of a
code block (I'm still on the fence about that in C; in Lua, I usually will
declare a new local variable when first needed).

> > 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. 

  Upvalues are just non-global variables in an outer scope.  I've never
thought of them as "long-range devices" and the concept is odd to me.



> One of their strong sides
> is "shooting" over several big "do...end" blocks. 

  Another strong side is encapsolation.  For example, this bit of code I
use:

	local next_id do
	  local id = 0
	
	  next_id = function()
	    id = id + 1
	    if id == 4294967295
	      id = 0
	    end
	
	    return id
	  end
	end

'id' is an upvalue in next_id().


> 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.

  How big is a "screen"?  24 lines?  70 lines?  81 lines?  Methinks it is
dependant upon the screen and user interface one is using.

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

  They work for Dirk; they may not work for you.  I line up sequential
assignments in my code:

	local iostream =
	{
	  close     = close,
	  flush     = flush,
	  lines     = lines,
	  read      = read,
	  seek      = seek,
	  setvbuf   = setvbuf,
	  write     = write,
	  
	  _readf    = accumulate_data,
	  _readbuf  = "",
	  _writebuf = "",
	  _sock     = conn,
	  _remote   = remote,
	  _pollset  = nfl.SOCKETS,
	  _eof      = false,
	}

  That works for me; it probably doesn't work for anybody else.  That's my
habits from Assembly language past showing here.

> 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.

  No, I'm afraid of accidental globals, not of shadowing a global value.  I
can't speak for Dirk.

> 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.

  What?

  -spc