* [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