* [Caml-list] Closure & Ref @ 2003-11-17 19:37 chris.danx 2003-11-17 21:02 ` Dustin Sallings 2003-11-17 21:43 ` Brian Hurt 0 siblings, 2 replies; 5+ messages in thread From: chris.danx @ 2003-11-17 19:37 UTC (permalink / raw) To: caml-list Hi, I was toying with ocaml just now and have successfully written a function that takes and int that produces a function that takes an int to add to the original. let prodAdd x = let value = ref x in fun y -> !value + y;; Now I want to do a function that takes a ref to a list and returns a function that adds items to the list and produce a function that returns another that returns the list. How do I do that? let prod_list_acc a = fun x -> a := x :: !a; true;; let return_acc a = fun () -> !a;; but that gives a "unit -> int list" =. How do you get a copy of the list values? This might seem like a crazy thing to do but I am toying with an idea relating to a paper I read on traits. Instead of having classes at all you can just have traits, closures and mutable values. 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] 5+ messages in thread
* Re: [Caml-list] Closure & Ref 2003-11-17 19:37 [Caml-list] Closure & Ref chris.danx @ 2003-11-17 21:02 ` Dustin Sallings 2003-11-17 21:48 ` Dustin Sallings 2003-11-17 21:43 ` Brian Hurt 1 sibling, 1 reply; 5+ messages in thread From: Dustin Sallings @ 2003-11-17 21:02 UTC (permalink / raw) To: chris.danx; +Cc: caml-list On Nov 17, 2003, at 11:37, chris.danx wrote: > let prodAdd x = > let value = ref x in > fun y -> !value + y;; This is very similar to let prodAdd x y = x + y;; The only difference is that I'm making a reference with the value of x. # let prodAdd x = let value = ref x in fun y -> !value + y;; val prodAdd : int -> int -> int = <fun> # let prodAdd2 x y = x + y;; val prodAdd2 : int -> int -> int = <fun> # prodAdd 1 2;; - : int = 3 # prodAdd2 1 2;; - : int = 3 # prodAdd 1;; - : int -> int = <fun> # prodAdd2 1;; - : int -> int = <fun> > Now I want to do a function that takes a ref to a list and returns a > function that adds items to the list and produce a function that > returns another that returns the list. How do I do that? > > let prod_list_acc a = > fun x -> a := x :: !a; true;; > > let return_acc a = > fun () -> !a;; > > but that gives a "unit -> int list" =. How do you get a copy of the > list values? > > > This might seem like a crazy thing to do but I am toying with an idea > relating to a paper I read on traits. Instead of having classes at > all you can just have traits, closures and mutable values. That's not a very functional style. It does seem to work for me with the following syntax, though: # let list_acc a x = a := x :: !a; ();; val list_acc : 'a list ref -> 'a -> unit = <fun> # let return_list a = !a;; val return_list : 'a ref -> 'a = <fun> # return_list a;; - : int list = [1; 2; 3; 4; 5] # list_acc a 6;; - : unit = () # return_list a;; - : int list = [6; 1; 2; 3; 4; 5] -- Dustin Sallings ------------------- 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] 5+ messages in thread
* Re: [Caml-list] Closure & Ref 2003-11-17 21:02 ` Dustin Sallings @ 2003-11-17 21:48 ` Dustin Sallings 0 siblings, 0 replies; 5+ messages in thread From: Dustin Sallings @ 2003-11-17 21:48 UTC (permalink / raw) To: Dustin Sallings; +Cc: caml-list, chris.danx On Nov 17, 2003, at 13:02, Dustin Sallings wrote: >> let prodAdd x = >> let value = ref x in >> fun y -> !value + y;; > > This is very similar to > > let prodAdd x y = x + y;; > > The only difference is that I'm making a reference with the value of > x. I don't know what happened to this sentence. It should read something more like, ``The only difference is that you're making a reference with the value of x unnecessarily.'' -- Dustin Sallings ------------------- 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] 5+ messages in thread
* Re: [Caml-list] Closure & Ref 2003-11-17 19:37 [Caml-list] Closure & Ref chris.danx 2003-11-17 21:02 ` Dustin Sallings @ 2003-11-17 21:43 ` Brian Hurt 2003-11-17 21:35 ` chris.danx 1 sibling, 1 reply; 5+ messages in thread From: Brian Hurt @ 2003-11-17 21:43 UTC (permalink / raw) To: chris.danx; +Cc: caml-list On Mon, 17 Nov 2003, chris.danx wrote: > Hi, > > I was toying with ocaml just now and have successfully written a > function that takes and int that produces a function that takes an int > to add to the original. > > let prodAdd x = > let value = ref x in > fun y -> !value + y;; Since you're not setting the reference, why have one? Instead, try: let prodAdd x = fun y -> x + y But we can do it simpler than that: let prodAdd x y = x + y And use partial function application. (prodAdd 4) returns a function which adds 4 to whatever int parameter passed to it. > > Now I want to do a function that takes a ref to a list and returns a > function that adds items to the list and produce a function that returns > another that returns the list. How do I do that? > > let prod_list_acc a = > fun x -> a := x :: !a; true;; > > let return_acc a = > fun () -> !a;; > > but that gives a "unit -> int list" =. How do you get a copy of the > list values? Now you're setting the reference. But prod_list_acc and return_acc need to share the reference. Now, I for one, hate globals. This is the result of programming for years in C. What I would do is write a function which returns a tuple of two functions, and accumlator function and a current list function, like: let make_listacc () = let r: int list ref = ref [] in let acc x = r := x :: !r and lst () = !r in acc, lst ;; This allows you to have multiple different lists being constructed independently. Note, the above code is actually more generic than it looks- I had to add an explicit type statement to make it "come out correct". Without the explicit type information: let make_listacc () = let r = ref [] in let acc x = r := x :: !r and lst () = !r in acc, lst ;; The function is both clearer than the original, and creates lists of any type, not just ints. If you hear me bitching about C++ and Java making generics "special and extraordinary", this is a classic example of what I'm kvetching about. You'd use make_listacc like: let my_acc, my_list = make_listacc() in my_acc 3; my_acc 4; my_acc 5; my_list () ;; The above code returns [5;4;3] (note, the list is built backward!). The most common way to access members of a list is to use what is called "list comprehensions". Don't let the names fool you- these are just functions that walk the list and do something on every element of the list. Look at List.iter and List.fold_left. So let's say I want to take a list of ints and sum them. I could simply do: List.fold_left (fun x y -> x + y) 0 lst Note that + is just a function, so I could just as easily have done: List.fold_left (+) 0 lst to do the same thing. The second most common way to access members of a list is to write a short recursive function. Say I wanted to know if the list contained a given number. I might write: let rec has_num x = function | [] -> false | h :: t -> if (h == x) then true else has_num x t ;; If you want to access specific members of a list (other than the head), I wouldn't recommend using a list, but instead some other datastructure (an array or hash table being the obvious choices). -- "Usenet is like a herd of performing elephants with diarrhea -- massive, difficult to redirect, awe-inspiring, entertaining, and a source of mind-boggling amounts of excrement when you least expect it." - Gene Spafford 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] 5+ messages in thread
* Re: [Caml-list] Closure & Ref 2003-11-17 21:43 ` Brian Hurt @ 2003-11-17 21:35 ` chris.danx 0 siblings, 0 replies; 5+ messages in thread From: chris.danx @ 2003-11-17 21:35 UTC (permalink / raw) To: Brian Hurt; +Cc: caml-list Brian Hurt wrote: > Since you're not setting the reference, why have one? Instead, try: > > let prodAdd x = fun y -> x + y > > But we can do it simpler than that: > > let prodAdd x y = x + y > > And use partial function application. (prodAdd 4) returns a function > which adds 4 to whatever int parameter passed to it. I didn't know OCaml had partial function application, thanks! I have programmed in Haskell before, but never got seriously into it (the things I wanted to do like IO where "advanced" in Haskell, whereas they're basic to me. That's one reason I want to learn OCaml, it doesn't so hard to do trivial interaction). > This allows you to have multiple different lists being constructed > independently. Note, the above code is actually more generic than it > looks- I had to add an explicit type statement to make it "come out > correct". Without the explicit type information: > > let make_listacc () = > let r = ref [] in > let acc x = r := x :: !r > and lst () = !r > in acc, lst > ;; > > The function is both clearer than the original, and creates lists of any > type, not just ints. If you hear me bitching about C++ and Java making > generics "special and extraordinary", this is a classic example of what > I'm kvetching about. I hear you. From my previous spell in FP I really got to like the ease of "generics" which are inconvient in C++ and a pain in Ada. GUIs and IO was just easier. [snip] > If you want to access specific members of a list (other than the head), I > wouldn't recommend using a list, but instead some other datastructure (an > array or hash table being the obvious choices). It was just a toy example to see if I could get that aspect of this idea to work in OCaml. Hmm... Thanks! ------------------- 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] 5+ messages in thread
end of thread, other threads:[~2003-11-17 21:48 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2003-11-17 19:37 [Caml-list] Closure & Ref chris.danx 2003-11-17 21:02 ` Dustin Sallings 2003-11-17 21:48 ` Dustin Sallings 2003-11-17 21:43 ` Brian Hurt 2003-11-17 21:35 ` chris.danx
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox