Python from Wise Guy's Viewpoint

J

John Atwood

Matthew Danish said:
Wrong on all counts.

* Most Common Lisp environments compile to native code, even when
working interactively.
SBCL, for example, has no interpreter whatsoever. The interpreter is
simulated by calling the compiler and evaluating the resulting
function immediately.

If the code is executed in the environment, and one can execute
arbitrary snippets of code, it's an interpreted environment,
regardless of whether the code executed is native, bytecode,
or other.
* There exists statically typed language implementations which do the
same (SML/NJ)

Yes, these are among those I have in mind when I say "Interpreters for
statically typed languages allow the same."
* The behavior of redefinition in a statically typed environment
is far different from the behavior in a dynamically typed environment.
For one thing, generativity of names kicks in, which makes it
basically impossible to redefine types and functions without
recompiling all uses (and thus restarting your program), in a static
environment.

Yes, and that's a good thing. It prevents the program form getting in an
unreachable/inconsistent state, and secondly, in an FP, especially a pure
FP, with explicit state, one need not run the program from the start to
test whatever code is of interest at the moment, because the state can be
created via test cases.


John
 
M

Matthew Danish

If the code is executed in the environment, and one can execute
arbitrary snippets of code, it's an interpreted environment,
regardless of whether the code executed is native, bytecode,
or other.

So long as you are clear on the meaning. For most people, calling
something an interpreted environment implies lack of compiler.
Yes, and that's a good thing. It prevents the program form getting in an
unreachable/inconsistent state, and secondly, in an FP, especially a pure
FP, with explicit state, one need not run the program from the start to
test whatever code is of interest at the moment, because the state can be
created via test cases.

And it also gets in the way of the flexibility traditionally associated
with dynamically typed languages. It gets in the way of development and
debugging as well. And as for pure FP, can you recreate network
connection state at will? So that the other end doesn't even know
something went wrong (besides the delay)?
 
M

Marcin 'Qrczak' Kowalczyk

Why would division on integers mean something different than division on
(floating point) doubles?

Because C did it this way and many languages are copying its conventions.
And C did it because it used / for integer division before it had floating
point types.

I was responding to "Something that annoys me about many statically-typed
languages is the insistence that arithmetic operations should return the
same type as the operands. 2 / 4 is 1/2, not 0."

While it is true that many statically typed languages do that, it's not
a consequence of static typing (others don't). The only fault of static
typing here is that it makes this choice relatively harmless, compared to
dynamically typed languages where it's a serious problem if this choice
is made.

I was going to respond "making 2/4 equal to 0 is unrelated to static or
dynamic typing", but it *is* related, only in a subtle way.
 
P

Pascal Costanza

Matthias said:
fun f A = "A"
| f B = "B"

I don't find this convincing. This is similar to the 20 * 30 example.

The resolution in both cases would be to define a default meaning if no
explicit type annotation exists. Done.

These examples don't allow me to write one single meaningful program
more than in a dynamically typed language.

My claim that dynamically typed languages have more expressive power
means that they allow you to write more programs that show useful
behavior at runtime. The strongest example I have are programs that
allow arbitrary changes to the definitions that are embedded inside of
them. That's the essence of metacircularity (runtime metaobject
protocols, etc). You cannot statically type check such programs by
definition.

I think that Neelakantan has better examples for programs that are
possible to write with a statically typed language, but not with
dynamically typed ones. (Not 100% sure yet, though.)


Pascal
 
P

Pascal Costanza

Stephen said:
Perhaps I'm just a low tech kind of guy but if I just want to run the
first ten then I comment out the rest. Even without a fancy IDE that
only take a few key presses.

....and it requires you to go to all the places where they are defined.

Yes, I know the answer: "But they should be all in one place." No, they
shouldn't need to be all in one place. For example, I might want to
place test code close to the definitions that they test. Or I might want
to organize them according to some other criteria.

No, it's not hard to find them all, then. I can use grep or my IDE to
find them. But that's still more work than just commenting them out. If
I seldomly need to find all test cases, I can trade locality of all test
cases for some other possible advantages.

Ah, another example: What if my test code is actually produced by some
macro, or some other code generation facility?


Pascal
 
M

Matthias Blume

Pascal Costanza said:
I don't find this convincing. This is similar to the 20 * 30 example.

The resolution in both cases would be to define a default meaning if
no explicit type annotation exists. Done.

Of course, you can always define a default meaning for the case that
no explicit (type) information is available. But what you are doing
is essentially providing such information: no explicit type annotation
amounts to having an implicit annotation.

By the way, this is how, e.g., SML does it anyway: If you write just
20*30 and nothing else is known, then the type is resolved to be
Int.int.

This does not invalidate the claim that you know the semantics of the
phrase only if you know the type. It just so happens that you always
know the type.
I think that Neelakantan has better examples for programs that are
possible to write with a statically typed language, but not with
dynamically typed ones. (Not 100% sure yet, though.)

There are no such programs, obviously. You can always translate a
statically typed program into a dynamically typed one (and vice
versa).

The advantage (as far as I am concerned) of the statically typed
program is in the guarantees that it provides: If I write

fun foo x = ...

and x is declared or inferred to be of type t, then I never again have
to worry about what happens should someone pass a non-t to foo
because that simply cannot happen. This all by itself is useful, but
it gets even more useful if t is an abstract type so that I have full
control over how and where t values are generated.

This sort of thing is most useful when designing libraries because in
this case you don't know yet (who will call foo and how (and you might
in fact never know). But you do know that whoever it is and however he
does it, he must pass a value of type t.

Matthias
 
P

Pascal Costanza

Andreas said:
The design of a type system is by no means canonical. In fact, it is
based on set of pragmatic decisions and trade-offs. Idealized, you start
with the trivial type system, which has only one type. Then you refine
it incrementally by distinguishing certain classes of values through
introduction of new types and typing rules. Introduction of typing rules
is based on the following criteria:

- Do they catch a lot of errors?
- Are these errors serious?
- Are they hard to localize otherwise?
- Does the refinement rule out useful constructions?
- Are such constructions common?
- Are they expressible by other means?
- Are the rules intuitive?
- Do they interact nicely with other rules?

And probably more. There are never any definite answers to any of these
questions. The trade-off depends on many factors, such as the problem
domain the language is used for. Usually the line is drawn based on
experience with other languages and known problem domains. In the case
of arbitrary recursive types, experience with languages that allowed
them has clearly shown that it caused much more grief than joy.

Hmm, could a kind of "meta type system protocol" be feasible? I.e., a
language environment in which you could tweak the type system to your
concrete needs, without having to change the language completely?


Pascal
 
P

Pascal Costanza

Matthias said:
The problem
is that for many algorithms people want to be sure that the compiler
represents their values in machine words. Infinite precision is
needed sometimes, but in the majority of cases it is overkill. If you
need infinite precision, specify the type (IntInf.int in SML's case).
A clever compiler might optimize that like a Lisp compiler does. In
most other cases, why take any chances?

I disagree strongly here. I am convinced that in most algorithms,
machine words don't matter at all. Have you ever seen in books on
algorithms that they actually _need_ to restrict them to values that are
representable in machine word sizes?

"Here is a proof for the correctness of the Quicksort algorithm, but
only for arrays with a maximum length of 65535." Ha! Nonsense! ;-)


Computers are fast enough and have enough memory nowadays. You are
talking about micro efficiency. That's not interesting anymore.


(but I have no problems if we agree to disagree here. we both don't have
the necessary empirical data to back our claims)

Pascal
 
P

Pascal Costanza

John said:
Yes, and that's a good thing. It prevents the program form getting in an
unreachable/inconsistent state,

Oh dear, that argument again.

No, to repeat this for the nth time, that's not _generally_ a good
thing. It also prevents the program from getting in a certain class of
states that would still be reachable/consistent. So, in some situations
it might be a _bad_ thing.


Pascal
 
M

Matthias Blume

Pascal Costanza said:
Computers are fast enough and have enough memory nowadays. You are
talking about micro efficiency. That's not interesting anymore.

I have worked on projects where people worried about *every cycle*.
(Most of the time I agree with you, though. Still, using infinite
precision by default is, IMO, a mistake. Having it around and at your
fingertips, though, is nice. That's why I added the long-missing
compiler support for IntInf to SML/NJ recently.)
(but I have no problems if we agree to disagree here.
Good.

we both don't have the necessary empirical data to back our claims)

Speak for yourself.

Matthias
 
P

Pascal Costanza

Matthias said:
There are no such programs, obviously. You can always translate a
statically typed program into a dynamically typed one (and vice
versa).

No, for christ's sake! There are dynamically typed programs that you
cannot translate into statically typed ones!

As soon as you add full-fledged runtime metaprogramming to a language,
and write a program that uses it, you cannot statically type check this
anymore, by definition, because you cannot statically determine anymore
in what ways such a program would change during its lifetime!

And don't tell me that "in 99% of all cases, you don't need this". This
just isn't true. And even if it were true, it wouldn't matter!

If there would only be _one_ useful program on earth that someone cared
about that would make use of runtime metaprogramming, this would make my
statement true that static typing decreases expressive power in possibly
serious ways. And there are definitely lots of them out there!
The advantage (as far as I am concerned) of the statically typed
program is in the guarantees that it provides: If I write

fun foo x = ...

and x is declared or inferred to be of type t, then I never again have
to worry about what happens should someone pass a non-t to foo
because that simply cannot happen. This all by itself is useful, but
it gets even more useful if t is an abstract type so that I have full
control over how and where t values are generated.

This sort of thing is most useful when designing libraries because in
this case you don't know yet (who will call foo and how (and you might
in fact never know). But you do know that whoever it is and however he
does it, he must pass a value of type t.

Yes, these things are all obvious. But these are not examples for an
increase of expressive power! These are only examples of _restricting_
the set of potentially useful programs! How hard is this to understand?

You _want_ this restriction. Why don't you _admit_ that it is a restriction?


Pascal
 
P

Pascal Costanza

Matthias said:
Speak for yourself.

You too.


This:
> I have worked on projects where people worried about *every cycle*.
^^^^^^^^
> (Most of the time I agree with you, though. Still, using infinite
> precision by default is, IMO, a mistake. Having it around and at your
^^^^^^
> fingertips, though, is nice. That's why I added the long-missing
> compiler support for IntInf to SML/NJ recently.)

is by any scientifical standard not enough evidence to back this:
The problem
is that for many algorithms people want to be sure that the compiler
represents their values in machine words. Infinite precision is
needed sometimes, but in the majority of cases it is overkill. If you
need infinite precision, specify the type (IntInf.int in SML's case).
A clever compiler might optimize that like a Lisp compiler does. In
most other cases, why take any chances?


Pascal
 
M

Matthias Blume

Pascal Costanza said:
No, for christ's sake! There are dynamically typed programs that you
cannot translate into statically typed ones!

Yes you can. (In the worst case scenario you lose all the benefits of
static typing. But a translation is *always* possible. After all,
dynamically typed programs are already statically typed in the trival
"one type fits all" sense.)
Yes, these things are all obvious. But these are not examples for an
increase of expressive power! These are only examples of _restricting_
the set of potentially useful programs! How hard is this to
understand?

You _want_ this restriction. Why don't you _admit_ that it is a restriction?

Who said that I don't admit that I want restrictions. That's the
whole point. Static typing increases my expressive power because I
can now *express restrictions* which I couldn't express before.
That's the whole point. Being able to express more programs is not
the issue, being able to express more restrictions and being told
early about their violations is!

[This whole discussion is entirely due to a mismatch of our notions of
what constitutes expressive power.]

Matthias
 
D

Daniel C. Wang

Pascal Costanza said:
I disagree strongly here. I am convinced that in most algorithms,
machine words don't matter at all. Have you ever seen in books on
algorithms that they actually _need_ to restrict them to values that
are representable in machine word sizes?

Hmmm.. lets see... AES and MD5 most if not all DSP/ signal processing
algorithms. There are quite a few.
 
?

=?ISO-8859-1?Q?Jens_Axel_S=F8gaard?=

Hmmm.. lets see... AES and MD5 most if not all DSP/ signal processing
algorithms. There are quite a few.

It's true that they are specified such that particularly efficient
implementations exists on machines with the proper word size. This
holds for many crypthographic algorithms.

This doesn't rule out other implementations though.

<Shame less self plug

<http://www.scheme.dk/md5/md5.html>

/>
 
P

Pascal Costanza

Matthias said:
Yes you can. (In the worst case scenario you lose all the benefits of
static typing. But a translation is *always* possible. After all,
dynamically typed programs are already statically typed in the trival
"one type fits all" sense.)

No, that's not all you need to do. Essentially you would need to write a
complete interpreter/compiler for the dynamically typed language on top
of the statically typed one, _if_ you want runtime metaprogramming.
That's not what I would call a straightforward translation.

But this is really getting tiring.
[This whole discussion is entirely due to a mismatch of our notions of
what constitutes expressive power.]

No, it's not. There's a class of programs that exhibit a certain
behavior at runtime that you cannot write in a statically typed language
_directly in the language itself_. There's no program that exhibits a
certain behavior at runtime that you can only write in a statically
typed language. [1]

That's a fact that you simply don't want to admit. But you're
objectively wrong here.

However, the horse is beaten to death by now.


Good bye.

Pascal

[11 Except perhaps for a class of programs that would change their
runtime and/or space complexity, provided they would need lots of
dynamic type checks. But I haven't sorted out yet whether this class
really exists.
 
S

Stephen J. Bevan

Pascal Costanza said:
...and it requires you to go to all the places where they are defined.

Yes, I know the answer: "But they should be all in one place." No,
they shouldn't need to be all in one place.

As I wrote, I'm a low tech guy, I put all the tests for a particular
feature in the same file. If I only want to run some of the tests in
the file then I comment out those tests. If I only want to run the
tests in some file rather than others then I comment out the names of
the files containing the tests I don't want to run. I can see how
things can get more complicated if you use other approaches, which is
one of the reasons I don't use those approaches. YMMV.

Ah, another example: What if my test code is actually produced by some
macro, or some other code generation facility?

Er, comment out either definition of the macro and the calls to it or
the code generation facility.
 
S

Stephen J. Bevan

Pascal Costanza said:
is that for many algorithms people want to be sure that the compiler
represents their values in machine words. Infinite precision is
needed sometimes, but in the majority of cases it is overkill. If you
need infinite precision, specify the type (IntInf.int in SML's case).
A clever compiler might optimize that like a Lisp compiler does. In
most other cases, why take any chances?

I disagree strongly here. I am convinced that in most algorithms,
machine words don't matter at all. Have you ever seen in books on
algorithms that they actually _need_ to restrict them to values that
are representable in machine word sizes?
[snip]
Computers are fast enough and have enough memory nowadays. You are
talking about micro efficiency. That's not interesting anymore.

Implement something like MD5, SHA-1, AES, ... etc. in your favourite
language and use the fastest compiler available to you to calculate
how many MB/s it can process. If it can get say with a factor of 2 of
C code then IMHO you'll have proved your point. If not, then either
your point stands but your favourite language doesn't have
sufficiently good compilers available yet, or exact sizes are required
in order to get good performance in this case.
 
M

Matthias Blume

Pascal Costanza said:

I am.
This:


is by any scientifical standard not enough evidence to back this:

It is more than enough evidence that there are programs which require
cycle-level efficiency and therefore cannot afford to use infinite
precision arithmetic.

It is, in my opinion, ridiculous to claim that most programs should
use infinite precision integers in almost all places (i.e., by
default). Infinite precision is rarely necessary and almost always
wasteful overkill.

And in any case, it is also completely besides the point in the
discussion of static checking vs. everything dynamic. (It just came
up as a side discussion after Andreas gave an example of ML code which
exhibits different semantics in different typing contexts -- a
discussion which seems to circle around the extremely questionable
idea that the only correct result of 20 * 30 has to be 600.)

Matthias
 
R

Raffael Cavallaro

Yes you can. (In the worst case scenario you lose all the benefits of
static typing. But a translation is *always* possible. After all,
dynamically typed programs are already statically typed in the trival
"one type fits all" sense.)

This is sophistry at its worst. If you "translate" a dynamically typed
program into a statically typed language by eliminating all the static
type checking, then WTF is the point of the static type checking?

It's also possible to "translate" any program into a turing machine
tape, so we should all start coding that way!

Introducing TuringTape(TM), the ultimate bondage and discipline
language!
 

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,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top