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