Velocity Reviews > Re: "Strong typing vs. strong testing"

# Re: "Strong typing vs. strong testing"

Paul Wallich
Guest
Posts: n/a

 09-29-2010
On 9/29/10 6:40 AM, Pascal J. Bourguignon wrote:
> George Neuner<(E-Mail Removed)> writes:
>
>> On Tue, 28 Sep 2010 12:15:07 -0700, Keith Thompson<(E-Mail Removed)>
>> wrote:
>>
>>> George Neuner<(E-Mail Removed)> writes:
>>>> On 28 Sep 2010 12:42:40 GMT, Albert van der Horst
>>>> <(E-Mail Removed)4all.nl> wrote:
>>>>> I would say the dimensional checking is underrated. It must be
>>>>> complemented with a hard and fast rule about only using standard
>>>>> (SI) units internally.
>>>>>
>>>>> Oil output internal : m^3/sec
>>>>> Oil output printed: kbarrels/day
>>>>
>>>> "barrel" is not an SI unit.
>>>
>>> He didn't say it was. Internal calculations are done in SI units (in
>>> this case, m^3/sec); on output, the internal units can be converted to
>>> whatever is convenient.

>>
>> That's true. But it is a situation where the conversion to SI units
>> loses precision and therefore probably shouldn't be done.
>>
>>>
>>>> And when speaking about oil there isn't
>>>> even a simple conversion.
>>>>
>>>> 42 US gallons ? 34.9723 imp gal ? 158.9873 L
>>>>
>>>> [In case those marks don't render, they are meant to be the
>>>> double-tilda sign meaning "approximately equal".]
>>>
>>> There are multiple different kinds of "barrels", but "barrels of oil"
>>> are (consistently, as far as I know) defined as 42 US liquid gallons.
>>> A US liquid gallon is, by definition, 231 cubic inches; an inch
>>> is, by definition, 0.0254 meter. So a barrel of oil is *exactly*
>>> 0.158987294928 m^3, and 1 m^3/sec is exactly 13.7365022817792
>>> kbarrels/day. (Please feel free to check my math.) That's
>>> admittedly a lot of digits, but there's no need for approximations
>>> (unless they're imposed by the numeric representation you're using).

>>
>> I don't care to check it ... the fact that the SI unit involves 12
>> decimal places whereas the imperial unit involves 3 tells me the
>> conversion probably shouldn't be done in a program that wants
>> accuracy.

[...]
>
> Now perhaps it all depends on whether you buy your oil from Total or
> from Texaco, but in my opinion, you're forgetting something: the last
> drop. You never get exactly 42 gallons of oil, there's always a little
> drop more or less, so what you get is perhaps 158.987 liter or
> 41.9999221 US gallons, or even 158.98 liter = 41.9980729 US gallons,
> where you need more significant digits.

And even that pales in comparison to the expansion and contraction of
petroleum products with temperature. Compensation to standard temp is
required in some jurisdictions but not in others...

Keith Thompson
Guest
Posts: n/a

 09-29-2010
Erik Max Francis <(E-Mail Removed)> writes:
> Keith Thompson wrote:
>> Erik Max Francis <(E-Mail Removed)> writes:
>> [...]
>>> >>> print c # floating point accuracy aside
>>> 299792458.0 m/s

>>
>> Actually, the speed of light is exactly 299792458.0 m/s by
>> definition. (The meter and the second are defined in terms of the
>> same wavelength of light; this was changed relatively recently.)

>
> I know. Hence why I wrote the comment "floating point accuracy aside"
> when printing it.

Ok. I took the comment to be an indication that the figure was
subject to floating point accuracy concerns; in fact you meant just
the opposite.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Thomas A. Russ
Guest
Posts: n/a

 09-29-2010
George Neuner <(E-Mail Removed)> writes:

> On Tue, 28 Sep 2010 12:15:07 -0700, Keith Thompson <(E-Mail Removed)>
> wrote:
> >He didn't say it was. Internal calculations are done in SI units (in
> >this case, m^3/sec); on output, the internal units can be converted to
> >whatever is convenient.

>
> That's true. But it is a situation where the conversion to SI units
> loses precision and therefore probably shouldn't be done.

I suppose that one has to choose between two fundamental designs for any
computational system of units. One can either store the results
internally in a canonical form, which generally means an internal
representation in SI units. Then all calculations are performed using
the interal units representation and conversion happens only on input or
output.

Or one can store the values in their original input form, and perform
conversions on the fly during calculations. For calculations one will
still need to have some canonical representation for cases where the
result value doesn't have a preferred unit provided. For internal
calculations this will often be the case.

Now whether one will necessarily have a loss of precision depends on
whether the conversion factors are exact or approximations. As long as
the factors are exact, one can have the internal representation be exact
as well. One method would be to use something like the Commmon Lisp
rational numbers or the Gnu mp library.

And a representation where one preserves the "preferred" unit for
display purposes based on the original data as entered is also nice.
Roman Cunis' Common Lisp library does that, and with the use of rational
numbers for storing values and conversion factors allows one to do nice
things like make sure that

30mph * 3h = 90mi

even when the internal representation is in SI units (m/s, s, m).

--
Thomas A. Russ, USC/Information Sciences Institute

George Neuner
Guest
Posts: n/a

 09-29-2010
On Wed, 29 Sep 2010 12:40:58 +0200, (E-Mail Removed) (Pascal J.
Bourguignon) wrote:

>George Neuner <(E-Mail Removed)> writes:
>
>> On Tue, 28 Sep 2010 12:15:07 -0700, Keith Thompson <(E-Mail Removed)>
>> wrote:
>>
>>>George Neuner <(E-Mail Removed)> writes:
>>>> On 28 Sep 2010 12:42:40 GMT, Albert van der Horst
>>>> <(E-Mail Removed)4all.nl> wrote:
>>>>>I would say the dimensional checking is underrated. It must be
>>>>>complemented with a hard and fast rule about only using standard
>>>>>(SI) units internally.
>>>>>
>>>>>Oil output internal : m^3/sec
>>>>>Oil output printed: kbarrels/day
>>>>
>>>> "barrel" is not an SI unit.
>>>
>>>He didn't say it was. Internal calculations are done in SI units (in
>>>this case, m^3/sec); on output, the internal units can be converted to
>>>whatever is convenient.

>>
>> That's true. But it is a situation where the conversion to SI units
>> loses precision and therefore probably shouldn't be done.
>>
>>>
>>>> And when speaking about oil there isn't
>>>> even a simple conversion.
>>>>
>>>> 42 US gallons ? 34.9723 imp gal ? 158.9873 L
>>>>
>>>> [In case those marks don't render, they are meant to be the
>>>> double-tilda sign meaning "approximately equal".]
>>>
>>>There are multiple different kinds of "barrels", but "barrels of oil"
>>>are (consistently, as far as I know) defined as 42 US liquid gallons.
>>>A US liquid gallon is, by definition, 231 cubic inches; an inch
>>>is, by definition, 0.0254 meter. So a barrel of oil is *exactly*
>>>0.158987294928 m^3, and 1 m^3/sec is exactly 13.7365022817792
>>>kbarrels/day. (Please feel free to check my math.) That's
>>>admittedly a lot of digits, but there's no need for approximations
>>>(unless they're imposed by the numeric representation you're using).

>>
>> I don't care to check it ... the fact that the SI unit involves 12
>> decimal places whereas the imperial unit involves 3 tells me the
>> conversion probably shouldn't be done in a program that wants
>> accuracy.

>
>
>Because perhaps you're thinking that oil is sent over the oceans, and
>sold retails in barrils of 42 gallons?
>
>Actually, when I buy oil, it's from a pump that's graduated in liters!
>
>It comes from trucks with citerns containing 24 m³.
>
>And these trucks get it from reservoirs of 23,850 m³.
>
>"Tankers move approximately 2,000,000,000 metric tons" says the English
>
>
>
>Now perhaps it all depends on whether you buy your oil from Total or
>from Texaco, but in my opinion, you're forgetting something: the last
>drop. You never get exactly 42 gallons of oil, there's always a little
>drop more or less, so what you get is perhaps 158.987 liter or
>41.9999221 US gallons, or even 158.98 liter = 41.9980729 US gallons,
>where you need more significant digits.

No. I'm just reacting to the "significant figures" issue. Real
world issues like US vs Eurozone and measurement error aside - and
without implying anyone here - many people seem to forget that
multiplying significant figures doesn't add them, and results to 12
decimal places are not necessarily any more accurate than results to 2
decimal places.

It makes sense to break macro barrel into micro units only when
necessary. When a refinery purchases 500,000 barrels, it is charged a
barrel price, not some multiple of gallon or liter price and
regardless of drop over/under. The refinery's process is continuous
and it needs a delivery if it has less than 20,000 barrels - so the
current reserve figure of 174,092 barrels is as accurate as is needed
(they need to order by tomorrow because delivery will take 10 days).
OTOH, because the refinery sells product to commercial vendors of
gasoline/petrol and heating oil in gallons or liters, it does makes
sense to track inventory and sales in (large multiples of) those
units.

Similarly, converting everything to m³ simply because you can does not
make sense. When talking about the natural gas reserve of the United
States, the figures are given in Km³ - a few thousand m³ either way is
irrelevant.

George

Squeamizh
Guest
Posts: n/a

 09-29-2010
On Sep 27, 10:46*am, namekuseijin <(E-Mail Removed)> wrote:
> On 27 set, 05:46, TheFlyingDutchman <(E-Mail Removed)> wrote:
>
>
>
>
>
> > On Sep 27, 12:58*am, (E-Mail Removed) (Pascal J. Bourguignon)
> > wrote:
> > > RG <(E-Mail Removed)> writes:
> > > > In article
> > > > <(E-Mail Removed)>,
> > > > *TheFlyingDutchman <(E-Mail Removed)> wrote:

>
> > > >> On Sep 22, 10:26*pm, "Scott L. Burson" <(E-Mail Removed)> wrote:
> > > >> > This might have been mentioned here before, but I just came across it: a
> > > >> > 2003 essay by Bruce Eckel on how reliable systems can get built in
> > > >> > dynamically-typed languages. *It echoes things we've all said here, but
> > > >> > I think it's interesting because it describes a conversion experience:
> > > >> > Eckel started out in the strong-typing camp and was won over.

>
> > > >> > * *https://docs.google.com/View?id=dcsvntt2_25wpjvbbhk

>
> > > >> > -- Scott

>
> > > >> If you are writing a function to determine the maximum of two numbers
> > > >> passed as arguents in a dynamic typed language, what is the normal
> > > >> procedure used by Eckel and others to handle someone passing in
> > > >> invalid values - such as a file handle for one varible and an array
> > > >> for the other?

>
> > > > The normal procedure is to hit such a person over the head with a stick
> > > > and shout "FOO".

>
> > > Moreover, the functions returning the maximum may be able to work on
> > > non-numbers, as long as they're comparable. *What's more, there are
> > > numbers that are NOT comparable by the operator you're thinking about!.

>
> > > So to implement your specifications, that function would have to be
> > > implemented for example as:

>
> > > (defmethod lessp ((x real) (y real)) (< x y))
> > > (defmethod lessp ((x complex) (y complex))
> > > * (or (< (real-part x) (real-part y))
> > > * * * (and (= (real-part x) (real-part y))
> > > * * * * * *(< (imag-part x) (imag-part y)))))

>
> > > (defun maximum (a b)
> > > * (if (lessp a b) b a))

>
> > > And then the client of that function could very well add methods:

>
> > > (defmethod lessp ((x symbol) (y t)) (lessp (string x) y))
> > > (defmethod lessp ((x t) (y symbol)) (lessp x (string y)))
> > > (defmethod lessp ((x string) (y string)) (string< x y))

>
> > > and call:

>
> > > (maximum 'hello "WORLD") --> "WORLD"

>
> > > and who are you to forbid it!?

>
> > > --
> > > __Pascal Bourguignon__ * * * * * * * * * *http://www.informatimago.com/-Hidequoted text -

>
> > > - Show quoted text -

>
> > in C I can have a function maximum(int a, int b) that will always
> > work. Never blow up, and never give an invalid answer. If someone
> > tries to call it incorrectly it is a compile error.
> > In a dynamic typed language maximum(a, b) can be called with incorrect
> > datatypes. Even if I make it so it can handle many types as you did
> > above, it could still be inadvertantly called with a file handle for a
> > parameter or some other type not provided for. So does Eckel and
> > others, when they are writing their dynamically typed code advocate
> > just letting the function blow up or give a bogus answer, or do they
> > check for valid types passed? If they are checking for valid types it
> > would seem that any benefits gained by not specifying type are lost by
> > checking for type. And if they don't check for type it would seem that
> > their code's error handling is poor.

>
> that is a lie.
>
> Compilation only makes sure that values provided at compilation-time
> are of the right datatype.
>
> What happens though is that in the real world, pretty much all
> computation depends on user provided values at runtime. *See where are
>
> this works at compilation time without warnings:
> int m=numbermax( 2, 6 );
>
> this too:
> int a, b, m;
> scanf( "%d", &a );
> scanf( "%d", &b );
> m=numbermax( a, b );
>
> no compiler issues, but will not work just as much as in python if
> user provides "foo" and "bar" for a and b... fail.
>
> What you do if you're feeling insecure and paranoid? *Just what
> dynamically typed languages do: *add runtime checks. *Unit tests are
> great to assert those.
>
> Fact is: *almost all user data from the external words comes into
> programs as strings. *No typesystem or compiler handles this fact all
> that graceful...

I disagree with your conclusion. Sure, the data was textual when it
was initially read by the program, but that should only be relevant to
the input processing code. The data is likely converted to some
internal representation immediately after it is read and validated,
and in a sanely-designed program, it maintains this representation
throughout its life time. If the structure of some data needs to
change during development, the compiler of a statically-typed language
will automatically tell you about any client code that was not updated
to account for the change. Dynamically typed languages do not provide
this assurance.

RG
Guest
Posts: n/a

 09-29-2010
In article
<(E-Mail Removed)>,
Squeamizh <(E-Mail Removed)> wrote:

> On Sep 27, 10:46Â*am, namekuseijin <(E-Mail Removed)> wrote:
> > On 27 set, 05:46, TheFlyingDutchman <(E-Mail Removed)> wrote:
> >
> >
> >
> >
> >
> > > On Sep 27, 12:58Â*am, (E-Mail Removed) (Pascal J. Bourguignon)
> > > wrote:
> > > > RG <(E-Mail Removed)> writes:
> > > > > In article
> > > > > <(E-Mail Removed)>,
> > > > > Â*TheFlyingDutchman <(E-Mail Removed)> wrote:

> >
> > > > >> On Sep 22, 10:26Â*pm, "Scott L. Burson" <(E-Mail Removed)> wrote:
> > > > >> > This might have been mentioned here before, but I just came across
> > > > >> > it: a
> > > > >> > 2003 essay by Bruce Eckel on how reliable systems can get built in
> > > > >> > dynamically-typed languages. Â*It echoes things we've all said
> > > > >> > here, but
> > > > >> > I think it's interesting because it describes a conversion
> > > > >> > experience:
> > > > >> > Eckel started out in the strong-typing camp and was won over.

> >
> > > > >> > Â* Â*https://docs.google.com/View?id=dcsvntt2_25wpjvbbhk

> >
> > > > >> > -- Scott

> >
> > > > >> If you are writing a function to determine the maximum of two
> > > > >> numbers
> > > > >> passed as arguents in a dynamic typed language, what is the normal
> > > > >> procedure used by Eckel and others to handle someone passing in
> > > > >> invalid values - such as a file handle for one varible and an array
> > > > >> for the other?

> >
> > > > > The normal procedure is to hit such a person over the head with a
> > > > > stick
> > > > > and shout "FOO".

> >
> > > > Moreover, the functions returning the maximum may be able to work on
> > > > non-numbers, as long as they're comparable. Â*What's more, there are
> > > > numbers that are NOT comparable by the operator you're thinking about!.

> >
> > > > So to implement your specifications, that function would have to be
> > > > implemented for example as:

> >
> > > > (defmethod lessp ((x real) (y real)) (< x y))
> > > > (defmethod lessp ((x complex) (y complex))
> > > > Â* (or (< (real-part x) (real-part y))
> > > > Â* Â* Â* (and (= (real-part x) (real-part y))
> > > > Â* Â* Â* Â* Â* Â*(< (imag-part x) (imag-part y)))))

> >
> > > > (defun maximum (a b)
> > > > Â* (if (lessp a b) b a))

> >
> > > > And then the client of that function could very well add methods:

> >
> > > > (defmethod lessp ((x symbol) (y t)) (lessp (string x) y))
> > > > (defmethod lessp ((x t) (y symbol)) (lessp x (string y)))
> > > > (defmethod lessp ((x string) (y string)) (string< x y))

> >
> > > > and call:

> >
> > > > (maximum 'hello "WORLD") --> "WORLD"

> >
> > > > and who are you to forbid it!?

> >
> > > > --
> > > > __Pascal Bourguignon__ Â* Â* Â* Â* Â* Â* Â* Â* Â*
> > > > Â*http://www.informatimago.com/-Hidequoted text -

> >
> > > > - Show quoted text -

> >
> > > in C I can have a function maximum(int a, int b) that will always
> > > work. Never blow up, and never give an invalid answer. If someone
> > > tries to call it incorrectly it is a compile error.
> > > In a dynamic typed language maximum(a, b) can be called with incorrect
> > > datatypes. Even if I make it so it can handle many types as you did
> > > above, it could still be inadvertantly called with a file handle for a
> > > parameter or some other type not provided for. So does Eckel and
> > > others, when they are writing their dynamically typed code advocate
> > > just letting the function blow up or give a bogus answer, or do they
> > > check for valid types passed? If they are checking for valid types it
> > > would seem that any benefits gained by not specifying type are lost by
> > > checking for type. And if they don't check for type it would seem that
> > > their code's error handling is poor.

> >
> > that is a lie.
> >
> > Compilation only makes sure that values provided at compilation-time
> > are of the right datatype.
> >
> > What happens though is that in the real world, pretty much all
> > computation depends on user provided values at runtime. Â*See where are
> >
> > this works at compilation time without warnings:
> > int m=numbermax( 2, 6 );
> >
> > this too:
> > int a, b, m;
> > scanf( "%d", &a );
> > scanf( "%d", &b );
> > m=numbermax( a, b );
> >
> > no compiler issues, but will not work just as much as in python if
> > user provides "foo" and "bar" for a and b... fail.
> >
> > What you do if you're feeling insecure and paranoid? Â*Just what
> > dynamically typed languages do: Â*add runtime checks. Â*Unit tests are
> > great to assert those.
> >
> > Fact is: Â*almost all user data from the external words comes into
> > programs as strings. Â*No typesystem or compiler handles this fact all
> > that graceful...

>
> I disagree with your conclusion. Sure, the data was textual when it
> was initially read by the program, but that should only be relevant to
> the input processing code. The data is likely converted to some
> internal representation immediately after it is read and validated,
> and in a sanely-designed program, it maintains this representation
> throughout its life time. If the structure of some data needs to
> change during development, the compiler of a statically-typed language
> will automatically tell you about any client code that was not updated
> to account for the change. Dynamically typed languages do not provide
> this assurance.

This is a red herring. You don't have to invoke run-time input to
demonstrate bugs in a statically typed language that are not caught by
the compiler. For example:

[ron@mighty:~]\$ cat foo.c
#include <stdio.h>

int maximum(int a, int b) {
return (a > b ? a : b);
}

int foo(int x) { return 9223372036854775807+x; }

int main () {
printf("%d\n", maximum(foo(1), 1));
return 0;
}
[ron@mighty:~]\$ gcc -Wall foo.c
[ron@mighty:~]\$ ./a.out
1

Even simple arithmetic is Turing-complete, so catching all type-related
errors at compile time would entail solving the halting problem.

rg

Squeamizh
Guest
Posts: n/a

 09-29-2010
On Sep 29, 3:02*pm, RG <(E-Mail Removed)> wrote:
> In article
> <(E-Mail Removed)>,
>
>
>
>
>
> *Squeamizh <(E-Mail Removed)> wrote:
> > On Sep 27, 10:46*am, namekuseijin <(E-Mail Removed)> wrote:
> > > On 27 set, 05:46, TheFlyingDutchman <(E-Mail Removed)> wrote:

>
> > > > On Sep 27, 12:58*am, (E-Mail Removed) (Pascal J. Bourguignon)
> > > > wrote:
> > > > > RG <(E-Mail Removed)> writes:
> > > > > > In article
> > > > > > <(E-Mail Removed)>,
> > > > > > *TheFlyingDutchman <(E-Mail Removed)> wrote:

>
> > > > > >> On Sep 22, 10:26*pm, "Scott L. Burson" <(E-Mail Removed)> wrote:
> > > > > >> > This might have been mentioned here before, but I just came across
> > > > > >> > it: a
> > > > > >> > 2003 essay by Bruce Eckel on how reliable systems can get built in
> > > > > >> > dynamically-typed languages. *It echoes things we've all said
> > > > > >> > here, but
> > > > > >> > I think it's interesting because it describes a conversion
> > > > > >> > experience:
> > > > > >> > Eckel started out in the strong-typing camp and was won over..

>
> > > > > >> > * *https://docs.google.com/View?id=dcsvntt2_25wpjvbbhk

>
> > > > > >> > -- Scott

>
> > > > > >> If you are writing a function to determine the maximum of two
> > > > > >> numbers
> > > > > >> passed as arguents in a dynamic typed language, what is the normal
> > > > > >> procedure used by Eckel and others to handle someone passing in
> > > > > >> invalid values - such as a file handle for one varible and an array
> > > > > >> for the other?

>
> > > > > > The normal procedure is to hit such a person over the head with a
> > > > > > stick
> > > > > > and shout "FOO".

>
> > > > > Moreover, the functions returning the maximum may be able to work on
> > > > > non-numbers, as long as they're comparable. *What's more, there are
> > > > > numbers that are NOT comparable by the operator you're thinking about!.

>
> > > > > So to implement your specifications, that function would have to be
> > > > > implemented for example as:

>
> > > > > (defmethod lessp ((x real) (y real)) (< x y))
> > > > > (defmethod lessp ((x complex) (y complex))
> > > > > * (or (< (real-part x) (real-part y))
> > > > > * * * (and (= (real-part x) (real-part y))
> > > > > * * * * * *(< (imag-part x) (imag-part y)))))

>
> > > > > (defun maximum (a b)
> > > > > * (if (lessp a b) b a))

>
> > > > > And then the client of that function could very well add methods:

>
> > > > > (defmethod lessp ((x symbol) (y t)) (lessp (string x) y))
> > > > > (defmethod lessp ((x t) (y symbol)) (lessp x (string y)))
> > > > > (defmethod lessp ((x string) (y string)) (string< x y))

>
> > > > > and call:

>
> > > > > (maximum 'hello "WORLD") --> "WORLD"

>
> > > > > and who are you to forbid it!?

>
> > > > > --
> > > > > __Pascal Bourguignon__ * * * * * * * * *
> > > > > *http://www.informatimago.com/-Hidequotedtext -

>
> > > > > - Show quoted text -

>
> > > > in C I can have a function maximum(int a, int b) that will always
> > > > work. Never blow up, and never give an invalid answer. If someone
> > > > tries to call it incorrectly it is a compile error.
> > > > In a dynamic typed language maximum(a, b) can be called with incorrect
> > > > datatypes. Even if I make it so it can handle many types as you did
> > > > above, it could still be inadvertantly called with a file handle for a
> > > > parameter or some other type not provided for. So does Eckel and
> > > > others, when they are writing their dynamically typed code advocate
> > > > just letting the function blow up or give a bogus answer, or do they
> > > > check for valid types passed? If they are checking for valid types it
> > > > would seem that any benefits gained by not specifying type are lost by
> > > > checking for type. And if they don't check for type it would seem that
> > > > their code's error handling is poor.

>
> > > that is a lie.

>
> > > Compilation only makes sure that values provided at compilation-time
> > > are of the right datatype.

>
> > > What happens though is that in the real world, pretty much all
> > > computation depends on user provided values at runtime. *See where are

>
> > > this works at compilation time without warnings:
> > > int m=numbermax( 2, 6 );

>
> > > this too:
> > > int a, b, m;
> > > scanf( "%d", &a );
> > > scanf( "%d", &b );
> > > m=numbermax( a, b );

>
> > > no compiler issues, but will not work just as much as in python if
> > > user provides "foo" and "bar" for a and b... fail.

>
> > > What you do if you're feeling insecure and paranoid? *Just what
> > > dynamically typed languages do: *add runtime checks. *Unit tests are
> > > great to assert those.

>
> > > Fact is: *almost all user data from the external words comes into
> > > programs as strings. *No typesystem or compiler handles this fact all
> > > that graceful...

>
> > I disagree with your conclusion. *Sure, the data was textual when it
> > was initially read by the program, but that should only be relevant to
> > the input processing code. *The data is likely converted to some
> > internal representation immediately after it is read and validated,
> > and in a sanely-designed program, it maintains this representation
> > throughout its life time. *If the structure of some data needs to
> > change during development, the compiler of a statically-typed language
> > will automatically tell you about any client code that was not updated
> > to account for the change. *Dynamically typed languages do not provide
> > this assurance.

>
> This is a red herring. *You don't have to invoke run-time input to
> demonstrate bugs in a statically typed language that are not caught by
> the compiler. *For example:
>
> [ron@mighty:~]\$ cat foo.c
> #include <stdio.h>
>
> int maximum(int a, int b) {
> * return (a > b ? a : b);
>
> }
>
> int foo(int x) { return 9223372036854775807+x; }
>
> int main () {
> * printf("%d\n", maximum(foo(1), 1));
> * return 0;}
>
> [ron@mighty:~]\$ gcc -Wall foo.c
> [ron@mighty:~]\$ ./a.out
> 1
>
> Even simple arithmetic is Turing-complete, so catching all type-related
> errors at compile time would entail solving the halting problem.
>
> rg

In short, static typing doesn't solve all conceivable problems.

We are all aware that there is no perfect software development process
or tool set. I'm interested in minimizing the number of problems I
run into during development, and the number of bugs that are in the
finished product. My opinion is that static typed languages are
better at this for large projects, for the reasons I stated in my
previous post.

RG
Guest
Posts: n/a

 09-29-2010
In article
<(E-Mail Removed)>,
Squeamizh <(E-Mail Removed)> wrote:

> On Sep 29, 3:02Â*pm, RG <(E-Mail Removed)> wrote:
> > In article
> > <(E-Mail Removed)>,
> >
> >
> >
> >
> >
> > Â*Squeamizh <(E-Mail Removed)> wrote:
> > > On Sep 27, 10:46Â*am, namekuseijin <(E-Mail Removed)> wrote:
> > > > On 27 set, 05:46, TheFlyingDutchman <(E-Mail Removed)> wrote:

> >
> > > > > On Sep 27, 12:58Â*am, (E-Mail Removed) (Pascal J. Bourguignon)
> > > > > wrote:
> > > > > > RG <(E-Mail Removed)> writes:
> > > > > > > In article
> > > > > > > <(E-Mail Removed)
> > > > > > > >,
> > > > > > > Â*TheFlyingDutchman <(E-Mail Removed)> wrote:

> >
> > > > > > >> On Sep 22, 10:26Â*pm, "Scott L. Burson" <(E-Mail Removed)> wrote:
> > > > > > >> > This might have been mentioned here before, but I just came
> > > > > > >> > across
> > > > > > >> > it: a
> > > > > > >> > 2003 essay by Bruce Eckel on how reliable systems can get
> > > > > > >> > built in
> > > > > > >> > dynamically-typed languages. Â*It echoes things we've all said
> > > > > > >> > here, but
> > > > > > >> > I think it's interesting because it describes a conversion
> > > > > > >> > experience:
> > > > > > >> > Eckel started out in the strong-typing camp and was won over.

> >
> > > > > > >> > Â* Â*https://docs.google.com/View?id=dcsvntt2_25wpjvbbhk

> >
> > > > > > >> > -- Scott

> >
> > > > > > >> If you are writing a function to determine the maximum of two
> > > > > > >> numbers
> > > > > > >> passed as arguents in a dynamic typed language, what is the
> > > > > > >> normal
> > > > > > >> procedure used by Eckel and others to handle someone passing in
> > > > > > >> invalid values - such as a file handle for one varible and an
> > > > > > >> array
> > > > > > >> for the other?

> >
> > > > > > > The normal procedure is to hit such a person over the head with a
> > > > > > > stick
> > > > > > > and shout "FOO".

> >
> > > > > > Moreover, the functions returning the maximum may be able to work
> > > > > > on
> > > > > > non-numbers, as long as they're comparable. Â*What's more, there are
> > > > > > numbers that are NOT comparable by the operator you're thinking
> > > > > > about!.

> >
> > > > > > So to implement your specifications, that function would have to be
> > > > > > implemented for example as:

> >
> > > > > > (defmethod lessp ((x real) (y real)) (< x y))
> > > > > > (defmethod lessp ((x complex) (y complex))
> > > > > > Â* (or (< (real-part x) (real-part y))
> > > > > > Â* Â* Â* (and (= (real-part x) (real-part y))
> > > > > > Â* Â* Â* Â* Â* Â*(< (imag-part x) (imag-part y)))))

> >
> > > > > > (defun maximum (a b)
> > > > > > Â* (if (lessp a b) b a))

> >
> > > > > > And then the client of that function could very well add methods:

> >
> > > > > > (defmethod lessp ((x symbol) (y t)) (lessp (string x) y))
> > > > > > (defmethod lessp ((x t) (y symbol)) (lessp x (string y)))
> > > > > > (defmethod lessp ((x string) (y string)) (string< x y))

> >
> > > > > > and call:

> >
> > > > > > (maximum 'hello "WORLD") --> "WORLD"

> >
> > > > > > and who are you to forbid it!?

> >
> > > > > > --
> > > > > > __Pascal Bourguignon__ Â* Â* Â* Â* Â* Â* Â* Â* Â*
> > > > > > Â*http://www.informatimago.com/-Hidequotedtext -

> >
> > > > > > - Show quoted text -

> >
> > > > > in C I can have a function maximum(int a, int b) that will always
> > > > > work. Never blow up, and never give an invalid answer. If someone
> > > > > tries to call it incorrectly it is a compile error.
> > > > > In a dynamic typed language maximum(a, b) can be called with
> > > > > incorrect
> > > > > datatypes. Even if I make it so it can handle many types as you did
> > > > > above, it could still be inadvertantly called with a file handle for
> > > > > a
> > > > > parameter or some other type not provided for. So does Eckel and
> > > > > others, when they are writing their dynamically typed code advocate
> > > > > just letting the function blow up or give a bogus answer, or do they
> > > > > check for valid types passed? If they are checking for valid types it
> > > > > would seem that any benefits gained by not specifying type are lost
> > > > > by
> > > > > checking for type. And if they don't check for type it would seem
> > > > > that
> > > > > their code's error handling is poor.

> >
> > > > that is a lie.

> >
> > > > Compilation only makes sure that values provided at compilation-time
> > > > are of the right datatype.

> >
> > > > What happens though is that in the real world, pretty much all
> > > > computation depends on user provided values at runtime. Â*See where are
> > > > we heading?

> >
> > > > this works at compilation time without warnings:
> > > > int m=numbermax( 2, 6 );

> >
> > > > this too:
> > > > int a, b, m;
> > > > scanf( "%d", &a );
> > > > scanf( "%d", &b );
> > > > m=numbermax( a, b );

> >
> > > > no compiler issues, but will not work just as much as in python if
> > > > user provides "foo" and "bar" for a and b... fail.

> >
> > > > What you do if you're feeling insecure and paranoid? Â*Just what
> > > > dynamically typed languages do: Â*add runtime checks. Â*Unit tests are
> > > > great to assert those.

> >
> > > > Fact is: Â*almost all user data from the external words comes into
> > > > programs as strings. Â*No typesystem or compiler handles this fact all
> > > > that graceful...

> >
> > > I disagree with your conclusion. Â*Sure, the data was textual when it
> > > was initially read by the program, but that should only be relevant to
> > > the input processing code. Â*The data is likely converted to some
> > > internal representation immediately after it is read and validated,
> > > and in a sanely-designed program, it maintains this representation
> > > throughout its life time. Â*If the structure of some data needs to
> > > change during development, the compiler of a statically-typed language
> > > will automatically tell you about any client code that was not updated
> > > to account for the change. Â*Dynamically typed languages do not provide
> > > this assurance.

> >
> > This is a red herring. Â*You don't have to invoke run-time input to
> > demonstrate bugs in a statically typed language that are not caught by
> > the compiler. Â*For example:
> >
> > [ron@mighty:~]\$ cat foo.c
> > #include <stdio.h>
> >
> > int maximum(int a, int b) {
> > Â* return (a > b ? a : b);
> >
> > }
> >
> > int foo(int x) { return 9223372036854775807+x; }
> >
> > int main () {
> > Â* printf("%d\n", maximum(foo(1), 1));
> > Â* return 0;}
> >
> > [ron@mighty:~]\$ gcc -Wall foo.c
> > [ron@mighty:~]\$ ./a.out
> > 1
> >
> > Even simple arithmetic is Turing-complete, so catching all type-related
> > errors at compile time would entail solving the halting problem.
> >
> > rg

>
> In short, static typing doesn't solve all conceivable problems.

More specifically, the claim made above:

> in C I can have a function maximum(int a, int b) that will always
> work. Never blow up, and never give an invalid answer.

is false. And it is not necessary to invoke the vagaries of run-time
input to demonstrate that it is false.

> We are all aware that there is no perfect software development process
> or tool set. I'm interested in minimizing the number of problems I
> run into during development, and the number of bugs that are in the
> finished product. My opinion is that static typed languages are
> better at this for large projects, for the reasons I stated in my
> previous post.

More power to you. What are you doing here on cll then?

rg

Thomas A. Russ
Guest
Posts: n/a

 09-29-2010
RG <(E-Mail Removed)> writes:
>
> More power to you. What are you doing here on cll then?

--
Thomas A. Russ, USC/Information Sciences Institute

Keith Thompson
Guest
Posts: n/a

 09-29-2010
RG <(E-Mail Removed)> writes:
> In article
> <(E-Mail Removed)>,
> Squeamizh <(E-Mail Removed)> wrote:
>> On Sep 29, 3:02Â*pm, RG <(E-Mail Removed)> wrote:

[...]
>> > This is a red herring. Â*You don't have to invoke run-time input to
>> > demonstrate bugs in a statically typed language that are not caught by
>> > the compiler. Â*For example:
>> >
>> > [ron@mighty:~]\$ cat foo.c
>> > #include <stdio.h>
>> >
>> > int maximum(int a, int b) {
>> > Â* return (a > b ? a : b);
>> >
>> > }
>> >
>> > int foo(int x) { return 9223372036854775807+x; }
>> >
>> > int main () {
>> > Â* printf("%d\n", maximum(foo(1), 1));
>> > Â* return 0;}
>> >
>> > [ron@mighty:~]\$ gcc -Wall foo.c
>> > [ron@mighty:~]\$ ./a.out
>> > 1
>> >
>> > Even simple arithmetic is Turing-complete, so catching all type-related
>> > errors at compile time would entail solving the halting problem.
>> >
>> > rg

>>
>> In short, static typing doesn't solve all conceivable problems.

>
> More specifically, the claim made above:
>
>> in C I can have a function maximum(int a, int b) that will always
>> work. Never blow up, and never give an invalid answer.

>
> is false. And it is not necessary to invoke the vagaries of run-time
> input to demonstrate that it is false.

But the above maximum() function does exactly that. The program's
behavior happens to be undefined or implementation-defined for reasons
unrelated to the maximum() function.

Depending on the range of type int on the given system, either the
behavior of the addition in foo() is undefined (because it overflows),
or the implicit conversion of the result to int either yields an
implementation-defined result or (in C99) raises an
implementation-defined signal; the latter can lead to undefined
behavior.

Since 9223372036854775807 is 2**63-1, what *typically* happens is that
the addition yields the value 0, but the C language doesn't require that
particular result. You then call maximum with arguments 0 and 1, and
it quite correctly returns 1.

>> We are all aware that there is no perfect software development process
>> or tool set. I'm interested in minimizing the number of problems I
>> run into during development, and the number of bugs that are in the
>> finished product. My opinion is that static typed languages are
>> better at this for large projects, for the reasons I stated in my
>> previous post.

>
> More power to you. What are you doing here on cll then?

This thread is cross-posted to several newsgroups, including
comp.lang.c.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"