Skip to content

Instantly share code, notes, and snippets.

@alandipert
Last active June 22, 2019 00:20
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save alandipert/2346460 to your computer and use it in GitHub Desktop.
Save alandipert/2346460 to your computer and use it in GitHub Desktop.
It's sweet that IFn is a protocol in ClojureScript
(extend-type js/RegExp
cljs.core/IFn
(-invoke ([this s] (re-matches this s))))
(#"foo.*" "foobar") ;=> "foobar"
(#"zoo.*" "foobar") ;=> nil
(filter #".*foo.*" ["foobar" "goobar" "foobaz"]) ;=> ("foobar" "foobaz")
@mjackson
Copy link

mjackson commented Apr 9, 2012

By way of explanation for anyone else who stumbles upon this gist, the IFn protocol is used for adding the ability to invoke an object as a function. In this example, instances of JavaScript's built-in RegExp constructor are made callable. This means you can use them in the same place you would normally use a function. As implemented, the result of invoking a RegExp object is the return value of the re-matches function using that regular expression and the given argument.

For those who understand JavaScript better than ClojureScript, this would be equivalent to the following JavaScript (which does not actually work, hence the sweet-ness):

var re = /abc/;
re('abc'); // "abc"
re('def'); // null

Copy link

ghost commented Apr 9, 2012

@fogus
Copy link

fogus commented Apr 11, 2012

It's a little known fact that ClojureScript does this (extends) already with strings to support keyword and symbol lookup. :-)

@mjackson
Copy link

@fogus Interesting! Could you point me to the source for this so I can see how it's done? I ack'd the ClojureScript source for extend-type and extend but didn't find the magic. :)

@alandipert
Copy link
Author

@mjijackson the behavior @fogus mentions is incidental, and is a result of the way :keywords are implemented atop JavaScript strings. That said, I would classify this behavior as seekrit and not sweet because it depends on implementation detail.

But then, maybe seekrit things are sweet?

@devn
Copy link

devn commented Mar 12, 2014

This Old Gist™

Despite the fact that this is seekrit I still point it out to clojure journeyfolk because I think it teaches deep Clojure by way of radical ClojureScript in one beautiful motion.

@mfikes
Copy link

mfikes commented Jan 17, 2016

@alandipert
Copy link
Author

@mfikes I can understand keywords, but why are symbols functions of collections? That seems like a juicy one to leave open for users.

Edit
Nevermind, answered my own question. Clojure does the same thing, which must have been the rationale. Fortunately regexes and many other atoms are available for IFn extension 😈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment