From: Alf P. Steinbach /Usenet on
* MRAB, on 12.07.2010 04:09:
> Alf P. Steinbach /Usenet wrote:
>> * MRAB, on 12.07.2010 00:37:
>>> Alf P. Steinbach /Usenet wrote:
>>>> * Stephen Hansen, on 11.07.2010 21:00:
>>>>> On 7/11/10 11:45 AM, wheres pythonmonks wrote:
>>>>>> Follow-up:
>>>>>> Is there a way to define compile-time constants in python and have
>>>>>> the
>>>>>> bytecode compiler optimize away expressions like:
>>>>>>
>>>>>> if is_my_extra_debugging_on: print ...
>>>>>>
>>>>>> when "is_my_extra_debugging" is set to false? I'd like to pay no
>>>>>> run-time penalty for such code when extra_debugging is disabled.
>>>>>
>>>>> Any code wrapped in a __debug__ guard is utterly ommitted if you run
>>>>> Python with the -O option. That, and asserts go away.
>>>>>
>>>>>> On #2: My point regarding the impossibility of writing the swap
>>>>>> function for ints is to explicitly understand that this isn't
>>>>>> possible, so as not to look for solutions along those lines when
>>>>>> trying to write python code.
>>>>>
>>>>> Its impossible because Python's calling and namespace semantics simply
>>>>> don't work like that. There's no references in the traditional sense,
>>>>> because there's no variables-- boxes that you put values in. There's
>>>>> just concrete objects. Objects are passed into the function and given
>>>>> new names; that those objects have names in the enclosing scope is
>>>>> something you don't know, can't access, and can't manipulate.. even
>>>>> the
>>>>> objects don't know what names they happen to be called.
>>>>>
>>>>> Check out http://effbot.org/zone/call-by-object.htm
>>>>
>>>> Oh, I wouldn't give that advice. It's meaningless mumbo-jumbo. Python
>>>> works like Java in this respect, that's all; neither Java nor Python
>>>> support 'swap'.
>>>>
>>>> Of course there are variables, that's why the docs call them variables.
>>>>
>>> In Java a variable is declared and exists even before the first
>>> assignment to it. In Python a 'variable' isn't declared and won't exist
>>> until the first 'assignment' to it.
>>
>> That is a misconception.
>>
>> In Python a variable is declared by having an assignment to it, which
>> for a local variable may be anywhere within a routine.
>>
>> If such a variable is used before it's been assigned to, then you get
>> an uninitialized variable exception. Clearly the variable must exist
>> in order for the exception to refer to it (not to mention the
>> exception occurring at all).
>>
>> def foo():
>> print( blah )
>> blah = "this is both an assignment and a declaration causing it to exist"
>>
>> foo()
>>
>> Clearly when the exception is raised, referring to the variable, the
>> variable exists.
>>
>> Contrary to your statement that is before the assignment.
>>
>> However, as stated up-thread, I do not expect facts, logic or general
>> reasoning to have any effect whatsoever on such hard-core religious
>> beliefs. And I do not care whether I convince you or not. But I *do
>> not* want the religious subset of the community to succeed too much in
>> propagating nonsense idiot beliefs to newbies -- hence the concrete
>> example that any newbie can try.
>>
> How about this:
>
> >>> def foo():
> print("Before:", locals())
> x = 0
> print("After:", locals())
>
>
> >>> foo()
> Before: {}
> After: {'x': 0}

How about it?

Note that you get the same result if you do

x = "blah"
def foo():
# print( x ) # Causes uninitialized variable exception here
print( "Before:", locals() )
x = 0
print( "After:", locals() )

However, if you remove the local assignment to x, then the out-commented print
statement will no longer cause an exception, it will then refer to the global.

The reason that it does throw an exception when you do have the local
assignment, is that the local x exists at that point. If it didn't exist it
could not have any effect. Things that don't exist generally have no effect,
except in the minds of the religious, like angels and so on.

On the basis of what locals() reports it should be OK to refer to the global x
as above. Judging by locals(), there's no local x that could get in the way. But
since it is not OK to refer to the global x, the result of locals() has nothing
to do with that: it doesn't tell you about the local x -- and no, the Python
interpreter does not look forward in time to see that it will appear.

In passing, I should perhaps have told you up front, your argument has nothing
substantial to do with the article you originally responded to, about the
semantics of variables. Your argument is the assertion that different languages
can't have similar or identical semantics for some feature. That's nonsense in
itself, plus, as you've seen, the difference that you focused on is not there,
and, third, what you do maintain is not there, doesn't exist, has a real effect.


Cheers & hth.,

- Alf

--
blog at <url: http://alfps.wordpress.com>
From: geremy condra on
On Sun, Jul 11, 2010 at 10:39 PM, Steven D'Aprano
<steve-REMOVE-THIS(a)cybersource.com.au> wrote:
> On Mon, 12 Jul 2010 03:12:10 +0200, Alf P. Steinbach /Usenet wrote:
>
>> * MRAB, on 12.07.2010 00:37:
> [...]
>>> In Java a variable is declared and exists even before the first
>>> assignment to it. In Python a 'variable' isn't declared and won't exist
>>> until the first 'assignment' to it.
>>
>> That is a misconception.
>>
>> In Python a variable is declared by having an assignment to it, which
>> for a local variable may be anywhere within a routine.
>
> Oh, I'm going to regret being sucked into this...
>
> In *CPython*, but not necessarily other implementations, variables which
> are local to a function are not kept in a dictionary-based namespace, but
> in slots in the code object (not to be confused with __slots__ used for
> classes). Python has STORE_FAST and LOAD_FAST byte-codes for accessing
> locals.
>
> This is intended as a speed, and possibly memory, optimization. I don't
> believe this is a requirement though, so implementations may not do this.
>
> It is true that the slot is created at compile time, and in *that sense*,
> local variables exist before they are bound. I'm not entirely convinced
> that this is the only sense that matters, but never mind. The error
> message given exposes this to the user:
>
>>>> def f():
> ...     print x
> ...     x = 1
> ...
>>>> f()
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
>  File "<stdin>", line 2, in f
> UnboundLocalError: local variable 'x' referenced before assignment
>
>
> If you try this with a global, you get this:
>
>>>> def f():
> ...     global x
> ...     print x
> ...
>>>> f()
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
>  File "<stdin>", line 3, in f
> NameError: global name 'x' is not defined
>
> In this case, there's no doubt that global variable "x" doesn't exist at
> all -- there is no key "x" in the global namespace.
>
>
> It seems to me that "a slot to hold the variable is created for local
> variables" is an implementation detail, not a language feature. CPython
> could easily hide the difference by changing the exception from
> UnboundLocalError to:
>
> NameError: local name 'x' does not exist
>
> and nobody would be any wiser. (Well, perhaps people who catch
> UnboundLocalError, but why would you do that?)
>
> I also note that UnboundLocalError is a subclass of NameError, so
> "variable exists but is not bound" is considered to be a special case of
> "variable doesn't exist" rather than a completely independent case. In
> that sense, I think I'm on solid ground to say that in Python variables
> don't exist until they are bound to a value, and leave it to pedants like
> you and I to mention that for CPython local variables have space reserved
> for them by the compiler before they are bound.

Very interesting, and a pleasant change of tone to boot. Thanks.

Geremy Condra
From: sturlamolden on
On 11 Jul, 21:37, "Alf P. Steinbach /Usenet" <alf.p.steinbach
+use...(a)gmail.com> wrote:

> Oh, I wouldn't give that advice. It's meaningless mumbo-jumbo. Python works like
> Java in this respect, that's all; neither Java nor Python support 'swap'.

x,y = y,x

From: Alf P. Steinbach /Usenet on
* sturlamolden, on 12.07.2010 06:52:
> On 11 Jul, 21:37, "Alf P. Steinbach /Usenet"<alf.p.steinbach
> +use...(a)gmail.com> wrote:
>
>> Oh, I wouldn't give that advice. It's meaningless mumbo-jumbo. Python works like
>> Java in this respect, that's all; neither Java nor Python support 'swap'.
>
> x,y = y,x
>

We're talking about defining a 'swap' routine that works on variables.

Since Java/Python doesn't support pass by reference of variables it's not
possible in these languages, i.e., you missed the point, or made a joke. :-)

However, C# is very similar to Java, nearly all the way, except that in C# you
can pass by reference. Remove that from C# and you have Java. Add that to Java
and you have C#, roughly. No change in other aspects is needed. E.g. (ignore
this if you've never heard about it, but it's a subtle point that you might be
wondering about now) both Java and C# implement the definite assignment rule.

I.e., there's nothing in the core semantics that prevents accessing/passing the
variables by reference, although for Python and Java it could be a
terminological nightmare, and for Python compounded to the n'th degree by the
general confusion of a subset of the Python community about basic concepts.

I don't know how C#'ers resolve the terminology...


Cheers & hth.,

- Alf

--
blog at <url: http://alfps.wordpress.com>
From: Stephen Hansen on
On 7/11/10 7:25 PM, Alf P. Steinbach /Usenet wrote:
> The alleged facts etc. you're referring are just that, alleged, by you.

Two people come together and have a debate. Both present arguments. Both
present cases. In the end, they are still in disagreement.

You declare us, "religious", and therefore our opinions, arguments,
facts, and conclusion are based solely on faith and unworthy of
consideration on their merits.

That, my friend, is an ad hominem attack. Hypocrite.

And you are plonked.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/