There is no protocol for "truthiness", which is what you want. nil and false 
are false, everything else is true.

Even if there were a protocol for truthiness, you could not use :yes and :no 
(keywords), you would have to create your own custom type and implement the 
protocol on it. (Think about it: what if the truthiness of a *specific* keyword 
depended on application code you didn't write? E.g. if some library globally 
redefined the truthiness protocol on keywords so that :no is false?)

Clojure is philosophically opposed to making truthiness user-definable. Many 
other languages (including lisp and scheme) have not-very-simple truthiness 
rules that Clojure deliberately simplified. Allowing user-definable truthiness 
would bring all that complexity back *and then some*.

You have a problem-domain-specific use of :yes and :no and a 
problem-domain-specific notion of truthiness. You can either use functions 
which implement that domain notion (which you have done, and which is the best 
approach I think), or you can write your *own* protocol for this and extend it 
either to custom YES NO types or keywords.

You could also create a boundary in your application where you convert from a 
:yes-:no representation to a more native true-false.

It smells like a bad design that you have the *same* function and code 
accepting both :yes and :no *and* true and false. Since this is a 
domain-specific problem and type, it seems like the same code shouldn't be used 
in both cases. I.e., your "not" function should be:

(defn a-not [answer]
  (case answer
    :yes :no
    :no :yes
    (throw (ex-info (str "Not a valid questionnaire answer: " (pr-str answer)) 
{}))))


On Wednesday, January 14, 2015 at 2:50:21 PM UTC-6, Yehonathan Sharvit wrote:
> In my app, I am using :yes and :no sometimes instead of true and false.
> 
> 
> 
> 
> I’d like to know what is the best way to extends the `not` function to be 
> able to handle :yes and :no properly.
> 
> 
> 
> 
> I was expecting some kind of Boolean protocol but I wasn’t able to find it.
> 
> 
> 
> 
> I could write this:
> 
> 
> 
> 
> 
> 
> (defn not [x]
> 
>   (case x
> 
>     :yes :no
> 
>     :no :yes
> 
>     (cljs.core.not x)))
> 
> 
> 
> 
> (map not [false true :yes :no]); (true false :no :yes)
> 
> 
> 
> 
> But I’m not sure it is the most idiomatic solution.
> 
> Any ideas?
> 
> 
> 
> —
> Sent from Mailbox

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to