caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* How to do this properly with OCaml?
@ 2005-07-22 14:26 Thomas Fischbacher
  2005-07-22 14:52 ` [Caml-list] " Eric Cooper
                   ` (4 more replies)
  0 siblings, 5 replies; 103+ messages in thread
From: Thomas Fischbacher @ 2005-07-22 14:26 UTC (permalink / raw)
  To: caml-list


I repeatedly stumble across problems where I would like to use a 
programming style which seems quite out of line with how one is supposed 
to use OCaml (to say it otherwise, it looks outright wrong and 
horrendously ugly), but which nevertheless might be just appropriate for 
the situation in question. So, I would like to hear the opinion of the 
OCaml community about this.

Imagine constructing a binary heap of tuples. It is somewhat neat to be 
able to just use an array to store the entries of the heap which is 
pre-allocated to some fixed size and replaced by a larger array whenever 
more space is needed. The only thing known about the heap's entries at 
compile time is that they are bound to be tuples, hence boxed objects,
but nothing else is known about their size or even type.

As one does not have a prototype of such a tuple at the time the array is 
created, it seems to me as if the best thing one could do in OCaml would 
be:

(1) Make an array of <tuple> option and initially fill it with None.

(2) Make an optional array of tuples which is None until the first entry 
is made.

One drawback of approach (2) is that when we "remove" entries from the 
heap, the underlying array will keep unnecessary references to values 
which by chance might be quite big, and which we might want to be 
reclaimed by GC, so that's not too beautiful for a general-purpose 
application.

The major drawback of (1), however, is that there is a further level of 
indirection for array entries, which means some unnecessary consing, as 
well as more work for the machine to get at a given entry.

If I just define a function

let whatever () = Obj.magic (1,2);

then 

let a = Array.make 10 (whatever());;

would give me more or less just what I want. An array of boxed things that 
I then would like to use as in:

# let () = a.(2) <- (1,2,3,4) in a.(2);;
- : int * int * int * int = (1, 2, 3, 4)
# let () = a.(3) <- (5,8,2,1) in a.(2);;
- : int * int * int * int = (1, 2, 3, 4)
# a.(3);;
- : int * int * int * int = (5, 8, 2, 1)

Mind you - in this case, I will only assign int*int*int*int tuples to that 
array, or the result of the evaluation of whatever() when I want to kill 
an entry. Plus, I guarantee never to look at any entry that is set to 
whatever().

In some other situation, I might be inclined to use the same code, but 
with string*bool instead of int*int*int*int. But again, I will promise 
never to put anything else but string*bool into the underlying array, and 
never look at entries which are not set properly. (Which, of course, 
includes never printing such an array at the toplevel unless it is fully 
occupied.)

Please don't tell me that "well, OCaml is not Lisp, after all". 
This I already know. But is there no proper way to get around that 
(technically speaking) unnecessary extra level of indirection that is 
forced upon me due to static type checking?

The very same problem appears in a different guise when one tries to write 
a function that flattens 'a array array -> 'a array. The best I could 
come up with here is:

let join_arrays aa =
  let len_total = Array.fold_left (fun sf a -> sf+Array.length a) 0 aa 
  and nr_arrays = Array.length aa
  in
  if len_total=0
  then
    if nr_arrays = 0 then [||] else aa.(0)
      (* ^ Take a close look! *)
  else
    (* Here, we face the problem that we have to get some value
       of the proper type to init the joined array with.
     *)
    let first_entry =
      (let rec seek pos =
	let array_here = aa.(pos) in
	if Array.length array_here = 0
	then seek (pos+1)
	else array_here.(0)
	    (* This is guaranteed to terminate, as len_total>0! *)
      in seek 0)
    in
    let result = Array.make len_total first_entry in
    let transfer_to_result arr offset =
      let nr = Array.length arr in
      for i = 0 to nr-1 do result.(i+offset) <- arr.(i) done
    in
    let rec populate nr_array_now offset =
      if nr_array_now = nr_arrays
      then result
      else 
	let array_now = aa.(nr_array_now) in
	let () = transfer_to_result array_now offset in
	populate (1+nr_array_now) (offset+Array.length array_now)
    in
    populate 0 0
;;

Of course, it is pretty awkward having to scan for the first element in 
the first nonempty array in an array of arrays, especially as that element 
really does not play a that special role.

Could anyone please tell me how to do all this in a more appropriate way?

-- 
regards,               tf@cip.physik.uni-muenchen.de              (o_
 Thomas Fischbacher -  http://www.cip.physik.uni-muenchen.de/~tf  //\
(lambda (n) ((lambda (p q r) (p p q r)) (lambda (g x y)           V_/_
(if (= x 0) y (g g (- x 1) (* x y)))) n 1))                  (Debian GNU)


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

end of thread, other threads:[~2005-07-31  3:10 UTC | newest]

Thread overview: 103+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-22 14:26 How to do this properly with OCaml? Thomas Fischbacher
2005-07-22 14:52 ` [Caml-list] " Eric Cooper
2005-07-22 15:26 ` [SPAM_PROBABLE] - [Caml-list] How to do this properly with OCaml? - Bayesian Filter detected spam Christophe Dehlinger
2005-07-22 18:58   ` [Caml-list] How to do this properly with OCaml? Stephane Glondu
2005-07-22 15:50 ` Berke Durak
2005-07-22 16:47   ` brogoff
2005-07-22 15:54 ` Michel Quercia
2005-07-23  5:00 ` Michael Alexander Hamburg
2005-07-23 12:34   ` Xavier Leroy
2005-07-23 13:16     ` Berke Durak
2005-07-23 16:36       ` Stephane Glondu
2005-07-23 18:27         ` Berke Durak
2005-07-23 18:50           ` Matthieu Sozeau
2005-07-24  8:35             ` Berke Durak
2005-07-23 19:18           ` Stephane Glondu
2005-07-23 19:35             ` Thomas Fischbacher
2005-07-23 19:50               ` Stephane Glondu
2005-07-23 19:59                 ` Thomas Fischbacher
2005-07-23 20:15                   ` Brian Hurt
2005-07-23 23:16                     ` james woodyatt
2005-07-23 23:27                   ` Stephane Glondu
2005-07-23 18:37     ` Michael Alexander Hamburg
2005-07-23 18:52       ` Bardur Arantsson
2005-07-23 21:35         ` [Caml-list] " Michael Alexander Hamburg
2005-07-23 19:19     ` [Caml-list] " Thomas Fischbacher
2005-07-24  7:27     ` [Caml-list] "Just say no!" campaign against Obj [was: How to do this properly with OCaml?] Alex Baretta
2005-07-24  8:02       ` [Caml-list] "Just say no!" campaign against Obj james woodyatt
2005-07-24 17:27       ` Stephane Glondu
2005-07-25  8:43         ` Alex Baretta
2005-07-24 21:37       ` [Caml-list] "Just say no!" campaign against Obj [was: How to do this properly with OCaml?] brogoff
2005-07-25  8:15         ` Alex Baretta
2005-07-25 17:08           ` brogoff
2005-07-25  8:57         ` Alex Baretta
2005-07-24 17:33     ` [Caml-list] How to do this properly with OCaml? skaller
2005-07-24 18:13       ` Stephane Glondu
2005-07-24 18:48         ` skaller
2005-07-24 19:14           ` Stephane Glondu
2005-07-24 20:29             ` skaller
2005-07-24 20:49               ` skaller
2005-07-24 21:08                 ` Stephane Glondu
2005-07-24 21:55                   ` skaller
2005-07-24 23:23                     ` Stephane Glondu
2005-07-25  0:32                       ` skaller
2005-07-25  6:45                         ` Stephane Glondu
2005-07-25 11:35                           ` skaller
2005-07-26  0:47                             ` Brian Hurt
2005-07-26  0:56                               ` Jere Sanisalo
2005-07-26  1:10                                 ` Brian Hurt
2005-07-26  1:34                                   ` Jere Sanisalo
2005-07-26  9:03                                     ` Richard Jones
2005-07-27 17:21                                     ` skaller
2005-07-27 19:44                                       ` [Caml-list] Games Jon Harrop
2005-07-27 20:35                                         ` Jere Sanisalo
2005-07-28  0:13                                           ` Jon Harrop
2005-07-28  1:12                                             ` Jere Sanisalo
2005-07-28  2:44                                               ` Jon Harrop
2005-07-28  4:49                                                 ` skaller
2005-07-28 19:48                                                   ` Jon Harrop
2005-07-28 21:32                                                     ` David Thomas
2005-07-28 22:31                                                       ` Jon Harrop
2005-07-29  1:44                                                         ` Michael Walter
2005-07-29  2:32                                                         ` David Thomas
2005-07-29  3:52                                                           ` skaller
2005-07-29 12:57                                                             ` David Thomas
2005-07-28 10:58                                               ` Gerd Stolpmann
2005-07-28 17:19                                         ` David Thomas
2005-07-28 19:22                                           ` Jon Harrop
2005-07-27 21:13                                       ` [Caml-list] How to do this properly with OCaml? Pal-Kristian Engstad
2005-07-27 22:28                                         ` skaller
2005-07-28  1:47                                           ` Michael Walter
2005-07-27 23:17                                         ` [Caml-list] Games Jon Harrop
2005-07-28  0:03                                         ` [Caml-list] How to do this properly with OCaml? Paul Snively
2005-07-28 18:26                                           ` Jonathan Bryant
2005-07-28 23:10                                             ` Paul Snively
2005-07-27 16:03                                   ` skaller
2005-07-26  1:01                               ` Stephane Glondu
2005-07-26  1:15                                 ` Brian Hurt
2005-07-27 15:33                                 ` skaller
2005-07-30 23:24                                   ` Thomas Fischbacher
2005-07-31  0:06                                     ` Jon Harrop
2005-07-31  3:10                                       ` skaller
2005-07-31  2:54                                     ` skaller
2005-07-26 20:32                               ` David Thomas
2005-07-27 15:05                               ` skaller
2005-07-27 15:29                                 ` Jon Harrop
2005-07-27 15:35                                   ` David Thomas
2005-07-27 20:11                                     ` skaller
2005-07-28 16:35                                       ` David Thomas
2005-07-30 23:33                                     ` Thomas Fischbacher
2005-07-31  0:39                                       ` james woodyatt
2005-07-27 19:59                                   ` skaller
2005-07-26  1:22                             ` Jon Harrop
2005-07-27 17:23                               ` skaller
2005-07-26  1:05                         ` Jon Harrop
2005-07-26  1:20                           ` Brian Hurt
2005-07-26  1:28                             ` Jon Harrop
2005-07-27 17:03                             ` skaller
2005-07-27 16:09                           ` skaller
2005-07-24 23:26               ` Brian Hurt
2005-07-25 17:21       ` Ken Rose
2005-07-25 19:19         ` skaller
2005-07-26  7:10           ` Alex Baretta
2005-07-23 18:58   ` Thomas Fischbacher

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).