From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id LAA18168; Fri, 5 Jul 2002 11:25:54 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id LAA18075 for ; Fri, 5 Jul 2002 11:25:53 +0200 (MET DST) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by concorde.inria.fr (8.11.1/8.11.1) with ESMTP id g659Pqf13777; Fri, 5 Jul 2002 11:25:52 +0200 (MET DST) Received: (from xleroy@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id LAA18331; Fri, 5 Jul 2002 11:25:51 +0200 (MET DST) Date: Fri, 5 Jul 2002 11:25:51 +0200 From: Xavier Leroy To: Francois Pottier Cc: caml-list@inria.fr Subject: Re: [Caml-list] Re: generic programming Message-ID: <20020705112551.B16273@pauillac.inria.fr> References: <200207030246.WAA28665@dewberry.cc.columbia.edu> <4.3.2.7.2.20020703102610.0248b280@mail.d6.com> <3D246739.4030204@ozemail.com.au> <20020705104249.B14853@pauillac.inria.fr> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Mailer: Mutt 1.0i In-Reply-To: <20020705104249.B14853@pauillac.inria.fr>; from francois.pottier@inria.fr on Fri, Jul 05, 2002 at 10:42:49AM +0200 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk > On Fri, Jul 05, 2002 at 01:18:17AM +1000, John Max Skaller wrote: > > > > Only two data structures in Ocaml readily admit iterators: lists and arrays. > > Other data structures like hastables, sets, maps, etc, have control > > inverted iterators, which are much weaker (that is, you have to provide > > a callback which is given each value in turn I guessed this is what John had in mind :-) Actually, if you're desperate, you can derive a C++-style iterator from a higher-order functional iterator (of the kind provided by the OCaml standard library) by "inverting the control", using threads or call/cc. See example below. Of course, I'm not advocating that anyone should use this trick in actual programs. Like François, I find functional iterators so much cleaner and better structured. Moreover, the extra "power" of imperative iterators isn't obvious to me. For instance, one could argue that imperative iterators allow iterating in parallel over several data structures. This is true, but how useful is iterating over two hashtables in parallel, knowing that you will *not* scan matching keys at the same time? - Xavier Leroy exception End_of_iteration let hashtbl_enumerator (h, chan) = Hashtbl.iter (fun key data -> Event.sync (Event.send chan (Some(key, data)))) h; Event.sync (Event.send chan None) class ['a,'b] hashtbl_iterator (h : ('a, 'b) Hashtbl.t) = object val chan = Event.new_channel () initializer (ignore (Thread.create hashtbl_enumerator (h, chan))) method next_element = match Event.sync (Event.receive chan) with None -> raise End_of_iteration | Some e -> e end ------------------- 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