Python from Wise Guy's Viewpoint

M

Marshall Spight

Pascal Bourguignon said:
The only untyped languages I know are assemblers. (ISTR that even
intercal can't be labelled "untyped" per se).

Are we speaking about assembler here?

BCPL!


Marshall
 
M

Marshall Spight

Pascal Costanza said:
What can happen in Java is the following:

- You might accidentally use the wrong class in a class cast.
- For the method you try to call, there happens to be a method with the
same name and signature in that class.

In this situation, the static type system would be happy, but the code
is buggy.

How is this any different a bug than if the programmer types the
wrong name of the method he wants to call? This doesn't demonstrate
anything that I can figure.

Here's a logically identical argument:

In a typed language, a programmer might type "a-b" when he meant
to type "a+b". The type system would be happy, but the code will
be buggy.

Well, yes, that's true.

My claim is: explicit downcasting is a technique, manually specified
by the programmer, that weakens the guarantees the compiler makes
to be exactly as weak as those guarantees made by a dynamically
typed language.

So I can see a valid complaint about the extra typing needed, but
I see no validity to the claim that this makes a statically typed
language any more bug-prone than a dynamically typed language.
Indeed, it gives the statically-typed languages *exactly the same*
degree of bug-proneness as a dynamically typed language for the
scope of a single function call, after which the languages returns
to being strikingly less prone to that specific class of bug. (In fact,
completely immune.)

In a decent dynamically typed language, you have proper name space
management, so that a method cannot ever be defined for a class only by
accident.

How can a method be defined "by accident?" I can't figure out what
you're trying to say.


Marshall
 
K

ketil+news

Pascal Costanza said:
Dirk Thierbach wrote:
As long as I am writing only tests, I don't care. When I am in the
mood of writing tests, I want to write as many tests as possible,
without having to think about whether my code is acceptable for the
static type checker or not.

Uh...the type system will let you *write* what you want, it will just
stop you from *running* those tests. Which are obviously going to
fail anyway. Okay, so perhaps you for some reason needs to write the
tests for nonexistent code, and then run something else that you keep
in the same file. You then need to add

concretemethod = undefined

which just goes to show you how useless static typing is.

-kzm
 
M

Marshall Spight

Joachim Durchholz said:
A test suite can never catch all permutations of data that may occur (on
a modern processor, you can't even check the increment-by-one operation
with that, the universe will end before the CPU has counted even half of
the full range).

Just to be pedantic, there are some circumstances where this is
possible. For example, it is quite possible to construct a test suite
that will exhaustively test the boolean "or" operator. There are
exactly four test cases, so that's not too bad.

It's worth mentioning this because it points out what you
have to do for a unit test suite to provide the degree of
coverage that any theorem-proving based system does:
you have to check the entire set of inputs for the function.
Sometimes I run into unit test boosters who feel that
they're provably correct when they have a test case
for every code path. But you'd have every code path
tested with just one test case for the "or" example,
whereas you need fully 4 test cases before you're
provably correct.

Hmmm. Should my test suite for "or" include
passing it strings and ints and checking to be
sure it gives an exception?


Marshall
 
M

Marshall Spight

Pascal Costanza said:
In a statically typed language, when I write a test case that calls a
specific method, I need to write at least one class that implements at
least that method, otherwise the code won't compile.

In a dynamically typed language I can concentrate on writing the test
cases first and don't need to write dummy code to make some arbitrary
static checker happy.

This is a non-issue. In both cases, you need the implementing code
if you want to be able to run the testcase, and you don't need the
implementing code if you don't.


Marshall
 
K

ketil+news

Yes it is a very big deal.

While Mr. Martin probably should get out more, I must admit that I
have a nagging feeling about typing and object orientation. Somebody
else correlated typing with imperativity, and I suspect dynamic typing
is a better match for OO than static typing. But I'm probably making
the common error of comparing with the rather pedestrian type systems
of C++ and Java, perhaps O'Haskell and OCaml have systems that work
better?

-kzm
 
P

Pascal Costanza

Marshall said:
How can a method be defined "by accident?" I can't figure out what
you're trying to say.

class C {
void m();
}

class D {
void m();
}

....

void doSomething (Object o) {
if (o instanceof C) {
((D)o).m();
}
}

"Oops, by accident method m is also defined in D, although I wanted to
call method m in C."

Doesn't happen in languages with proper name space management. (The
problem is that Java gives you only the illusion of well-behaved
namespaces.)

Pascal

P.S, before anyone repeats the same issue again: Yes, Java has a badly
designed static type system. The example was not a very good one in the
first place. Doesn't matter wrt to my essential message though.
 
P

Pascal Costanza

Uh...the type system will let you *write* what you want, it will just
stop you from *running* those tests. Which are obviously going to
fail anyway. Okay, so perhaps you for some reason needs to write the
tests for nonexistent code, and then run something else that you keep
in the same file.

+ not "for some reason". Writing tests for nonexistent code is in fact
one of the key ideas of extreme programming.

+ No, I don't want to run code that happens to be in the same file. My
development environment can already do some very useful things with the
test code even if it isn't statically type-checkable yet.


Pascal
 
M

Mike Silva

Marshall Spight said:
I find that an odd conclusion. Given that the cost of bugs is so high
(especially in the cited case) I don't see a good reason for discarding
*anything* that leads to better correctness. Yes, bignums is a good
idea: overflow bugs in this day and age are as bad as C-style buffer
overruns. Why work with a language that allows them when there
are languages that don't?

As I understand it, the Operand Error that caused the grief was a
hardware trap in the 68k FPU. Seems that this trap would have been
programmed to do the same thing regardless of the language used.

Also, I wouldn't call this an overflow "bug." The code was written to
assume (based on proofs) that any overflow indicated a hardware
failure, and to take the designed action for hardware failure. It
would have been trivial for the programmers to prevent the overflow or
handle it in another way. Instead, they made a deliberate decision
that the default exception handling was exactly the right response for
overflow on this variable.

Mike
 
P

Pascal Costanza

Marshall said:
This is a non-issue. In both cases, you need the implementing code
if you want to be able to run the testcase, and you don't need the
implementing code if you don't.

No, in a dynamically typed language, I don't need the implementation to
be able to run the testcase.

Among other things:

- the test cases can serve as a kind of todo-list. I run the testsuite,
and it gives me an exception. This shows what portion of code I can work
on next.

- when a test case gives me an exception, I can inspect the runtime
environment and analyze how far the test case got, what it already
successfully did, what is missing, and maybe even why it is missing.
With a statically typed language, I wouldn't be able to get that far.

Furthermore, when I am still in the exceptional situation, I can change
variable settings, define a function on the fly, return some value from
a yet undefined method by hand to see if it can make the rest of the
code work, and so on.


Pascal
 
M

Mike Silva

Marshall Spight said:
I find that an odd conclusion. Given that the cost of bugs is so high
(especially in the cited case) I don't see a good reason for discarding
*anything* that leads to better correctness. Yes, bignums is a good
idea: overflow bugs in this day and age are as bad as C-style buffer
overruns. Why work with a language that allows them when there
are languages that don't?

As I understand it, the Operand Error that caused the grief was a
hardware trap in the 68k FPU. Seems that this trap would have been
programmed to do the same thing regardless of the language used.

Also, I wouldn't call this an overflow "bug." The code was written to
assume (based on proofs) that any overflow indicated a hardware
failure, and to take the designed action for hardware failure. It
would have been trivial for the programmers to prevent the overflow or
handle it in another way. Instead, they made a deliberate decision
that the default exception handling was exactly the right response for
overflow on this variable.

Mike

(Google is gagging right now, so appologies for any multiple posts)
 
M

Marshall Spight

Pascal Costanza said:
Assertions cannot become out-of-date. If an assertion doesn't hold
anymore, it will be flagged by the test suite.

This is only correct if all assertions receive coverage from the
test suite, which requires significant discipline, manual testcase
writing, and recurring manual verification, and even then,
it is only true at runtime. And assertions only verify what
you manually specify.

The benefits of a type system require significantly less manual
work, and find errors at compile time. Also, they verify that
type errors provable do not occur anywhere in the program,
vs. just where you manually specify.


Marshall
 
M

Marshall Spight

Pascal Costanza said:
... there exist programs that work but
that cannot be statically typechecked. These programs objectively exist.
By definition, I cannot express them in a statically typed language.

I agree these programs exist.

It would be really interesting to see a small but useful example
of a program that will not pass a statically typed language.
It seems to me that how easy it is to generate such programs
will be an interesting metric.

Anyone? (Sorry, I'm a static typing guy, so my brain is
warped away from such programs. :)


Marshall
 
P

Pascal Costanza

Marshall said:
I agree these programs exist.

It would be really interesting to see a small but useful example
of a program that will not pass a statically typed language.
It seems to me that how easy it is to generate such programs
will be an interesting metric.

Anyone? (Sorry, I'm a static typing guy, so my brain is
warped away from such programs. :)

Have you ever used a program that has required you to enter a number?

The check whether you have really typed a number is a dynamic check, right?


Pascal
 
M

Marshall Spight

Kenny Tilton said:
Lights out for static typing.

That kind of statement reminds me a lot of the people
who were saying in 1985 that CISC computing was
dead.

Anyway, I've argued elsewhere with Uncle Bob about
the issues raised in the quoted blog, and one thing
that came out of those arguments was that much of
what he was talking about was true for C++ vs.
Python, but not true for C++ vs. Java. In particular,
it's not clear to me that what he's referring to is
anything besides just rapid turnaround in getting
from a file edit to a running program. Java and
Python are both good about that, with Python
probably having the edge, but C++ can take a
*long* time to compile.

I'll probably get flamed for that statement, eh?


Marshall
 
M

Marshall Spight

Paul F. Dietz said:
(7) Developing reliable software also requires extensive testing to
detect bugs other than type errors, and
(8) These tests will usually detect most of the bugs that static
type checking would have detected.

Whether and to what degree (8) is true is the big open
question in this debate. Does anyone have any objective
metrics? Anyone know how to get them?

This strikes me as a very hard thing to quantify.


Marshall
 
B

Brian McNamara!

Pascal Costanza said:
Have you ever used a program that has required you to enter a number?

The check whether you have really typed a number is a dynamic check, right?

Yes, but this doesn't imply we can't write a statically-typed program to
handle the situation...

I can imagine Haskell code like

y = do x <- myread "34"
return x * 2
z = do x <- myread "foo"
return x * 2

where

myread :: String -> Maybe a
y, z :: Maybe Int

and "y" ends up with the value "Just 68" whereas "z" is "Nothing".
 
E

Erann Gat

Pascal Costanza said:
No, in a dynamically typed language, I don't need the implementation to
be able to run the testcase.

Among other things:

- the test cases can serve as a kind of todo-list. I run the testsuite,
and it gives me an exception. This shows what portion of code I can work
on next.

- when a test case gives me an exception, I can inspect the runtime
environment and analyze how far the test case got, what it already
successfully did, what is missing, and maybe even why it is missing.
With a statically typed language, I wouldn't be able to get that far.

To be fair, you can do both of those things in statically typed langauges
too, except that you get the error at compile time rather than run time.
Furthermore, when I am still in the exceptional situation, I can change
variable settings, define a function on the fly, return some value from
a yet undefined method by hand to see if it can make the rest of the
code work, and so on.

This is a good point.

E.
 
P

Pascal Costanza

Brian said:
Yes, but this doesn't imply we can't write a statically-typed program to
handle the situation...

I can imagine Haskell code like

y = do x <- myread "34"
return x * 2
z = do x <- myread "foo"
return x * 2

where

myread :: String -> Maybe a
y, z :: Maybe Int

and "y" ends up with the value "Just 68" whereas "z" is "Nothing".

The code you have given above doesn't give the user any feedback, right?
Do you really think that this is useful?


Pascal
 
M

Marshall Spight

Pascal Costanza said:
No, in a dynamically typed language, I don't need the implementation to
be able to run the testcase.

You need it to be able to run the testcase and have it succeed.
If you just want to fail with undefined method, that's exactly
the same as the compile error.

Among other things:

- the test cases can serve as a kind of todo-list. I run the testsuite,
and it gives me an exception. This shows what portion of code I can work
on next.

The compile errors also serve as a kind of todo list. I run the compiler,
and it gives me an error. This shows what portion of the code
I have to write next.

- when a test case gives me an exception, I can inspect the runtime
environment and analyze how far the test case got, what it already
successfully did, what is missing, and maybe even why it is missing.
With a statically typed language, I wouldn't be able to get that far.

Okay, so if you want to write testcases for two methods without
writing either, you have to stub in *both* methods and write
one before you can execute the testcases for one successfully.
You'd have to do this eventually anyway; the static compiler
will impose the requirement that you write stubs for the second
one before you execute the first. So I'd admit that the statically
typed language would put a tiny ordering on trivial tasks that
wouldn't otherwise be there.

(Aren't you supposed to write the method right after you
write the testcases, though?)

All those other things you've mentioned are also possible
for statically typed languages as well. (Inspect the runtime
environment, analyze how far, etc.)

Furthermore, when I am still in the exceptional situation, I can change
variable settings, define a function on the fly, return some value from
a yet undefined method by hand to see if it can make the rest of the
code work, and so on.

I'll acknowledge dynamic languages have an advantage in interactive
execution, which may be considerable.


Marshall
 

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
474,172
Messages
2,570,934
Members
47,477
Latest member
ColumbusMa

Latest Threads

Top