caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Easy solution in OCaml?
@ 2003-04-25  6:05 Siegfried Gonzi
  2003-04-25  8:19 ` sebastien FURIC
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Siegfried Gonzi @ 2003-04-25  6:05 UTC (permalink / raw)
  To: caml-list

Hi:

First off: It is not homework. I am 29 and writing my PhD in physics. 
Often I am contemplating whether it would be possible to use OCaml in 
combination with my beloved Bigloo to perform statistical evaluations. I 
am not sure whether there are any out there who /can/ do this 
evaluations with OCaml what you normally would do with Matlab. The 
problem what arises: type system and working against the compiler. In 
Scheme changing a solution from lets say integer-array to double-array 
is easy, but in Clean for example you would have to change all your 
dependencies.
I often skim over the libraries and came to the conclusion: C, C++, 
OCaml impossible for me to see any elegance; Clean a bit better; 
Bigloo/Scheme: I am not sure here, because everything looks the same 
maybe this is cheating, but I think it looks the most elegant and less 
intimitating from all.


Rationale: given a list of 12 month.  I would like to calculate the 
quarterly means and skip any nan. Easy? Yes it is but only on paper and 
in Scheme:

e.g: [1,2,4,-1,45,56,45,56,8]

nan=-1.0

result: [(1+2+3)/3, (45+56)/2, (45+56+8)/3]

I wrote a program in Scheme in order to perform the aformentioned task. 
In Scheme I wrote it as functional as possible, but I fail to do this in 
Ocaml. I mean doing it in OCaml via loops would be straightforward, but 
I didn't succeed in coming up with a solution of:

- relies on pattern matching?
- is short and and shouldn't resemble imperative style

Currently I do not have Clean installed, but I think I would have no 
problems to do the above requirement in Clean. I find the following 
irritating in OCaml:

- why if-then constructs? I think this was called "guards" in Clean? Can 
I use block-structure instead? I hate blocks ala Python but never mind 
to use it in Clean's way.
- why begin-end constructs? In Scheme begin-end constructs are ordinary, 
but I find it irritating to use it in OCaml.
- is it possible to give type information for readbility. In Clean I 
often wroten upon entry of the function:

sum:: Int Real -> Int
sum a b = ...

The above is not provocating. I learn best when I see how other would 
solve it in an /elegant functional way/.

Regards,
S. Gonzi

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-25  6:05 [Caml-list] Easy solution in OCaml? Siegfried Gonzi
@ 2003-04-25  8:19 ` sebastien FURIC
  2003-04-25 15:46 ` Brian Hurt
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 17+ messages in thread
From: sebastien FURIC @ 2003-04-25  8:19 UTC (permalink / raw)
  To: Siegfried Gonzi; +Cc: OCaml Mailing list

 Hi Siegfried,

 I wrote the following Ocaml program that performs the task using
functors.
 The "interresting stuff" is in module Means: It computes the means
given rules you define into the NUMERICTYPE module you pass to the
functor. As you can see, there is no need to change the code even if you
change your numeric type or the meaning of is_nan, zero, one, + and /.

 module type NUMERICTYPE =
  sig
     type t
     val is_nan: t -> bool
     val zero: t
     val one: t
     val ( + ): t -> t -> t
     val ( / ): t -> t -> t
   end

 module type MEANS =
  sig
    type t
    val quarterly_means: t list -> t * t * t * t
  end

 module Means(NumericType : NUMERICTYPE) : (MEANS with type t =
NumericType.t) =
  struct
    open NumericType
    type t = NumericType.t
    let mean xs =
      let rec mean' sum n = function
        | [] -> sum / n
        | x :: xs when is_nan x -> mean' sum n xs
        | x :: xs -> mean' (sum + x) (n + one) xs
      in mean' zero zero xs
    let quarterly_means = function
      | [a; b; c; d; e; f; g; h; i; j; k; l] ->
        mean [a; b; c], mean [d; e; f], mean [g; h; i], mean [j; k; l]
      | _ -> failwith "quarterly_means: 12 months expected"
  end

(* tests *)
module Integer =
  struct
     type t = int
     let is_nan i = i = -1
     let zero = 0
     let one = 1
     let ( + ) = ( + )
     let ( / ) = ( / )
   end
;;

module Float =
  struct
     type t = float
     let is_nan f = classify_float f = FP_nan
     let zero = 0.0
     let one = 1.0
     let ( + ) = ( +. )
     let ( / ) = ( /. )
   end
;;

module MeansInteger = Means(Integer);;
MeansInteger.quarterly_means
  [1; 2; 4; -1; 45; 56; 45; 56; 8; 10; 30; 5];;

module MeansFloat = Means(Float);;
MeansFloat.quarterly_means
  [1.0; 2.0; 4.0; 0.0 /. 0.0; 45.0; 56.0; 45.0; 56.0; 8.0; 10.0; 30.0;
5.0];;

 Cheers,

 Sébastien.

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-25  6:05 [Caml-list] Easy solution in OCaml? Siegfried Gonzi
  2003-04-25  8:19 ` sebastien FURIC
@ 2003-04-25 15:46 ` Brian Hurt
  2003-04-25 16:34   ` Ville-Pertti Keinonen
  2003-04-26 13:45   ` Siegfried Gonzi
  2003-04-25 16:59 ` [Caml-list] Easy solution in OCaml? Markus Mottl
  2003-04-28 17:45 ` malc
  3 siblings, 2 replies; 17+ messages in thread
From: Brian Hurt @ 2003-04-25 15:46 UTC (permalink / raw)
  To: Siegfried Gonzi; +Cc: caml-list

On Fri, 25 Apr 2003, Siegfried Gonzi wrote:

> Hi:
> 
> First off: It is not homework. I am 29 and writing my PhD in physics. 
> Often I am contemplating whether it would be possible to use OCaml in 
> combination with my beloved Bigloo to perform statistical evaluations. I 
> am not sure whether there are any out there who /can/ do this 
> evaluations with OCaml what you normally would do with Matlab. The 
> problem what arises: type system and working against the compiler. In 
> Scheme changing a solution from lets say integer-array to double-array 
> is easy, but in Clean for example you would have to change all your 
> dependencies.

I find that if you're working against the compiler, either a) you haven't 
thought the problem through, b) there's an easy solution you're missing, 
or c) you have a bug.

Converting, at run time, from a list of ints to a list of floats is 
trivial in Ocaml:  just do:

let convert_int_list_to_float_list = List.map float_of_int ;;

A similiar function for arrays using Array.map is easy as well.  Note that 
at run time, you have to go through and transform each element (that's 
what List.map does).  You have to do this in any language, because to the 
machine floats are not ints.  Some languages just hide this from you, but 
you have to do it sooner or later anyways.

> I often skim over the libraries and came to the conclusion: C, C++, 
> OCaml impossible for me to see any elegance; Clean a bit better; 
> Bigloo/Scheme: I am not sure here, because everything looks the same 
> maybe this is cheating, but I think it looks the most elegant and less 
> intimitating from all.
> 

One man's elegance is another man's ugliness.  Got to agree with you about 
the C and C++ libraries, though.

> 
> Rationale: given a list of 12 month.  I would like to calculate the 
> quarterly means and skip any nan. Easy? Yes it is but only on paper and 
> in Scheme:
> 
> e.g: [1,2,4,-1,45,56,45,56,8]
> 
> nan=-1.0
> 
> result: [(1+2+3)/3, (45+56)/2, (45+56+8)/3]

let rec sum3 lst =
    match lst with
        [] -> []
        | a :: b :: c :: t -> 
            let s = (if a >= 0 then a else 0) +
                    (if b >= 0 then b else 0) +
                    (if c >= 0 then c else 0)
            and k = (if a >= 0 then 1 else 0) +
                    (if b >= 0 then 1 else 0) +
                    (if c >= 0 then 1 else 0)
            in
               (* Since we're only dealing with 12 months, it's OK not to
                  be tail recursive *)
               (s/k) :: (sum3 t)
        | _ -> assert false (* list is not a multiple of 3 in length *)

Or you could use List.fold_left and an internal function.  Which has the 
advantage of being parameterizable:

let sumN numElems lst =
    let foldfunc = fun (accum, sum, cnt, tot) elem ->
        if (elem >= 0) then
            if (cnt == numElems) then
                if (tot == 0) then
                    ( ( 0 :: accum ), elem, 1, 1 )
                else
                    ( ( (sum/tot) :: accum ), elem, 1, 1)
            else
                ( accum, sum + elem, cnt + 1, tot + 1 )
        else
            if (cnt == numElems) then
                if (tot == 0) then
                    ( ( 0 :: accum ), 0, 1, 0 )
                else
                    ( ( (sum/tot) :: accum ), 0, 1, 0)
            else
                ( accum, sum, cnt + 1, tot )
    in
    let res = List.fold_left foldfunc ([], 0, 0, 0) lst
    in
    match res with
        (accum, sum, cnt, tot) ->
            if (tot > 0) then
                List.rev ( (sum/tot) :: accum )
            else
                List.rev ( 0 :: accum )
;;


> - why if-then constructs? I think this was called "guards" in Clean? Can 
> I use block-structure instead? I hate blocks ala Python but never mind 
> to use it in Clean's way.

Gaurds can be used in Ocaml as well- at least, we have something called 
(IIRC) gaurds, used in pattern matching.

> - why begin-end constructs? In Scheme begin-end constructs are ordinary, 
> but I find it irritating to use it in OCaml.

Begin/end are generally only used to solve shift/reduce conflicts to 
reduce (dangling elses, and in a few other places).

> - is it possible to give type information for readbility. In Clean I 
> often wroten upon entry of the function:

Yep.  You can either give type information peicemeal, using parens, like:
    let sum (x : int) (y : float) = x + (int_of_float y)
(which says foo takes two parameters- an int and a float), or for the 
whole function:
    let sum : int -> float -> int = fun x y -> x + (int_of_float y)

This is usefull for two reasons, in my experience: sometimes, it lets the 
compiler produce better code (for example, consider the function:
let foo x y = x == y
If you know that x and y will always be integers, doing:
let foo (x:int) (y:int) = x == y
allows the compiler to inline integer equals, rather than calling the 
generic compare function- much faster).

The other use is to nail down annoying type errors.  This lets you tell 
the compiler what type something *should* be, and then see where the type 
errors occur.  But generally, you can just let type inference do it's job, 
for example:

let sum x y = x + (int_of_float y)

gets the right type inferred without effort.

Hope this helps.

Brian


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-25 15:46 ` Brian Hurt
@ 2003-04-25 16:34   ` Ville-Pertti Keinonen
  2003-04-26 13:45   ` Siegfried Gonzi
  1 sibling, 0 replies; 17+ messages in thread
From: Ville-Pertti Keinonen @ 2003-04-25 16:34 UTC (permalink / raw)
  To: Brian Hurt; +Cc: Siegfried Gonzi, caml-list


On Friday, Apr 25, 2003, at 18:46 Europe/Helsinki, Brian Hurt wrote:
> This is usefull for two reasons, in my experience: sometimes, it lets 
> the
> compiler produce better code (for example, consider the function:
> let foo x y = x == y
> If you know that x and y will always be integers, doing:
> let foo (x:int) (y:int) = x == y
> allows the compiler to inline integer equals, rather than calling the
> generic compare function- much faster).

Actually, this is not true for your example, since you're comparing 
physical equality.  Comparing physical equality (==, !=) is always 
efficient.  Structural equality (=, <>) and order (>, >=, <, <=) will 
require calls to generic functions for unknown or indirect types.

This is equivalent to eq? vs. equal? in Scheme, but there is no 
non-traversing middle case similar to eqv?.

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-25  6:05 [Caml-list] Easy solution in OCaml? Siegfried Gonzi
  2003-04-25  8:19 ` sebastien FURIC
  2003-04-25 15:46 ` Brian Hurt
@ 2003-04-25 16:59 ` Markus Mottl
  2003-04-26  6:25   ` Siegfried Gonzi
  2003-04-27 14:13   ` Siegfried Gonzi
  2003-04-28 17:45 ` malc
  3 siblings, 2 replies; 17+ messages in thread
From: Markus Mottl @ 2003-04-25 16:59 UTC (permalink / raw)
  To: Siegfried Gonzi; +Cc: caml-list

Siegfried Gonzi schrieb am Freitag, den 25. April 2003:
> Often I am contemplating whether it would be possible to use
> OCaml in combination with my beloved Bigloo to perform statistical
> evaluations. I am not sure whether there are any out there who /can/
> do this evaluations with OCaml what you normally would do with Matlab.

For heavy duty statistics you better use tailor-made libraries, e.g. the
OCaml-interface to the GSL (Gnu Scientific Library) OCaml-GSL:

  http://oandrieu.nerim.net/ocaml/gsl/

possibly in combination with other linear algebra libraries, e.g. LACAML:

  http://www.oefai.at/~markus/home/ocaml_sources.html#LACAML

This should give you top-performance on really large data.

> The problem what arises: type system and working against the compiler.

Mandatory rule for OCaml-beginners: NEVER try to work against the
compiler. The compiler is your friend.

> Rationale: given a list of 12 month.  I would like to calculate the 
> quarterly means and skip any nan. Easy? Yes it is but only on paper and 
> in Scheme:

Or in OCaml, if you know how to do it elegantly and reasonably efficiently:

  let coll (len, sum as acc) n = if n >= 0 then len + 1, sum + n else acc

  let qmeans =
    let rec loop acc = function
      | a :: b :: c :: t ->
          let len, sum = coll (coll (coll (0, 0) a) b) c in
          loop ((if len = 0 then 0.0 else float sum /. float len) :: acc) t
      | [] -> List.rev acc
      | _ -> failwith "qmeans: illegal list" in
    loop []

> In Scheme I wrote it as functional as possible, but I fail to do this in 
> Ocaml. I mean doing it in OCaml via loops would be straightforward, but 
> I didn't succeed in coming up with a solution of:
> 
> - relies on pattern matching?

Yes, you have to match the list.

> - is short and and shouldn't resemble imperative style

See above.

> - why if-then constructs? I think this was called "guards" in Clean?

I actually find it strange that there is no such thing like if-then-else
in Clean. OCaml also supports guards, but they are not always best style.

> - why begin-end constructs? In Scheme begin-end constructs are ordinary, 
> but I find it irritating to use it in OCaml.

You can use parentheses instead.

> - is it possible to give type information for readbility.

Yes, e.g.:

  let qmeans : int list -> float list = ...

Regards,
Markus Mottl

-- 
Markus Mottl          http://www.oefai.at/~markus          markus@oefai.at

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-25 16:59 ` [Caml-list] Easy solution in OCaml? Markus Mottl
@ 2003-04-26  6:25   ` Siegfried Gonzi
  2003-04-27 14:13   ` Siegfried Gonzi
  1 sibling, 0 replies; 17+ messages in thread
From: Siegfried Gonzi @ 2003-04-26  6:25 UTC (permalink / raw)
  To: Markus Mottl; +Cc: caml-list

Markus Mottl wrote:

>
>
>>- why if-then constructs? I think this was called "guards" in Clean?
>>
>
>I actually find it strange that there is no such thing like if-then-else
>in Clean. OCaml also supports guards, but they are not always best style.
>
Hi:

Thanks for your answer. My Clean is a bit outdated but I am sure if-else 
exists in Clean too. But I agree you would have to dig out a deep hole 
in order to encounter if-then in the Clean manual.

I am not sure why, but I find if-then disturbing in OCaml.

Regards,
S. Gonzi

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-25 15:46 ` Brian Hurt
  2003-04-25 16:34   ` Ville-Pertti Keinonen
@ 2003-04-26 13:45   ` Siegfried Gonzi
  2003-04-26 21:51     ` Brian Hurt
  1 sibling, 1 reply; 17+ messages in thread
From: Siegfried Gonzi @ 2003-04-26 13:45 UTC (permalink / raw)
  To: Brian Hurt; +Cc: caml-list

>
>
>
>
Brian Hurt wrote:

>I find that if you're working against the compiler, either a) you haven't 
>thought the problem through, b) there's an easy solution you're missing, 
>or c) you have a bug.
>

I think this is a very interesting question. What I love about Scheme 
(or even Python lists) is the fact that you can put into a list what you 
want. I had a problem the other day which was as follows:

I have a Scheme function which extracts floating-point values from 
strings located in a file:

==
12.33,43.4,4.56,nan,1.23
23.3,34.4,nan,1.2,0
...
==

The extracted floating point numbers become stored into an array:

(vector (vector 12.33 43.4 4.56 -1.0 1.23) (vector 23.3 34.4 -1.0 1.2 0.0))

My boss gave me a file which he urgently had to evaluate in order to 
fullfill a time schedule (some measurements from  the field of 
experimental physics). But there was a problem, because the file was as 
follows:

==
name1,2.23,2.23,23.4
name2,23.34,23.34,.223
...
==

The first entry was an annotation but my Scheme function expects a 
string which can be converted to a floating point number. But Scheme is 
your friend here, because one more line in my file-reading function and 
you get something like this:

((name1 2.23 2.334) (name2 3.34 23.2 ...))

In Ocaml I would have to skip the first entry because it is not a 
floating-point value. All my other functions were not affected, because 
passing around arrays or lists does not mean you must put forward 
floating-points or string arrays or whatever.

I agree upon that the above feature can sometimes lead to bad hacks, 
because you the return value of a function can consist of a list where 
you put things into the list which you decide later on whether you want 
augment the list by other parameters, for example:

Your first version of the function has as return value: (list (list 2 3 4))

A year later you decide you want something like this: (list (list 2 3 4) 
(vector 3 4 5) "hi guy")

The goody here is all your other functions which expect the output of 
the above function must not be re-written, as opposed to Clean or OCaml 
where you would have to re-write all your functions because the 
structure of your return-list has changed.

>This is usefull for two reasons, in my experience: sometimes, it lets the 
>compiler produce better code (for example, consider the function:
>let foo x y = x == y
>If you know that x and y will always be integers, doing:
>let foo (x:int) (y:int) = x == y
>allows the compiler to inline integer equals, rather than calling the 
>generic compare function- much faster).
>
I doubt that type correctness is always better or leads to failure-free 
program execution.  Yesterday I faced the following situation: dividing 
the two vectors:

(vector 0.0 0.0  23.34 23.4)
through
(vector 0.0 0.0 0.0 23.4)

I forgot to check that division by zero is not a good idea, but the good 
old Bigloo compiler didn't rebel and had as output:

(vector #f #f #f 1.0)

Maybe a bad example because in OCaml you could use exceptions or 
something like this, but in this case the OCaml program had aborted 
(this is also true for C,...). I am not sure how long it would have gone 
good, but the Scheme program had not aborted in a safety-critical 
system-environment. I am really often surprised how forgiving Scheme and 
also CommonLisp actually are in such situations.


Regards,
S. Gonzi


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-26 13:45   ` Siegfried Gonzi
@ 2003-04-26 21:51     ` Brian Hurt
  2003-04-27 15:01       ` Siegfried Gonzi
  2003-04-27 16:33       ` [Caml-list] Re: IEEE-754 (was: Easy solution in OCaml?) Christophe TROESTLER
  0 siblings, 2 replies; 17+ messages in thread
From: Brian Hurt @ 2003-04-26 21:51 UTC (permalink / raw)
  To: Siegfried Gonzi; +Cc: Brian Hurt, Ocaml Mailing List

On Sat, 26 Apr 2003, Siegfried Gonzi wrote:

> >I find that if you're working against the compiler, either a) you haven't 
> >thought the problem through, b) there's an easy solution you're missing, 
> >or c) you have a bug.
> >
> 
> I think this is a very interesting question. What I love about Scheme 
> (or even Python lists) is the fact that you can put into a list what you 
> want. I had a problem the other day which was as follows:
> 
> I have a Scheme function which extracts floating-point values from 
> strings located in a file:
> 
> ==
> 12.33,43.4,4.56,nan,1.23
> 23.3,34.4,nan,1.2,0
> ...
> ==
> 
> The extracted floating point numbers become stored into an array:
> 
> (vector (vector 12.33 43.4 4.56 -1.0 1.23) (vector 23.3 34.4 -1.0 1.2 0.0))
> 
> My boss gave me a file which he urgently had to evaluate in order to 
> fullfill a time schedule (some measurements from  the field of 
> experimental physics). But there was a problem, because the file was as 
> follows:
> 
> ==
> name1,2.23,2.23,23.4
> name2,23.34,23.34,.223
> ...
> ==
> 
> The first entry was an annotation but my Scheme function expects a 
> string which can be converted to a floating point number. But Scheme is 
> your friend here, because one more line in my file-reading function and 
> you get something like this:
> 
> ((name1 2.23 2.334) (name2 3.34 23.2 ...))
> 
> In Ocaml I would have to skip the first entry because it is not a 
> floating-point value. All my other functions were not affected, because 
> passing around arrays or lists does not mean you must put forward 
> floating-points or string arrays or whatever.

You have to skip the first entry anyways, because it's not a floating
point value.  Or you have to have special handling for strings and floats
seperately- every time you pull an element out of the list, you need to go
"is this a string or a float?" and handle it correctly.  Otherwise, please
define what "name1" /. 3.0 should be.

How you put strings and floats into the same list is you define a type, 
call it foo_t for the moment:

type foo_t =
    String of string
    | Float of float
    ;;

And make it a list of foo_t's.  You can now pick apart your list by, for
example:

let print_list lst =
    let rec loop lst =
        match lst with
            [] -> () (* End the recursion *)
            | String(s) :: t ->
                print_string (s ^ " ");
                loop t
            | Float(x) :: t ->
                print_string ((string_of_float x) ^ " ");
                loop t
    in
    print_string "( ";
    loop lst;
    print_string ")\n"

Now, let's say at a later point you want integers in your string as well, 
so you extend foo_t to be:

type foo_t =
    String of string
    | Float of float
    | Int of int
    ;;


But being a forgetfull sort (like I am all the time), you forget to update 
print_string.  The next time you try to compile, ocaml tells you:

File "temp.ml", line 10, characters 8-274:
Warning: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
Int _::_

You constantly see (or at least I constantly see) the same pattern 
repeated over and over- pulling an Object out of a data structure and then 
running it through a tree of if typeofs to figure out what sort of 
creature you just pulled out.  And when you add a new type to the 
structure, all those if trees need a new branch.  In Ocaml, you can do the 
same thing, but the compiler checks your work and warns you if you forgot 
a place.

If the string is always just the first element, you might consider using a
tuple or structure.  But the short form is, you have a problem.  And one
the language shouldn't just let you sweep under the rug, as we'll see.

> 
> I agree upon that the above feature can sometimes lead to bad hacks, 
> because you the return value of a function can consist of a list where 
> you put things into the list which you decide later on whether you want 
> augment the list by other parameters, for example:
> 
> Your first version of the function has as return value: (list (list 2 3 4))
> 
> A year later you decide you want something like this: (list (list 2 3 4) 
> (vector 3 4 5) "hi guy")
> 
> The goody here is all your other functions which expect the output of 
> the above function must not be re-written, as opposed to Clean or OCaml 
> where you would have to re-write all your functions because the 
> structure of your return-list has changed.

If you don't know what you just pulled out of a list, how can you do 
anything with it?  About all you can do with it is to move it around.  
Take it out of one data structure and put it into another.  Or pass it to 
some other function.  Which you can quite happily do with Ocaml- take a 
look at List.map or Array.of_list in the standard libraries for examples.

But once you want to do something more with the elements than just move 
them around, you need to know what they are- what type they are.  So let's 
say I'm expecting that I'm dealing with an int list list (your first 
example there).  I could easily convert this to a float list list by 
doing:

let conv lst = List.map (fun l -> List.map (float_of_int) l) lst

With some suitable generic handling, instead of calling List.map, I just 
call map, so when I hit an array of ints instead of a list of ints, I call 
Array.map and not List.map.  It could be done, it'd be of limited use but 
it could be done.  But what am I supposed to do with the string "hi guy"?  
Should it treat the string as a list of char, implicitly convert it to a 
list of int, and then convert the list of int to a list of float, 
returning [104.; 105.; 32.; 103.; 117.; 121.]?  What sensible thing can 
you do here?

This is what I meant about a bug in your program or not thinking the 
design through.  If there is a reason you're putting a string into that 
list, it means something.  Decide what it means, and at each point you 
handle elements from that list, decide what to do if you see a string- 
even if it's just "ignore it and go on", think about it and decide.

> 
> >This is usefull for two reasons, in my experience: sometimes, it lets the 
> >compiler produce better code (for example, consider the function:
> >let foo x y = x == y
> >If you know that x and y will always be integers, doing:
> >let foo (x:int) (y:int) = x == y
> >allows the compiler to inline integer equals, rather than calling the 
> >generic compare function- much faster).
> >
> I doubt that type correctness is always better or leads to failure-free 
> program execution.  

Type correctness is not a panacea- bugs can still sneak past.  Not even 
proofs of code correctness is good enough- they just prove the code does 
what it's designed to do, not what it's *supposed* to do.  Unfortunately, 
no CPU architecture I know of includes a DWIM instruction (despite long 
standing and unremitting demand)...

Type correctness does catch a lot of bugs, often even surprisingly deep 
bugs.  And every bug the compiler catches is one less you have to hunt 
down yourself...

> Yesterday I faced the following situation: dividing 
> the two vectors:
> 
> (vector 0.0 0.0  23.34 23.4)
> through
> (vector 0.0 0.0 0.0 23.4)
> 
> I forgot to check that division by zero is not a good idea, but the good 
> old Bigloo compiler didn't rebel and had as output:
> 
> (vector #f #f #f 1.0)
> 
> Maybe a bad example because in OCaml you could use exceptions or 
> something like this, but in this case the OCaml program had aborted 
> (this is also true for C,...). I am not sure how long it would have gone 
> good, but the Scheme program had not aborted in a safety-critical 
> system-environment. I am really often surprised how forgiving Scheme and 
> also CommonLisp actually are in such situations.


Hmm?  What platform are you on?  Linux on x86:

$ ocaml
        Objective Caml version 3.06

# 1. /. 0. ;;
- : float = inf.
# 0. /. 0. ;;
- : float = nan.
# 0. /. 1. ;;
- : float = 0.
# let x = [ 0.0 ; 1.0 ; 0.0 ; 1.0 ]
  and y = [ 0.0 ; 0.0 ; 1.0 ; 1.0 ] ;;
val x : float list = [0.; 1.; 0.; 1.]
val y : float list = [0.; 0.; 1.; 1.]
# let rec vdiv a b =
  match a, b with
      [], [] -> []
      | x :: at, y :: bt -> (x /. y) :: (vdiv at bt)
      | _ -> assert false
  ;;
val vdiv : float list -> float list -> float list = <fun>
# vdiv x y ;;
- : float list = [nan.; inf.; 0.; 1.]
# 

No exceptions for me.

Brian


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-25 16:59 ` [Caml-list] Easy solution in OCaml? Markus Mottl
  2003-04-26  6:25   ` Siegfried Gonzi
@ 2003-04-27 14:13   ` Siegfried Gonzi
  2003-04-27 16:54     ` Eray Ozkural
  1 sibling, 1 reply; 17+ messages in thread
From: Siegfried Gonzi @ 2003-04-27 14:13 UTC (permalink / raw)
  To: Markus Mottl; +Cc: caml-list

>
>
>
>Markus Mottl wrote:
>
>>
>
>Or in OCaml, if you know how to do it elegantly and reasonably efficiently:
>
>  let coll (len, sum as acc) n = if n >= 0 then len + 1, sum + n else acc
>
>  let qmeans =
>    let rec loop acc = function
>      | a :: b :: c :: t ->
>          let len, sum = coll (coll (coll (0, 0) a) b) c in
>          loop ((if len = 0 then 0.0 else float sum /. float len) :: acc) t
>      | [] -> List.rev acc
>      | _ -> failwith "qmeans: illegal list" in
>    loop []
>
As comparison I post my Clean version (it is more general or could be 
made general, lets say for a list with 24 hours). But I am still not 
contended, because why isn't it possible to use more elegant 
"functional-constructs" which lead to short, easy to read and easy to 
comprehend solutions (see also my post on comp.lang.functional):

==
module stat
import StdEnv


quarter:: [Real] Real -> [Real]
quarter ls nan = sum_it 0 0.0 0 ls []
where
	sum_it:: Int Real Int [Real] [Real] -> [Real]
	sum_it counter sum n [] erg = reverse erg
	sum_it counter sum n [h:t] erg
		| (counter == 2) 
			| n > 0 = sum_it 0 0.0 0 t [(sum/toReal(n)):erg]
			        = sum_it 0 0.0 0 t [nan:erg]
		| h > nan  = sum_it (counter+1) (sum+h) (n+1) t erg
		| otherwise = sum_it (counter+1) sum n t erg
		
Start = quarter [1.0,2.0,-1.0,3.4,3.4,-1.0,-1.0,2.3,3.4,-1.0,-1.0,-1.0] (-1.0)
==



Regards,
S. Gonzi


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-26 21:51     ` Brian Hurt
@ 2003-04-27 15:01       ` Siegfried Gonzi
  2003-04-28 15:43         ` Brian Hurt
  2003-04-29  5:46         ` John Max Skaller
  2003-04-27 16:33       ` [Caml-list] Re: IEEE-754 (was: Easy solution in OCaml?) Christophe TROESTLER
  1 sibling, 2 replies; 17+ messages in thread
From: Siegfried Gonzi @ 2003-04-27 15:01 UTC (permalink / raw)
  To: Brian Hurt; +Cc: Ocaml Mailing List

>
>
>Brian Hurt wrote:
>
>
>If you don't know what you just pulled out of a list, how can you do 
>anything with it?  About all you can do with it is to move it around.  
>Take it out of one data structure and put it into another.  Or pass it to 
>some other function.  Which you can quite happily do with Ocaml- take a 
>look at List.map or Array.of_list in the standard libraries for examples.
>
>But once you want to do something more with the elements than just move 
>them around, you need to know what they are- what type they are.  So let's 
>say I'm expecting that I'm dealing with an int list list (your first 
>example there).  I could easily convert this to a float list list by 
>doing:
>
>let conv lst = List.map (fun l -> List.map (float_of_int) l) lst
>
>With some suitable generic handling, instead of calling List.map, I just 
>call map, so when I hit an array of ints instead of a list of ints, I call 
>Array.map and not List.map.  It could be done, it'd be of limited use but 
>it could be done.  But what am I supposed to do with the string "hi guy"?  
>Should it treat the string as a list of char, implicitly convert it to a 
>list of int, and then convert the list of int to a list of float, 
>returning [104.; 105.; 32.; 103.; 117.; 121.]?  What sensible thing can 
>you do here?
>
>This is what I meant about a bug in your program or not thinking the 
>design through.  If there is a reason you're putting a string into that 
>list, it means something.  Decide what it means, and at each point you 
>handle elements from that list, decide what to do if you see a string- 
>even if it's just "ignore it and go on", think about it and decide.
>

Before I commence I have to say: there exists actually only 2 functional 
languages which  deserve to be used by industry: this is OCaml and 
Haskell. Okay, in the Scheme realm only Bigloo (and mybe PLT Scheme) 
stands for "ready for industry".  But I have to say that Clean's elegant 
syntax is way, way, way above OCaml ones.


It is often very comfortable to use this sort of bad hacking, because in 
science when you develop new functions or tries to solve problems you 
often do not know in advance what you want and not.

For example: function1 has as return: erg1 = (list (list 2 3 4))

function2 expects output from function1  and function2 uses this output 
as follows:

(list-ref  erg1 0)

But now I decide for reason of its own that erg1 should include just one 
more information:

erg1 = (list1 (list 2 3 4)  (list (vector 2 3 4) "nice day"))

function2 now is not affected because it always uses the first element 
of the list, but it dramatically shortens your development time, because 
you do not have to cope with other structures or tuples in erg1 as you 
would do lets say in Clean. And you do not have to change  all your 
other dependencies.

This was the reason to ask in my first post of the topic are there any 
guys out there who successfully use OCaml for data evaluation or lets 
call it statistic (which means reading files, coping with array and 
lists and that sort of). Maybe the aforementioned bad feature of 
Scheme/Lisp/Python... makes them that usefull for coping with "dynamic" 
data.

This also  leads to the question: is development time really reduced in 
(strict typed) functional programming, or is it only reduced when you 
compare quicksort in Haskell and the verbose version in C.


Regards,
S. Gonzi


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Caml-list] Re: IEEE-754 (was: Easy solution in OCaml?)
  2003-04-26 21:51     ` Brian Hurt
  2003-04-27 15:01       ` Siegfried Gonzi
@ 2003-04-27 16:33       ` Christophe TROESTLER
  1 sibling, 0 replies; 17+ messages in thread
From: Christophe TROESTLER @ 2003-04-27 16:33 UTC (permalink / raw)
  To: siegfried.gonzi; +Cc: brian.hurt, caml-list

On Sat, 26 Apr 2003, Brian Hurt <brian.hurt@qlogic.com> wrote:
> 
> On Sat, 26 Apr 2003, Siegfried Gonzi wrote:
> 
> > dividing the two vectors:
> > (vector 0.0 0.0  23.34 23.4) through (vector 0.0 0.0 0.0 23.4)
> > 
> > (vector #f #f #f 1.0)
> 
> Hmm?  What platform are you on?  Linux on x86:
> 
> # let x = [ 0.0 ; 1.0 ; 0.0 ; 1.0 ]
>   and y = [ 0.0 ; 0.0 ; 1.0 ; 1.0 ] ;;

List.map2 ( /. ) x y

> - : float list = [nan.; inf.; 0.; 1.]

This is a feature of IEEE-754 arithmetic which means it should work
this way on virtually all architectures.

BTW, may I take this opportunity to advertise my little wishlist in
this respect ?  I'd like to have:

FAST is_nan : float -> bool 
     is_finite : float -> bool
               (I know it is possible to define them with
                classify_float but is is not fast)
and  copysign : float -> float -> float

Cheers,
ChriS

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-27 14:13   ` Siegfried Gonzi
@ 2003-04-27 16:54     ` Eray Ozkural
  2003-04-28  5:00       ` Siegfried Gonzi
  0 siblings, 1 reply; 17+ messages in thread
From: Eray Ozkural @ 2003-04-27 16:54 UTC (permalink / raw)
  To: Siegfried Gonzi, Markus Mottl; +Cc: caml-list

On Sunday 27 April 2003 17:13, Siegfried Gonzi wrote:
> quarter:: [Real] Real -> [Real]
> quarter ls nan = sum_it 0 0.0 0 ls []
> where

Ah! Why don't we have "where" in ocaml? I really miss it!

Thanks,

-- 
Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>
Comp. Sci. Dept., Bilkent University, Ankara  KDE Project: http://www.kde.org
www: http://www.cs.bilkent.edu.tr/~erayo  Malfunction: http://mp3.com/ariza
GPG public key fingerprint: 360C 852F 88B0 A745 F31B  EA0F 7C07 AE16 874D 539C

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-27 16:54     ` Eray Ozkural
@ 2003-04-28  5:00       ` Siegfried Gonzi
  0 siblings, 0 replies; 17+ messages in thread
From: Siegfried Gonzi @ 2003-04-28  5:00 UTC (permalink / raw)
  To: erayo; +Cc: Markus Mottl, caml-list

>
>
>
>Eray Ozkural wrote:
>
>On Sunday 27 April 2003 17:13, Siegfried Gonzi wrote:
>
>>quarter:: [Real] Real -> [Real]
>>quarter ls nan = sum_it 0 0.0 0 ls []
>>where
>>
>
>Ah! Why don't we have "where" in ocaml? I really miss it!
>
>Thanks,
>


Hi guys:

I diged out my old Clean manuals and tried everything starting from 
foldr, list-comprehension, function composition (f o g o g), but I did 
fail and my general solution is as follows:

==
module stat
import StdEnv

       
meanFromList:: [Real] Real -> Real
meanFromList ls nan
    # ls_nan = filter ((<) nan) ls
    # n = length(ls_nan)
    | n > 0 = sum(ls_nan)/toReal(n)
    | otherwise = nan
   
   
qMeans:: [Real] Real Int -> [Real]
qMeans [] nan q = []
qMeans ls nan q = [(meanFromList (take q ls) nan):(qMeans (drop q ls) 
nan q)]


Start =  qMeans [toReal(x) \\ x<-[1..100]] (-1.0) 2
==

The solution needs the following Clean standard functions: filter, 
length, sum, take and drop.

The overhead of take and drop is negligible.

Regards,
S. Gonzi
PS: Or if you like where:
==
qMeans:: [Real] Real Int -> [Real]
qMeans [] nan q = []
qMeans ls nan q = [(meanFromList (take q ls) nan):(qMeans (drop q ls) 
nan q)]
where
        meanFromList:: [Real] Real -> Real
        meanFromList ls nan
                # ls_nan = filter ((<) nan) ls
                # n = length(ls_nan)
                | n > 0 = sum(ls_nan)/toReal(n)
                | otherwise = nan
==

>



-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-27 15:01       ` Siegfried Gonzi
@ 2003-04-28 15:43         ` Brian Hurt
  2003-04-29  5:46         ` John Max Skaller
  1 sibling, 0 replies; 17+ messages in thread
From: Brian Hurt @ 2003-04-28 15:43 UTC (permalink / raw)
  To: Siegfried Gonzi; +Cc: Brian Hurt, Ocaml Mailing List

On Sun, 27 Apr 2003, Siegfried Gonzi wrote:

> It is often very comfortable to use this sort of bad hacking, because in 
> science when you develop new functions or tries to solve problems you 
> often do not know in advance what you want and not.
> 
> For example: function1 has as return: erg1 = (list (list 2 3 4))
> 
> function2 expects output from function1  and function2 uses this output 
> as follows:
> 
> (list-ref  erg1 0)
> 
> But now I decide for reason of its own that erg1 should include just one 
> more information:
> 
> erg1 = (list1 (list 2 3 4)  (list (vector 2 3 4) "nice day"))
> 
> function2 now is not affected because it always uses the first element 
> of the list, but it dramatically shortens your development time, because 
> you do not have to cope with other structures or tuples in erg1 as you 
> would do lets say in Clean. And you do not have to change  all your 
> other dependencies.

It allows you to ignore the bug.  And it may not bite you.  But that 
doesn't mean it's still not a bug.  Otherwise, you need to define what 
"nice day"/3 is.

Although it's looking like you want to use tuples, not lists.  It's 
perfectly valid, in ocaml, to do:

[ 2; 3; 4 ], ( [| 2; 3; 4 |], "nice day" )

Tuples are sort of a lazy man's structure.  Or you can actually define a 
structure- which has the advantage that you can reference members by name, 
and ignore members you don't care about.  So you might want to do:

type foo_t = { datalist : int list ; 
               datavector : int array ; 
               otherinfo : string
             };;

let get_foo : ... -> foo_t = fun ... -> ... ;;

(* All I want to deal with is the int list- ignore the rest *)
    let mylist = (get_foo ...).datalist
    in ...

This allows you to add elements to the structure foo_t and the above code 
will simply ignore them.

> 
> This was the reason to ask in my first post of the topic are there any 
> guys out there who successfully use OCaml for data evaluation or lets 
> call it statistic (which means reading files, coping with array and 
> lists and that sort of). Maybe the aforementioned bad feature of 
> Scheme/Lisp/Python... makes them that usefull for coping with "dynamic" 
> data.

It lets you program by coincidence.  Which may be forgivable for a 
throw-away program, but it's still a bad idea.  Nothing is as permanent as 
that which is called temporary.

> 
> This also  leads to the question: is development time really reduced in 
> (strict typed) functional programming, or is it only reduced when you 
> compare quicksort in Haskell and the verbose version in C.
> 

I'm a C pro.  It's been my main language for more than a decade now.  I
mean, I know what a sequence point is- and why they exist.  I'm an ocaml
newbie, I've only been coding in Ocaml for a couple of months now, and I'm
still learning the language (so my code is likely not going to be the best
example of how to do things in Ocaml).  But I'm already at least as
efficient in Ocaml than I am in C, in terms of correct behaviors per hour
of work.

There are lots of reasons for this, but one of the big ones is the type
checking system plus type inference.  I have, on occasion, had to stare at
an ocaml error message for upwards of ten minutes to figure out what was
wrong.  As I become more familiar with ocaml, such "puzzler" errors are
becoming less and less frequent.  If I have to fire up a debugger,
reproduce the problem, and figure out what the problem is, ten minutes is
closer to the minimum.  The worst bug I've ever had to track down took me
a solid *month* of 60-hour weeks to figure out (and resulted in a two-line
change in the code).  So every bug, every problem, the compiler can find
for me is an incredible time savings and an incredible productivity boost.

Yes, I compile with warnings on.  All of them.  And treat warnings as 
errors.  And no, my code doesn't have signifigantly more typedefs than 
normal code does- because even in my C code I think about what types 
things should be.  Loop variables are not implicitly an int, for example 
(actually, size_t is the most common loop variable type in my code).  If 
the variables are the correct type to begin with, you don't need to 
typecast them.

With type inference, most of the bondage & discipline aspects of strong
typing (that we all learned to hate with languages like Pascal and Java)
are gone.  You get all the benefits of strong typing without the
annoyances.  Let the compiler figure out what types things should be.

Brian


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-25  6:05 [Caml-list] Easy solution in OCaml? Siegfried Gonzi
                   ` (2 preceding siblings ...)
  2003-04-25 16:59 ` [Caml-list] Easy solution in OCaml? Markus Mottl
@ 2003-04-28 17:45 ` malc
  2003-04-28 18:16   ` Shivkumar Chandrasekaran
  3 siblings, 1 reply; 17+ messages in thread
From: malc @ 2003-04-28 17:45 UTC (permalink / raw)
  To: Siegfried Gonzi; +Cc: caml-list

On Fri, 25 Apr 2003, Siegfried Gonzi wrote:

> Hi:
>
> First off: It is not homework. I am 29 and writing my PhD in physics.
> Often I am contemplating whether it would be possible to use OCaml in
> combination with my beloved Bigloo to perform statistical evaluations. I
> am not sure whether there are any out there who /can/ do this
> evaluations with OCaml what you normally would do with Matlab. The
> problem what arises: type system and working against the compiler. In
> Scheme changing a solution from lets say integer-array to double-array
> is easy, but in Clean for example you would have to change all your
> dependencies.
> I often skim over the libraries and came to the conclusion: C, C++,
> OCaml impossible for me to see any elegance; Clean a bit better;
> Bigloo/Scheme: I am not sure here, because everything looks the same
> maybe this is cheating, but I think it looks the most elegant and less
> intimitating from all.
>
>
> Rationale: given a list of 12 month.  I would like to calculate the
> quarterly means and skip any nan. Easy? Yes it is but only on paper and
> in Scheme:
>
> e.g: [1,2,4,-1,45,56,45,56,8]
>
> nan=-1.0
>
> result: [(1+2+3)/3, (45+56)/2, (45+56+8)/3]

let nan = -1

let mean a b c = (a + b + c) / 3

let rec qmean = function
    a :: b :: c :: rest -> mean a b c :: qmean rest
  | [] -> []
  | otherwise -> failwith "malformed list"

let _ =
  let months = [1; 2; 4; -1; 45; 56; 45; 56; 8] in
  let denan = List.map (fun x -> if x = nan then 0 else x) months in
  qmean denan


-- 
mailto:malc@pulsesoft.com

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-28 17:45 ` malc
@ 2003-04-28 18:16   ` Shivkumar Chandrasekaran
  0 siblings, 0 replies; 17+ messages in thread
From: Shivkumar Chandrasekaran @ 2003-04-28 18:16 UTC (permalink / raw)
  To: caml-list

Not quite, I think. How about:

  (* supplied by user *)
val is_nan : 'a -> bool
val add : 'a -> 'a -> 'a
val div : 'a -> 'a -> 'a
val from_int : int -> 'a
(* that's all from the user *)

let q_means is_nan add div from_int ms = function
   let sum a b c =
     let filter_nan n = if is_nan n then (from_int 0) else n in
     add (add (filter_nan a) (filter_nan b)) (filter_nan c)
   and cardinality a b c =
     let filter_nan n = if is_nan n then 0 else 1 in
     from_int ((filter_nan a) + (filter_nan b) + (filter_nan c)) in
   let rec qm ms = function
     a :: b :: c :: rest -> div (sum a b c) (cardinality a b c) :: qm 
rest
   | [] -> []
   | _ -> failwith "Malformed list" in
   qm ms

A good test case is: [-1;-1;-1]

--shiv--

On Monday, April 28, 2003, at 10:45 AM, malc wrote:

> On Fri, 25 Apr 2003, Siegfried Gonzi wrote:
>
>> Hi:
>>
>> First off: It is not homework. I am 29 and writing my PhD in physics.
>> Often I am contemplating whether it would be possible to use OCaml in
>> combination with my beloved Bigloo to perform statistical 
>> evaluations. I
>> am not sure whether there are any out there who /can/ do this
>> evaluations with OCaml what you normally would do with Matlab. The
>> problem what arises: type system and working against the compiler. In
>> Scheme changing a solution from lets say integer-array to double-array
>> is easy, but in Clean for example you would have to change all your
>> dependencies.
>> I often skim over the libraries and came to the conclusion: C, C++,
>> OCaml impossible for me to see any elegance; Clean a bit better;
>> Bigloo/Scheme: I am not sure here, because everything looks the same
>> maybe this is cheating, but I think it looks the most elegant and less
>> intimitating from all.
>>
>>
>> Rationale: given a list of 12 month.  I would like to calculate the
>> quarterly means and skip any nan. Easy? Yes it is but only on paper 
>> and
>> in Scheme:
>>
>> e.g: [1,2,4,-1,45,56,45,56,8]
>>
>> nan=-1.0
>>
>> result: [(1+2+3)/3, (45+56)/2, (45+56+8)/3]
>
> let nan = -1
>
> let mean a b c = (a + b + c) / 3
>
> let rec qmean = function
>     a :: b :: c :: rest -> mean a b c :: qmean rest
>   | [] -> []
>   | otherwise -> failwith "malformed list"
>
> let _ =
>   let months = [1; 2; 4; -1; 45; 56; 45; 56; 8] in
>   let denan = List.map (fun x -> if x = nan then 0 else x) months in
>   qmean denan
>
>
> -- 
> mailto:malc@pulsesoft.com
>
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives: 
> http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: 
> http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>
--shiv--

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Caml-list] Easy solution in OCaml?
  2003-04-27 15:01       ` Siegfried Gonzi
  2003-04-28 15:43         ` Brian Hurt
@ 2003-04-29  5:46         ` John Max Skaller
  1 sibling, 0 replies; 17+ messages in thread
From: John Max Skaller @ 2003-04-29  5:46 UTC (permalink / raw)
  To: Siegfried Gonzi; +Cc: Brian Hurt, Ocaml Mailing List

Siegfried Gonzi wrote:

> This also  leads to the question: is development time really reduced in 
> (strict typed) functional programming, or is it only reduced when you 
> compare quicksort in Haskell and the verbose version in C.


It depends on the kind of project AND what 

you mean by "development time". I'd include

everything needed to be confident the result
was correct.

Two projects

http://interscrtipt.sf.net -- in Python
(A literate programming tool)

http://felix.sf.next -- in Ocaml
(A compiler for an algol-like language)

Interscript verges on unmaintainability.
Lightweight OO style without static typing.

Felix is relatively easy to extend despite
being considerably more complex. The implementation
is procedural at the top level with heavy use
of functional programming (mainly pure with memoisation)
for computations.

I shudder in horror at the idea of rewriting Felix
in C++. The loss of basic functional stuff like
closures and functional mapping (as well as variants)
would make a difficult project unmanageable .. and
that's just translating it, forget about new development.

SO my answer is: Ocaml provides an excellent blend of
both procedural and functional styles that make
development of moderate sized projects very efficient.
[moderate = 10K to 10M LOC]. I write small things
in Python and try to avoid C++ unless I can generate it
(despite being a member of the ISO committee standardising it).

-- 
John Max Skaller, mailto:skaller@ozemail.com.au
snail:10/1 Toxteth Rd, Glebe, NSW 2037, Australia.
voice:61-2-9660-0850


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2003-04-29  6:18 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-25  6:05 [Caml-list] Easy solution in OCaml? Siegfried Gonzi
2003-04-25  8:19 ` sebastien FURIC
2003-04-25 15:46 ` Brian Hurt
2003-04-25 16:34   ` Ville-Pertti Keinonen
2003-04-26 13:45   ` Siegfried Gonzi
2003-04-26 21:51     ` Brian Hurt
2003-04-27 15:01       ` Siegfried Gonzi
2003-04-28 15:43         ` Brian Hurt
2003-04-29  5:46         ` John Max Skaller
2003-04-27 16:33       ` [Caml-list] Re: IEEE-754 (was: Easy solution in OCaml?) Christophe TROESTLER
2003-04-25 16:59 ` [Caml-list] Easy solution in OCaml? Markus Mottl
2003-04-26  6:25   ` Siegfried Gonzi
2003-04-27 14:13   ` Siegfried Gonzi
2003-04-27 16:54     ` Eray Ozkural
2003-04-28  5:00       ` Siegfried Gonzi
2003-04-28 17:45 ` malc
2003-04-28 18:16   ` Shivkumar Chandrasekaran

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).