Version française
Home     About     Download     Resources     Contact us    
Browse thread
Estimating the size of the ocaml community
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jon Harrop <jon@j...>
Subject: Re: [Caml-list] The boon of static type checking
On Friday 04 February 2005 02:56, Michael Walter wrote:
> On Fri, 4 Feb 2005 02:33:40 +0000, Jon Harrop <jon@jdh30.plus.com> wrote:
> > The last time I made such a change it took a day to get
> > the program working again, rather than a month.
>
> Are you using heavy casting and such without proper abstractions in
> your C++ code?

No. The code is freely available here:

http://www.chem.pwf.cam.ac.uk/~jdh30/programming/opengl/smoke/index.html

> Pr what kind of changes did you want to make?

IIRC, one development was to change the core data structure from a list to a 
tree. The code to implement a simple tree is unwieldy in C++ (e.g. 1975 LOC 
in stl_tree.h and stl_map.h vs 198 LOC in map.ml). My ocaml implementation 
uses trees and graphs throughout now.

> How did  
> you feel that the static type checker of C++ didn't provide you with
> similar help?

As the C++ type system cannot represent (and, therefore, statically check) 
polymorphism properly, altering a generic data structure expressed using 
templates results in reams of errors, mostly pointing to wrong places. In 
contrast, the worst I get with ocaml is an error in the wrong place because a 
previous function has been inferred to have a wrong type. Even this problem 
is much less common and trivial to trace. Also, it would be even easier to 
solve with an IDE which threw up the inferred types.

As the C++ type system cannot represent (and, therefore, statically check) 
modules and variant types, shoehorning solutions into using class hierarchies 
and being forced to use pointers results in verbose code and weaker type 
checking. In contrast, the equivalent ocaml code is succinct and thoroughly 
checked. This brevity can also be attributed to the ability to pattern match.

Obviously such problems would have been virtually impossible to weed out had I 
chosen to use a language with dynamic type checking, which is precisely I why 
I left such languages at the door many years ago...

> > I'm not sure what "multiple-value-bind" is. I'd have guessed "let a, b, c
> > = 1, 2, 3".
>
> It's a macro in Common Lisp (see [1]). In O'caml-ish syntax, it also
> does "let a, b = 1, 2, 3" (3 is discarded) and "let a, b, c = 1, 2" (c
> is bound to nil).

These seem pretty pointless to me, but what about:

# let {a=a; b=b; c=_} = expr;;

or

# let x = expr in
  ... x.a ... x.b ...;;

and then

# let (a, b), c = expr, None;;

(if you must).

On Friday 04 February 2005 09:29, Thomas Fischbacher wrote:
> If I multiply a speed (in m/s) with a mass (in kg)...

Yes, absolutely! I believe you have correctly identified dimensionality as a 
very important and useful system of (phantom) types used in physics. The 
OCaml type system goes some way to allowing such things to be enforced. 
Dynamically typed languages do not. So how can you come to the conclusion 
than going from dynamic typing to OCaml's static typing is a step in the 
wrong direction?

> So it's even more than "just returning more than one value without having
> to cons" (which already is quite nice - but this essentially can always be
> emulated via going to CPS, which establishes full call/return symmetry).
> It's about giviny gou extra choice. Either: "Nice that you can also
> provide me extra information, but I really don't care here", or: "I can
> as well make use of this other piece of information which you
> already obtained anyway." Same function, same call.

Sure, but what's wrong with using fst and snd for pairs, and records instead 
of n-tuples? You get the same functionality and an explicit definition of 
what is happening with only a couple of extra key strokes.

> > Use the top-level.
>
> That entirely misses the point!
>
> I talked about getting debug traces from an involved run.

Which you can do from the top level. If you have to output the information 
from a running, native-code compiled binary then write the print and 
string_of functions yourself:

let string_of_list f l = "["^String.concat "; " (List.map f l)^"]"
let string_of_pair f (a, b) = "("^f a^", "^f b^")"
print_endline (string_of_list (string_of_pair string_of_int) x)

Considering the first two can be factored out of a wide variety of programs, 
it really isn't a huge amount of typing...

On Friday 04 February 2005 09:41, you wrote:
> On Fri, Feb 04, 2005 at 02:33:40AM +0000, Jon Harrop wrote:
> > 5. More pattern matching: [|1; 2; ...|] and [|...; 2; 1|]. (expressivity)
>
> And this pattern which could be used all the time in web programming:
>  | "prefix" ^ str ->
>
> 8. Regular expressions in the language!

Nooo! Got to stick to O(1) pattern matching, so you are allowed either of:

| "prefix" ^ ... -> expr
| ... ^ "suffix" -> expr

but neither of your suggestions. :-)

9. Complex number notation.

On Friday 04 February 2005 09:36, Thomas Fischbacher wrote:
> On Fri, 4 Feb 2005, Ville-Pertti Keinonen wrote:
> > As an obvious example, neither Common Lisp or Scheme have
> > pattern-matching.  Accessing data via pattern matching is often far more
> > convenient than via c[ad]+r, slot accessors etc.
>
> Sure! But Lisp gives me the freedom to add it via a library. Which also
> kind of says that it's unnecessary to complicate the core language by
> putting in such a conceptually ad-hoc feature.

That's obviously completely wrong and a blatant troll so I'll stop replying 
now.

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.