469,290 Members | 1,882 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,290 developers. It's quick & easy.

Can a simple a==b 'hang' in and endless loop?


In the process of learning about some deeper details of Python I am
curious if it is possible to write a 'prefix' code assigning to a and b
something special, so, that Python gets trapped in an endless loop in a
line with:

if a==b: print 'OK'

I mean, it would be of much help to me on my way to understanding Python
to know how such prefix code leading to an endless loop can look like
and if it is eventually not possible to write such code, to know why it
is not possible?

My own first rough idea was to create generators which never end and use
them in the '==' comparison, but I have not well understood how to write
and use generators yet, so I expect from studying this special case to
come to some enlightenment.

Claudio
Jan 18 '06
73 4008
Steve Holden wrote:
Claudio Grondi wrote:
Steve Holden wrote:
Claudio Grondi wrote:
Steven D'Aprano wrote:
> Claudio Grondi wrote:
>
>
>
>> Exactly this is what Python does under the hood when writing
>> a = "some string"
>> b = "some string"
>> where a and b are actually, in terms of C, pointer to Python
>> object data structures which provide strings as arrays where it is
>> possible to say a[0], but ... if here
>> if(a==b):
>> print "True"
>> _does not_ print True, the Python engine is definitely broken.
>
>
>
>
>
> Why are you comparing C behaviour to Python behaviour? What is the
> point of the discussion?


The point is to find a way to create in Python two indentifiers a
and b without manipulating any of the __eq__ and to __eq__ related
functions in a way, that the simple
if a==b: print 'a==b'
statement results in an endless loop.
To my knowledge this is not possible to achieve in C, but is
probably achievable in Python.
So finally we understand what you are looking for (though not why ...).

I will intentionally not elaborate here about the why, as my
experience with this thread has already shown, that this is not only
not helpful in getting the answer to the actual question, but results
in 'hiding' the goal to the reader which needs to be revealed as it
gets lost in the explanation.
>>>
>>> a = [1]
>>> a.append(a)
>>> a
[1, [...]]
>>>
>>> b = [1]
>>> b.append(b)
>>> a == b
Traceback (most recent call last):
File "<stdin>", line 1, in ?
RuntimeError: maximum recursion depth exceeded in cmp
>>>

Is this what you seek? Not quite "an endless loop", but probably as
close as you are going to get given the necessariliy recursive data
structures required to induce it.

Wow! I haven't got this evil idea myself yet (even if as I understand
there is no problem to achieve similar thing also in C), so I have
learned a bit more about Python again. Am I right supposing, that this
becomes possible because the .append() goes not that far to try to
generate the actual list (getting trapped in the endless loop) and
only lets the second list element point to the object with the list
itself. The trouble with it becomes apparent later when working with
such bad defined list as it is the case when applying the '=='
operator to it.
Thank you for sharing this with me, but again ...

Yes, clearly Python is able to create recursive data structures of this
type, just as C and Java are. As you can see when the interpreter prints
the representation of such lists, the __repr__() method does indeed
detect such recursion
and places ellipses ("...")

The Python tutorial '3.2 The standard type hierarchy' says:
"""
Ellipsis: This type has a single value. There is a single object with
this value. This object is accessed through the built-in name Ellipsis.
It is used to indicate the presence of the "..." syntax in a slice. Its
truth value is true.
"""
Not very helpful in understanding what it is, so it still belongs to the
dark unknown area of Python to me.
Any hints towards enlightenment what this from the geometry known term
'ellipsis' mean in Python? Googling shows, that I am not the first who
doesn't know what it is in context of Python, so probably there is
already a good explanation somewhere, but where?
in the output to
indicate it.

When you say "Python goes not so far as to try to generate the actual
list" you reveal a misunderstanding about Python. The interpreter
responds to the statement

a.append(a)

just as it responds to every other append() method call: it adds a new
item to the list and binds (i.e. stores a reference to) the argument (in
this case the list as itself) to that new item. No special cases are
required here, this is what the interpreter always does.
this is still _not_ what I am looking for, because Python detects here
the problem and throws an exception. What I am looking for is an
endless loop where there is no any response from Python about a problem.
Ah, I see. So you want Python to be a worse language than it actually
is. I don't think you are going to find what you are looking for.

Does it mean you reject to try to give a solution because of the reason
why I seek for it, or do you want to say, that there is to your
knowledge no possible solution except those you have already given?

Claudio
regards
Steve

Jan 19 '06 #51
On Thu, 19 Jan 2006 08:06:50 +0100 in comp.lang.python, "Fredrik
Lundh" <fr*****@pythonware.com> wrote:
Dave Hansen wrote:

[bo****@gmail.com wrote]
>Fuzzyman wrote: [...] >> In this case :
>>
>> a = ['some string']
>> b = ['somestring']
>> a == b
>> False (probably)
>That depends, the C syntax is like this :
>
>char *a="hello";
>char *b="hello";
>
>assert(a==b);
>
>// true, the compiler knows the two hello are the same and assign the
>same address(sort of id() in python) to a and b


No. The C standard says the compiler is _allowed_ to re-use character
literal constants, but is not _required_ to do so.


I could have sworn that fuzzyman's example contained a literal string in
an array, and an array comparision, so why are you talking about com-
paring string literals ? a compiler for which


I was responding to bonono's example, not fuzzyman's. Perhaps a more
appropriate response would have been that his example (besides being
incorrect) didn't match the situation under consideration.

char* a[] = { "some string" };
char* b[] = { "some string" };

...

if (a == b)
printf("True\n");

prints True is definitely broken.


Definitely. However,

if (a[0] == b[0])
puts("True");

May or may not print "True." Either answer is allowed. In C.

Regards,
-=Dave

--
Change is inevitable, progress is not.
Jan 19 '06 #52
On Thu, 19 Jan 2006 10:25:12 +0100
Claudio Grondi <cl************@freenet.de> wrote:
From the one side I am glad that Python cares about
memory allocation
for me, but on the other side I have trouble to accept,
that I have no direct access to the memory area where
data are stored in order to manipulate them. Having this
possibility would enormously speed up some conversions,
because it were possible to get them down to a
redefinition of the data structure without being forced
to loop over the actual content or use a special
extension library written in C for doing that.


It is precisely this power that makes C such a dangerous
language to program in -- it's what makes it so easy to
crash your program, any other program running on the same
machine, and shoot yourself and your dog each in the foot.

Sometimes you really do need that power, and isn't
it wonderful that we have C for those times?

If you find yourself really needing this kind of capability
in Python, then you can write an extension module to create
it.

As a compromise, BTW, there is also Pyrex, which gives you
C-like capabilities from a more Python-like language, and
was specifically created for making Python Extensions. I
believe, for example, that Soya 3D now uses Pyrex in
preference to C for highly-optimized code.

For everyday use, though, I recommend keeping the guard
rails firmly in place.

Imagine what the world would be like if we didn't have plugs
and outlets? What if every time you wanted to move a lamp
you had shut off the power and rewire your house? Safe
abstraction levels are a big time-saver.

--
Terry Hancock (ha*****@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Jan 19 '06 #53
Steve Holden wrote:
Claudio Grondi wrote:
Steven D'Aprano wrote:
[...]
The higher level of abstraction/indirection in Python results in making
the concepts of 'value', 'having a value' or 'comparing values'
useless,
where it helps in C to express the difference between address and
content at that address and to distinguish between the information
telling _what_ is stored in memory and the information about _where_ it
is stored.

In Python, you never care _where_ anything is stored. The id() function
returns the unique ID of an object, which as an implementation detail
may
be the actual memory address, but that's just an implementation
detail. In
any case, given a memory address, you can't do anything with that
knowledge.


The question here is, if this a handicap or a welcome feature?

A welcome feature, absolutely no doubt about it.
From the one side I am glad that Python cares about memory allocation
for me, but on the other side I have trouble to accept, that I have no
direct access to the memory area where data are stored in order to
manipulate them. Having this possibility would enormously speed up
some conversions, because it were possible to get them down to a
redefinition of the data structure without being forced to loop over
the actual content or use a special extension library written in C for
doing that.

Well, if this isn't a case of premature optimization I've never seen
one. You apparently haven't yet written a single line of your
appliction, yet you are already concerned about its efficiency.

Wrong guess.
1. First, make it work. I did.
2. Then, if it doesn;t work fast enough, make it work faster. I did it, too.

Exactly in this order.

And out of this experience I mean to know, that it seems to be no other
way for fast conversions as using own extension modules or existing
ones. But if it necessary to use more than one existing extension module
and the modules used are not compatible to each other, the problem
persists.
And because I haven't mastered to write an own CPython extension module
yet, my idea was to try to understand how Python works under the hood in
order to find a workaround, but it seems, that there is none, so I have
to master Pyrex first, then the problems will go away, right?

In other words, there is no way to avoid C programming in case available
extension modules don't fit as solution for the task where speed
matters, because there is no low level access to the data in Python.

In this context I wish Python would have an 'advanced mode' I could
switch to, to get low level access to the data - is it a bad idea?

Claudio
regards
Steve

Jan 19 '06 #54
On Wed, 18 Jan 2006 17:10:09 +0100
Claudio Grondi <cl************@freenet.de> wrote:
or when the objects being members of the list redefine
__eq__ so, that no matter how different they are, the
lists always compare True.


If those objects have redefined __eq__ so that they are all
equal in value to each other, then this is quite intuitive,
although not necessarily very useful -- the author of the
objects is saying that "one is as good as another". I can't
think of any kind of object for which such a definition of
value would be useful.

But in the real world ...

Lets consider a real example. Suppose I have a variety of
"fill level" indicators (class 'fl' below). They may
contain, let's say, a numerical value and a unit of liquid
measure (and probably an epsilon for float comparisons,
BTW):
a = fl(1.04, 'pint')
b = fl(1.00, 'liter')
a == b True
a = [fl(1.04,'pint')]
b = [fl(1.00,'liter')]
a == b

True

(Not tested, because I'm not going to waste time writing fl
right now!)

The point is, the author of this hypothetical 'fl' class
wants its value to be isomorphic to the amount of liquid its
representation would contain, regardless of choice of units
(and probably to within a reasonable experimental error to
take care of float precision).

The author of a class has the power to DEFINE what "value"
is in Python. And that is an extremely useful capability. If
the interpreter were to impose this definition (which is
what you seem to be asking for when you complain that
"value" has no meaning in Python), that would terribly
reduce the utility of Python.

In general, the use of "value" (that is, "value"
distinct from "identity") implies that some kind of math is
going to be done with the objects. This is true even with
strings, in that comparison and other operators are defined
with respect to them, and depend on their literal value (not
their identity as an object in memory).

If objects NEED to only be compared by identity, then they
should leave __eq__ alone and identity will be used when
they are compared.

--
Terry Hancock (ha*****@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Jan 19 '06 #55
On Thu, 19 Jan 2006 14:22:34 +0100
Claudio Grondi <cl************@freenet.de> wrote:
this is still _not_ what I am looking for, because Python
detects here the problem and throws an exception. What I
am looking for is an endless loop where there is no any
response from Python about a problem.


I seriously doubt that what you are looking for exists.
Without manipulating __eq__, python comparisons are pretty
straightforward. Unless the object itself were infinite,
you couldn't get an infinite loop, and you've seen what
happens when you create an infinite object by recursion.

"""
Two boys sat near the airport, enthralled to watch the
planes launching, but strangely disappointed. One turned
to the other, and said "Aww, that one didn't blow up
either".
"""
;-)

Cheers,
Terry

--
Terry Hancock (ha*****@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Jan 19 '06 #56
In article <dq**********@newsreader3.netcologne.de>,
Claudio Grondi <cl************@freenet.de> wrote:
....
You seem here to try to give a definition of the term 'value' for
Python. If I understand it right, the definition of the term can't be
generally given for many reasons. It depends at least on type and in
advanced usage it can be arbitrary defined or changed.
Yes!
That is why I mean, that it makes no sense to talk in Python about
value. I see not much sense in taking existing term in order to redefine
it for a new context - the result is always increase of confusion. Let
give it another name in order to know, that it must be defined for the
context it is used before it becomes meaningful.
Any suggestions?


Aargh, you are so close. The thing you're talking about is,
exactly, "value". The realization you just had, that is so valid,
is that it is futile to talk about value, per se. Changing the
word you use will do nothing to improve this.

Donn Cave, do**@u.washington.edu
Jan 19 '06 #57
On 2006-01-19, Terry Hancock <ha*****@anansispaceworks.com> wrote:
It is precisely this power that makes C such a dangerous
language to program in -- it's what makes it so easy to crash
your program, any other program running on the same machine,


Nonsense. Under Windows 3.0 that may be true, but on any real
OS, you can't "crash any other program running on the same
machien" in C, assembly, Python, or Lisp.

--
Grant Edwards grante Yow! PEGGY FLEMMING is
at stealing BASKET BALLS to
visi.com feed the babies in VERMONT.
Jan 19 '06 #58
Claudio Grondi wrote:
The Python tutorial '3.2 The standard type hierarchy' says:
"""
Ellipsis: This type has a single value. There is a single object with
this value. This object is accessed through the built-in name Ellipsis.
It is used to indicate the presence of the "..." syntax in a slice. Its
truth value is true.
"""
Not very helpful in understanding what it is, so it still belongs to the
dark unknown area of Python to me.
Any hints towards enlightenment what this from the geometry known term
'ellipsis' mean in Python? Googling shows, that I am not the first who
doesn't know what it is in context of Python, so probably there is
already a good explanation somewhere, but where?
Ellipsis has a very well-known meaning -- but it's not geometry at all
(that's ellipse). From Webster online:

Ellipsis (noun):
1 a : the omission of one or more words that are obviously understood
but that must be supplied to make a construction grammatically complete
b : a sudden leap from one topic to another
2 : marks or a mark (as ... or or --) indicating an omission (as of
words) or a pause
Does it mean you reject to try to give a solution because of the reason
why I seek for it, or do you want to say, that there is to your
knowledge no possible solution except those you have already given?


Your problem is badly specified. It seems to boil down to:

Given a and b as some combination of builtin types, is it possible for
the equality comparison (a==b) to hang?

The answer, so far as I know, is 'no'. That said, the answer is useless.

Firstly, you ignore the possiblity that '==' raises some form of error.
I don't know of any builtins that raise TypeError or the like on
comparison, but you've already seen examples that generate recursion
errors. In fact, since the situations likely to lead to looping in ==
constructs use recursion anyway (calling == on members of structure
types), your "infinite loop" becomes a stack depth error.

Secondly, you also ignore objects with overloaded or otherwise custom
__eq__ methods -- the default and well-documented way of supplying
equality comparisons to custom objects, which are first-class citizens
in a Python environment. (In fact, (1).__cmp__(1) [which provides a
general comparison] works.) Since these methods can contain arbitrary
Python code, comparison in Python *can* cause an infinite loop, IO, or
your grandmother to find out just what you've been hiding on your computer.

If you want to find out something about the principles behind Python,
ask about the principles flat-out; don't construct a contrived case like
this and wonder when the community's response is mostly confusion.
Jan 19 '06 #59
Grant Edwards wrote:
It is precisely this power that makes C such a dangerous
language to program in -- it's what makes it so easy to crash
your program, any other program running on the same machine,


Nonsense. Under Windows 3.0 that may be true, but on any real
OS, you can't "crash any other program running on the same
machien" in C, assembly, Python, or Lisp.


given that it's trivial to create fork bombs and memory monsters in all
those languages, I think you might need to define the term "real OS".

(or do you run all your programs in a virtual sandbox ?)

</F>

Jan 19 '06 #60
On 2006-01-19, Fredrik Lundh <fr*****@pythonware.com> wrote:
> It is precisely this power that makes C such a dangerous
> language to program in -- it's what makes it so easy to crash
> your program, any other program running on the same machine,


Nonsense. Under Windows 3.0 that may be true, but on any real
OS, you can't "crash any other program running on the same
machien" in C, assembly, Python, or Lisp.


given that it's trivial to create fork bombs and memory monsters in all
those languages, I think you might need to define the term "real OS".

(or do you run all your programs in a virtual sandbox ?)


I guess I never called that sort of DOS attack "crashing"
another program. If that's the sort of think he's talking
about, those are just as trivial to do do in Python as they are
in C.

--
Grant Edwards grante Yow! Is a tattoo
at real, like a curb or a
visi.com battleship? Or are we
suffering in Safeway?
Jan 19 '06 #61
Dennis Lee Bieber wrote:
On Thu, 19 Jan 2006 17:25:38 +0100, Claudio Grondi
<cl************@freenet.de> declaimed the following in comp.lang.python:

Any hints towards enlightenment what this from the geometry known term
'ellipsis' mean in Python? Googling shows, that I am not the first who

Geometry: singular ellipse, plural ellipses -- sort of a flattened
circle
Punctuation: singular ellipsis -- a mark (typically three ...,
typographically a single character "") used to represent omitted text.
For example, trimming the middle of a quote, such as:
"Any hints towards ... term 'ellipsis' mean in Python?"

In the case of python, you would have to examine slice notation and
some history...

Unless things have changed, nothing in the core Python language
/uses/ the ellipsis in slicing. It was added, apparently, for use in
numerical extension modules where the ellipsis represent
missing/unspecified array indices in an extended slice.


As shown just above in this thread the code:
a = [1]
a.append(a)
a

[1, [...]]
uses it, so it seems, that things have changed.

Claudio
Jan 19 '06 #62
Donn Cave wrote:
In article <dq**********@newsreader3.netcologne.de>,
Claudio Grondi <cl************@freenet.de> wrote:
....
You seem here to try to give a definition of the term 'value' for
Python. If I understand it right, the definition of the term can't be
generally given for many reasons. It depends at least on type and in
advanced usage it can be arbitrary defined or changed.

Yes!

That is why I mean, that it makes no sense to talk in Python about
value. I see not much sense in taking existing term in order to redefine
it for a new context - the result is always increase of confusion. Let
give it another name in order to know, that it must be defined for the
context it is used before it becomes meaningful.
Any suggestions?

Aargh, you are so close. The thing you're talking about is,
exactly, "value". The realization you just had, that is so valid,
is that it is futile to talk about value, per se. Changing the
word you use will do nothing to improve this.

That's right, but I mean, that it could help to avoid confusion
resulting from the fact, that one believes to know the native meaning of
the term 'value' and tries to apply it to Python.

Claudio
Donn Cave, do**@u.washington.edu

Jan 19 '06 #63
In article <dq**********@newsreader3.netcologne.de>,
Claudio Grondi <cl************@freenet.de> wrote:
Donn Cave wrote: ....
exactly, "value". The realization you just had, that is so valid,
is that it is futile to talk about value, per se. Changing the
word you use will do nothing to improve this.

That's right, but I mean, that it could help to avoid confusion
resulting from the fact, that one believes to know the native meaning of
the term 'value' and tries to apply it to Python.


There is no confusion, as long as you stay away from futile
analysis of the meaning of value. If you insist on that,
then no alternative word will help you.

Donn Cave, do**@u.washington.eduu
Jan 19 '06 #64
On Thu, 19 Jan 2006 17:42:40 -0000
Grant Edwards <gr****@visi.com> wrote:
On 2006-01-19, Fredrik Lundh <fr*****@pythonware.com>
wrote:
> It is precisely this power that makes C such a

dangerous > > language to program in -- it's what makes
it so easy to crash > > your program, any other program
running on the same machine, >
Nonsense. Under Windows 3.0 that may be true, but on

any real > OS, you can't "crash any other program running
on the same > machien" in C, assembly, Python, or Lisp.

given that it's trivial to create fork bombs and memory
monsters in all those languages, I think you might need
to define the term "real OS".

(or do you run all your programs in a virtual sandbox ?)


I guess I never called that sort of DOS attack "crashing"
another program. If that's the sort of think he's talking
about, those are just as trivial to do do in Python as
they are in C.


But you do agree that you can shoot your dog in the foot
with it, though, I take it? ;-)

Yes, true multitasking operating systems and CPUs that
support them with protected memory spaces are a good thing.
My C experience mostly dates from machines that didn't have
those features.

Cheers,
Terry

--
Terry Hancock (ha*****@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Jan 19 '06 #65
On Thu, 19 Jan 2006 19:30:18 +0100
Claudio Grondi <cl************@freenet.de> wrote:
Dennis Lee Bieber wrote:
On Thu, 19 Jan 2006 17:25:38 +0100, Claudio Grondi
<cl************@freenet.de> declaimed the following in
comp.lang.python:
As shown just above in this thread the code: >>> a = [1]
>>> a.append(a)
>>> a

[1, [...]]
uses it, so it seems, that things have changed.


No it doesn't. It just uses "...".

That would be like complaining if I wrote an object
representation like:

<MyObject is 2>

that I was "using" the keyword "is" inconsistently. Wrong.
I'm not using it at all -- I'm just using the string "is".

Same above. Although the deeper meaning "an ellipsis shows
an omission" is preserved. The ellipsis in the recursive
definition substitutes for a literal representation which
is conceptually infinite (although due to recursion limits
is really finite).

--
Terry Hancock (ha*****@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Jan 19 '06 #66
Claudio Grondi wrote:
Dennis Lee Bieber wrote:
On Thu, 19 Jan 2006 17:25:38 +0100, Claudio Grondi
<cl************@freenet.de> declaimed the following in comp.lang.python:
Any hints towards enlightenment what this from the geometry known term
'ellipsis' mean in Python? Googling shows, that I am not the first who

Geometry: singular ellipse, plural ellipses -- sort of a flattened
circle
Punctuation: singular ellipsis -- a mark (typically three ...,
typographically a single character "") used to represent omitted text.
For example, trimming the middle of a quote, such as:
"Any hints towards ... term 'ellipsis' mean in Python?"

In the case of python, you would have to examine slice notation and
some history...

Unless things have changed, nothing in the core Python language
/uses/ the ellipsis in slicing. It was added, apparently, for use in
numerical extension modules where the ellipsis represent
missing/unspecified array indices in an extended slice.

As shown just above in this thread the code:
>>> a = [1]
>>> a.append(a)
>>> a

[1, [...]]
uses it, so it seems, that things have changed.

Nope, that's just a linguistic snafu on my part. In English the term
"ellipsis" describes "..." and means "Omission from a text of one or
more words that are obviously understood but that must be supplied to
make a construction grammatically correct". So I described the three
dots as an ellipsis without reference to its meaning in Python.

I hope this hasn't seriously inconvenienced you. However, it does seem
like you are "looking for trouble" here -- i.e. looking to prove that
Python is broken, when what's actually broken appears to be *your
understanding* of Python.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Jan 19 '06 #67
On 2006-01-19, Terry Hancock <ha*****@anansispaceworks.com> wrote:
given that it's trivial to create fork bombs and memory
monsters in all those languages, I think you might need
to define the term "real OS".

(or do you run all your programs in a virtual sandbox ?)
I guess I never called that sort of DOS attack "crashing"
another program. If that's the sort of think he's talking
about, those are just as trivial to do do in Python as
they are in C.


But you do agree that you can shoot your dog in the foot
with it, though, I take it? ;-)


Oh, definitely. And with C++ you can blow the poor creature's
leg entirely off.
Yes, true multitasking operating systems and CPUs that support
them with protected memory spaces are a good thing. My C
experience mostly dates from machines that didn't have those
features.


Though it doesn't make writing a correct program much easier, a
real OS mitigates to a large extent the damage you can do with
C. That said, I only write in C when Python isn't a choice.

--
Grant Edwards grante Yow! I joined scientology
at at a garage sale!!
visi.com
Jan 19 '06 #68
Claudio Grondi wrote:
You seem here to try to give a definition of the term 'value' for
Python. If I understand it right, the definition of the term can't be
generally given for many reasons. It depends at least on type and in
advanced usage it can be arbitrary defined or changed.
That is why I mean, that it makes no sense to talk in Python about
value. I see not much sense in taking existing term in order to redefine
it for a new context - the result is always increase of confusion. Let
give it another name in order to know, that it must be defined for the
context it is used before it becomes meaningful.
Any suggestions?


I think I understand what you mean. In e.g. C you have variables
with values. A variable is a location in memory where you can place
values of a certain type.

This "world-view" doesn't fit if you want to understand Python.

You always have three "thingies" in Python, instead of the two in
C. In C terminology you could say that you always use void pointers
in Python. (Of course, it's not as bad as it sounds, because of
all runtime checks and memory management etc, but you know that.)

So, in Python you have references, objects and content.

Sometimes the reference is just a slot in a container, e.g. if you
have "[0]" in your code, the list contains a reference to an
integer object with the content 0.

I think most people consider "value" and "content" to be synonyms,
but from the perspective of a variable name in the source code,
e.g. "a='hello'", there is always one level of indirection, since
there is always a pointer in between (and you can get that with
"id(a)").

The Python manuals refer to the names in Python programs (such as
"a" in "a=1") as variables, but some think that it's better to
call them "names" or "references", since they lack properties many
people associate with variables, for instance type.

If I return to C lingo again, datastructures in Python are always
made with malloc, and it's just these datastructures on the heap
that contain interesting values (or contents if you prefer that).

In C, pointers are particular types, and you can create pointer
chains that have an arbitrary length. Python don't have pointers.
You always get one level of idirection automatically, and the
referencing and derefencing is handled automatically. If you want
to chain data structures you can easily do that with containers
such as lists, or with classes you define yourself.

I don't think there are really any controversies concerning values
though. It's the content of the malloced datastructure. It's not
as ovbiously available in Python as in C, but it's still meaningful
to talk about it.

Then we get to the case of comparision operators in Python, such
as == and > etc. For simple types, they are used to compare the
values/contents of the compared objects in a fairly obvious way.
For containers such as list, Python declares that two lists are
equal if they have the same number of elements, and a pair-wise
comparision of all elements compare equal. E.g. ([a,b] == [c,d])
== (a==c and b==d). For classes you define, you get to decide
yourself how to implement comparisions.

This freedom in how to compare things shouldn't really influence
your view on values in Python. Values aren't defined through the
comparision operator.

One fundamental difference between C and Python is that C is a low
level language where you can directly access and manipulate the
computer memory. Python is a high level language where you can't
to that. You are limited to more abstract operations. I can see
how that makes thing feel more fuzzy. It's a bit like a car with
the hood welded shut. Also, Python is more flexible and customizable.
The comparision operators aren't hardwired to some basic machine
language instructions, their behaviour is defined in your code. It's
like fly-by-wire in modern airplanes. When the pilot pulls a lever,
it doesn't directly cause a rudder to move on a wing, it tells the
steering computer where the plane should go, and the computer decides
what rudders to move, and how much. That doesn't mean that it's
pointless to discuss rudders in modern airplanes.
Jan 20 '06 #69
Magnus Lycka wrote:
Claudio Grondi wrote:
You seem here to try to give a definition of the term 'value' for
Python. If I understand it right, the definition of the term can't be
generally given for many reasons. It depends at least on type and in
advanced usage it can be arbitrary defined or changed.
That is why I mean, that it makes no sense to talk in Python about
value. I see not much sense in taking existing term in order to
redefine it for a new context - the result is always increase of
confusion. Let give it another name in order to know, that it must be
defined for the context it is used before it becomes meaningful.
Any suggestions?

I think I understand what you mean. In e.g. C you have variables
with values. A variable is a location in memory where you can place
values of a certain type.

This "world-view" doesn't fit if you want to understand Python.

You always have three "thingies" in Python, instead of the two in
C. In C terminology you could say that you always use void pointers
in Python. (Of course, it's not as bad as it sounds, because of
all runtime checks and memory management etc, but you know that.)

So, in Python you have references, objects and content.

Sometimes the reference is just a slot in a container, e.g. if you
have "[0]" in your code, the list contains a reference to an
integer object with the content 0.

I think most people consider "value" and "content" to be synonyms,
but from the perspective of a variable name in the source code,
e.g. "a='hello'", there is always one level of indirection, since
there is always a pointer in between (and you can get that with
"id(a)").

The Python manuals refer to the names in Python programs (such as
"a" in "a=1") as variables, but some think that it's better to
call them "names" or "references", since they lack properties many
people associate with variables, for instance type.

If I return to C lingo again, datastructures in Python are always
made with malloc, and it's just these datastructures on the heap
that contain interesting values (or contents if you prefer that).

In C, pointers are particular types, and you can create pointer
chains that have an arbitrary length. Python don't have pointers.
You always get one level of idirection automatically, and the
referencing and derefencing is handled automatically. If you want
to chain data structures you can easily do that with containers
such as lists, or with classes you define yourself.

I don't think there are really any controversies concerning values
though. It's the content of the malloced datastructure. It's not
as ovbiously available in Python as in C, but it's still meaningful
to talk about it.

Then we get to the case of comparision operators in Python, such
as == and > etc. For simple types, they are used to compare the
values/contents of the compared objects in a fairly obvious way.
For containers such as list, Python declares that two lists are
equal if they have the same number of elements, and a pair-wise
comparision of all elements compare equal. E.g. ([a,b] == [c,d])
== (a==c and b==d). For classes you define, you get to decide
yourself how to implement comparisions.

This freedom in how to compare things shouldn't really influence
your view on values in Python. Values aren't defined through the
comparision operator.

One fundamental difference between C and Python is that C is a low
level language where you can directly access and manipulate the
computer memory. Python is a high level language where you can't
to that. You are limited to more abstract operations. I can see
how that makes thing feel more fuzzy. It's a bit like a car with
the hood welded shut. Also, Python is more flexible and customizable.
The comparision operators aren't hardwired to some basic machine
language instructions, their behaviour is defined in your code. It's
like fly-by-wire in modern airplanes. When the pilot pulls a lever,
it doesn't directly cause a rudder to move on a wing, it tells the
steering computer where the plane should go, and the computer decides
what rudders to move, and how much. That doesn't mean that it's
pointless to discuss rudders in modern airplanes.


I welcome what you wrote as you seem to get some understanding of what I
am intending to tell. From what you have written I am not 100% sure if
you are already there, or you are only close to what I mean, so lets try
to clarify it.
I am happy to see the term 'content' as it express much better what is
stored in an object, because 'content' is a quite general term and
therefore it is no problem to say it can be any of value, function,
class, operator, type etc.

So I see the Python terminology resolved using following hierarchy of
terms:

- on the top level there is a name called in Python terms _identifier_
being a substitute for a reference to a Python object.
- one lever deeper referenced by an identifier is a Python _object_ with
all the functionality and data it represent. All this what makes an
object i.e. various kind of data stored in it, functions, classes,
types, etc. provided is called Python object content, short _content_.
- one level deeper, in the object itself they may be various data stored
as integer values, strings, etc. . An object can, but need not to hold
any data which can be one single _value_ or more of them. The values an
object holds can be but need not to be used for exposing them, i.e. some
values can be 'hidden' from being present in an object and used only for
internal object purposes.

Let's summarize providing following rough draft of hierarchy of terms:

identifier ->(dereferencing)->object->(is container for)->content->(is a
superordinate concept covering one or more of)->value, function, class,
type, object, etc.

Any comments, refinements, corrections, adjustments?

Claudio
Jan 20 '06 #70
On Thu, 19 Jan 2006 10:08:38 +0100, Claudio Grondi wrote:
The point is to find a way to create in Python two indentifiers a and b
without manipulating any of the __eq__ and to __eq__ related functions
in a way, that the simple
if a==b: print 'a==b'
statement results in an endless loop.
Why would you want to?
To my knowledge this is not possible to achieve in C, but is probably
achievable in Python.


I doubt it.

The closest I can think of is something like this:
a = []
a.append(a)
b = []
b.append(b)
a == b

which I'm told used to cause an endless loop in early versions of Python,
but now simply returns True.

--
Steven.

Jan 21 '06 #71
Steven D'Aprano wrote:
On Thu, 19 Jan 2006 10:08:38 +0100, Claudio Grondi wrote:

The point is to find a way to create in Python two indentifiers a and b
without manipulating any of the __eq__ and to __eq__ related functions
in a way, that the simple
if a==b: print 'a==b'
statement results in an endless loop.

Why would you want to?

To my knowledge this is not possible to achieve in C, but is probably
achievable in Python.

I doubt it.

The closest I can think of is something like this:
a = []
a.append(a)
b = []
b.append(b)
a == b

which I'm told used to cause an endless loop in early versions of Python,
but now simply returns True.


Python 2.4.2 (#67, Sep 28 2005, 12:41:11) [MSC v.1310 32 bit (Intel)] on
win32 - IDLE 1.1.2
a=[]
a.append(a)
b=[]
b.append(b)
a==b
Traceback (most recent call last):
File "<pyshell#4>", line 1, in -toplevel-
a==b
RuntimeError: maximum recursion depth exceeded in cmp


Claudio
Jan 21 '06 #72
On Sat, 21 Jan 2006 01:12:28 +0100, Claudio Grondi wrote:
Python 2.4.2 (#67, Sep 28 2005, 12:41:11) [MSC v.1310 32 bit (Intel)] on
win32 - IDLE 1.1.2
>>> a=[]
>>> a.append(a)
>>> b=[]
>>> b.append(b)
>>> a==b
Traceback (most recent call last):
File "<pyshell#4>", line 1, in -toplevel-
a==b
RuntimeError: maximum recursion depth exceeded in cmp >>>
Works for me:
Python 2.3.3 (#1, May 7 2004, 10:31:40)
[GCC 3.3.3 20040412 (Red Hat Linux 3.3.3-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information. a = []
a.append(a)
b = []
b.append(b)
a == b

True
Maybe IDLE is playing silly buggers, or perhaps Python 2.4.2 has a bug.
--
Steven.

Jan 21 '06 #73
[Claudio Grondi]
Python 2.4.2 (#67, Sep 28 2005, 12:41:11) [MSC v.1310 32 bit (Intel)] on win32 - IDLE 1.1.2
>>> a=[]
>>> a.append(a)
>>> b=[]
>>> b.append(b)
>>> a==b
Traceback (most recent call last):
File "<pyshell#4>", line 1, in -toplevel-
a==b
RuntimeError: maximum recursion depth exceeded in cmp
|[Steven D'Aprano] Works for me:
Under a different version of Python, though.
Python 2.3.3 (#1, May 7 2004, 10:31:40)
[GCC 3.3.3 20040412 (Red Hat Linux 3.3.3-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information. a = []
a.append(a)
b = []
b.append(b)
a == b

True
Maybe IDLE is playing silly buggers, or perhaps Python 2.4.2 has a bug.


It's neither. From the NEWS file for Python 2.4a1:

"""
- Python no longer tries to be smart about recursive comparisons.
When comparing containers with cyclic references to themselves it
will now just hit the recursion limit. See SF patch 825639.
"""
Jan 21 '06 #74

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.