From: Raffael Cavallaro
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <raffaelcavallaro-4FF564.20373517112003@netnews.attbi.com>
In article <·····················@news.demon.co.uk>,
 Adrian Hey <····@NoSpicedHam.iee.org> wrote:

> The only extra work I can think of is that a static type system does
> force you to give some thought to correctness as you write your
> code. 

By "thought to correctness" you really mean, thinking in a type system, 
an additional burden I don't want to take on, especially for such little 
benefit - virtually all of these type errors will be caught by other 
necessary testing. 

> But anybody who doesn't do that as a matter of routine is
> storing up a heap of trouble for themselves further down the line. 

No, they are storing up failed tests and runtime exceptions, which lead 
to corrections.

I wan't to run my program at any stage, knowing that it isn't fully 
correct yet, and ignore those errors I choose to, and attend to those I 
want to, when I want to. I don't wan't the compiler dictating the order 
in which I must move my program toward correctness (i.e., fix the type 
errors *first* or I won't let your program run). Type errors aren't all 
that important to me, since I know they'll either be caught in other 
necessary testing, or disappear as my code is refined and refactored.

> So maybe you could
> illustrate what extra work your talking about if we chose a specific
> example we are both familiar with, the phonecodes problem. I posted
> a Haskell solution which you can dig out of the google if you like.
> How do you think the presence of a static type system impeded development
> of this program?

This is tantamount to asking us to retroactively get inside your head 
and know everything that you were doing and thinking from the time you 
first read the spec, to the time your program compiled and tested 
correctly. The extra work is having to conform your thought about the 
problem to Haskell's type system, and being forced to correct any type 
errors before your program is allowed to run. This extra work isn't 
going to be visible in the finished code any more than the initial list 
based, throw away drafts of a lisp solution would be visible in a final 
program that uses CLOS or hash tables.

From: Joachim Durchholz
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpd01c$5cm$1@news.oberberg.net>
Raffael Cavallaro wrote:

> Adrian Hey <····@NoSpicedHam.iee.org> wrote:
> 
>> The only extra work I can think of is that a static type system
>> does force you to give some thought to correctness as you write
>> your code.
> 
> By "thought to correctness" you really mean, thinking in a type
> system, an additional burden I don't want to take on, especially for
> such little benefit - virtually all of these type errors will be
> caught by other necessary testing.

If you say "type", you think Integer, Real, or some record type.

Functional data types are (mostly) variant records (similar to Pascal,
but type-safe: the type used is encoded, and the language will not allow
you to reinterpret memory bits by assuming the wrong type).
The "thought to correctness" is thinking which data should go in what
records, what functions should operate on them, what these functions can
assume and what they cannot. Designing your data structures has a
profound effect on program correctness (a phenomenon that functional
programming shares with OO).

> I wan't to run my program at any stage, knowing that it isn't fully 
> correct yet, and ignore those errors I choose to, and attend to those
> I want to, when I want to.

You're not making a case for dynamic typing here. You're making a case
for classifying type errors as warnings. (Which isn't unreasonable in my
eyes, even though I don't adhere to this style of coding - but hey,
people are different and ought to be.)

> The extra work is having to conform your thought about the problem to
> Haskell's type system, and being forced to correct any type errors
> before your program is allowed to run. This extra work isn't going to
> be visible in the finished code any more than the initial list based,
> throw away drafts of a lisp solution would be visible in a final 
> program that uses CLOS or hash tables.

Static checking forces one's attention to some class of errors (namely 
whatever errors the type system happens to be able to exclude). I agree 
that this can be annoying, and sometimes it can force attention away 
from the real issues (particularly when you're refactoring large 
libraries, as I did).
I'd rate the importance as somewhere in the middle between "important" 
and "irrelevant".
It would be easy to handle: turn type errors into warnings, and have the 
compiler insert exception-throwing code in places where the type error 
would cause problems. (And, probably, add compiler flags that make type 
errors and - possibly - other diagnostics into errors if that's the 
policy for the shop in question.) That way, you'd get the best of both 
worlds: precise information on those errors that the machine can 
diagnose, and an example at run-time where you can actually inspect the 
values if the general diagnosis was uninterpretable. (I don't think that 
having examples at run-time is too helpful for the seasoned programmer, 
but it could be a tremendous help when learning to work with static type 
inference. Every fall, comp.lang.functional resounds with lots of pleas 
for help interpreting a type error message, so there's certainly a case 
here.)

Regards,
Jo
From: Marco Antoniotti
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <LDtub.219$KR3.111778@typhoon.nyu.edu>
Joachim Durchholz wrote:

> Raffael Cavallaro wrote:
> 
>> Adrian Hey <····@NoSpicedHam.iee.org> wrote:
>>
>>> The only extra work I can think of is that a static type system
>>> does force you to give some thought to correctness as you write
>>> your code.
>>
>>
>> By "thought to correctness" you really mean, thinking in a type
>> system, an additional burden I don't want to take on, especially for
>> such little benefit - virtually all of these type errors will be
>> caught by other necessary testing.
> 
> 
> If you say "type", you think Integer, Real, or some record type.
> 
> Functional data types are (mostly) variant records (similar to Pascal,
> but type-safe: the type used is encoded, and the language will not allow
> you to reinterpret memory bits by assuming the wrong type).

I think it is very difficult to have #C(3.14 4) be interpreted as a 
symbol or a string or a FOO (where FOO was defined as a class) in Common 
Lisp.

Cheers
--
Marco
From: Joachim Durchholz
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpfr3j$9fa$1@news.oberberg.net>
Marco Antoniotti wrote:
>> Functional data types are (mostly) variant records (similar to Pascal,
>> but type-safe: the type used is encoded, and the language will not allow
>> you to reinterpret memory bits by assuming the wrong type).
> 
> I think it is very difficult to have #C(3.14 4) be interpreted as a 
> symbol or a string or a FOO (where FOO was defined as a class) in Common 
> Lisp.

Assuming that "#C(3.14 4)" is a literal representation for 3.14+i*4: 
yes, nobody would confuse that. If type errors could occur just at that 
point, static type checking would indeed be pointless.

However, if the code is
   (foo bar baz)
and bar and baz are just names that may have some value, inspecting the 
local program code isn't going to tell you whether these names will 
stand for integers, strings, complex numbers, or something entirely 
different. To check whether the above code is correct, you have to look 
up the definition of foo and see whether it assumes (say) complex 
numbers in its arguments, and that's easy, it's just a single look-up 
away. However, you also have to inspect all code paths that might inject 
values into bar and baz, and that's going to be a task that's growing 
roughly linearly with program size.
Static type checking is nothing more than doing these linear-time checks 
for you. Even better, it's doing it for all such cases in one go, so the 
total effort to do type checking isn't O(N^2) but O(N), and (even 
better) it's going from human effort to machine effort.

Regards,
Jo
From: Adrian Hey
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpdghg$ajl$1$830fa7b3@news.demon.co.uk>
Raffael Cavallaro wrote:

> In article <·····················@news.demon.co.uk>,
>  Adrian Hey <····@NoSpicedHam.iee.org> wrote:
> 
>> The only extra work I can think of is that a static type system does
>> force you to give some thought to correctness as you write your
>> code.
> 
> By "thought to correctness" you really mean, thinking in a type system,

No that isn't what I meant. Though I using that caricature makes you happy
please continue.

> an additional burden I don't want to take on,

It is not a burden, though learning a new language might be. 

> especially for such little benefit

The benefits are not "little".

> virtually all of these type errors will be caught by other necessary
> testing.

Virtually all, or all? and they won't be so easy to diagnose in any
event.

Thinking about types must be an important part of correctness, even in an
untyped or "dynamically typed" language. Surely when you define a
function you must have some idea what are and are not safe arguments?
and what "type" (in a very loose informal sense) of result the function
will return. You'll also need some way to communicate this information
to other users of the function, or even just to remind yourself later on.

Since nobody appears to want to demonstrate this alleged extra work
with the phonecodes example, perhaps if we chose a different simpler
example somebody will. Excuse me if I use Haskell, but I think this is
will be clear enough even to non-Haskellers.

I chose the foldr function..

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f default []     = default -- How to deal with emtpty list
foldr f default (a:as) = f a (foldr f default as)

The first line is an (optional!) type signature. The lower case
letters are universally quantified type variables, which means
the actual types can be anything at all, so long as they match
properly in any actual use of foldr (the same lower case letter
always stands for the same actual type in any expression involving
foldr).

Typical use might be:

sum :: Num n => [n] -> n -- Sums any list of Num(bers)
sum ns = foldr (+) 0 ns  -- (+) is overloaded for all Num(bers)

concat :: [[a]] -> [a]
concat as = foldr (++) [] as -- ++ joins 2 lists.

In general the first argument can be any function of type..
 A -> B -> B , where A and B are actual types
but it is an error to use a function of type..
 B -> A -> B , for example
(a common enough mistake that I make from time to time).

This is real logical error (not the type system being awkward
or getting in the way) that isn't going to go away and will have
to be fixed sooner or later. If the Haskell compiler permitted
such expressions I'd still have 1 more bug to find by some other
means.  

So I ask, if I was using Lisp (for arguments sake)..

 How do I communicate to other users what are and are not legal
 arguments?

 Why is it easier to detect *and* diagnose such errors using
 unit tests, especially considering that typically the error won't
 be detected until the first argument (f) is actually applied (and
 often not even then I suspect), making diagnosis of the real problem
 much harder.

 Where is the extra work in the Haskell solution that isn't
 required one way or another in any (correct) implementation of
 foldr in any language?

>> So maybe you could
>> illustrate what extra work your talking about if we chose a specific
>> example we are both familiar with, the phonecodes problem. I posted
>> a Haskell solution which you can dig out of the google if you like.
>> How do you think the presence of a static type system impeded development
>> of this program?
> 
> This is tantamount to asking us to retroactively get inside your head
> and know everything that you were doing and thinking from the time you
> first read the spec, to the time your program compiled and tested
> correctly. The extra work is having to conform your thought about the
> problem to Haskell's type system, and being forced to correct any type
> errors before your program is allowed to run. This extra work isn't
> going to be visible in the finished code any more than the initial list
> based, throw away drafts of a lisp solution would be visible in a final
> program that uses CLOS or hash tables.

This "extra work" wasn't extra work at all, all type errors were real
logical flaws and would need correction anyway before the program stood
any chance of working, even if Haskell did provide some way of turning
type checking off.

I see fact that they were detected and diagnosed automagically, without
me having to write or run a single line of test code as a *big* win,
not a "little benefit". (In fact in this case once the program typechecked
it did indeed work first time).

Regards
--
Adrian Hey
From: Raffael Cavallaro
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <raffaelcavallaro-42C38A.18560118112003@netnews.attbi.com>
In article <·····················@news.demon.co.uk>,
 Adrian Hey <····@NoSpicedHam.iee.org> wrote:

> I see fact that they were detected and diagnosed automagically, without
> me having to write or run a single line of test code as a *big* win,
> not a "little benefit". (In fact in this case once the program typechecked
> it did indeed work first time).

Because you assume, incorrectly, that one would have to write separate 
tests to detect runtime type errors if one did not have static typing. 
Experience shows this is not the case. Runtime type errors are caught 
and fixed when running tests for *other things* No special runtime type 
error tests are written, and yet, miraculously, the runtime type errors 
are exposed and corrected anyway. Maybe type errors aren't so difficult 
to spot that we need to bend our thinking to appease a rigid, automated 
system so that it can detect them for us.

The extra work with Haskell, once again, and I fear it must be for the 
final time, since I grow weary of having others not actually take in 
what I'm writing, consists in taking on the additional burden of making 
one's thought about the problem conform to the Haskell type system. This 
is over and above learning Haskell syntax, Haskell built in function 
names, etc. In lisp, one does not have to conform one's thought about 
the problem to a type system just to get simple code to execute.

Once again, a simple example:

raffaelc$ ghci
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.0.1, for Haskell 
98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base ... linking ... done.
Prelude> 5 + 5   
10 
Prelude> 5 + 2.5
7.5

-- so far so good, Haskell will not complain about adding an integer and 
-- a float. Unfortunately, not so for lists...

Prelude> let list1 = 1:2:3:4:[]
Prelude> list1
[1,2,3,4]
Prelude> let list2 = 5:6:7:8:[]
Prelude> list2
[5,6,7,8]
Prelude> list1 ++ list2
[1,2,3,4,5,6,7,8]
Prelude> let list3 = 9.1:10.0:11.7:12.1:[]
Prelude> list3
[9.1,10.0,11.7,12.1]
Prelude> list1 ++ list3

<interactive>:1:
    Couldn't match `Integer' against `Double'
        Expected type: [Integer]
        Inferred type: [Double]
    In the second argument of `(++)', namely `list3'
    In the definition of `it': it = list1 ++ list3

This is broken, especially as Haskell has no complaints about mixing 
integers and floats in artimetic. Nevertheless, I can't, by default, use 
integers and floats in the same list. How silly. Now, in lisp:

raffaelc$ openmcl
Welcome to OpenMCL Version (Alpha: Darwin) 0.14-031018!
? (+ 5 5)
10
? (+ 5 2.5)
7.5
;; same as in Haskell, integers and floats mix in arithmetic.
;; but in lisp, they can be mixed in lists as well.

? (setq list1 (list 1 2 3 4))
(1 2 3 4)
? list1
(1 2 3 4)
? (setq list2 (list 5 6 7 8))
(5 6 7 8)
? list2
(5 6 7 8)
? (append list1 list2)
(1 2 3 4 5 6 7 8)
? (setq list3 (list 9.1 10.0 11.7 12.1))
(9.1 10.0 11.7 12.1)
? (append list1 list3)
(1 2 3 4 9.1 10.0 11.7 12.1)
? (reduce #'+ (append list1 list3))
52.9
;; we never got here in Haskell because we couldn't join a list
;; of integers and alist of floats. If we wan't to get to this simple
;; result, using Haskell, we have to first be interrupted by the
;; type checker, then define a new datatype just so
;; we can put integers and floats in the same list.

Lisp is consistent. It just works, and I don't have to go out of my way 
to define a new datatype just to get lists that can have both integers 
and floats in them. I don't wan't to be interrupted for petty book 
keeping tasks like this. I don't want to bend my thinking to conform to 
Haskell's type-system-sillyness, especially as virtually all the type 
errors its type checker will flag, will be found anyway, when I run 
other tests I am going to run anyway (no, *not* additional type checking 
tests).
From: Tomasz Zielonka
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <slrnbrle7v.66t.t.zielonka@zodiac.mimuw.edu.pl>
Raffael Cavallaro wrote:
> 
> The extra work with Haskell, once again, and I fear it must be for the 
> final time, since I grow weary of having others not actually take in 
> what I'm writing, consists in taking on the additional burden of making 
> one's thought about the problem conform to the Haskell type system. This 
> is over and above learning Haskell syntax, Haskell built in function 
> names, etc. In lisp, one does not have to conform one's thought about 
> the problem to a type system just to get simple code to execute.

How can you possibly know that, when you just don't understand Haskell?
You just showed that in your post.

> Prelude> 5 + 2.5
> 7.5

Here you are adding two floats, not an integer and a float. The rest of
your post is wrong because of this misunderstanding.

PS. You are tripping on 'monomorphism restriction'.
    Run ghci with -fno-monomorphism-restriction and try your code again.
    It's late, so I won't go in the details now.

Tom

-- 
.signature: Too many levels of symbolic links
From: Mark Carroll
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <nXp*z-Q7p@news.chiark.greenend.org.uk>
In article <······································@netnews.attbi.com>,
Raffael Cavallaro  <················@junk.mail.me.not.mac.com> wrote:
(snip)
>Prelude> 5 + 5   
>10 
>Prelude> 5 + 2.5
>7.5
>
>-- so far so good, Haskell will not complain about adding an integer and 
>-- a float. Unfortunately, not so for lists...

Of course it will:

> let x = 4 :: Int
> let y = 5 :: Double
> x + y

<interactive>:1:
    Couldn't match `Int' against `Double'
	Expected type: Int
	Inferred type: Double
    In the second argument of `(+)', namely `y'
    In the definition of `it': it = x + y

Your mistake is in thinking that 5 can only be parsed as an integer.

(snip)
>This is broken, especially as Haskell has no complaints about mixing 
>integers and floats in artimetic. Nevertheless, I can't, by default, use 
(snip)

Yes, it does.

(snip)
>Lisp is consistent. It just works, and I don't have to go out of my way 
(snip)

Haskell is consistent too. Of course, for completeness:

> let list1 = 1:2:3:4:[] :: [Double]
> let list3 = 9.1:10.0:11.7:12.1:[]
> list1 ++ list3
[1.0,2.0,3.0,4.0,9.1,10.0,11.7,12.1]

-- Mark
From: Mark Carroll
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <ahh*pNV7p@news.chiark.greenend.org.uk>
In article <······································@netnews.attbi.com>,
Raffael Cavallaro  <················@junk.mail.me.not.mac.com> wrote:
(snip)
>change what these things *are*. So Haskell allows a literal integer to 
>be added to a literal float. That it does so by reading the literal 
>integer as a float is useful and correct behviour in my opinion. The 
>fact that it will not let you do:
>
>Prelude> let x = 5 :: Int
>Prelude> let y = 9 :: Double
>Prelude> x + y
>
>by inferring that I wish to now read the 5 :: Int as a Double so that it 
>can be added to a Double, is an inconsistency, and yet another example 
(snip)

No, it's not inconsistent. It may have let you read the literal
integer as a float above, but the ":: Int" means exactly "read this as
an Int", so its complaint is quite reasonable, because once read, it's
read. There is never any implicit casting of things of type Int to
things of type Float or Double going on, nor could an "x = 5" in a
program have the choice of whether it's to be read as an integer or a
float deferred to runtime.

You should note the complication due to interaction at the command
line, of course. If I write a program that starts "x = 5" then it will
look ahead (with static analysis) to see if that x is used as a Double
or an Int or whatever before deciding how to try reading it. Its
treatment is entirely consistent: once it's read a data value as one
thing, it won't implicitly cast it to something else later. At the
interactive prompt, it guessed, sometimes wrongly, because it couldn't
look ahead. A nice example of the difference lookahead makes is:

Prelude> let x = 5
Prelude> sqrt x

<interactive>:1:
    No instance for (Floating Integer)
      arising from use of `sqrt' at <interactive>:1
    In the definition of `it': it = sqrt x
Prelude> let x = 5 in sqrt x
2.23606797749979

So, really, the only "inconsistency" is exactly at the interactive
prompt when it can't look ahead and makes a wrong guess.

>of how the default is to strictness, with flexibility optional. I prefer 
>a flexible default, to which I add strictness later on.

I'm glad to see you talk in terms of preferences instead of the One
True Way. (-: It sounds like you like implicit casting to be done for
you dynamically, at least in some circumstances.

Generally, I like to have to explicitly ask for a cast when I want
one, because I want them pretty infrequently so a compiler complaint
about that sort of thing is more likely to indicate a bug, so I prefer
it to make a fuss. The extra typing to ask for the cast is no trouble:
for me, the "typing" part of coding is the fast part, it's the
thinking that isn't. Would such bugs also be easily tracked down with
dynamic type checking and unit testing? Maybe. The static approach
works nicely for me, though.

-- Mark
From: Raffael Cavallaro
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <raffaelcavallaro-AEBDD6.10123620112003@netnews.attbi.com>
In article <·········@news.chiark.greenend.org.uk>,
 Mark Carroll <·····@chiark.greenend.org.uk> wrote:

> Generally, I like to have to explicitly ask for a cast when I want
> one, because I want them pretty infrequently so a compiler complaint
> about that sort of thing is more likely to indicate a bug, so I prefer
> it to make a fuss.

And I prefer a compiler that has a reasonable default system for casting 
values, such as casting an integer to a float when combining integers 
with floats in arithmetic, rather than a compiler that makes a fuss 
about such things.
From: Feuer
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <3FBCE618.6AF9C622@his.com>
Raffael Cavallaro wrote:

> And I prefer a compiler that has a reasonable default system for casting
> values, such as casting an integer to a float when combining integers
> with floats in arithmetic, rather than a compiler that makes a fuss
> about such things.

The only operations that one would really want to combine would be
multiplication and the raising of a float to an int power.  For the
raising to a power, entirely different mechanisms of computation
are probably intended, so it does not seem unreasonable to separate
the two.  Adding an int to a float is almost always a bad idea.  So it
makes sense to me to require an explicit conversion for the case
of multiplication.

David
From: Dirk Thierbach
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <nppq81-m3g.ln1@ID-7776.user.dfncis.de>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote:
> This is broken, especially as Haskell has no complaints about mixing 
> integers and floats in artimetic. 

It's not broken, but you have to understand how it works. Literals
are automatically converted to the type they are used with. Once
you have named a list, you have fixed the type, so the literals
won't convert any longer.

> Nevertheless, I can't, by default, use integers and floats in the
> same list.

If you don't name them, it's no problem:

Main> [1,2,3]++[5.5]
[1.0,2.0,3.0,5.5]

The point is that usually one *does not* want to mix different numeric
types, because the implicit conversions may introduce bugs. This
has already been discussed in length. (One of the most annoying things
in this discussion is that it seems to be necessary to repeat everything
four or five times).

If it is the heart's desire of every Lisper to ignore these problems
and mix numeric types, then just write the apropriate module for it
and have done with it, once and for all. See my other post for an
example how that can look like.

> Lisp is consistent. It just works, 

and gives you all the problems implicit conversions have.

> and I don't have to go out of my way to define a new datatype just
> to get lists that can have both integers and floats in them. I don't
> wan't to be interrupted for petty book keeping tasks like this.

You are comparing libraries instead of type systems. Lisp has library
functions that deal with mixed numeric types. Haskell hasn't. That's
the only difference. 

> I don't want to bend my thinking to conform to Haskell's
> type-system-sillyness, especially as virtually all the type errors
> its type checker will flag, will be found anyway, when I run other
> tests I am going to run anyway (no, *not* additional type checking
> tests).

Repeating your mantra all the time doesn't make it true.

- Dirk
From: Raffael Cavallaro
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <raffaelcavallaro-952E6D.00015919112003@netnews.attbi.com>
In article <··············@ID-7776.user.dfncis.de>,
 Dirk Thierbach <··········@gmx.de> wrote:

> The point is that usually one *does not* want to mix different numeric
> types, because the implicit conversions may introduce bugs.

I do it all the time. Fortunately, what you and the B&D fetish designers 
of Haskell think "one *does not* want" are not binding on me (pun 
intended), as I can use lisp.
From: Dirk Thierbach
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <4bpr81-vm.ln1@ID-7776.user.dfncis.de>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote:
> In article <··············@ID-7776.user.dfncis.de>,
> Dirk Thierbach <··········@gmx.de> wrote:

>> The point is that usually one *does not* want to mix different numeric
>> types, because the implicit conversions may introduce bugs.

> I do it all the time. Fortunately, what you and the B&D fetish designers 
> of Haskell think "one *does not* want" are not binding on me (pun 
> intended), as I can use lisp.

And then you are risking to introduce subtle conversion bugs that are
difficult to find and probably won't be covered by your unit
tests. This is exactly the same attitude that lead to the race
condition bug mentioned at the start of the threat. If you want to
shoot yourself in the foot, please feel free to do it, but don't
expect everybody else to agree with you that this silly, mostly
useless and dangerous feature must be present by default.

- Dirk
From: Dirk Thierbach
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <3m1t81-a65.ln1@ID-7776.user.dfncis.de>
Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote:
> Again, you see it as useless, I, and everyone who uses lisp, where this 
> behaviour is the default, see it as useful and reasonable.

Try (= (- 1.3 3/10) 1). Surprised by the result? And you do that all 
the time? Then try 1.3 - (3%10) == 1 in GHCI (you need to import Ratio).

- Dirk
From: Mario S. Mommer
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <fzekw4vva1.fsf@cupid.igpm.rwth-aachen.de>
Dirk Thierbach <··········@gmx.de> writes:
> Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote:
> > Again, you see it as useless, I, and everyone who uses lisp, where this 
> > behaviour is the default, see it as useful and reasonable.
> 
> Try (= (- 1.3 3/10) 1). Surprised by the result? And you do that all 
> the time? Then try 1.3 - (3%10) == 1 in GHCI (you need to import Ratio).

If it writes "true", it is either "lying" to the user by promoting 1.3
to 13/10, or is using a float with base 10. With a standard float

1.3 - 3/10 = 0.99999994 definately different from 1

This is the nature of floating point arithmetic.

Suppose you rewrite the above to

        a - (3%10) == 1

where a is some variable given at run time. Does it still work when
you type in 1.3?
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <pan.2003.11.20.00.11.10.173850@knm.org.pl>
On Wed, 19 Nov 2003 23:38:30 +0100, Mario S. Mommer wrote:

>> Try (= (- 1.3 3/10) 1). Surprised by the result? And you do that all 
>> the time? Then try 1.3 - (3%10) == 1 in GHCI (you need to import Ratio).
> 
> If it writes "true", it is either "lying" to the user by promoting 1.3
> to 13/10, or is using a float with base 10.

Treating 1.3 as 13/10 is obviously not lying. The literal 1.3 when
interpreted as of the type Rational yields exactly 13/10, and interpreted
as Double it's some binary approximation. 1.3 is overloaded over all
numeric types which can represent fractions, it's not more Double than
Rational.

(BTW, Hugs is broken here, it reads decimal fractions as Doubles first;
GHC is correct.)

> Suppose you rewrite the above to
> 
>         a - (3%10) == 1
> 
> where a is some variable given at run time. Does it still work when
> you type in 1.3?

Unfortunately 1.3 can't be read directly as type Rational in the sense
of the standard function 'read' which converts printed representations to
values (there isn't any theoretical reason why it couldn't, it just does
not; the type of a value to be read is known from the context anyway).
Haskell doesn't provide a function to read decimal fractions as rationals
at runtime, you would have to write your own.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Mario S. Mommer
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <fzbrr6rf2x.fsf@cupid.igpm.rwth-aachen.de>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
> On Wed, 19 Nov 2003 23:38:30 +0100, Mario S. Mommer wrote:
> 
> >> Try (= (- 1.3 3/10) 1). Surprised by the result? And you do that all 
> >> the time? Then try 1.3 - (3%10) == 1 in GHCI (you need to import Ratio).
> > 
> > If it writes "true", it is either "lying" to the user by promoting 1.3
> > to 13/10, or is using a float with base 10.
> 
> Treating 1.3 as 13/10 is obviously not lying. The literal 1.3 when
> interpreted as of the type Rational yields exactly 13/10, and interpreted
> as Double it's some binary approximation. 1.3 is overloaded over all
> numeric types which can represent fractions, it's not more Double than
> Rational.

Ok, ok.

While all this is nice, I fear it might be misguided. I wonder what
happens if you would execute, in this setting you describe, the
following (admittedly silly) "program" (sorry, my Haskel is rather
nonexistant).

        a = 1

        do a hundred times
             a <-- 7.8125 * 1/10 * a^2

(warning: this might have unpleasant side effects)

Suppose you have code as the above somewhere in your program, and then
one day you suddenly upgrade to that rational lib you describe. Does
your type checker notice the danger?

> > Suppose you rewrite the above to
> > 
> >         a - (3%10) == 1
> > 
> > where a is some variable given at run time. Does it still work when
> > you type in 1.3?
> 
> Unfortunately 1.3 can't be read directly as type Rational in the sense
> of the standard function 'read' which converts printed representations to
> values (there isn't any theoretical reason why it couldn't, it just does
> not; the type of a value to be read is known from the context anyway).
> Haskell doesn't provide a function to read decimal fractions as rationals
> at runtime, you would have to write your own.

Does 'read' accept 10/13?
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <pan.2003.11.20.21.41.56.639491@knm.org.pl>
On Thu, 20 Nov 2003 20:54:14 +0100, Mario S. Mommer wrote:

>         a = 1
> 
>         do a hundred times
>              a <-- 7.8125 * 1/10 * a^2
> 
> (warning: this might have unpleasant side effects)
> 
> Suppose you have code as the above somewhere in your program, and then
> one day you suddenly upgrade to that rational lib you describe. Does
> your type checker notice the danger?

If you evaluate it in rationals, the numerators and denominators would
go up and the memory will overflow. Such danger is inherent in working
with rationals - I don't think it's the typechecker's job to warn against
it, it's impossible to statically distinguish between safe and unsafe uses
of rationals. It will blow up in Lisp as well if you write 125/16 for
7.8125, and it will give an inaccurate answer with 7.8125 - there is no
perfect solution. In Lisp the way of performing of such computations
depends on the way the literals are written; in Haskell it depends on the
expected type (inferred from the context if not given explicitly inside
the computation).

> Does 'read' accept 10/13?

No, but it accepts 10%13.

You can write 10/13 :: Rational in the source, which is interpreted as
dividing two rationals which yields a rational. % divides two integers
and produces a rational.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Mario S. Mommer
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <fzsmkiy97k.fsf@cupid.igpm.rwth-aachen.de>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
> On Thu, 20 Nov 2003 20:54:14 +0100, Mario S. Mommer wrote:
> 
> >         a = 1
> > 
> >         do a hundred times
> >              a <-- 7.8125 * 1/10 * a^2
> > 
> > (warning: this might have unpleasant side effects)
> > 
> > Suppose you have code as the above somewhere in your program, and then
> > one day you suddenly upgrade to that rational lib you describe. Does
> > your type checker notice the danger?
> 
> If you evaluate it in rationals, the numerators and denominators would
> go up and the memory will overflow. Such danger is inherent in working
> with rationals - I don't think it's the typechecker's job to warn against
> it, it's impossible to statically distinguish between safe and unsafe uses
> of rationals. It will blow up in Lisp as well if you write 125/16 for
> 7.8125, and it will give an inaccurate answer with 7.8125 - there is no
> perfect solution.

I never said there was. Although note carefully that the result you
get with 7.8125 the float is a rather good approximation......

> In Lisp the way of performing of such computations depends on the
> way the literals are written; in Haskell it depends on the expected
> type (inferred from the context if not given explicitly inside the
> computation).

Yes, yes, agreed. What I was asking is, suppose you had some code as
the above. It works, because it converts 7.8125 to float and goes on
from there. Then one day you compile it together with this rational
lib you mention - does the compiler warn you that there has been a
change, and that you might want to rewrite that piece of code?

I ask you because one of the claims made was that static type checking
ensured that changes like that would trigger apropriate errors, so no
piece of code would magically stop working *without warning* because
something changed somewhere else. This one could be a rather nasty
counterexample.
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <pan.2003.11.20.22.45.37.698174@knm.org.pl>
On Thu, 20 Nov 2003 23:19:11 +0100, Mario S. Mommer wrote:

> I ask you because one of the claims made was that static type checking
> ensured that changes like that would trigger apropriate errors, so no
> piece of code would magically stop working *without warning* because
> something changed somewhere else. This one could be a rather nasty
> counterexample.

It works well when used on Doubles and exhausts resources when used on
Rationals. In any system or language you can write a piece of code which
works for some arguments and doesn't work for others, and nobody claims
that if a statically typed piece of code once worked for some arguments,
it will work always for any other arguments. The same happens in Lisp:
you can write a function which uses integers and + - * / which works when
floats are passed as arguments and blows up on rationals.

Erann Gat complained that in OCaml one has to use different arithmetic
operators for different types, and now you complain that in Haskell
the same code can be used for doubles and rationals (with different
performance characteristics of course, which is inherent to these types).
Lispers, please make up your mind :-)

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Darius
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <20031120180202.00002c14.ddarius@hotpop.com>
On Thu, 20 Nov 2003 23:45:58 +0100
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> wrote:

> On Thu, 20 Nov 2003 23:19:11 +0100, Mario S. Mommer wrote:
> 
> > I ask you because one of the claims made was that static type
> > checking ensured that changes like that would trigger apropriate
> > errors, so no piece of code would magically stop working *without
> > warning* because something changed somewhere else. This one could be
> > a rather nasty counterexample.
> 
> It works well when used on Doubles and exhausts resources when used on
> Rationals. In any system or language you can write a piece of code
> which works for some arguments and doesn't work for others, and nobody
> claims that if a statically typed piece of code once worked for some
> arguments, it will work always for any other arguments. 

Of course, you can just tell the compiler that the code only works
properly on finite precision floats.

> The same happens in Lisp:
> you can write a function which uses integers and + - * / which works
> when floats are passed as arguments and blows up on rationals.
> 
> Erann Gat complained that in OCaml one has to use different arithmetic
> operators for different types, and now you complain that in Haskell
> the same code can be used for doubles and rationals (with different
> performance characteristics of course, which is inherent to these
> types). Lispers, please make up your mind :-)
> 
> -- 
>    __("<         Marcin Kowalczyk
>    \__/       ······@knm.org.pl
>     ^^     http://qrnik.knm.org.pl/~qrczak/
> 
From: Dirk Thierbach
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <16e291-fi6.ln1@ID-7776.user.dfncis.de>
Mario S. Mommer <········@yahoo.com> wrote:

>> >         a = 1
>> >         do a hundred times
>> >              a <-- 7.8125 * 1/10 * a^2
>> > 

> Yes, yes, agreed. What I was asking is, suppose you had some code as
> the above. It works, because it converts 7.8125 to float and goes on
> from there. Then one day you compile it together with this rational
> lib you mention - does the compiler warn you that there has been a
> change, and that you might want to rewrite that piece of code?

Yes. If you want a float here, you have to insert 'fromRational'
as in

f a = 7.8125 * fromRational (1%10) * a^2

result = iterate f 1 !! 100

and you have to explicitely declare somewhere in your program
that you want to use a float, for example by

result :: Float

If you decide later that you want a Double everywhere instead of a Float,
just change that to

result :: Double

You don't have to change anything else, as you would have to in C or Java.
And if you wanted to use floats instead of rationals in the first place,
you just use 1/10 instead of 1%10.

- Dirk
From: Jesse Tov
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <slrnbrvfrk.4ug.tov@tov.student.harvard.edu>
Mario S Mommer <········@yahoo.com>:
> Then one day you compile it together with this rational
> lib you mention - does the compiler warn you that there has been a
> change, and that you might want to rewrite that piece of code?

I think maybe it's been unclear for non-Haskellers in this thread that the
rationals aren't in some separate library.  The type Rational is in the
standard library, but you might have to import part of it to get extra
functions for working with Rationals.  I didn't load anything extra here:
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.0.1, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base ... linking ... done.
Prelude> 2/3
0.6666666666666666
Prelude> 2/3 :: Rational
2 % 3
Prelude> (2::Rational)/3
2 % 3
Prelude> (2::Double)/(3::Rational)

<interactive>:1:
    Couldn't match `Double' against `Rational'
        Expected type: Double
        Inferred type: Rational
    When checking the type signature of the expression: 3 :: Rational
    In the second argument of `(/)', namely `(3 :: Rational)'


What's going on here is the term "2/3" is treated differently depending
on what type information I give, but there's no library that I could link
against that would change its meaning.  In a program, if I were to write
   b = 1/3
the type of b would be determined by how it's used, but it definitely
won't change in pathological ways.

Jesse
From: ··········@ii.uib.no
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <egad6rmj2h.fsf@sefirot.ii.uib.no>
Mario S. Mommer <········@yahoo.com> writes:

> This is the nature of floating point arithmetic.

Surely you agree that the result is mathematically incorrect?

> Suppose you rewrite the above to
> 
>         a - (3%10) == 1
> 
> where a is some variable given at run time. Does it still work when
> you type in 1.3?

Yes it does:

  Prelude Ratio> let test a = a - (3%10) == 1
  Prelude Ratio> test 1.3
  True

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
From: Dirk Thierbach
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <70mu81-o31.ln1@ID-7776.user.dfncis.de>
Mario S. Mommer <········@yahoo.com> wrote:
> Dirk Thierbach <··········@gmx.de> writes:
>> Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote:
>> > Again, you see it as useless, I, and everyone who uses lisp, where this 
>> > behaviour is the default, see it as useful and reasonable.
>> 
>> Try (= (- 1.3 3/10) 1). Surprised by the result? And you do that all 
>> the time? Then try 1.3 - (3%10) == 1 in GHCI (you need to import Ratio).

> If it writes "true", it is either "lying" to the user by promoting 1.3
> to 13/10, 

That's what it does, However, it is not lying to the user, it is
converting the literal to the most apropriate type -- in this case,
a rational number. If I had used transcendental functions in this
example, then it would have converted it to a real number.

> Suppose you rewrite the above to
> 
>        a - (3%10) == 1
> 
> where a is some variable given at run time. Does it still work when
> you type in 1.3?

Yes, and it will even explain you why it does so, because the type checker
will infer that the type of 'a' is rational (actually, it will get a 
more general type, but that's beside the point at the moment).

Floats have limited precision. They behave very different than integers
or rationals with unlimited precision. So you want to have control over
when your program uses the one, and when it uses the other. A flexible
polymorphic static type system gives you that kind of control, while
at the same time allowing to use the same code for different kinds of
numbers, if you want.

Automatic conversion, OTOH, means that if I type by accident 1.0
instead of 1 in some part of the program, a completely different part
of the program might fail. And if it does, I'll have to do a very
long debugging session to find the bug. 

Raffael usually doesn't encounter this kind of errors, because in
normal applications, you don't mix integers and floats wildly. And in
the few cases where you do, it doesn't hurt to manually insert a
conversion. As with uniformly and non-uniformly used lists, you
normally have a clear idea what is the correct thing for your current
task. And refusing to think about those issues, for no other reason
because you don't *want* to think about them (especially if you can
offload the boring part to the typechecker -- if there's no problem,
you won't even notice it) is irresponsible and sloppy. It's like not
thinking about possible race conditions when using threads, and just
doing the first thing that comes to mind.

- Dirk
From: Mario S. Mommer
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <fz3cci7ve7.fsf@cupid.igpm.rwth-aachen.de>
Dirk Thierbach <··········@gmx.de> writes:
> > Suppose you rewrite the above to
> > 
> >        a - (3%10) == 1
> > 
> > where a is some variable given at run time. Does it still work when
> > you type in 1.3?
> 
> Yes, and it will even explain you why it does so, because the type checker
> will infer that the type of 'a' is rational (actually, it will get a 
> more general type, but that's beside the point at the moment).

Interesting - somebody else comented that this isn't the case, but
whatever. I think it would have been more reasonable to add base 10
floats. It would have the same effect, but you would not loose the
good properties of floating point numbers.

> Floats have limited precision. They behave very different than integers
> or rationals with unlimited precision. So you want to have control over
> when your program uses the one, and when it uses the other. A flexible
> polymorphic static type system gives you that kind of control, while
> at the same time allowing to use the same code for different kinds of
> numbers, if you want.

I have control over these things without a static type system. Must be
that I have superpowers.

> Automatic conversion, OTOH, means that if I type by accident 1.0
> instead of 1 in some part of the program, a completely different part
> of the program might fail. And if it does, I'll have to do a very
> long debugging session to find the bug. 

I wonder what is wrong that this happens to you so often.

> Raffael usually doesn't encounter this kind of errors, because in
> normal applications, you don't mix integers and floats wildly. And in
> the few cases where you do, it doesn't hurt to manually insert a
> conversion.

You would have to insert the conversion that the compiler would have
inserted anyway (no gain) or a different one (I have to do that too).

> As with uniformly and non-uniformly used lists, you
> normally have a clear idea what is the correct thing for your current
> task. And refusing to think about those issues, for no other reason
> because you don't *want* to think about them

Why do you asume that there is no other reason? My experience shows me
that not taking these decissions does not cause me any grief, and is
extremely cool if late in the game I want to change something.

> (especially if you can
> offload the boring part to the typechecker -- if there's no problem,
> you won't even notice it)

Since to be able to do that, it seems, I have to abandon CLs
incredibly powerfull dynamism, I would certainly notice. In fact, it
would be a great loss for me. Just to buy me some dubious security.

> is irresponsible and sloppy.

Oh please. So if I disagree with you it is because i'm irresponsible
and sloppy?

> It's like not thinking about possible race conditions when using
> threads, and just doing the first thing that comes to mind.

You must be kidding. This is like saying that driving a bike without a
helmet is like manipulating gasoline while smoking.
From: Dirk Thierbach
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <jad291-fi6.ln1@ID-7776.user.dfncis.de>
Mario S. Mommer <········@yahoo.com> wrote:
> Dirk Thierbach <··········@gmx.de> writes:
>> > Suppose you rewrite the above to
>> > 
>> >        a - (3%10) == 1
>> > 
>> > where a is some variable given at run time. Does it still work when
>> > you type in 1.3?
>> 
>> Yes, and it will even explain you why it does so, because the type checker
>> will infer that the type of 'a' is rational (actually, it will get a 
>> more general type, but that's beside the point at the moment).

> Interesting - somebody else comented that this isn't the case, but
> whatever. 

Main> let f a = a - 3%10 == 1
Main> :t f
forall a. (Num (Ratio a), Integral a) => Ratio a -> Bool
Main> f 1.3
True

> I think it would have been more reasonable to add base 10
> floats. It would have the same effect, but you would not loose the
> good properties of floating point numbers.

That's no problem. Write the library, and you can have base 10 floats,
too.

> I have control over these things without a static type system. 

I doubt you have.

>> Automatic conversion, OTOH, means that if I type by accident 1.0
>> instead of 1 in some part of the program, a completely different part
>> of the program might fail. And if it does, I'll have to do a very
>> long debugging session to find the bug. 

> I wonder what is wrong that this happens to you so often.

It doesn't happen to me, for obvious reasons :-) And it doesn't happen
to you, for the same reason as given below:

>> Raffael usually doesn't encounter this kind of errors, because in
>> normal applications, you don't mix integers and floats wildly.

The point I am trying to make is that the need to mix different types
of numbers is by far not as important as the dynamic typers seem to
think.

>> And in the few cases where you do, it doesn't hurt to manually
>> insert a conversion.

> You would have to insert the conversion that the compiler would have
> inserted anyway (no gain) or a different one (I have to do that too).

The gain is that the compiler says: Think. Here you convert an integer
to a float, and you may loose precision. Is that really what you want?
If yes, just type in the conversion function (or maybe use a conversion
function that checks for loss of digits). If no, you should rethink
your code.

>> As with uniformly and non-uniformly used lists, you
>> normally have a clear idea what is the correct thing for your current
>> task. And refusing to think about those issues, for no other reason
>> because you don't *want* to think about them

> Why do you asume that there is no other reason? My experience shows me
> that not taking these decissions does not cause me any grief, and is
> extremely cool if late in the game I want to change something.

And my experience shows me that I very seldom feel the need to mix
numeric types, so the absence of an automatic conversion feature
doesn't hurt me. And, with polymorphic types and type classes, I can
still change everything late in the game, if I want to -- after all,
type inference is automatic.

So while I agree that have to take these choices in static type systems
like C++ and Java definitely hurts a lot, and I don't like it there, 
either, I really don't see what you loose compared to a system like
Haskell's.

>> (especially if you can offload the boring part to the typechecker
>> -- if there's no problem, you won't even notice it)

> Since to be able to do that, it seems, I have to abandon CLs
> incredibly powerfull dynamism, I would certainly notice. In fact, it
> would be a great loss for me. Just to buy me some dubious security.

The point I am trying to make is that it doesn't hurt as much as you
would think. OTOH, by observation, the first thing that the Lispers
seem to do is to try to mix different numeric types, and then
complain loudly when it doesn't work.

I just cannot get it into my head why it should be such an important
feature.

>> It's like not thinking about possible race conditions when using
>> threads, and just doing the first thing that comes to mind.

> You must be kidding. This is like saying that driving a bike without a
> helmet is like manipulating gasoline while smoking.

It's certainly a different severity, but it's the same *attitude*: You
just put your head in the sand, and you start complaining and see it
as a burden if someone (for example the type checker) reminds you that
you might get a problem at this and this place in your code, instead
of thinking about it for a few seconds.

- Dirk
From: Mario S. Mommer
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <fzk75phgfh.fsf@cupid.igpm.rwth-aachen.de>
Dirk Thierbach <··········@gmx.de> writes:
> > I have control over these things without a static type system. 
> 
> I doubt you have.

:-)) What I do not doubt is that you haven't got an idea.

> It doesn't happen to me, for obvious reasons :-) And it doesn't happen
> to you, for the same reason as given below:

First of all, I deal a lot with numbers. These errors you seem to
loathe _never_ happen to me. Other errors - yes. But your type checker
would be blind to them.

> The point I am trying to make is that the need to mix different types
> of numbers is by far not as important as the dynamic typers seem to
> think.

Mixing integers and rationals should not pose any problem at all. The
correct behavior here is reserved for the dynamic type system; it is
impossible to implement reliably in a static framework. This is just
an example, and its importance lies in the fact that it illustrates
the fundamental weakness of any type system, dynamic or otherwise: it
is dumb. A dynamic type system has advantages here simply because it
acts on real behavior it can measure and not on alleged or suspected
behavior.

> The gain is that the compiler says: Think. Here you convert an integer
> to a float, and you may loose precision. Is that really what you want?
> If yes, just type in the conversion function (or maybe use a conversion
> function that checks for loss of digits). If no, you should rethink
> your code.

If for this trick I have to give up CLs flexibility, this is not a
gain but a huge loss. Besides: you are wrong if you think that you are
not losing precision only because all your numbers are of the same
type.

> So while I agree that have to take these choices in static type systems
> like C++ and Java definitely hurts a lot, and I don't like it there, 
> either, I really don't see what you loose compared to a system like
> Haskell's.

Flexibility. People have said it is absolutely impossible to
"retrofit" CL with static typing, unless you throw away lots of
flexibility (no wonder. Since when is 'static' a synonym for
'flexible'?). So, if you prefer a static type system, then go ahead
and use one, but please stop telling me what to do.

It might also be an illuminating experience for you to go over to
comp.lang.python and ask them why they don't just use Haskell. Who
knows, maybe they'll flock in masses to Haskell once you convince them
that they urgently need some discipline.

> > Since to be able to do that, it seems, I have to abandon CLs
> > incredibly powerfull dynamism, I would certainly notice. In fact, it
> > would be a great loss for me. Just to buy me some dubious security.
> 
> The point I am trying to make is that it doesn't hurt as much as you
> would think. OTOH, by observation, the first thing that the Lispers
> seem to do is to try to mix different numeric types, and then
> complain loudly when it doesn't work.

With exact types it works perfectly well in CL. Automatically. It does
not work so in Haskell. And with exact and inexact types there are
clear and obvious semantics. Why prohibit them? Just because some
people are paranoid?

Your type system would refuse to let me write

        4*pi/3;

which is not wrong in any sense (and please don't come with "but you
could have written it '4.0*pi/3.0' in Haskell" - I do not want to be
jumping over stupid limitations all the time), but would not object to
something like

double norm (double x,double y) {
        return 1.0/(x^2-x-2.0);
}

where the denominator might eventually become zero and trigger a
thermonuclear disaster [1].

*I* do not want the kind of type system you advocate: It just annoys
me, it takes flexibility away from me, and it's help is
insignificant. It amounts to an intrusive version of ms-clippy.

---

[1] Now /that's/ a line of argumentation you can relate with.
From: Tomasz Zielonka
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <slrnbs4es0.r5d.t.zielonka@zodiac.mimuw.edu.pl>
Mario S Mommer wrote:
> 
> Your type system would refuse to let me write
> 
>         4*pi/3;

> which is not wrong in any sense (and please don't come with "but you
> could have written it '4.0*pi/3.0' in Haskell" - I do not want to be
> jumping over stupid limitations all the time) 

You can write 4*pi/3 in Haskell. It's perfectly OK. You are probably
confusing it with OCaml.

Best regards,
Tom

-- 
.signature: Too many levels of symbolic links
From: Dirk Thierbach
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <2vba91-l3a.ln1@ID-7776.user.dfncis.de>
Mario S. Mommer <········@yahoo.com> wrote:

> Dirk Thierbach <··········@gmx.de> writes:
>> > I have control over these things without a static type system. 

>> I doubt you have.

> :-)) What I do not doubt is that you haven't got an idea.

So how do you control it?

> Mixing integers and rationals should not pose any problem at all. 

Yes.

> The correct behavior here is reserved for the dynamic type system;
> it is impossible to implement reliably in a static framework.

Excuse me, but this is nonsense. It's easy to write a library
that introduces a new type that mixes rationals and integers and
autoconverts when necessary. There's a reason no such library
exists as a standard: It works fine without it; but if you insist
you have to use one, that's no problem.

> This is just an example, and its importance lies in the fact that it
> illustrates the fundamental weakness of any type system, dynamic or
> otherwise: it is dumb. 

It's smart enough to do the dumb work for me.

> A dynamic type system has advantages here simply because it acts on
> real behavior it can measure and not on alleged or suspected
> behavior.

Hu? I have no idea what you're talking about.

[Using the type system to point out "dubious" parts of the program
> If for this trick I have to give up CLs flexibility, 

No, you haven't.

> Besides: you are wrong if you think that you are not losing
> precision only because all your numbers are of the same type.

I don't think that, and I never said I did. 

>> So while I agree that have to take these choices in static type systems
>> like C++ and Java definitely hurts a lot, and I don't like it there, 
>> either, I really don't see what you loose compared to a system like
>> Haskell's.

> Flexibility. 

No, you don't.

> People have said it is absolutely impossible to "retrofit" CL with
> static typing, unless you throw away lots of flexibility

No. They have said it is impossible to "retrofit" CL with a good
static typing unless you change lots of details of the language, 
because CL was not designed with static typing in mind. This is
completely independent of flexibility.

> So, if you prefer a static type system, then go ahead and use one,
> but please stop telling me what to do.

I never told you what to do. I fact, I have repeatedly said that I
don't want anyone to convert from CL to any other language (please
look it up.) All I want is to make people rethink that with static
typing, you don't automatically "loose flexibility", "have to do a lot
of extra work to please the compiler", etc.

> It might also be an illuminating experience for you to go over to
> comp.lang.python and ask them why they don't just use Haskell. Who
> knows, maybe they'll flock in masses to Haskell once you convince them
> that they urgently need some discipline.

Again: I don't want to convert anyone to use any other language.

> Your type system would refuse to let me write
> 
>        4*pi/3;

It doesn't. 

> *I* do not want the kind of type system you advocate: It just annoys
> me, 

That may be true, but from your arguments so far, it seems to annoy
you mostly because you don't understand it.

> it takes flexibility away from me, and it's help is insignificant.

No on both points.

> It amounts to an intrusive version of ms-clippy.

If it helps you, I hate ms-clippy, and the way static typing works
in C++ or Java annoys me, it takes flexibility from me, and it's
help is insignificant there. I do share your experiences in this
respect, and I also share your experiences that dynamic typing in
Lisp is a good way to get rid of them.

Why is it so hard to even *imagine* that there might be a way to
make a static typing system that still gives you (almost) all the
flexibility of dynamic typing, with (almost) no costs? 

From the number of false statements made above I slowly suspect
that you don't even want to *listen* to what is actually said.

- Dirk
From: Mario S. Mommer
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <fzekvwpasl.fsf@cupid.igpm.rwth-aachen.de>
Dirk Thierbach <··········@gmx.de> writes:
> Mario S. Mommer <········@yahoo.com> wrote:
> > Dirk Thierbach <··········@gmx.de> writes:
> >> > I have control over these things without a static type system. 
> >> I doubt you have.
> > :-)) What I do not doubt is that you haven't got an idea.
> So how do you control it?

I tell the computer what to do and it does it. You may call it
intimidation if you want.

> > The correct behavior here is reserved for the dynamic type system;
> > it is impossible to implement reliably in a static framework.
> 
> Excuse me, but this is nonsense. It's easy to write a library
> that introduces a new type that mixes rationals and integers and
> autoconverts when necessary.

So I have to write a library to get behavior I get somewhere else for
free, and only to make your compiler happy. Besides, laboriously
writing a dynamic type system on top of a static one and then saying
"you see? no problem" is not very convincing.

> There's a reason no such library exists as a standard: It works fine
> without it; but if you insist you have to use one, that's no
> problem.

Having to write a library for it hardly qualifies as "no problem". I
think it is more plausible that those who value such a feature are
using dynamic languages instead.

> > Your type system would refuse to let me write
> > 
> >        4*pi/3;
> 
> It doesn't. 

Others have already commented that this would be illegal in OCaml, and
only works in Haskell because it parses the above "4" as 4.0. So if n
is an integer,

n*pi

seems to be an "error" there too, which is the kind of behavior I
thought you were advocating. If not, then please excuse the
misunderstanding.

> > it takes flexibility away from me, and it's help is insignificant.
> 
> No on both points.

It might well be that you do not value any flexibility beyond what a
statically typed language would give you, and thus the loss of
flexibility would not matter /to you/. It might well be that for some
reason you really need something constantly overlooking every move you
make so you don't get into any possibly conceivable or inconceivable
trouble at all, so /for you/ the help is significant. I do not need
your permission to have a different take on this.
From: Pascal Bourguignon
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <87n0asq8q1.fsf@thalassa.informatimago.com>
Dirk Thierbach <··········@gmx.de> writes:

> Raffael Cavallaro <················@junk.mail.me.not.mac.com> wrote:
> > Again, you see it as useless, I, and everyone who uses lisp, where this 
> > behaviour is the default, see it as useful and reasonable.
> 
> Try (= (- 1.3 3/10) 1). Surprised by the result? And you do that all 
> the time? Then try 1.3 - (3%10) == 1 in GHCI (you need to import Ratio).

Personnaly, I'm not  surprized. 1.3 is a figment  of your imagination.
13/10 is real, and: (= (- 13/10 3/10) 1) is T.

Now we could  advocate for the abolition of  floating point numbers in
Common-Lisp  and have  the reader  produce rationals  for  all strings
matching "[0-9]+.[0-9]+" NAFS(*).




(*): Not A Formal Specification, you would take into account the input
     base, and the "E[-+]?[0-9]+" suffixes (but there would be no need
     for a "D" suffix.

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
From: Joachim Durchholz
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <bpfrgc$a2j$1@news.oberberg.net>
Raffael Cavallaro wrote:
> I do it all the time. Fortunately, what you and the B&D fetish
> designers of Haskell think "one *does not* want" are not binding on
> me (pun intended), as I can use lisp.

If you want to do name calling ("B&D fetish designers of Haskell", 
indeed...), please go to the advocacy groups. comp.lang.* groups are for 
explaining and understanding things; if you're disinterested in 
understanding the issues raised in a given thread, this thread isn't 
interesting for you.
Even more relevantly, your flames are uninteresting to your audience, 
and you're wasting their time.

Regards,
Jo
From: Raffael Cavallaro
Subject: Re: Why I don't believe in static typing
Date: 
Message-ID: <raffaelcavallaro-E8F9DB.14493219112003@netnews.attbi.com>
In article <············@news.oberberg.net>,
 Joachim Durchholz <·················@web.de> wrote:

> Raffael Cavallaro wrote:
> > I do it all the time. Fortunately, what you and the B&D fetish
> > designers of Haskell think "one *does not* want" are not binding on
> > me (pun intended), as I can use lisp.

this bit here ^^^^^^^ signals that I was writing a joke. Sorry if that 
wan't clear.