Perl is worse!

Martijn Faassen m.faassen at vet.uu.nl
Sun Jul 30 17:07:02 EDT 2000


Steve Lamb <grey at despair.rpglink.com> wrote:
> On 29 Jul 2000 02:50:37 GMT, Martijn Faassen <m.faassen at vet.uu.nl> wrote:
>>Right -- that's why I didn't understand why you complained about the
>>extensive exception checking or other checks you need in Python; if you
>>*know* a string can be safely converted to an integer, int() does the
>>job just fine by itself.

>     Because Python can toss two types out.  String or None, only one of which
> can be converted.

Yes, obviously, as there is an infinity of 'types' (classes, and such).
Python tosses out lots and lots of combinations, otherwise it'd be hard
to remember what happens when for the programmer, and the implementation
could become very hairy. The latter reason is not the most important
one, though; the former is.

If you want an 'int()' that can deal with more things, make your own
int() like function; it's not hard.

>>Ahum, the first! Especially if it deals with critical data, or *money*.
>>Imagine I get a string by accident (there's a bug in the program) instead
>>of a number, and the string evaluates to 0, and suddenly what I'm selling
>>in my e-commerce store is *free*, I'd be rather upset. I'd rather have the
>>software not working in case of such input!

>     Assumption it is dealing with money.  What about logs processing?

Depends on the application. If I want the program to tolerate mistakes,
I can always make it tolerate mistakes by catching and handling some
exceptions. It's harder to do the reverse though; if the system tolerate
mistakes in the first place I can't easily 'harden' it to suddenly catch
human errors (in the input parsing routines, for instance).

Of course there are tradeoffs; static typechecking apologists would say
this demands overrides all others. In the Python and Perl communities
we tend to say there is such a thing as flexibility, and speed of
implementation; these are important too. There are other strategies
towards keeping bugs away from your code, after all, such as testing.
(which is healthy no matter how many types you have anyway)

>>It's not a meaningless statement. Sometimes it's very handy to get the
>>representation of some Python object. For instance:

>>>>> def foo(): pass
>>>>> [many complicated steps later]
>>...ah, but what is bar now?
>>>>> bar
>><function foo at 80c8f68>

>     Right, I understand thta.  Which is why I keep pointing out that it is
> meaningless in the context of a script.  You tell me why I would need to know
> that in a script and maybe we can get around this.  I just see no need, ever,
> for something that cannot be accessed by the script in the first place.

It can:

print bar

The trouble is with the way expressions can be statements in Python. Some
expressions just don't have any side effects, and if you use an expression
as a statement (without any assignment involved, for instance), 
such expressions are meaningless. It's definitely very hard to check
for the side-effects thing; you'd need a pretty heavy program analysis and
even then it could be tricky. Perhaps there's an easier way around and
just forbid any expression that isn't a call to be a statement. But
perhaps there are objections to this approach too.

It would seem to be that this is an implementation problem; not a lot
of time has been invested in fixing it because not a lot of people trip
over this one, apparently. You did, though, so perhaps we need to change
it, if possible.

>>In non-interactive mode it isn't useful, I think (I'd love to hear some
>>cases outside the function call example) so we could propose a patch to
>>Python that trips over this (in the case of non-calls).

>     See, we're in agreement.

Yes, but you seemed to say this was something inconsistent; it's not
inconsistent. I just seems to be a fairly tough problem.

>>That statement sounds good in rethorics, but in practice I'd rather
>>have the computer give up on things if I'm trying to do things that
>>don't seem to make any sense immediately. That way I need to remember
>>less.

>     To me it is remembering more.  "Now, this variable coming in from that
> file over there, going through this code over here in a different module,
> entering in here... was it converted twice or three times and what do I need
> to do with it now."

>     Vs.

>     "Here it is, those checks said it is this, do it."

Ahum, the latter isn't really possible in Python. Your integer wil never
ever be converted to a noninteger. Pass it through as many routines
as you like, it won't ever happen. For mutable variables such as lists
or class instances, it can happen; their contents can change over time. But
they'll (some exceptions possible for class instances, but rare) remain
the same thing all the time, still.

Your variable name may be pointing to something new and different though,
but that can happen in Perl just the same.

And you need to remember what all your operations do to any data type
that they may encounter. I don't.

>>Unless you made it possible that b contained something that couldn't be
>>turned into a number, such as None. If you made that possible you aren't
>>sure beyond all doubt that the variable contains a number, right?

>     Which is, of course, a product of the lanauge.  I know it is going to be a
> digit or empty.  Sad part is Python makes empty None and None mutable into
> pretty much nothing.

That's not sad; Python is just pointing out to you that (in your initial
statement) you were *wrong*. 'b' does *not* always contain a number.
You were thinking sloppily, and Python caught you.

1 isn't mutable into anything at all either, by the way. Neither are
strings. The name 'b' can however be made to point to something else.
That is an entirely different thing though, and from the way you're
speaking I'm not entirely clear whether you understand this yet.

>>Sure, but it is the same in Python, right? Except that in the end you have
>>to cast your integers to ints or whatever other thing you were expecting
>>from your input.

>     So why, then, when I have done the check should I have to do it, again,
> for the sake of the language.

Because the language can do different things with strings than with
numbers. You have to tell the language that the object you're referring to
with 'b' is the object that can to arithmatic; not the object that can
you can get characters from.

And note that if you really insist, the language leaves you free to define
an object that can do both. Not that I'd consider this object to look
very pretty. If you drive your philosophy of 'data' to the extreme, you'd
need an object that defines operations for *everything*. :)
(as your distinction between data and objects is not correct, especially
not in Python; data has behavior and objects have state)


Regards,

Martijn
-- 
History of the 20th Century: WW1, WW2, WW3?
No, WWW -- Could we be going in the right direction?



More information about the Python-list mailing list