lua-users home
lua-l archive

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


On 13/05/2020 16:22, Andrea wrote:
[snip]

Now forgive me for asking this, even if I am a programmer I am not a
Computer Science Engineer. My question is: why are new scopes created by
"if", "for" and other statements and not only by function definitions and
do...end statements? If one wanted a new scope one could easily type "do"
(as in other languages we just open a curly brace). So why this is done
implicitly? What is the advantage or the theoretical reason? Again forgive
me for this maybe silly question - remember my background is not in
computer science.

From a practical POV, lexical scopes help reduce the amount of 
information a programmer must hold in their mind while comprehending a 
piece of code.
Human mind has different kinds of memories (short-term, long-term, 
visual, aural, etc.) that play a role in understanding a piece of code.
If the piece of code is short, then the task of understanding it is 
easier. But even if it is short, it could be a mess because it 
references lots of stuff defined "far away".
Lexical scopes help keeping the information textually localized. Thus it 
is quite intuitive to make structured statements other than do-end also 
be lexical scope, so that whatever is visually enclosed in some textual 
block is also self-contained from a scoping POV.
Adding an extra block to introduce a scope in, say, an if branch 
increases visual clutter: you must add a block AND you typically must 
indent it. This is bad for visual memory, and another level of 
indentation makes this worse. You could write the things to avoid an 
extra level of indentation, but then the things start to become ugly
In other words, making any block a scope, keep the things tidy.

Compare:


if condition then
 for x = 1,10 do
  local y = (..stuff...)
  -- do some other stuff; y is not needed outside the loop
 end
end

Without lexical scoping of if and for statement bodies, you would end up with the equivalent thing:
if condition then
  do
   for x = 1,10 do
     local y = (..stuff...)
     -- do some other stuff; y is not needed outside the loop
   end
  end
end

or, to avoid extra indents:

if condition then do
 for x = 1,10 do
   local y = (..stuff...)
   -- do some other stuff; y is not needed outside the loop
 end end
end

Ok, maybe manageable. But if we have another if inside the loop body?
Or the loop is a repeat-until, which has no do-end block? And if Lua authors decide to introduce another statement having a block structure?
Your brain would continually struggle to separate the concept of block 
to that of lexical scope.
Moreover the "end" keyword would sometimes end a scope (if paired with 
do) and sometimes not. You would have nightmares when debugging complex 
code when trying to sort out where a scope actually ends!
Try to understand where a scope end and where a block ends when you find 
something like:
  end end
end end

or

     end
    end
  end
end

at the end of a group of statement that could have ended simply like this:

  end
end

Add to that another issue: why would you want some blocks NOT to be also lexical scopes? The only immediate reason that comes to mind is "flexibility", but do you really need to be able to define a variable in an inner block that could be visible outside that block? Wouldn't it be clearer to define that variable outside the inner block to begin with? The block = scope equation makes leaking information to outer scopes less likely.
You may have heard about the "Principle of Least Surprise" in 
engineering (also in SW engineering, then). It can be stated in various 
ways, but in this case you could spell it as "things that look similar 
should behave similarly (unless you really cannot do otherwise)".
Any deviation from this principle puts a burden on the brain of the 
reader of the code.
More effort for the brain means more chances to do mistakes (that's why 
expert programmers advise younger ones "not to be too clever" when 
writing code. If you can code something in a boring, plain, easily 
readable way, in 10 lines that's much better than write an equivalent 
masterpiece of obfuscated code in 5 lines (unless you are doing it for 
fun, of course) using every corner case or obscure feature of the language.
That obfuscated, clever code WILL bite the maintainer of that code in 
the future, and that maintainer could be an older you!
Any programmer which has some years of programming under their belt will 
tell you of the experience of having to modify some old code made by 
themselves some years before and thinking "WTF?!? Did I really write 
this crap?!?" or "What the heck was this code intended to do?!?".


[snip]

   Andrea



_______________________________________________
lua-l mailing list -- lua-l@lists.lua.org
To unsubscribe send an email to lua-l-leave@lists.lua.org


Cheers!

-- Lorenzo
_______________________________________________
lua-l mailing list -- lua-l@lists.lua.org
To unsubscribe send an email to lua-l-leave@lists.lua.org