PEP 3107 and stronger typing (note: probably a newbie question)

S

Stephen R Laniel

Before I ask anything, let me note that this is surely an
old question that has inspired its share of flame wars; I'm
new to Python, but not new to how Internet discussions work.
So if there's a canonical thread or web page that documents
the whole battle, feel free to point me to it.

Reading [1], I wonder: why isn't the compiler making better
use of (purely optional) type labeling? Why not make a compiler
directive so that

a) it will check the types of all my arguments and return
values, and maybe even
b) do some type inference up the call stack?

E.g.,

def( Class1 arg1, Class2 arg2, ..., ClassN argN ):
someStuff()

would check the types of the arguments, whereas

def( arg1, arg2, ..., argN):
someStuff()

would not? I.e., if I *want* strong static
type-checking, why shouldn't I be able to get it? Is it that
allowing this as a compile-time option would mess up too
many knobs to make it optional?

Again, probably an old debate. I'd like to know why Guido's
decided that not only is strong static typing
productivity-reducing [2], but that it should be *forbidden*.

[1] - http://www.python.org/dev/peps/pep-3107/
[2] - http://www.artima.com/intv/strongweakP.html

--
Stephen R. Laniel
(e-mail address removed)
Cell: +(617) 308-5571
http://laniels.org/
PGP key: http://laniels.org/slaniel.key
 
P

Paddy

Before I ask anything, let me note that this is surely an
old question that has inspired its share of flame wars; I'm
new to Python, but not new to how Internet discussions work.
So if there's a canonical thread or web page that documents
the whole battle, feel free to point me to it.

Reading [1], I wonder: why isn't the compiler making better
use of (purely optional) type labeling? Why not make a compiler
directive so that

a) it will check the types of all my arguments and return
values, and maybe even
b) do some type inference up the call stack?

E.g.,

def( Class1 arg1, Class2 arg2, ..., ClassN argN ):
someStuff()

would check the types of the arguments, whereas

def( arg1, arg2, ..., argN):
someStuff()

would not? I.e., if I *want* strong static
type-checking, why shouldn't I be able to get it? Is it that
allowing this as a compile-time option would mess up too
many knobs to make it optional?

Again, probably an old debate. I'd like to know why Guido's
decided that not only is strong static typing
productivity-reducing [2], but that it should be *forbidden*.

[1] -http://www.python.org/dev/peps/pep-3107/
[2] -http://www.artima.com/intv/strongweakP.html

--
Stephen R. Laniel
(e-mail address removed)
Cell: +(617) 308-5571http://laniels.org/
PGP key:http://laniels.org/slaniel.key

You have already raised hackles with the title of your post.
Python has very strog type checking already. It does not
have static type checking which may be what you meant.

It seems that if we want to have Python compile down to
machine code then we may have to confine names to
only refer to objects of one type. (as well as None).
I would prefer it if we weren't also required to
explicitly state the types of variable names.
The reasons are that I am not new to Python and prefer
the dynamism of names and the reliance on tests and
coverage over static type checking.

As you state that you are new to Python, why not try
the Python way; gain proficiency; then think again
about the issue. If you are still of like mind then
your proficiency should enable you to give more
convincing reasons to the ccommunity.

- Paddy.


It would need support. Are you volunteering effort?
 
B

bruno.desthuilliers

Before I ask anything, let me note that this is surely an
old question that has inspired its share of flame wars; I'm
new to Python, but not new to how Internet discussions work.
So if there's a canonical thread or web page that documents
the whole battle, feel free to point me to it.

Reading [1], I wonder: why isn't the compiler making better
use of (purely optional) type labeling? Why not make a compiler
directive so that

a) it will check the types of all my arguments and return
values, and maybe even
b) do some type inference up the call stack?

E.g.,

def( Class1 arg1, Class2 arg2, ..., ClassN argN ):
someStuff()

would check the types of the arguments, whereas

def( arg1, arg2, ..., argN):
someStuff()

would not? I.e., if I *want* strong static
type-checking,

Then you should use another language.
why shouldn't I be able to get it?

Use Java and you'll get it.
Is it that
allowing this as a compile-time option would mess up too
many knobs to make it optional?


Given that one can add/replace/remove methods and attributes
dynamically either on a per-class or per-instance basis, and even
dynamically change the class of an object, I fail to see how static
typechecking could be meaningfull.

Again, probably an old debate. I'd like to know why Guido's
decided that not only is strong static typing
productivity-reducing [2],

He did not "decide".

but that it should be *forbidden*.

I failed to see this word in the given url.
[1] -http://www.python.org/dev/peps/pep-3107/
[2] -http://www.artima.com/intv/strongweakP.html






--
Stephen R. Laniel
(e-mail address removed)
Cell: +(617) 308-5571http://laniels.org/
PGP key:http://laniels.org/slaniel.key
 
M

Michael Hoffman

Stephen said:
This is what I meant about knowing how Internet discussions
go.

You originally said "Before I ask anything, let me note that this is
surely an old question that has inspired its share of flame wars; I'm
new to Python, but not new to how Internet discussions work."

In that context, there is no way that this response was a flame. I find
that Pythoneers want to use the right tool for the job. This isn't
always Python. It might be Perl, or OCaml, or Java, or C, or JCL. If you
want static type checking, Python definitely isn't the right tool for you.

If you asked Java programmers why you couldn't turn *off* Java's static
type checking if you wanted to, you'd probably get a similar response.
 
P

Paddy

This is what I meant about knowing how Internet discussions
go.

And knowing that, why not take more care with the tone of
your original post, or do more searching and/or lurking
before posting?

Your original post *could* be paraphrased as:
I'm new to Python, Python doesn't have X, X is
obviously a great feature can't you give me X
in Python? P.S. Its obviously been debated before
but I haven't looked - send me a link. I know this
might start a flame war, but I'll ask anyway.

And sure enough, you then goad a regular *contributor*
to comp.lang.python .

I suggest you rephrase your question in a less
confrontational tone but only if you are interested
in civil answers.

- Paddy.
 
P

Paddy

Before I ask anything, let me note that this is surely an
old question that has inspired its share of flame wars; I'm
new to Python, but not new to how Internet discussions work.
So if there's a canonical thread or web page that documents
the whole battle, feel free to point me to it.

Reading [1], I wonder: why isn't the compiler making better
use of (purely optional) type labeling? Why not make a compiler
directive so that

a) it will check the types of all my arguments and return
values, and maybe even
b) do some type inference up the call stack?

E.g.,

def( Class1 arg1, Class2 arg2, ..., ClassN argN ):
someStuff()

would check the types of the arguments, whereas

def( arg1, arg2, ..., argN):
someStuff()

would not? I.e., if I *want* strong static
type-checking, why shouldn't I be able to get it? Is it that
allowing this as a compile-time option would mess up too
many knobs to make it optional?

Again, probably an old debate. I'd like to know why Guido's
decided that not only is strong static typing
productivity-reducing [2], but that it should be *forbidden*.

[1] -http://www.python.org/dev/peps/pep-3107/
[2] -http://www.artima.com/intv/strongweakP.html

--
Stephen R. Laniel
(e-mail address removed)
Cell: +(617) 308-5571http://laniels.org/
PGP key:http://laniels.org/slaniel.key

have you seen language Boo? It adds static typing to Python
inspired syntax: http://boo.codehaus.org/

- Paddy.
 
S

Stephen R Laniel

If you asked Java programmers why you couldn't turn *off* Java's static
type checking if you wanted to, you'd probably get a similar response.

Perhaps it would help for me to explain what I'd like.

Under both Perl and Python, I've found myself
having/wanting to write things like so:

def my_func( int_arg, str_arg ):
try:
int_arg = int( int_arg )
str_arg = str( str_arg )
except ValueError:
sys.stderr.write( "Args are not of the right type\n" )
sys.exit(1)

Granted, in a dynamic language we won't always (maybe "won't
often") have a situation where the types are known this well
at compile time. But sometimes we will. And it would be nice
to catch these before the program even runs.

So my question is: would bolting on "static type checking
when we can, no type checking when we can't" be too much
to ask?

My reason for asking initially was that the PEP adds all
kinds of information to the function prototype -- e.g.
(quoting from there)

def foobar( a: Integer, b: Sequence ) -> String:

so why not, I reasoned, use this information at compile
time?

Of course I understand the virtue of writing code with good
doctests, etc. But my question is why we can't get some more
static typing as well. Given the tools that'll be in Python
3.0, that doesn't seem unreasonable to ask.

Apparently it is unreasonable. I'm sorry I asked.

--
Stephen R. Laniel
(e-mail address removed)
Cell: +(617) 308-5571
http://laniels.org/
PGP key: http://laniels.org/slaniel.key
 
D

Diez B. Roggisch

Of course I understand the virtue of writing code with good
doctests, etc. But my question is why we can't get some more
static typing as well. Given the tools that'll be in Python
3.0, that doesn't seem unreasonable to ask.

That is exactly the problem - there is no "some more" static typing.
There is static typing - or not. You can't have it "just a bit".

You can have type annotations to create guarding statements and then
allow better optimized code below that - if everything is "safe".

But static analysis that will allow for compiletime typing error checks
will need _all_ code to be statically typed.

And still not catch all runtime errors, which is basically an instance
of the halting problem.

The somewhat grumpy response you might have gotten is simply because the
whole subject has been discussed about a bazillion times - but never
ever somebody _created_ something that would work. Just asking for it
with vague ideas how that would create a better world.

Diez
 
G

George Sakkis

Perhaps it would help for me to explain what I'd like.

Under both Perl and Python, I've found myself
having/wanting to write things like so:

def my_func( int_arg, str_arg ):
try:
int_arg = int( int_arg )
str_arg = str( str_arg )
except ValueError:
sys.stderr.write( "Args are not of the right type\n" )
sys.exit(1)

After several hundreds of such checks, good luck making the 2.0
version of your application Unicode-friendly.
Granted, in a dynamic language we won't always (maybe "won't
often") have a situation where the types are known this well
at compile time. But sometimes we will. And it would be nice
to catch these before the program even runs.

Optional typing has its merits but your example is more of a
counterexample, an example where the explicit try/catch doesn't really
buy you anything. You'd get essentially the same effect if you just
attempted the conversion and let any exception propagate:

def my_func(some_non_hungarian_notation_meaningful_name,
other_non_hungarian_notation_meaningful_name):
a = int(some_non_hungarian_notation_meaningful_name)
b = str(other_non_hungarian_notation_meaningful_name)


More often than not the types that you *think* are required will turn
out to be more (and sometimes less) restrictive than necessary. Still,
If you're addicted to manifest typing [1], the typechecking module [2]
may give you a warm and fuzzy feeling:

from typecheck import accepts

@accepts(int, str)
my_func(some_non_hungarian_notation_meaningful_name,
other_non_hungarian_notation_meaningful_name):


HTH,
George


[1] http://c2.com/cgi/wiki?ManifestTyping
[2] http://oakwinter.com/code/typecheck/tutorial/basics.html
 
B

Ben Finney

Stephen R Laniel said:
Perhaps it would help for me to explain what I'd like.

Thanks for taking the time to think about the request and re-formulate
it.
Under both Perl and Python, I've found myself
having/wanting to write things like so:

def my_func( int_arg, str_arg ):
try:
int_arg = int( int_arg )
str_arg = str( str_arg )
except ValueError:
sys.stderr.write( "Args are not of the right type\n" )
sys.exit(1)

The first question that comes to mind -- and you'll find this question
asked of hundreds of people who come to this list with similar stated
goals -- is this: Why are you doing the above?

In Python, the pattern is to allow that exception to propagate back to
the code that tried to use the function, which is the one that is
apparently using the function incorrectly.

That is, you haven't actually told us what you'd like. You've shown us
a function that effectively does nothing but create a str and and int
-- and then discard them. What does this function need to do that you
want to catch an exception and abort inside the function?
 
K

kaens

That is exactly the problem - there is no "some more" static typing.
There is static typing - or not. You can't have it "just a bit".

Couldn't a language be made so that if you declared a variable like, say:

string foo = "I'm a string"

it would be a string, and always a string, and if you declared a variable like

foo = "i'm a dynamic variable"

it would be considered dynamic?

This doesn't seem like it would be too hard to add in to a language
that already had dynamic typing (But then again, I am inexperienced -
although interested in - language design).

It seems to me like this could be really useful, but I'm not aware of
any language implementing something like this.
 
A

Alex Martelli

kaens said:
Couldn't a language be made so that if you declared a variable like, say:

string foo = "I'm a string"

it would be a string, and always a string, and if you declared a variable like

foo = "i'm a dynamic variable"

it would be considered dynamic?

It would surely be possible to design a language like that, yes. I
suspect that, if you wanted to have both names 'constrained to a type'
and others 'not constrained', it would be better to have more symmetry
between the two situations (e.g., the "duck" type in Boo); but many
languages exist to prove that inferior design choices are often taken.

This doesn't seem like it would be too hard to add in to a language
that already had dynamic typing (But then again, I am inexperienced -
although interested in - language design).

It would be extremely cumbersome to start from the implementation of a
language with dynamic typing and extend it to allow the static kind --
each and every name (and item of a container, etc, etc) would have to
carry around an extra pointer to a typechecking function (possibly null
for names that must not be checked). You'd have to carry the whole
mechanism around at runtime since many assignments could in fact not be
checked statically, of course -- consider assigning a "dynamic"
[unchecked] name to a "static" [checked] one, for example; but, more:

class Foo: ...

class Bar: ...

static Foo foo

static Bar bar

....

foo = bar

this kind of thing would also have to be checked at runtime, since there
might be around a

class FooBar(Foo, Bar): ...

and bar might validly be an instance of FooBar -- therefore ALSO an
instance of Foo, thus validly assignable to foo.

Basically, absent the kind of static analysis that you'd do for type
inferencing (study Boo, SML, or Haskell, to learn more about type
inferencing), VERY few assignments could be tagged as invalid at
compile-time in a language with multiple inheritance. Badly designed
static languages (ones without type inferencing) often try to hide that
by forcing the programmer to be redundant, e.g. in specifying a "cast",
but even then runtime checks are often necessary. E.g., even in Java,

Foo foo;
Bar bar;
....
bar = (Bar) foo;

implies a runtime check if either Foo or Bar is an interface (and
well-written OO programs should use interfaces, *NOT* concrete classes,
more often than not: cfr the classic "Design Patterns" book, or Lakos'
excelent book on large scale software in C++, for more about that).

In short, if you really want to avoid (as far as possible) runtime
checks, you should really use a language designed for type inferencing
(Boo is, and in some other ways it's reminiscent of Python; however
there are far more books &c for other languages such as SML and
Haskell). Or, you could read Robert Martin's classic essay at
<http://www.artima.com/weblogs/viewpost.jsp?thread=4639> and ponder
whether Uncle Bob might not have a point...


Alex
 
E

Evan Klitzke

Couldn't a language be made so that if you declared a variable like, say:

string foo = "I'm a string"

it would be a string, and always a string, and if you declared a variable like

foo = "i'm a dynamic variable"

it would be considered dynamic?

This doesn't seem like it would be too hard to add in to a language
that already had dynamic typing (But then again, I am inexperienced -
although interested in - language design).

It seems to me like this could be really useful, but I'm not aware of
any language implementing something like this.

I think the main issue is that while you _could_ do that, the fact
that the language allows dynamic variables essentially precludes the
possibility of doing static checks for type issues (see Terry's post
for a better explanation of the issue). So you are by and large not
going to catch type errors until runtime anyway, and this is a feature
that Python already provides (if you try to mix different types in an
incompatible way you'll get a TypeError). I think that raising an
exception is the correct way to deal with type errors in this context.

So it's not that this issue is useless, but rather that it isn't
useful enough to warrant someone implementing it. If there was a good
implementation, and people really liked it and saw how great it was, I
don't think there's any fundamental opposition to its inclusion in the
language. But this hasn't happened yet.
 
B

Bruno Desthuilliers

Stephen R Laniel a écrit :
This is what I meant about knowing how Internet discussions
go.
Please let not forget the context.

You said:
"I'm new to Python",

and then :
"if I *want* strong static type-checking, why shouldn't I be able to get
it?"

You obviously don't know Python enough to understand why static
typechecking doesn't belong to Python. Trying to explain would be a
waste of time, because you have to experiment it in real-life situation
to fully understand.

So to put things briefly, Python with static typechecking would not be
Python anymore - it would be another language. Which implies that if you
want static typechecking, you'll have to use another language one way or
another.
 
D

Diez B. Roggisch

kaens said:
Couldn't a language be made so that if you declared a variable like, say:

string foo = "I'm a string"

it would be a string, and always a string, and if you declared a
variable like

foo = "i'm a dynamic variable"

it would be considered dynamic?

This doesn't seem like it would be too hard to add in to a language
that already had dynamic typing (But then again, I am inexperienced -
although interested in - language design).

It isn't too hard. All it needs is a bucket at a name that contains a
type reference.

But what you DO with that is the hard thing. Just enforcing types at
runtime is easy. Making JIT-compilation for such code and then put
guarding statements around it - somewhat harder, but easier than full
type inference.

But the OP wanted compile-time static typing checks. And _thats_
virtually impossible unless _everything_ is statically typed. And even
if it is, the ClassCastExceptions of Java prove that.

Take this classic example from the java-world that is statically
correct, but will fail at runtime

class A

class B extends A

B[] bs = new B[100];
A[] as = bs;
as[0] = new A();


The problem here is that the as-array has less type information, and
because of polymorphism rules is allowed to actually hold an B-array.
But that can't allow mere A-objects to be assigned to it!

So the JVM introduces a runtime type check here.

Mixing static and dynamic type information like proposed will only make
this problem more severe, as you know even less about your types. Thus
the whole purpose of static checking vanishes, and the whole thing
shifts to a purely runtime checking.
It seems to me like this could be really useful, but I'm not aware of
any language implementing something like this.

Which _might_ be a hint... :)

Diez
 
B

Bruno Desthuilliers

Stephen R Laniel a écrit :
Perhaps it would help for me to explain what I'd like.

Under both Perl and Python, I've found myself
having/wanting to write things like so:

def my_func( int_arg, str_arg ):
try:
int_arg = int( int_arg )
str_arg = str( str_arg )
except ValueError:
sys.stderr.write( "Args are not of the right type\n" )
sys.exit(1)

Just a question : what will happen if you get rid of the try/except
block ?-)
 
M

Méta-MCI

Hi!
Given that one can add/replace/remove methods and attributes
dynamically either on a per-class or per-instance basis, and even
dynamically change the class of an object, I fail to see how static
typechecking could be meaningfull.

Et toc !
 
B

Bjoern Schliessmann

Stephen said:
This is what I meant about knowing how Internet discussions
go.

I agree. I also notice that (rather newbie-) OPs with not-so-simple
questions are easily offended by technical answers. I'd love to
know why.

Regards,


Björn
 
S

Stephen R Laniel

I agree. I also notice that (rather newbie-) OPs with not-so-simple
questions are easily offended by technical answers. I'd love to
know why.

One doesn't like to get meta on such things, as so often
happens, so I'll be brief. The way I read my original post
was like so: "I know lots of people have probably had a
similar question, so please point me to a canonical answer
is there is one. So here's the question...". To me, an
appropriate answer there is, "That's a good question, and
many people have asked it. Here's why it's unlikely that
static type-checking makes sense in the context of Python,
and why it couldn't just be added in pieces." We got there
eventually, but only after what seemed to me to be a bout of
rudeness. Now, maybe my own followup clarified something
that I should have included in the original.

"Use another language" is not a technical answer. "Python
could not adopt static typing without substantially changing
the language and destroying what everyone loves about it,
and here are examples of where the problem shows up" is.

But I've just gone meta, so I'll stop.

--
Stephen R. Laniel
(e-mail address removed)
Cell: +(617) 308-5571
http://laniels.org/
PGP key: http://laniels.org/slaniel.key
 

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

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top