Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: reference initialization
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Pierre Weis <Pierre.Weis@i...>
Subject: Re: reference initialization
> Okay, I withdraw my argument that the Java strategy is better then
> the ML strategy However, I'd like to use the following example
> to make my point clear.
> 
> I want to combine two arrays into one. Here is the code in OCaml.
> 
> let combine_arrays a b =
>   let alen = Array.length a in
>   let blen = Array.length b in
>   let c = Array.make (alen + blen) ?
>   in begin
>     for i = 0 to alen - 1 do
>       c.(i) <- a.(i)
>     done;
>     for i = 0 to blen -1 do
>       c.(alen + i) <- b.(i)
>     done
>   end
> 
> Of course, you need to provide ? to make the above code work.
> Here is my argument:
> 
> (1) If you try to provide ?, the code becomes repulsive.

Not exactly, you just have to find one element into a. For instance:
 let alen = Array.length a in
 if alen = 0 then b (or Array.copy b if you need a fresh array) else
 let ? = a.(0) in
 let c = ...

  for i = 1 to alen - 1 do
   ...

> (2) If you really want to make sure that 'c' is well-initialized,
> you should probably check this after those two loops. The question
> is how to incorporate the checking result into the type system.
> (3) If you initialize 'c' with a (wrong) value, it seems to me
> that nothing is achieved.
> (4) Also, the problem cannot be solved using option type.
> 
> This is a precise senario that I had in mind, where the kind of
> mandatory array initialization in ML-like langugages is simply
> inappropriate, isn't it?

You should consider that there is a general initialisation function in
the Array module, named Array.init, that allocates for you a fresh
array then fill it with values obtained by calling an arbitrary
supplied function:

# Array.init;;
- : int -> f:(int -> 'a) -> 'a array = <fun>

Using it, you don't need to bother with any dummy initialization value:

let combine_arrays a b =
  let alen = Array.length a in
  let blen = Array.length b in
  let init i = if i < alen then a.(i) else b.(i) in
  Array.init (alen + blen) init

This code ensures the ``always initialized strategy'' of ML, and seems
to me elegant and clear (but note that it uses higher-order
functionality). Have I missed something ?

Best regards,

PS: An even shorter version of combine_arrays should be
    let combine_arrays = Array.append

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://cristal.inria.fr/~weis/