Hi All,
I quite like Clojure but have been confused from time to time on particular
design choices. I find understanding the root cause of these decisions
helps to understand the language better. As example, the fact that
complement and not are separate functions has been puzzling me for a bit
[1]. The implementation of not and complement is roughly;
(defn not [x] (if x false true))
(defn complement [f]
(fn
([] (not (f)))
([x] (not (f x)))
([x y] (not (f x y)))
([x y & zs] (not (apply f x y zs)))))
What I'm wondering is if it's purely for performance, historical or idiomatic
reasons that it's not;
(defn fnot [arg]
(if (ifn? arg)
(fn
([] (fnot (arg)))
([x] (fnot (arg x)))
([x y] (fnot (arg x y)))
([x y & zs] (fnot (apply arg x y zs))))
(if arg false true)))
Perhaps a multi-method could also be appropriate here, though I'm not exactly
certain what the appropriate dispatch function would be. I follow why bit-not
is a separate function as the intended meaning is clearly different, but the
implied meaning of not seems to be the same as complement which is why it seems
odd that they are different methods.
After doing some experimentation with these, I finally realized that (not
identity) yields false, but I'm not quite following that use case. I'm guessing
the idiomatic argument against fnot is that it would complect not and
complement unnecessarily?
While pouring through the clojure.core source, I also saw a few functions like
not-every? which use (comp not every?) instead of (complement every?). This led
me to question why complement is not implemented as;
(defn complement [f] (comp not f))
Is there a difference that I'm just not seeing? Or is that just a side effect
of either performance or dependency ordering in clojure.core [2].
I think I may have answered my own question concerning fnot in a roundabout
manner, but I found the process of discovering this illuminating. Can anyone
else shed light on this, or am I correct in concluding that fnot would complect
not and complement?
Thanks,
Charlie
1. I frequently misread comp as complement and not compose in point free code,
so perhaps that confusion is why complement is oddly jarring to me.
2. not-every? and not-any? are implemented using def instead of defn and
manually set meta :arglist, despite defn already being defined, is this just
for historical reasons?
--
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