3 ms·
As simple as this: (defprotocol Foo (bar-ify [this])) (extend-type java.lang.String Foo (bar-ify [this] (.concat this "Bar"))) (bar-ify "He
by swannodette 17y ago
As simple as this:
(defprotocol Foo
(bar-ify [this]))
(extend-type java.lang.String
Foo
(bar-ify [this] (.concat this "Bar")))
(bar-ify "Hello world!")
Everything can be redefined interactively at the REPL. Also due to Rich Hickey's mad skills you get pretty much Java method dispatch performance.
EDIT: There is a gross misunderstanding about how this works. The following is invalid and will throw an exception, please take the time to understand this:
user> (ns baz)
baz> (bar-ify "foo")
Your changes will not affect use of java.lang.String in other libs.
- chousuke 17y agoI'd like to clarify that Protocols just generate a bunch of functions and a Protocol object (and an interface, but that's an implementation/interop detail). The functions are the interesting things in most cases. However, they're also namespaced like everything else. You can do the following though: user> (defprotocol Foo (describe [object])) user> (extend-type java.lang.String Foo (describe [string] "a String")) (ns bar) bar> (user/describe "String") -> "a String" bar> (extend-type java.lang.Object user/Foo (describe [obj] "an Object")) bar> (in-ns 'user) user> (describe 3) -> "an Object" user> (describe "Hello") -> "a String" So there is potential for two libraries extending the same things and causing a conflict if the semantics differ, but I'm not too concerned about that. It would be rather rude to extend someone else's protocol to cover someone else's java class without documenting that you do so.