The set *is* a function (it implements IFn). complement accepts a
function as input, so that works.
Character/isWhitespace is a Java static method, which is not a first-
class function, and thus can't be passed directly to complement.
The #(...) syntax is shorthand for (fn [...] ...), which introduces a
new anonymous function. What you've written there is equivalent to
(defn whitespace? [c]
(Character/isWhitespace c))
(take-while (complement whitespace?) "the quick")
... i.e., you've made a function that calls a Java static method on
its input.
> Could I do something like that
> in my own code (not sure I'd want to, just curious what magic is at
> work here)?
In your Java code, implement IFn. That's the magic. In your Clojure
code, just hand around functions.
In addition to functions, several of Clojure's other objects are
"invokable"--they can operate successfully as the first item in a call
expression (a list in code).
Invoking a set returns the element in the set that's = to the argument
or nil
Invoking a map returns the value in the map whose corresponding key is
= to the argument or nil
Invoking a keyword requires a map as its argument and returns the
value in the map corresponding to the key that's = to the keyword or nil
"Being invokable" in Clojure is equivalent to implementing the IFn
interface. You can see in this diagram which objects in Clojure
implement IFn:
(IFn is at the lower right).
The core function "ifn?" can also let you know if something is
invokable:
Clojure 1.1.0-alpha-SNAPSHOT
user=> (ifn? #{:a :b :c})
true
user=> (ifn? 3)
false
user=> (fn? #{:a :b :c})
false
user=>
--Steve
For all those who want to understand how the class hierarchies map to
various Clojure abstractions, I have broken down that (rather
daunting) graph into separate areas in various slides from the
tutorial I gave at ILC09:
http://clojure.googlegroups.com/web/tutorial.pdf
There you can much more clearly see how the collections, seqs, refs,
and various concepts like
sequential/associative/counted/reversible/metadata/callability/java
collection/java interop are organized.
Rich