It's already possible, but metadata is the wrong tool. Wrap all return values that "might" have multiple values in a vector, and return/bind as many elements as you want. Add macros to make it less ugly, stir awhile, and you have multiple values.
Using metadata for this purpose would have real problems: the metadata for multiple-values would bubble up unintentionally from some functions, and not from others, giving the mistaken impression that the higher-level functions are returning multiple values. Consider: (defn values [v & vs] (vary-meta v assoc ::values vs)) (defmacro mv-bind [names val & body] `(let [~names (cons ~val (-> ~val meta ::values))] ~@body)) (mv-bind [x y] (values {:age 20} "steve") (if-not y x (assoc x :name y))) This all looks good (aside from the fact that it won't work for types that can't have metadata, such as integers), right? But from what I understand of Common Lisp (and that's not a lot), this is a broken version of its multiple values. Specifically, a function that's not concerned at all with multiple values, such as conj, will accidentally return multiple values if its args were carrying around multiple-value metadata: (mv-bind [x y] (conj (values [1 2] "whatever") 3 4) [x y]) ; returns [[1 2 3 4] "whatever"]! In contrast, here's a snippet of me trying something similar at an SBCL repl: * (multiple-value-bind (x y) (values 1 2) (list x y)) (1 2) * (multiple-value-bind (x y) (identity (values 1 2)) (list x y)) (1 NIL) On Mar 25, 9:19 am, Joop Kiefte <iko...@gmail.com> wrote: > Would it be possible to create something like CL's multiple values this way? > > 2011/3/25 James Reeves <jree...@weavejester.com>: > > > > > > > > > On 25 March 2011 10:41, msappler <msapp...@web.de> wrote: > >> Never used metadata until now. > > >> I had an insight yesterday that I want to share with you: > > >>http://resatori.com/metadata-insight > > > In my view, it depends whether your :id key is a surrogate key or a natural > > key. > > > Object metadata should not affect object equality, so if your :id key > > is just an internal database identifier, you could include it as > > metadata. > > > But if your :id key is exposed to the outside world, then it should > > not be metadata, because changing the :id would change the external > > representation of the object, and therefore affect equality. > > > I should also point out that if you want information hiding, then > > object composition might be a better solution. For example: > > > (defprotocol Identifiable > > (id [self] "Return an object's unique id")) > > > (deftype DBRef [db-id data] > > Identifiable > > (id [_] db-id) > > clojure.lang.IDeref > > (deref [_] data)) > > > (defn db-ref [id data] > > (DBRef. id data)) > > > Then we can get information about the reference, and deref it to get > > its contents: > > > (def user > > (db-ref 193 {:login "fred"})) > > > => (id user) > > 193 > > => @user > > {:login fred} > > > - James > > > -- > > 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 -- 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