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
orlambda
), and not declared global in that functionEnclosing-function — Names assigned in the local scope of any and all statically enclosing functions (
def
orlambda
), from inner to outerGlobal (module) — Names assigned at the top-level of a module file, or by executing a
global
statement in adef
within the fileBuilt-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
(incode3
,code4
, andcode5
) - E: Any enclosing functions (if the whole example were in another
def
) - G: Were there any
x
declared globally in the module (incode1
)? - 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
Simulate Keystroke in Linux With Python
Return Value of X = Os.System(..)
Short Description of the Scoping Rules
What Is the Meaning of Single and Double Underscore Before an Object Name
What Is the Purpose of the Single Underscore "_" Variable in Python
How to Check Whether a File Exists Without Exceptions
Find All Files in a Directory With Extension .Txt in Python
How to Copy a Dictionary and Only Edit the Copy
How to Pass Arguments to a Button Command in Tkinter
Create a Dictionary With Comprehension
Post Values from an HTML Form and Access Them in a Flask View
Why Is the Command Bound to a Button or Event Executed When Declared
How to Count the Occurrences of a List Item
How to Parse an Iso 8601-Formatted Date
How to Read/Process Command Line Arguments