Collections of non-arbitrary objects ?

M

Marc 'BlackJack' Rintsch

walterbyrd a écrit :

No, because this operation is not implemented for strings - IOW, strings
doesn't understand this message. What would be the meaning of dividing
strings anyway ? (while concatening string is a well-known operation).

As someone else already mentioned dividing strings is splitting. The Pike
language does this:

http://pike.ida.liu.se/generated/manual/ref/chapter_4.html

Scroll down to ``string / string``. The definition of ``string / float``
is neat too. Something I really miss in everyday programming in Python,
not. ;-)

Ciao,
Marc 'BlackJack' Rintsch
 
B

Ben Finney

walterbyrd said:
a = [1,2,3]
b = a
a[1] = 'spam'

Here, I have changed b, without an explicit assignment.

No. Both 'a' and 'b' are names bound to a single object; you're
changing that object. This is a subtle difference, but it's one that
is confusing you in this instance.
So let's say I have list L, and I have a routine that expects every
item in L to be a dictionary like: {'name':'joe', 'job':'dev',
'pay': min_wage}.

If that routine expects objects of a particular *type*, instead of
objects that exhibit expected *behaviour*, the routine is poorly
designed.
Not only could the app crash if an incorrect item where inserted
into L. But the app could crash if an incorrect item were inserted
in lists X,Y, or Z.

When the routine tries to deal with an object that doesn't behave as
expected, an exception will be raised. If the exception goes uncaught,
then Python will exit and throw the exception to the user; I suppose
you could call this a "crash".
Of course, you can always work around this by just programming very
carefully, and doing a lot of error checking. That is always true in
any language.

Better is to catch the exception at a level where it can be dealt
with; this is usually the same level where those non-conforming
objects were placed in the list to begin with.
BTW: I think polymorphism is great and all. But it does have (and
IMO should have) it's limitations. For example, I don't think you
can divide a string by another string.

Indeed, and you'll get an exception raised if you try. Catch that
exception at a level where there's enough context to make sense of it,
and deal with it in whatever way you see fit.
 
G

Gabriel Genellina

I have probably expressed this incorrectly. What I meant was:
a = [1,2,3]
b = a
a[1] = 'spam'

Here, I have changed b, without an explicit assignment. After I
assigned a to b, I never did another "b =" yet b changed anyway
because I changed a. I am not saying there is anything wrong with
this, I'm just explaining what I meant.

I think you should benefit reading this short article:
http://effbot.org/zone/python-objects.htm
 
P

Paul Rubin

Bruno Desthuilliers said:
You know, Python is now something like 17 years old, and is used by a
*lot* of peoples for a *lot* of programs - some of them far from
trivial. I think you can be confident in this experience. IOW, just
write your code, and you'll find out that the kind of problems you
seem to fear so much will not happens that often.

Assembler and Cobol have been around even longer...
 
B

Bruno Desthuilliers

walterbyrd a écrit :


I have probably expressed this incorrectly. What I meant was:

a = [1,2,3]
b = a
a[1] = 'spam'


Here, I have changed b, without an explicit assignment.

You haven't changed b, you have changed the object bound to name 'b'.
Which happens to be also bound to name 'a'.
After I
assigned a to b,

Well, I guess the term "assignment" is misleading you then. "binding"
would be more accurate - you bound names 'a' and 'b' to the same object.
Then, whether you access this object via name 'a' or name 'b', you're
still accessing the same object.
I never did another "b =" yet b changed anyway

Doing 'b = some_other_object' would still not 'change b' - you don't
change a name - but rebind name 'b' to another object.

You perhaps don't know this, but most statically typed languages have
the notion of either pointers or references, that can cause similar -
and usually worse - problems.
because I changed a. I am not saying there is anything wrong with
this, I'm just explaining what I meant.
>
So let's say I have list L, and I have a routine that expects every
item in L to be a dictionary like: {'name':'joe', 'job':'dev', 'pay':
min_wage}.

Not only could the app crash if an incorrect item where inserted into
L. But the app could crash if an incorrect item were inserted in lists
X,Y, or Z.

Yes - assuming names L, X, Y and Z are bound to the same list.

And it would also crash if one the dicts was modified between the moment
it is added to the list and the moment you pass the list to your
function. Which makes "typed" lists totally useless anyway. And even if
you use a smarter 'correctness' test (like a callback function checking
that every item added or inserted supports keying and has the correct
keys), it would still be useless since you could still manage to modify
one of the items of the list *after* it has been added to it.
Of course, you can always work around this by just programming very
carefully,

You do program carefully, don't you ?-)
and doing a lot of error checking.

That's usually not even necessary - most of the time (ie: almost
always), you'll have a nice traceback in the minutes following the
moment you introduced the error.
That is always true in
any language.

Nope. In Python, you seldom have to do error *checking* - the language
do it for you (that's what exceptions are for). What you have to do is
1/ testing, and 2/ error *handling*.

Now did you actually had any effective problem with Python's dynamism ?
Or are you just scared ?

You know, Python is now something like 17 years old, and is used by a
*lot* of peoples for a *lot* of programs - some of them far from
trivial. I think you can be confident in this experience. IOW, just
write your code, and you'll find out that the kind of problems you seem
to fear so much will not happens that often.
But, I think sometimes it's helpful to use a structure that is little
more restrictive, to sort of enforce a degree of integrity.

Sometimes you do have to check the validity of the data you are supposed
to work on, true - mostly when it comes to program inputs (be it wia
files, sockets, forms, environment, whatever). Once this is done, you
shouldn't have to worry too much - just let Python crash when there's
something wrong, carefully read the traceback, and correct the offending
code (which is very likely in the last modifications you made).
An example
I have already given: why use tuples instead of a list? Tuples are
actually a bit more restrictive.

You don't use tuples "instead of" lists. Lists are collections, tuples
are structured data.
I don't think there is anything wrong with the data structures that
exist in python. I was just wondering if there was a structure that
would restrict a collection to only allow certain types.

Not builtin. You can roll your own if it makes you happy, but that would
be a waste of time - been here, done that, you see...
The
"restrictedlist" class discussed in another thread may be the sort of
thing I was looking for.

So please take time to read the whole thread.
BTW: I think polymorphism is great and all. But it does have (and IMO
should have) it's limitations.

Yes, indeed - if an object doesn't understand a message, then you have
an exception. But since the only way to know if an object can handle a
message is to send the message (please refer to my previous post),
enforcing 'type'-based (with 'type'=='class') restriction in Python is
not only useless, it's also harmful. IOW, stop fighting against the
language - just use it.
For example, I don't think you can
divide a string by another string.

No, because this operation is not implemented for strings - IOW, strings
doesn't understand this message. What would be the meaning of dividing
strings anyway ? (while concatening string is a well-known operation).
 
M

Michele Simionato

That also hides attribute errors that occur within some_func. I think
I'd rather know when elmt has an implementation of some_func that is
buggy. Thus I prefer the hasattr version.

Or possibly

try:
do_func = elmt.some_func
except AttributeError:
do_stuff()
else:
do_func()

(internally hasattr is doing that anyway).

Michele Simionato
 
W

walterbyrd

On Jun 24, 10:31 pm, Bruno Desthuilliers
You perhaps don't know this, but most statically typed languages have
the notion of either pointers or references, that can cause similar -
and usually worse - problems.

Yes, but those languages also have the notion of structures that do
not allow arbitrary collections. That is what I was wondering about
when I started the thread. It's fine that python has four different
ways of creating collections of arbitrary data types, but I thought it
might be helpful if python had, at least, one way of a creating a
collection of non-arbitrary data.
You do program carefully, don't you ?-)

I try. But things like typos are a normal part a life.
Now did you actually had any effective problem with Python's dynamism ?
Or are you just scared ?

Just scared.
> You know, Python is now something like 17 years old, and is used by a
*lot* of peoples for a *lot* of programs - some of them far from
trivial. I think you can be confident in this experience. IOW, just
write your code, and you'll find out that the kind of problems you seem
to fear so much will not happens that often.

Of course, BASIC is over 40 years old, also used by a *lot* of people.
A lot of non-trivial apps have been written in BASIC. But, BASIC is
often criticized for it's lack of structure. A language's longevity,
and/or popularity, don't mean there isn't room for improvement. Guido
must think python has a lot of room for improvement since he's
completely throwing out backward compatibility with python 3000.
You don't use tuples "instead of" lists. Lists are collections, tuples
are structured data.

It seems to me that tuple are essentially immutable lists. So why
impose that immutability restriction on a data collection? Why not
just have lists and not tuples? What can a tuple do that a list can
not do? Why was python designed so that tuples could be used for
dictionary indexes, but not lists? Could it be because imposing that
restriction on a data collection insures a certain degree of
integrity? My point is: sometimes imposing some restrictions can give
a degree in built-in integrity. Maybe you don't need that integrity
insurance, if you code carefully enough, but can you always count on
that?

BTW: I'm not assuming that it will always be me running my own app.
Sure, if an exception occureed while I was running my own app, I'd
probably know what to do. But if somebody else (who - god forbid -
didn't know python was running the app, things might be more difficult.
 
B

Bruno Desthuilliers

walterbyrd a écrit :
Yes, but those languages also have the notion of structures that do
not allow arbitrary collections.

Ever played with casting in C ?
That is what I was wondering about
when I started the thread. It's fine that python has four different
ways of creating collections of arbitrary data types, but I thought it
might be helpful if python had, at least, one way of a creating a
collection of non-arbitrary data.

As I explained, while technically possible (and not specially
difficult), this is a waste of time given Python's dynamism.
I try. But things like typos are a normal part a life.

So are they in any language. I fail to see much difference here.
Just scared.

So take a deep breath and try to just do the simplest thing (in this
case: using builtin collection types). Usually, it JustWorks(tm).
Of course, BASIC is over 40 years old, also used by a *lot* of people.

Not the same kind of people I'd say !-)
A lot of non-trivial apps have been written in BASIC. But, BASIC is
often criticized for it's lack of structure.

Old time basic effectively lacks of "structure", since it uses goto's
instead of functions, loops and conditionals (google for "structured
programming").

What I meant here is that one of the lessons of this collective
experience is that 'typed' containers are more often harmful than useful.
A language's longevity,
and/or popularity, don't mean there isn't room for improvement.

Indeed. But declarative static typechecking wouldn't be an improvement.
Guido
must think python has a lot of room for improvement since he's
completely throwing out backward compatibility with python 3000.

Not "completely throwing out". Just allowing *some* major breakages -
the kind you usually get with each major release of other languages, but
that Python managed to avoid as much as possible so far.
It seems to me that tuple are essentially immutable lists.

They are not (even if you can use them that way too). FWIW and IIRC,
this is a FAQ.
So why
impose that immutability restriction on a data collection?

Because tuples are *not* collections. They are *structured data*. The
canonical tuple is a SQL database row.
Why not
just have lists and not tuples?

because tuples are not lists.
What can a tuple do that a list can
not do?

Be immutable.
Why was python designed so that tuples could be used for
dictionary indexes, but not lists?

How would you compute a hash from a generic mutable collection ?
Could it be because imposing that
restriction on a data collection insures a certain degree of
integrity?

Once again: tuples are *not* collections. Would you define a string as a
collection ?
My point is: sometimes imposing some restrictions can give
a degree in built-in integrity.

Yes. But the kind of restriction you're talking about won't buy you
much, as I already explained, and, in practice, happens to be mostly
useless.
Maybe you don't need that integrity
insurance, if you code carefully enough,

Maybe you don't need that "integrity insurance", period ?-)
but can you always count on
that?

It seems that tens of thousands of Python users are doing fine without this.
BTW: I'm not assuming that it will always be me running my own app.
Sure, if an exception occureed while I was running my own app, I'd
probably know what to do. But if somebody else (who - god forbid -
didn't know python was running the app, things might be more difficult.
The canonical solution is to have an application-level error handler
that logs uncaught exceptions (so the developper can get at them),
display a user-friendly error message (eventually giving the user a way
to submit a bug report to the developper), and try to crash as cleanly
as possible.

However careful and serious you are wrt/ programming and testing, your
program *will* have bugs (unless it's some kind of hello world). Better
learn to live with it.

Let's suppose you implement a restrictedList. It of course raises an
exception when trying to add a 'non-compliant' item. All this happening
at runtime, of course. Now let's suppose there's one such error in your
code that managed to pass thru tests. What's going to happen ? Yes,
exactly the same thing as if you used a plain list - just somewhere else
in the code. For the final user, the result will be *exactly* the same :
a crash.
 
W

walterbyrd

walterbyrda écrit :



So are they in any language. I fail to see much difference here.

For example: if I mis-type a variable name in C, the program will
probably not even compile. Whereas, with Python, the program will
probably run, but may give unexpected results.

Not "completely throwing out". Just allowing *some* major breakages -
the kind you usually get with each major release of other languages, but
that Python managed to avoid as much as possible so far.

I don't know, but here is a direct quote from Guido's blog: "Python
3.0 will break backwards compatibility. Totally."

http://www.artima.com/weblogs/viewpost.jsp?thread=208549
They are not (even if you can use them that way too). FWIW and IIRC,
this is a FAQ.

A few posters here have stated that tuples are not just immutable but
when I compare lists, to tuples, I notice that both are ordered
collections of arbitrary objects, with the primary difference being
that list are mutable, and tuples are not. It seems to me that if a
list were immutable, it would be a tuple. That is the one big
difference.

Tuples have been compared to records/structures in other languages.
But, in general, I can not use a for loop to loop through the fields
in a record, and I can not sort those fields either.
 
S

Steve Holden

walterbyrd said:
For example: if I mis-type a variable name in C, the program will
probably not even compile. Whereas, with Python, the program will
probably run, but may give unexpected results.



I don't know, but here is a direct quote from Guido's blog: "Python
3.0 will break backwards compatibility. Totally."
By which he means he is not, for this one major release only, committed
to maintaining backwards compatibility with previous versions (which was
pretty good, though not perfect).
http://www.artima.com/weblogs/viewpost.jsp?thread=208549


A few posters here have stated that tuples are not just immutable but
when I compare lists, to tuples, I notice that both are ordered
collections of arbitrary objects, with the primary difference being
that list are mutable, and tuples are not. It seems to me that if a
list were immutable, it would be a tuple. That is the one big
difference.

Tuples have been compared to records/structures in other languages.
But, in general, I can not use a for loop to loop through the fields
in a record, and I can not sort those fields either.
Think of a tuple as an ordered collection. A given element's ordinal
position indicates its semantics (meaning, significance), and generally
it won't make sense to iterate over the elements of a tuple (though
naturally that doesn't stop people, and neither does the interpreter).

Lists are intended for numbered "sets of things", and when all the
"things" are of the same or closely-related types it's natural to
iterate over them.

Those who don't "see the need" for tuples need not use them, and their
programs probably won't be much worse as a result.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------
 
P

Paul Rubin

Steve Holden said:
Think of a tuple as an ordered collection. A given element's ordinal
position indicates its semantics (meaning, significance), and
generally it won't make sense to iterate over the elements of a tuple
(though naturally that doesn't stop people, and neither does the
interpreter).

def f(*a): ...

is a fundamental language feature and really only makes sense in
the context of iterating over tuples.
 
B

Bruno Desthuilliers

walterbyrd a écrit :
For example: if I mis-type a variable name in C, the program will
probably not even compile.

It sometimes happens - but chances are low, for sure.
Whereas, with Python, the program will
probably run, but may give unexpected results.
Yes, true. Well, in some cases. In one case, to be true: the use of the
'=' operator. IIRC, any other use of an undefined symbol will raise an
exception. But this has to do with how symbols are defined in Python
(ie: the fact that binding => definition), and has nothing to do with
static (compile-time) type checking.
I don't know, but here is a direct quote from Guido's blog: "Python
3.0 will break backwards compatibility. Totally."

http://www.artima.com/weblogs/viewpost.jsp?thread=208549

Please take it with a grain of the salt. This is mostly about getting
rid of long-time deprecated features.
A few posters here have stated that tuples are not just immutable but
when I compare lists, to tuples, I notice that both are ordered
collections of arbitrary objects, with the primary difference being
that list are mutable, and tuples are not.

This is of course technically true. And you forgot to compare to sets,
while we're at it. But the answer to your questions about tuples is not
technical - it's about use case.
It seems to me that if a
list were immutable, it would be a tuple. That is the one big
difference.
>
Tuples have been compared to records/structures in other languages.
But, in general, I can not use a for loop to loop through the fields
in a record,

For which definition of "in general" ? I can do this with at least
Python, PHP, Javascript, Ruby, and probably Java (IIRC).
and I can not sort those fields either.

Did you try to sort a tuple ?
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'tuple' object has no attribute 'sort'
 
W

walterbyrd

Did you try to sort a tuple ?

Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'tuple' object has no attribute 'sort'

I can do this:

Which, although senseless, effectively sorts the x tuple. But, you are
right, I am not really sorting the tuple, I'm sorting a list, which
has been made from the tuple, then changing it back to a tuple.

Actually, I can even do it in one line:

x = tuple(sorted(list((3,2,1))))
 
S

Steve Holden

Paul said:
def f(*a): ...

is a fundamental language feature and really only makes sense in
the context of iterating over tuples.

That's true, but given that individual arguments are bound to names in
the local namespace I'd have to argue (if I wanted to argue at all) that
the choice of a tuple over a list was pretty arbitrary, and that it
would actually be "more Pythonic" to allow modification of the argument
list in the same way as sys.argv is mutable.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------
 
B

Bruno Desthuilliers

walterbyrd a écrit :
I can do this:

>
Which, although senseless, effectively sorts the x tuple.
Err...

But, you are
right, I am not really sorting the tuple,
Indeed.

I'm sorting a list, which
has been made from the tuple, then changing it back to a tuple.

Exactly. You're in fact *creating* a new tuple - how you do it is
somewhat irrelevant. This is certainly not the same thing as in-place
sorting.

From a purely practical POV, using tuples as "frozen lists" can
sometimes make sens - be it for micro-optimization (tuples are cheaper
than lists). But still, you'll find that in most cases(with most==almost
always), tuples are used for (eventually heterogenous) data *where the
order is significant* (fields in a db row, argument list, base classes
lists, 2D or 3D points, etc), and can not be changed without changing
the semantic of the data, while lists are used to collect (more or less)
homogenous data where the order doesn't impact the semantic of the data
(which is one of the reasons why list can be sorted and tuples cannot).
As a matter of fact, a dict can be build from a list of (key,value)
tuples - and it's obvious that the order of the elements in each tuple
is significant, while the order of tuples in the list is not.

HTH
 

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,773
Messages
2,569,594
Members
45,121
Latest member
LowellMcGu
Top