Short Description of the Scoping Rules

Short description of the scoping rules?

Actually, a concise rule for Python Scope resolution, from Learning Python, 3rd. Ed.. (These rules are specific to variable names, not attributes. If you reference it without a period, these rules apply.)

LEGB Rule

  • Local — Names assigned in any way within a function (def or lambda), and not declared global in that function

  • Enclosing-function — Names assigned in the local scope of any and all statically enclosing functions (def or lambda), from inner to outer

  • Global (module) — Names assigned at the top-level of a module file, or by executing a global statement in a def within the file

  • Built-in (Python) — Names preassigned in the built-in names module: open, range, SyntaxError, etc

So, in the case of

code1
class Foo:
code2
def spam():
code3
for code4:
code5
x()

The for loop does not have its own namespace. In LEGB order, the scopes would be

  • L: Local in def spam (in code3, code4, and code5)
  • E: Any enclosing functions (if the whole example were in another def)
  • G: Were there any x declared globally in the module (in code1)?
  • B: Any builtin x in Python.

x will never be found in code2 (even in cases where you might expect it would, see Antti's answer or here).

Scoping rules in Lua

The scope of a local variable begins at the first statement after its
declaration and lasts until the last non-void statement of the
innermost block that includes the declaration.

Lua manual

What are the scoping rules for bind or for expressions in general?

In short: Typically the syntactical correctness is a step in compilers/interpreters that is done before the semantical correctness check (type systems, etc.). There are good reasons to separate the two.

What I don't understand is the underlying rule. How can the compiler decide that the second lambda is a closure of the first one without this being apparent from the syntax?

The Haskell compiler (like most, if not nearly all reasonable languages) are not apparent of the semantics, or the type system when they parse expressions. This is a consequence of the language grammar as described in the Haskell '98 report.

The body of a lambda expression thus extends as far to the right as possible (without hitting closing parenthesis.

In this expression such a behavior wouldn't even make sense:

\x -> x + 1 . \y -> x + y

No perhaps not. But typically parsing is done without knowledge of the types. Since that would be "unstable". Imagine that you write 2 + 3 * 4. Most people will see this as 2 + (3 * 4), perhaps some languages will interpret this differently, but eventually programmers get used to that. Now imagine that whether or not 3 being a float results in interpreting the expression differently, so 2 + 3.0 * 4 then all of a sudden is interpreted as (2 + 3.0) * 4. Here one can still say that the language has some explicit rules. But if later on, we replace 2, 3 and 4 by an identifier, then we are really getting into trouble, since altering the type of that identifier, could give a totally different meaning to a lot of expressions in the program.

In general it however frequently makes sense to extend lambda expressions to the right, as you found out with the first expression. For example if you write:

f a b = 2 * a + b

then this is equivalent to:

\a -> (\b -> 2 * a + b)

or less verbose:

\a -> \b -> 2 * a + b

What does scope mean

@Martjin Pieters clarifications and answers are awesome, but I'd like to add that beyond python, scope is a computer science/programming concept that spans across basically all programming languages currently in use.

To learn more about what scope is, generally, aside from in python, I'd start here:
http://en.wikipedia.org/wiki/Scope_(computer_science)

Many languages, including python, follow the same set of basic scoping rules, but the details can be different between languages. Thus, if you're really asking "what is scope?" then starting at a general source may be more useful than learning the intricacies of python's scoping (at least at first).

Error when referencing a inside a function without using `global` keyword in python

As soon as you write n = ..., n becomes a local variable for the entire function scope. To make the name n refer to the global variable, you must use the global statement.

In the second example, there is no assignment to n, so n is undefined. It's a free variable, and its value will be taken from the closest enclosing scope where n is defined.



Related Topics



Leave a reply



Submit