Cool, so I guess it's the clojure of equivalent of Ruby's eigenclasses: f = "some object" class << f def foo "new foo method on f" end end
f.foo # => "new foo method on f" It's a shame this mechanism only works for values implementing IMeta, but I understand the JVM is a little prohibitive in this regard. Even so I suppose the main use of this is that it lets a caller give you a value, and you can return a plussed up version with new capabilities, without having to return a wrapped value. Wrapped values are sometimes problematic because they introduce new representations of existing types, and this allows an API to return values to the caller that behave the same as what went in. Neat! R. On Tue, 6 Nov 2018 at 15:51, Alex Miller <a...@puredanger.com> wrote: > > On Tuesday, November 6, 2018 at 9:25:31 AM UTC-6, John Schmidt wrote: >> >> Nice to see continued progress on Clojure 1.10! >> >> It is not clear to me what metadata extension provides that is not >> already possible with direct definitions or external extensions. Some >> additional background or a small motivating example would be much >> appreciated in clearing up the confusion! >> > > Metadata extension allows you to implement protocols on a per-value basis > (the others are type/class-oriented). This opens up a whole new range of > potential uses for protocols. Rich was already using this approach for the > new datafy/nav functionality - this made it generic for all protocols. > > Any collection instance can carry metadata, so you can take any collection > instance and dynamically extend a protocol to it by adding metadata. So if > you think about something like Component, which has a Lifecycle protocol > for start/stop, you can now make lightweight components without needing to > make a type or reify: > > $ clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.10.0-beta5"}, > com.stuartsierra/component {:mvn/version "0.3.2"}}}' > Clojure 1.10.0-beta5 > user=> (require '[com.stuartsierra.component :as component]) > nil > user=> (def c (with-meta {:state :init} > {`component/start (fn [c] (assoc c :state :started)) > `component/stop (fn [c] (assoc c :state :stopped))})) > #'user/c > user=> (component/start c) > {:state :started} > user=> (component/stop c) > {:state :stopped} > > > -- > 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 unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.