From: Michael Alexander Hamburg <hamburg@fas.harvard.edu>
To: Thomas Fischbacher <Thomas.Fischbacher@Physik.Uni-Muenchen.DE>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] How to do this properly with OCaml?
Date: Sat, 23 Jul 2005 01:00:27 -0400 (EDT) [thread overview]
Message-ID: <Pine.LNX.4.58.0507230057110.28297@ls01.fas.harvard.edu> (raw)
In-Reply-To: <Pine.LNX.4.61.0507221552070.27560@katrin.cip.physik.uni-muenchen.de>
I was constructing a binary heap of tuples the other day. After pondering
these options, I just used Obj.magic 0 as the null value in the array.
The heap was in a module, so nothing else could see the array, and I could
prove that the code never accessed the null elements, so the use of
Obj.magic seemed justified.
Mike
On Fri, 22 Jul 2005, Thomas Fischbacher wrote:
>
> 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)
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
next prev parent reply other threads:[~2005-07-23 5:00 UTC|newest]
Thread overview: 105+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-07-22 14:26 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 [this message]
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
2005-07-26 1:32 Jon Harrop
[not found] <200507271635.28931.jon@ffconsultancy.com>
2005-07-27 16:31 ` David Thomas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.58.0507230057110.28297@ls01.fas.harvard.edu \
--to=hamburg@fas.harvard.edu \
--cc=Thomas.Fischbacher@Physik.Uni-Muenchen.DE \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox