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 <[email protected]> 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 [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected].
> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.