Re: Idiomatically returning one or two values from a function.
On Wed, Sep 28, 2011 at 12:15, Daniel Solano Gomez cloj...@sattvik.com wrote: On Wed Sep 28 18:52 2011, Daniel Pittman wrote: I have problem that I have been thrashing back and forth over the best design of for a week now, and I can't work out the nicest way to handle it. Specifically, I have a collection of functions that return a primary result, and might also return a secondary annotation about that result. Why not always return a vector? That is more or less what a tuple is. *nod* Thanks, to you, and the other contributors. That feels like the right answer, and I guess I was hung up on not forcing a single value to be returned in a wrapper so much that I couldn't see it staring at me. Daniel -- ♲ Made with 100 percent post-consumer electrons -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Idiomatically returning one or two values from a function.
Meikel Brandmeyer m...@kotka.de writes: you can return always a vector. (fn [] [true]) (fn [] [true {:foo 12}]) And then use destructuring on the return value. (let [[value annotations] (...)] (when annotations ..)) My first idea was to add metadata to the return value, but that doesn't work for java types like Boolean. As a workaround, you could let your functions return (defn foo [] ;; calculate real-return-val (with-meta (constantly real-return-val) {:foo 1, :bar 2})) Wrap that in a `annotated-return' macro and always use that in your functions. The cost is, that now `foo' returns a function returning the result, so you have to call it using ((foo)) or (apply (foo))... But at least you can then do (let [f (foo) r (f) m (meta f)] ;; the result is r, the metadata is m ) Again, wrap that in some `annotated-call' macro, so that you can do (annotated-call foo [result meta] (do-stuff-with result meta)) Hm, but well, that's only a workaround. Metadata could be so useful if it was possible to attach it to anything, not only anything in clojure. I myself once had the need to put metadata on java objects, but that doesn't work either... Bye, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Idiomatically returning one or two values from a function.
G'day. I have problem that I have been thrashing back and forth over the best design of for a week now, and I can't work out the nicest way to handle it. Specifically, I have a collection of functions that return a primary result, and might also return a secondary annotation about that result. The current implementation is: (fn [] true) ; primary only (fn [] (annotated-return true {:foo 12})) ; with annotation `annotated-return` actually wraps a record, and then the handling code can determine if the result is specifically that type, or if it is anything else, to select between the two cases. In a bunch of other languages I would use a `pair` or `tuple`, but Clojure doesn't have a native type that maps closely to that. Worse, though, it doesn't have a native type that isn't a valid return from one of these methods. (Set, Vector, List, and Map are all used. :) The alternatively I can think of are limited: I don't like the idea of guessing based on a two element vector return or so, since I want this to be pretty much impossible to accidentally break. I considered using meta-data, but that can't attach to a primitive value, and those are definitely valid results. So, is there a better way to do this? At this point I am tempted to step aside from functional code, and use stateful mutation of some sort to maintain the annotations: (fn [] (annotate-by-side-effort {:foo 12}) true) Daniel -- ♲ Made with 100 percent post-consumer electrons -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Idiomatically returning one or two values from a function.
On Wed Sep 28 18:52 2011, Daniel Pittman wrote: G'day. I have problem that I have been thrashing back and forth over the best design of for a week now, and I can't work out the nicest way to handle it. Specifically, I have a collection of functions that return a primary result, and might also return a secondary annotation about that result. The current implementation is: (fn [] true) ; primary only (fn [] (annotated-return true {:foo 12})) ; with annotation `annotated-return` actually wraps a record, and then the handling code can determine if the result is specifically that type, or if it is anything else, to select between the two cases. In a bunch of other languages I would use a `pair` or `tuple`, but Clojure doesn't have a native type that maps closely to that. Worse, though, it doesn't have a native type that isn't a valid return from one of these methods. (Set, Vector, List, and Map are all used. :) The alternatively I can think of are limited: I don't like the idea of guessing based on a two element vector return or so, since I want this to be pretty much impossible to accidentally break. Why not always return a vector? That is more or less what a tuple is. (fn [] [true]) ; primary only (fn [] [true {:foo 12}]) ; with annotation That way, your data is always (first x) and your metadata is always (second x). If you want to use something more typed-like, you could return a map: (fn [] {:result true}) (fn [] {:result true :metadata {:foo 12}}) For this approach, you could write helper functions to make the code less painful to read and write. If performance is a concern, you can try a record. I considered using meta-data, but that can't attach to a primitive value, and those are definitely valid results. So, is there a better way to do this? At this point I am tempted to step aside from functional code, and use stateful mutation of some sort to maintain the annotations: (fn [] (annotate-by-side-effort {:foo 12}) true) Daniel -- ♲ Made with 100 percent post-consumer electrons -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en signature.asc Description: Digital signature
Re: Idiomatically returning one or two values from a function.
Hi, you can return always a vector. (fn [] [true]) (fn [] [true {:foo 12}]) And then use destructuring on the return value. (let [[value annotations] (...)] (when annotations ..)) Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en