From: Joachim Durchholz
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpcu48$2ig$1@news.oberberg.net>
Erann Gat wrote:
> 
> You have badly misunderstood my point.  I do not blame this failure on the
> language.  I blame this failure on the mindset that because the compiler
> catches certain kinds of errors that you can get away with less testing
> than if it didn't.  In other words, I am not saying static typing is bad,
> just that one of the benefits that many people cite for it is not really a
> net benefit.

Non sequitur.

Static typing didn't catch the error - no surprise here, nobody in his 
right mind would claim that. (That manager who said that static typing 
would tell you all the places where to change the code obviously 
over-generalized - only if a change affects the signature of a function 
does static typing help spotting the other affected places; the race 
condition obviously wasn't of that error class.)

Being lulled into a false sense of security can happen with /any/ 
testing method, be it unit tests, static typing, black-box testing, or 
whatever. One should apply all available test methods and not rely on 
just one.

Given the reasoning of the previous paragraph, I draw the exactly 
reverse conclusion: Removing a test method increases the likelihood that 
a given bug will slip through.

So here's my litmus test for language testability:
   Does it enable as many test paradigms as possible?

Lisp doesn't qualify, it makes static testing (type checking, automatic 
proving) difficult, as it gives very little easily verifiable guarantees 
what a given piece of code does.

C++ doesn't qualify: no introspection and a syntax that requires several 
months from a highly qualified expert to write a useful parser, so tools 
that inspect the code have a hard time. On top of that, a highly 
complicated semantics that makes analyzing the code even more difficult.

Java sort-of qualifies: its introspection facilities give tools a 
foothold that they can work with. However, its type system is too weak: 
as soon as containers come into play, it fails to give the guarantees 
that the programmer knows could be given (every single type cast is such 
a failed guarantee).
Note that even when Java acquires parametric classes (scheduled for this 
year IIRC), its type system will remain too weak: parallel type 
hierarchies (e.g. Driver and Vehicle, the problem is with the drive() 
routine in the, say, Ship/Captain subclasses) will continue to require 
type casts. This is a typical problem of most if not all statically 
typed OO languages.

Typical functional languages with static typing sort-of qualify from the 
other side: they usually have an extremely regular syntax and semantics, 
so writing tools (including testing tools) should be comparatively easy, 
so they /should/ qualify; however, these tools often aren't present (or 
they don't get the high visibility that they deserve, I don't know), so 
for me, they fall a bit short of their potential.

Regards,
Jo

From: Erann Gat
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <gat-1811031117200001@k-137-79-50-101.jpl.nasa.gov>
In article <············@news.oberberg.net>, Joachim Durchholz
<·················@web.de> wrote:

> Being lulled into a false sense of security can happen with /any/ 
> testing method, be it unit tests, static typing, black-box testing, or 
> whatever.

Static typing is not a testing method.  That's the whole point.  It is a
technique that purports to eliminate a certain class of run-time errors
and therefore (presumably) the need to test for them.

E.
From: Joachim Durchholz
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpfoka$5st$1@news.oberberg.net>
Erann Gat wrote:

> Joachim Durchholz <·················@web.de> wrote:
> 
>>Being lulled into a false sense of security can happen with /any/ 
>>testing method, be it unit tests, static typing, black-box testing, or 
>>whatever.
> 
> Static typing is not a testing method.

Wrong.
Running a program through a type checker /is/ a test.
It is a kind of code walk-through, as it inspects every single line of 
code and tries to spot a specific class of things that could go wrong. 
Just being 100% automated doesn't prevent it from being a test.

Regards,
Jo
From: Pascal Costanza
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpd061$tlo$1@f1node01.rhrz.uni-bonn.de>
Joachim Durchholz wrote:

> So here's my litmus test for language testability:
>   Does it enable as many test paradigms as possible?
> 
> Lisp doesn't qualify, it makes static testing (type checking, automatic 
> proving) difficult, as it gives very little easily verifiable guarantees 
> what a given piece of code does.
[...]

> Java sort-of qualifies: its introspection facilities give tools a 
> foothold that they can work with.
[...]

A question for understanding: What makes you think that Java's 
introspective features are better suited than Lisp's?

(Note: When you refer to "Lisp", in c.l.l this typically means Common 
Lisp and Scheme. Noone is using LISP anymore as it was defined until, 
roughly, the end of the 70's.)


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Joachim Durchholz
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpd52h$chk$1@news.oberberg.net>
Pascal Costanza wrote:

> Joachim Durchholz wrote:
> 
>> So here's my litmus test for language testability: Does it enable 
>> as many test paradigms as possible?
>> 
>> Lisp doesn't qualify, it makes static testing (type checking, 
>> automatic proving) difficult, as it gives very little easily 
>> verifiable guarantees what a given piece of code does.
> 
> [...]
> 
>> Java sort-of qualifies: its introspection facilities give tools a 
>> foothold that they can work with.
> 
> [...]
> 
> A question for understanding: What makes you think that Java's 
> introspective features are better suited than Lisp's?

Lisp makes it far easier to access the definitions of data types and
functions, but interpreting the definitions is far more difficult
because it imposes far less restrictions on what the individual
definitions actually do. (It's the downside of unrestricted power.)

I fear I didn't make clear enough that I was talking about testing &
verification in a fully automated manner, particularly the automation of
test case selection.

> (Note: When you refer to "Lisp", in c.l.l this typically means Common
> Lisp and Scheme. Noone is using LISP anymore as it was defined 
> until, roughly, the end of the 70's.)

That's understood.
Actually I'm not even talking about the standard Lisps of the '80ies 
(which were Interlisp and its likes; Scheme and CL had just started to 
interest Lisp programmers in general, at least here in Europe).

Regards,
Jo
From: Pascal Costanza
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpd8ds$16vs$1@f1node01.rhrz.uni-bonn.de>
Joachim Durchholz wrote:
> Pascal Costanza wrote:
> 
>> Joachim Durchholz wrote:
>>
>>> So here's my litmus test for language testability: Does it enable as 
>>> many test paradigms as possible?
>>>
>>> Lisp doesn't qualify, it makes static testing (type checking, 
>>> automatic proving) difficult, as it gives very little easily 
>>> verifiable guarantees what a given piece of code does.
>>
>>
>> [...]
>>
>>> Java sort-of qualifies: its introspection facilities give tools a 
>>> foothold that they can work with.
>>
>>
>> [...]
>>
>> A question for understanding: What makes you think that Java's 
>> introspective features are better suited than Lisp's?
> 
> Lisp makes it far easier to access the definitions of data types and
> functions, but interpreting the definitions is far more difficult
> because it imposes far less restrictions on what the individual
> definitions actually do. (It's the downside of unrestricted power.)

It's possible to impose the restrictions you want in Common Lisp, and a 
portable way to analyze these restrictions during macro expansion is in 
the works. Some CL implementations already have a limited form of such 
analysis facilities, as per CLtL2. I don't know enough about Scheme 
implementations, but they probably provide similar facilities.

Of course, as soon as you start to want to have most, or even all of 
your code checked, it might have been better to have started with a 
language that provides static checks by default. Especially if you don't 
want to wait for Lisp implementations to provide the same degree of 
static checkability.

But again: a) It would be better if you could provide a static type 
system as an additional tool in some futuristic "unified" language 
framework. b) There is a class of programs and/or a programming style 
that rather needs dynamic checking by default. The essence here is that 
you can take advantage of "type" errors at runtime. There are 
programs/programming styles in which you _want_ "type" errors at 
runtime, however bizarre this might sound to the ears of a static typer.

> I fear I didn't make clear enough that I was talking about testing &
> verification in a fully automated manner, particularly the automation of
> test case selection.

So how do you statically analyze the following piece of code in Java?

Class.forName(someStringExpression)
      .getMethod(someOtherStringExpression,
                 someParameterTypeArrayExpression)
      .invoke(someObject,someConcreteParameterArray);

>> (Note: When you refer to "Lisp", in c.l.l this typically means Common
>> Lisp and Scheme. Noone is using LISP anymore as it was defined until, 
>> roughly, the end of the 70's.)
> 
> That's understood.
> Actually I'm not even talking about the standard Lisps of the '80ies 
> (which were Interlisp and its likes; Scheme and CL had just started to 
> interest Lisp programmers in general, at least here in Europe).

OK, just wanted to be sure about this.


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Matthias
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <36wsmkl21ri.fsf@chagall.ti.uni-mannheim.de>
Pascal Costanza <········@web.de> writes:

> b) There is a class of programs and/or a programming style
> that rather needs dynamic checking by default. The essence here is
> that you can take advantage of "type" errors at runtime. There are
> programs/programming styles in which you _want_ "type" errors at
> runtime, however bizarre this might sound to the ears of a static
> typer.

I think that's true.  There is also a class of programs where static
type checking can help find _nontrivial_ errors.  Multithreaded
programs might belong to this class:

  http://www.cuj.com/documents/s=7998/cujcexp1902alexandr/

So, there's reason enough for both worlds to coexist. :-)
From: Joachim Durchholz
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpdd3k$o5n$1@news.oberberg.net>
Matthias wrote:
> So, there's reason enough for both worlds to coexist. :-)

I'd prefer it if the two worlds were integrated, so that we wouldn't be 
forced to choose which of them to throw away for any given project...

Regards,
Jo
From: Dirk Thierbach
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <oiop81-il5.ln1@ID-7776.user.dfncis.de>
Pascal Costanza <········@web.de> wrote:

> Of course, as soon as you start to want to have most, or even all of 
> your code checked, it might have been better to have started with a 
> language that provides static checks by default. 

Yes. That's exactly the point.

> Especially if you don't want to wait for Lisp implementations to
> provide the same degree of static checkability.

For reasons already discussed, I don't think this is going to happen.
(It is not *necessary* that Lisp does everything you can do in other
languages. It's fine as it is.)

> But again: a) It would be better if you could provide a static type 
> system as an additional tool in some futuristic "unified" language 
> framework. 

Yes, it would. I think that if there is really need for it, one
could probably modify Haskell or OCaml to "go dynamic" if type
inference fails. Introduce a "top" type, do something clever about
compositionality so you still retain a reasonable amount of type
inference, tag everything that comes "into" a top type at runtime
with the appropriate type, and insert dynamic type checks everywhere
where they are needed. And print big fat warnings :-)

But that would be a huge effort, with (from the "static typers" point
of view) little benefit.

> b) There is a class of programs and/or a programming style 
> that rather needs dynamic checking by default. The essence here is that 
> you can take advantage of "type" errors at runtime. There are 
> programs/programming styles in which you _want_ "type" errors at 
> runtime, however bizarre this might sound to the ears of a static typer.

Yes. In those cases, use a dynamically typed language. All languages
have advantages and disadvantages. No language does everything equally
well.

- DIrk
From: Joachim Durchholz
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpg0bl$h1l$1@news.oberberg.net>
Dirk Thierbach wrote:
>>But again: a) It would be better if you could provide a static type 
>>system as an additional tool in some futuristic "unified" language 
>>framework. 
> 
> [...]
> But that would be a huge effort, with (from the "static typers" point
> of view) little benefit.

I'm a "static typer" myself, but I'd consider this more than "little" 
benefit.
When maintaining a large (>100.000 LOC) GUI library, I had to do some 
large-scale surgery; the total change was scheduled to take about a 
week, during which the state would be type-wise inconsistent. In other 
words, I had to postpone all tests and checks for several days until the 
type checker was happy again.
The surgery was about speeding up certain operations; had the compiler 
issued warnings instead of aborting compilation, I would have been able 
to do some preliminary tests during the change. The way things were, I 
found out that I could have spared about 50% of the changes because they 
turned out to be ineffective. Since the compiler didn't let me run the 
system in an inconsistent state, I didn't discover that until it was too 
late.
What was worse was that postponing the tests made me forget about them 
when doing final testing, which lead to some nasty surprises during 
regression testing, extending the effort by another day or two.

The inevitable grain of salt, as with most war stories: the language 
doesn't have type inference. A large part of the changes were simply 
adapting function signatures.
However, even when subtracting that effort, warnings instead of errors 
would still have made a significant difference.

I don't think that there's any noticeable improvement for small-scale 
example programs. Issues like forgetting details because the compiler 
imposes a given task order don't become relevant until atomic changes 
extend beyond, say, a day or two.

>>b) There is a class of programs and/or a programming style 
>>that rather needs dynamic checking by default. The essence here is that 
>>you can take advantage of "type" errors at runtime. There are 
>>programs/programming styles in which you _want_ "type" errors at 
>>runtime, however bizarre this might sound to the ears of a static typer.

Hmm... I checked the URL. Biologists doing IT research? This sounds more 
like a creative abuse of technology (not a bad thing in itself, but 
unless you know a /lot/ about software technology, the conclusions drawn 
from such experiments tend to disregard alternative, non-abusive 
approaches).
But I didn't have the time to read the paper in its entirety, so I'll 
reserve judgement until later.

Regards,
Jo
From: Joachim Durchholz
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpdcmd$ng6$1@news.oberberg.net>
Pascal Costanza wrote:
> 
> Of course, as soon as you start to want to have most, or even all of 
> your code checked, it might have been better to have started with a 
> language that provides static checks by default. Especially if you don't 
> want to wait for Lisp implementations to provide the same degree of 
> static checkability.

*grin* that's exactly what I wanted to write first.

> But again: a) It would be better if you could provide a static type 
> system as an additional tool in some futuristic "unified" language 
> framework.

Agreed.

 > b) There is a class of programs and/or a programming style
> that rather needs dynamic checking by default. The essence here is that 
> you can take advantage of "type" errors at runtime. There are 
> programs/programming styles in which you _want_ "type" errors at 
> runtime, however bizarre this might sound to the ears of a static typer.

It indeed sounds bizarre.
However, it might be due to a difference in the definition of the term 
"type". For me, a type is essentially a tag that I associate with some 
piece of data; it may be as precise or imprecise as I wish.
The imprecise-precise spectrum is indeed large; as has been demonstrated 
in other threads, it's possible to go from fully dynamic type checking 
to ropes-and-shackles discipline-and-bondage style.
(Maybe one should say "fine grain vs. coarse grain" instead of "precise 
and imprecise".)

 From this perspective, saying "you need to exploit type errors" doesn't 
make much sense; if this indeed happens to static typer, the knee-jerk 
reaction would be to modify the type system until it properly includes 
those types that were previously outside the type checking system.
(Note that with "proper" static typing, the majority of entities uses 
types that were defined by the programmer. The type system is part of 
the programmer's expressivity just as the program text proper. That's 
one of the reasons why the idea of "a type system just restricts me" 
sounds absurd.)

>> I fear I didn't make clear enough that I was talking about testing &
>> verification in a fully automated manner, particularly the automation of
>> test case selection.
> 
> So how do you statically analyze the following piece of code in Java?
> 
> Class.forName(someStringExpression)
>      .getMethod(someOtherStringExpression,
>                 someParameterTypeArrayExpression)
>      .invoke(someObject,someConcreteParameterArray);

Initially, I wouldn't, but it might be an interesting exercize to get 
some degree of static checking into this type of code. For example, the 
someOtherStringExpression could exclude some errors by restricting it to 
a javaIdentifierExpression (of JavaIdentifierExpression type), of which 
we might know that they could only be constructed given a Class object. 
This would, for example, prevent class names from leaking into the 
function name space (it would also trivially prevent invalid identifiers 
from being accepted as function names, but that's indeed just a trivial 
example).
In practice, the kind of guarantee that can be gained this way isn't too 
interesting. Any application that I can imagine for this kind of work is 
just a thin wrapper around the introspection APIs, and wrappers don't 
usually need much checking to give us enough confidence in their 
workings. Things get really interesting only if you do something "thick" 
above them. For example, for a refactoring browser that uses Java's 
introspection API, it might indeed be a good idea to separate the name 
spaces for classes, types, and parameter names by putting each into a 
separate type even though all are just strings at their heart. Of 
course, this doesn't just keep the name spaces apart, we could (if 
that's desired) also add guarantees that the names originated from a 
Class object, simply by not providing constructors other than those that 
used the Class objects. Such guarantees can be helpful when constructing 
guarantees that the refactored code will indeed call the same routines 
as before, for example.

Regards,
Jo