variable declaration

  • Thread starter Alexander Zatvornitskiy
  • Start date
A

Antoon Pardon

Op 2005-02-05 said:
[ ... ]

With a rebinding operator, the intent of the last line can be made explicit:

def collapse(iterable):
it = iter(iterable)
lastitem = it.next()
yield lastitem
for item in it:
if item != lastitem:
yield item
lastitem .= item

(Note that doing this *will* slow the code down, though, since it has to check
for the existence of the name before rebinding it)

I think that most of the time it won't slow down the code as the
checking will have been done during the compilation phase. It
may even speed up code like this, because the compilation
phase will have established that it is a rebinding and so
code for testing whether a new variable is created or not
is not necessarry here.
 
A

Antoon Pardon

Op 2005-02-05 said:
(e-mail address removed)3.n5025.z2.fidonet.org (Alexander


Let me answer that by way of counter-example.

Yesterday I was writing a little perl script. I always use "use strict" in
perl, which forces me to declare my variables. Unfortunately, my code was
giving me the wrong answer, even though the interpreter wasn't giving me
any error messages.

After a while of head-scratching, it turned out that I had written "$sum{x}
+= $y" instead of "$sum{$x} += $y". The need to declare variables didn't
find the problem. I *still* needed to test my work. Given that I needed
to write tests anyway, the crutch of having to declare my variables really
didn't do me any good.

I you come to the conclusion that it doesn't do you any good, why did
you use it? I find it odd that someone who prefers to use it in a
language where it is optional is argues that it shouldn't be included
as an option is an other language. I would think that if he thinks
it so bad he wouldn't use it in that other language in the first place.
 
N

Nick Coghlan

Antoon said:
[ ... ]

With a rebinding operator, the intent of the last line can be made explicit:

def collapse(iterable):
it = iter(iterable)
lastitem = it.next()
yield lastitem
for item in it:
if item != lastitem:
yield item
lastitem .= item

(Note that doing this *will* slow the code down, though, since it has to check
for the existence of the name before rebinding it)


I think that most of the time it won't slow down the code as the
checking will have been done during the compilation phase. It
may even speed up code like this, because the compilation
phase will have established that it is a rebinding and so
code for testing whether a new variable is created or not
is not necessarry here.

Since unbound locals are generally detected at runtime rather than compile time,
I see no real reason why this case would be any different. Static checks would
be in the hands the tools like pychecker (as is currently the case for
references to unbound locals)

Py> def f():
.... x
.... x= 3
....
Py> f()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment

So I'd expect the compiler to generate slower code for it (probably just a
LOAD/STORE pair instead of just a STORE instruction), but the optimiser should
eventually be able to do something to eliminate the performance penalty due to
the technically unnecessary LOAD. I doubt it will be able to beat a STORE_FAST
when it comes to trying to get a performance improvement, though :)

Cheers,
Nick.
 
A

Antoon Pardon

Op 2005-02-07 said:
Antoon said:
[ ... ]

With a rebinding operator, the intent of the last line can be made explicit:

def collapse(iterable):
it = iter(iterable)
lastitem = it.next()
yield lastitem
for item in it:
if item != lastitem:
yield item
lastitem .= item

(Note that doing this *will* slow the code down, though, since it has to check
for the existence of the name before rebinding it)


I think that most of the time it won't slow down the code as the
checking will have been done during the compilation phase. It
may even speed up code like this, because the compilation
phase will have established that it is a rebinding and so
code for testing whether a new variable is created or not
is not necessarry here.

Since unbound locals are generally detected at runtime rather than compile time,
I see no real reason why this case would be any different. Static checks would
be in the hands the tools like pychecker (as is currently the case for
references to unbound locals)

Py> def f():
... x
... x= 3
...
Py> f()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment

So I'd expect the compiler to generate slower code for it (probably just a
LOAD/STORE pair instead of just a STORE instruction),

Why should we limit ourselves to instructions already existing.
The compilor might generate a RESTORE instruction.
but the optimiser should
eventually be able to do something to eliminate the performance penalty due to
the technically unnecessary LOAD. I doubt it will be able to beat a STORE_FAST
when it comes to trying to get a performance improvement, though :)

But maybe a RESTORE_FAST could.
 
A

Alexander Zatvornitskiy

ðÒÉ×ÅÔ Alex!

05 ÆÅ×ÒÁÌÑ 2005 × 17:00, Alex Martelli × Ó×ÏÅÍ ÐÉÓØÍÅ Ë All ÐÉÓÁÌ: AM> 'global' is an ugly wart,

Ok,
===
def hi():
print "hello!"
===
What is it? Statement or declaration? After interpreter see this lines, it add
information about function "hi" and it's body to his memory. Look at this:
var S
Interpreter see this line and add information about variable S to the memory. I
don't find big difference.
By the way keyword "def" is as bad as "var", from your point of view? :)

AM> to all intents and purposes working "as if"
AM> it was a declaration. If I had to vote about the one worst formal
AM> defect of Python, it would surely be 'global'.
Second worsest - 'def'? :)

AM> What you keep demanding is a way to inject far worse ugliness, and in
AM> a context in which the typical behavior of pointy-haired bosses will
AM> be to make it unavoidable for many of the people who work with Python.
AM> I am strongly convinced that, if you had your wish, the total amount
AM> of happiness in the world would be quite substantially diminished, and
AM> I will do anything I can to stop it from happening.

:) "Star Wars IX" :)
If your boss is rather smart, you can explain your position. Even if he is not
agree, he will give you freedom.
If your boss is stupid, find another one:)
Of course, if you will explain him in such a way "hey, boss, you will never
understand this language, go back to your playground", you have no chance:)

AM> There IS no meaning to your (several) sentences above-quoted, that it
AM> can help anybody to "try to undestand": it's simply an insanely bad
AM> attempt at totally invalid parallels.
I understand your opinion. From my point of view, you don't even try to
understand.
AM> Do yourself a favor: don't even _try_ to be funny in a language you
AM> have so much trouble with. Your communication in English is badly
AM> enough impaired even without such lame attempts at humor: don't made
AM> bad things even worse -- the result is NOT funny, anyway, just totally
AM> garbled.

But, I am friendly, even with my opponents. I think it is my good trait.

AM> There IS no ``problem "in general"'': Python does a pretty good job
AM> of
AM> diagnosing as many errors as can be diagnosed ***without demanding
AM> absurdities such as redundancy on the programmer's part***. Period.

AM> To show how absurd that would be: why not force every line of the
AM> program to be written twice, then -- this would help diagnose typos,
AM> because the interpreter could immediately mark as errors any case in
AM> which the two copies aren't equal. Heck, why stop at TWICE -- even
AM> MORE errors will be caught if every line has to be written TEN times.
AM> Or a million. Why not? *AS MANY ERRORS AS [it] CAN* is an
AM> *ABSURD* objective, if you don't qualify it with *WHILE AVOIDING ANY
AM> ENFORCED REDUNDANCY* introduced solely for that purpose.

Hmm. It's clever move. I can't resist here.
Well, I agree that keyword "var" is to long. Programs are not look pretty with
it, especialy in situations like this:
for var x in xrange(10):...
But I still think declaration of variables is good idea. But with shorter
syntax. May be, smth like this: ~S, or `S or .S, or S`, S~ , S. , and so on. Of
course it must be optional feauture: use it if you want or don't use if you
don't want.

AM> I've been programming essentially full-time in Python for about three
AM> years, plus a few more years before then when I used Python as much
AM> as
AM> I could, even though my salary was mostly earned with C++, Visual
AM> Basic, Java, perl, and so on. My REAL LIFE EXPERIENCE programming in
AM> Python temms me that the time I've "wasted on search" etc due to the
AM> lack of variable declaration is ***FUNDAMENTALLY NOTHING AT ALL***.
AM> Other hundreds of thousands of man-hours of similar Python programming
AM> experience on the part of hundreds of other programmers essentially
AM> confirm these findings.

AM> Your, what, TENS?, of man-hours spent programming in Python tell you
AM> otherwise.

Do you ever wrote programs for engineering calculations? Dozens of variables
with names like lambda_1, phi_k, epsilon, d2f_dx2, grad_z and so on. You wrote
it, start it and see that it work wrong. You start debugging. Look at every
line, and attentively compare written in the screen and in the paper: is it
correct? My experience say that often errors caused by typos in names of vars
(more precisely, writing one name instead of another).
You may say: give better names for your variables! Ha, I'am often don't
understand that they mean! They are written for me by an engineer! He is
thinking in that terms, they is natural for him. He and his collegues want to
see error messages as "lambda_1 must be between 2 and 75".
So I'am sure: any checking will help. If I'am sure that interpreter can't
create "epsElon" I will not check the left side of "=" operator. If I can't be
sure in it, I will check it. It will take time. That's all.
Recent years I'am not often work with engineering calculations, but I want to
use Python for them also - if they will be.

AM> Fine, then *USE ANOTHER LANGUAGE* and be happy, and let US
AM> be just as happy by continuing to use Python -- almost all languages
AM> do things the way you want, so ***leave alone*** the few happy oases
AM> such as Python and Ruby where programmers can happily avoid the
AM> idiotic redundancy of variable declarations, and not even PHBs can
AM> impose otherwise.

Bad boss will find a way to make your life worse:) With, or without,
availibility of variable declarations.

AM> Like experience shows in all cases of such idiotic redundancies, the
AM> real waste of time comes in the BAZILLION cases where your program
AM> WOULD be just fine -- except you missed one redundancy, so you have to
AM> go and put it in to make the gods of redundancy happy again. That
AM> happens with VASTLY higher frequency than the cases where the enforced
AM> redundancy saves you a comparable amount of time by catching some
AM> error earlier.

AM> Plus, the FALSE confidence coming from redundancy works against you by
AM> kidding you into believing that a BAZILLION other typos can't still be
AM> lurking in your code, just because you've eliminated one TINY subset
AM> of such typos (typos in names of variables that happen to leave the
AM> mangled names syntactically valid BUT different from any other
AM> variable) -- and *ONLY* that tiny subset of such typos which happened
AM> on the left of a plain '=' (since all others, happening on the RIGHT
AM> of an '=' or on the left of an _augmented_ '=', were already caught),
AM> and ONLY regarding barenames (such typos on any but the rightmost
AM> component of compound names were already caught intrinsically, and
AM> catching those on the rightmost component is trivially easier than
AM> introducing a {YECCCCHH} 'vars' as you so stubbornly insist)...

AM> Basically you're focusing on maybe ONE IN A MILLION of the errors you
AM> could make and want to pervert the whole foundation of Python, and
AM> seriously hamper the productivity of hundreds of thousands of Python
AM> programmers in every normal case!, to save maybe two minutes in such a
AM> one-in-a-million case.

AM> I consider this one of the worst ideas to have been proposed on this
AM> newsgroup over the years, which _IS_ saying something. Oh, you're not
AM> the only one, for sure -- there must have been a dozen before you, at
AM> least. Fortunately, even though almost each and every one of them has
AM> wasted more of everybody's time with such ideas, than even their
AM> scare-tactics claim of ``wastes of time'' due to lack of declarations
AM> could account for, Python is still intact. A few of the stubborn
AM> lovers of declarations tried doing without, and, to their
AM> astonishment, found out that everybody else, with years of Python
AM> experience, was right, and they, without ANY such experience, were
AM> wrong (just incredible, eh?!); others have gone away to find their
AM> bliss in Perl, PHP, or whatever -- good riddance, and don't let the
AM> door slam behind you as you go, please.

Don't be so ... I don't find the equivalent english word. Smth like: Take it
more easy.


Alexander, (e-mail address removed)
 
A

Alexander Zatvornitskiy

ðÒÉ×ÅÔ Nick!

06 ÆÅ×ÒÁÌÑ 2005 × 02:54, Nick Coghlan × Ó×ÏÅÍ ÐÉÓØÍÅ Ë Python List ÐÉÓÁÌ:
NC> An alternate proposal, where the decision to request rebinding
NC> semantics is made at the point of assignment:

NC> epsilon = 0
NC> S = 0
NC> while epsilon < 10:
NC> S .= S + epsilon
NC> epselon .= epsilon + 1 #interpreter should show error here
NC> print S
Well, I think

epsilon. = 0
S. = 0
while epsilon < 10:
S = S + epsilon
epselon = epsilon + 1 #interpreter should show error here
print S

will be little bit more pretty, from my point of view. Or may be smth like
this:
`S=0
~S=0
S~=0
S`=0
and so on. But, I think, your idea look more preaty than my previous (with var
keyword)


Alexander, (e-mail address removed)
 
A

Alex Martelli

Alexander Zatvornitskiy
?????? Alex!

05 ??????? 2005 ? 17:00, Alex Martelli ? ????? ?????? ? All ?????:
AM> 'global' is an ugly wart,

Ok,
===
def hi():
print "hello!"
===
What is it? Statement or declaration?

Statement, obviously.
After interpreter see this lines, it add
information about function "hi" and it's body to his memory. Look at this:

Utterly false, like most of the unqualified, arrogant assertions you
keep making.

If and when the interpreter *EXECUTES* this *STATEMENT*, it binds or
rebinds name 'hi' in the current scope to a new function object -- just
like it would if the statement was, say, an assignment such as:

hi = new.function( ... )

with the appropriate arguments. So, wondering if `def' "is a
declaration" is just about as stupid as wondering if an assignment
statement "is a declaration".

If the statement is not EXECUTED -- it does not suffice for it to be
merely *SEEN*, and your assertion about this is pure and unadulterated
POPPYCOCK, just like everything else you've been posting -- then no new
function object is made, and nothing is bound or re-bound to name 'hi'
in the current scope -- for 'def' just as for assignment, same thing.

If either statement is executed repeatedly, it builds a new function
object each time. Not particularly meaningful when the function object
is trivial in this way, but if it was at all significant that would be
easy to verify -- just give the function some meaningfully mutable
values, such as argument defaults, and you can mutate each independent
function object separately at will.

'global', of course, is, alas, totally different -- which makes it a
wart.

var S
Interpreter see this line and add information about variable S to the
memory. I don't find big difference.

That's because you criticize what you completely fail to understand, and
your arrogance is such that you appear to not feel any need to perform a
modicum of research to avoid showing everybody your total ignorance
coupled with perfect willingness to spout about subjects you don't
grasp.
By the way keyword "def" is as bad as "var", from your point of view? :)

Obviously not: 'def' is an excellent executable statement, just like
'class' or assignment. 'var' is (or rather, thank Guido, WOULD BE, if
Python developers were as incompetent and incapable as you) reason
enough to throw the language in the closest dustbin.
Do you ever wrote programs for engineering calculations? Dozens of
variables

I was a senior developer for a major CAD SW house for 12 years, rising
to the rank of "senior software consultant". Engineering enough for
you?
with names like lambda_1, phi_k, epsilon, d2f_dx2, grad_z and so on. You
wrote

Not when _I_ wrote the code. Clarity of naming is always important,
whether the computations are "engineering", "accounting", or whatever.
You may say: give better names for your variables! Ha, I'am often don't
understand that they mean! They are written for me by an engineer! He is

A good programmer understand what he or she IS programming. I am not
surprised that you're used to coding without a glimmer of comprehension:
your readiness to publically post unfounded criticisms of a language
about which you're most obviously totally clueless clearly show that
doing without comprehending is something you're quite used to.
AM> wrong (just incredible, eh?!); others have gone away to find their
AM> bliss in Perl, PHP, or whatever -- good riddance, and don't let the
AM> door slam behind you as you go, please.

Don't be so ... I don't find the equivalent english word. Smth like: Take it
more easy.

Don't have much experience with Southern Europeans of hot Latin blood,
hm? We're ALWAYS intense about our feelings. Of course, afterwards we
go bask in our delightful weather sipping our delightful cheap wines, so
there's no risk of our lives being stressful -- it must be very
different in the frozen North.


Alex
 
S

Steve Holden

Alexander said:
ðÒÉ×ÅÔ Alex!

05 ÆÅ×ÒÁÌÑ 2005 × 17:00, Alex Martelli × Ó×ÏÅÍ ÐÉÓØÍÅ Ë All ÐÉÓÁÌ:
AM> 'global' is an ugly wart,

Ok,
===
def hi():
print "hello!"
===
What is it? Statement or declaration? After interpreter see this lines, it add
information about function "hi" and it's body to his memory. Look at this:
var S
Interpreter see this line and add information about variable S to the memory. I
don't find big difference.
By the way keyword "def" is as bad as "var", from your point of view? :)
If your colloquial English is good enough to understand the word
"bollocks" then you might begin to realize how irritating your arguments
are becoming.

If, as you suggest, def were a declaration, then it should either not be
possible to write

if __debug__:
def func(x):
print x, "is bollocks"

or, if it were possible, then func would have a code object bound to it
whether or not __debug__ were true.

In point of fact this is perfectly legal Python, which results in no
binding to the name func when __debug__ is false, precisely *because the
def statement is executable* - and it is so by design.
AM> to all intents and purposes working "as if"
AM> it was a declaration. If I had to vote about the one worst formal
AM> defect of Python, it would surely be 'global'.
Second worsest - 'def'? :)
The reason global is a wart can clearly be seen in the following example:
... if tf:
... global x
... x = v
...
This makes it apparent that the global statement is *not* executable,
the only one in the language that is not.

[...]
But, I am friendly, even with my opponents. I think it is my good trait.
You are, of course, entitled to your opinion, self-serving though it may
be. A friendly idiot is still an idiot.

[...]
But I still think declaration of variables is good idea. But with shorter
syntax. May be, smth like this: ~S, or `S or .S, or S`, S~ , S. , and so on. Of
course it must be optional feauture: use it if you want or don't use if you
don't want.
Why not make it even shorter by omitting it altogether. Oh, sorry, it
can be as short as you want as long as it isn't actually zero length?
This is insanity ...
[...]

Don't be so ... I don't find the equivalent english word. Smth like: Take it
more easy.
Please don't insult the martellibot. He did, after all, write "Python in
a Nutshell" and co-edited the "Python Cookbook", and he has established
a reputation with his consistent long-term contribution to Python and
this newsgroup. Instead, ask yourself why your remarks engender such a
response from a pillar of the Python community. What are your credentials?

regards
Steve
 
B

Brian van den Broek

Steve Holden said unto the world upon 2005-02-07 17:51:
The reason global is a wart can clearly be seen in the following example:

... if tf:
... global x
... x = v
...

This makes it apparent that the global statement is *not* executable,
the only one in the language that is not.

regards
Steve

Hi,

Steve's example makes my brain hurt. :)

I'd appreciate it if someone could tell me if I am understanding the
example correctly. (My grasp of the terminology and issues at play is
a bit shaky.)

Let me simplify Steve's example to:

..def hurts_my_brain(v):
.. if False: # unlike Steve's eg, ensuring that the
.. global x # nested block is never hit at runtime
.. x = v

(I checked, and it works the same as the original eg, modulo change of
function name.)

Is the right way to understand it in this vicinity:

At compile time (by which I mean when the Python bytecode is built)
the global statement is hit and has the effect of `bumping up' the
function local name `x' to the module namespace, making the function
local name `x' synonymous with the module global name `x'. At runtime,
the `global x' is never reached, but it has already, at compile time,
had its effect on the nature of the function object hurts_my_brain.
Further, if the function had instead said 'if True:' the global
statement would have been reached at runtime, but would have been
without effect due to this, having already been `used up' in the
creation of the bytecode.


Can it then be further (truly :) ) said that

if False:
# thousands of lines of code here

would effect the structure of the function object's bytecode, but not
its behaviour when run? Or, at most, would cause a performance effect
due to the bytecode being bloated by thousands of line's worth of code
that would never get executed?

Thanks for any confirmation of my understanding / rectification of
same. Best,

Brian vdB
 
T

Terry Reedy

Brian van den Broek said:
Is the right way to understand it in this vicinity:

In the vicinity, but not quite exact
At compile time (by which I mean when the Python bytecode is built)

Compile time is when the def statement is executed
the global statement is hit and has the effect of `bumping up' the
function local name `x' to the module namespace, making the function local
name `x' synonymous with the module global name `x'.

Global make 'x' global. Period. There is no local 'x'.
At runtime, the `global x' is never reached,

In CPython, at least, it is not even there to be reached (see below).
It is strictly a compile time declaration. At runtime, it is equivalent to
'pass'.
but it has already, at compile time, had its effect on the nature of the
function object

Right. With 2.2:

def f():
if False: global x
x = 1

import dis
dis.dis(f)
0 SET_LINENO 1

3 SET_LINENO 2
6 LOAD_GLOBAL 0 (False)
9 JUMP_IF_FALSE 7 (to 19)
12 POP_TOP

13 SET_LINENO 2
16 JUMP_FORWARD 1 (to 20) 23 LOAD_CONST 1 (1)
26 STORE_GLOBAL 1 (x)
29 LOAD_CONST 0 (None)
32 RETURN_VALUE

Two points: there is no byte code for the global declaration; x is directly
stored as global.

Terry J. Reedy
 
A

Alex Martelli

Terry Reedy said:
In the vicinity, but not quite exact


Compile time is when the def statement is executed

I disagree: compile time is when the compiler is running (for example,
the compiler is the component which diagnoses syntax errors, while other
errors are diagnosed ``at runtime'').

Bytecode is built before def executes -- indeed it's built whether def
executes or not. Cfr:
.... if wo:
.... def g(): pass
.... (None, <code object g at 0x382a60, file "<stdin>", line 3>)

the 'def g' hasn't executed (yet?), but the bytecode is built (and
stored as the first constantvalue in f, save the ubiquitous None).

If the ``if wo: def ...'' construct was in a module being imported, the
mechanics would be similar -- although in this case I think you could
tell only if a syntax error was present in the def statement (I may be
wrong, but offhand I don't think the codeobject is saved in this case).

Or, try this one:

``compile time'' here is when the 'compile' built-in runs; and we can
see the code object ``x'' is already built even though the def has not
been executed yet.


Alex
 
F

Fredrik Lundh

Terry said:
Compile time is when the def statement is executed

no, that's run time. "def" is an executable statement, just like "print", "for",
assignments, "import", etc.

the entire module is compiled (to bytecode) before any part of it is executed.
the compiler handles "global" and "from __future__", everything else is done
at runtime.

</F>
 
N

Nick Coghlan

Antoon Pardon wrote:eek:ns already existing.
The compilor might generate a RESTORE instruction.

Whether it is done as a LOAD/STORE or a RESTORE, it has to perform the same work
- check the name exists in the local namespace, and throw an exception if it
doesn't. If it the name does exist, perform a normal store operation.
But maybe a RESTORE_FAST could.

STORE_FAST is set up to store a local as fast as is reasonably possible. The
space for the local is preallocated in the fast locals C array. How is an
instruction which does that *and something else* ever meant to be faster?

Cheers,
Nick.
 
J

Just

Nick Coghlan said:
Antoon Pardon wrote:eek:ns already existing.

Whether it is done as a LOAD/STORE or a RESTORE, it has to perform the same
work
- check the name exists in the local namespace, and throw an exception if it
doesn't. If it the name does exist, perform a normal store operation.

But the compiler would _know_ in which scope the variable was defined,
no?

Just
 
P

Peter Otten

Fredrik said:
executed. the compiler handles "global" and "from __future__", everything
else is done at runtime.

and __debug__, too, it seems:
.... if __debug__:
.... global x
.... x = 42
....Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'x' is not defined

Peter
 
D

Duncan Booth

Brian said:
Can it then be further (truly :) ) said that

if False:
# thousands of lines of code here

would effect the structure of the function object's bytecode, but not
its behaviour when run? Or, at most, would cause a performance effect
due to the bytecode being bloated by thousands of line's worth of code
that would never get executed?

Yes, but that purely an implementation detail.

if 0:
# thousands of lines of code here

has no effect at all on the bytecode, it it optimised out entirely. 'if
False:' is not optimised out in Python 2.4 or earlier, but might be in
later versions.

Now, to really get your brain hurting, see what this one does:

def hurts_my_brain(v):
if 0: # unlike Steve's eg, ensuring that the
global x # nested block is never hit at runtime
x = v

I'll give you a clue, it's not the same as your:

def hurts_my_brain(v):
if False: # unlike Steve's eg, ensuring that the
global x # nested block is never hit at runtime
x = v

So the global statement is a wart which isn't executed at runtime, but
behaves differently when the bytecode it doesn't generate is optimised out.
 
A

Antoon Pardon

Op 2005-02-08 said:
Antoon Pardon wrote:eek:ns already existing.

Whether it is done as a LOAD/STORE or a RESTORE, it has to perform the same work
- check the name exists in the local namespace, and throw an exception if it
doesn't. If it the name does exist, perform a normal store operation.

It has to check if the name exists anyway. Because if it doesn't it has
to be created in the namespace directory and in the other case only
the value part has to be changed.

I have the impression you are looking at this too much from the view
of the current implementation where putting a an entry in
a directory is seen as an atomic operation.

So a possibility might be to augment dictionaries with a put method.
d.put(key, value) would throw an exception if the key wasn't already
in the dictionary but would otherwise behave as d[key] = value.

A STORE would then be implemented as a d[key] = value
A RESTORE would then be implemented as a d.put(key,value)

The latter wouldn't have to do more, it would just behave
different.
STORE_FAST is set up to store a local as fast as is reasonably possible. The
space for the local is preallocated in the fast locals C array. How is an
instruction which does that *and something else* ever meant to be faster?

I don't know enough about pythons internals to answer here. Maybe you
have a point in this case, but you already stated that a RESTORE
would need more work then a STORE where IMO that was not the case,
so I'm not convinced the same kind of solution is not applicable here.
 
A

Alexander Zatvornitskiy

Hi, Peter!


PO> You are now on a slippery slope. I'd rather think of ways to write my
PO> code in a way for it to succeed or at least fail in an obvious way.
Ok, fixed.
PO> I don't consider a scenario likely where you both misspell a name
PO> nearly as often as you write it correctly, and do that in a situation
PO> where the program enters an infinite loop instead of just complaining
PO> with an exception, which is by far the most likely reaction to a
PO> misspelt name.
Let say, you have variable or class field 'PowerOfGenerator', or 'lambda_k'.
You decide to rename it to 'ReactivePowerOfGenerator' or 'lambda_kx'. But, for
some reasons, you forget to do it everywhere, for example in function with
first lines like this:

PowerOfGenerator=TakeFromSensor()
if PowerOfGenerator>xxx:
....
RecalcPower(PowerOfGenerator)
PutToTheDatabase(PowerOfGenerator)
....
Here, python will not help you. The worst thing is that in such calculations
you often receive plausible results.

Another example. Let say you have variable PowerOfGenerator in your program.
But, it is only active power, so you have to (1)rename PowerOfGenerator to
ActivePowerOfGenerator, (2)calculate ReactivePowerOfGenerator, and (3)calculate
new PowerOfGenerator by formula
PowerOfGenerator=sqrt(ReactivePowerOfGenerator**2+ActivePowerOfGenerator**2)
With var declarations, on step (1) you just rename PowerOfGenerator to
ActivePowerOfGenerator in the place of its declaration, and compile your
program. Compiler will show you all places where you have to rename variables.
After it, on step (3) you can safely and peacefully add new PowerOfGenerator
variable.

Of course, I am trying to use more short variable names, but its just an
example.

PO> Code not written is always errorfree, and in that spirit I'd rather
PO> strive to write the function more concisely as

PO> def loop2():
PO> s = 0
PO> for delta in range(10):
PO> s += delta
PO> print s

PO> This illustrates another problem with your approach: would you have
PO> to declare globals/builtins like range(), too?
if I understand you right, it can be done this way (with '~' instead of 'var'):
~s=0
for ~delta in range(10)
s+=delta

[skip]

PO> I suggested pychecker more as a psychological bridge while you gain
PO> trust in the Python way of ensuring reliable programs, i. e. writing
PO> small and readable functions/classes that do one thing well and can
PO> easily be tested. Administrative overhead -- as well as excessive
PO> comments -- only serve to bury what is actually going on.

Your explanation is most "non-religious" in comparison with all others I see in
this newsgroup. Thank you, now I see that lack of var declarations is not
stupid oversight, but it may have reasons.
From the other side, I still think that optional var declaration is good idea,
for example in functions which are big and operate with tens of variables,
non-decomposable by their nature. Such functions occurs in some domains. And,
in situations like above.

PO> I guess that means no, not a good idea.

PO> On the other hand, taking all names used in a function and looking
PO> for similar ones, e. g. by calculating the Levenshtein distance,
PO> might be worthwhile...

Hmm, what is the Levenshtein distance between 'x1' and 'x2'? Or between kappa_i
and kappa_j? :)

Alexander, (e-mail address removed)
 
N

Nick Coghlan

Just said:
But the compiler would _know_ in which scope the variable was defined,
no?

I wouldn't expect the behaviour of name rebinding to be any different from other
forms of augmented assignment as far as the existence of the left-hand side goes.

Py> def f():
.... x += 1
....
Py> f()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment
 
N

Nick Coghlan

Antoon said:
I have the impression you are looking at this too much from the view
of the current implementation where putting a an entry in
a directory is seen as an atomic operation.

Yes and no. I *am* looking at it from an implementation point of view, but
dictionaries have nothing to do with the relevant part of the implementation.

The CPython *_FAST opcodes relate to functions' local variables. Behind the
scenes they are implemented as integer indexing operations into a pre-sized C
array. Operations don't come much faster than that :)

Could a rebinding operation *theoretically* be quicker for the other cases which
involve a real dictionary (or something that looks like one)? Well, perhaps.
Although I can't see how the rebinding operation would gain a benefit that a
standard binding operation wouldn't gain if placed at the exact same point.

Cheers,
Nick.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top