clojure-style-guide icon indicating copy to clipboard operation
clojure-style-guide copied to clipboard

Suffixing names of boolean values with a question mark?

Open danielcompton opened this issue 6 years ago • 16 comments

When writing Clojure, I often will add a ? suffix to any boolean let bindings or defs. There is a strong convention of doing this for functions that return booleans.

Is there similar consensus that names of boolean values should be suffixed with a question mark?

See https://github.com/bbatsov/clojure-style-guide/issues/136 as a similar issue, as well as https://guide.clojure.style/#pred-with-question-mark.

danielcompton avatar Jul 26 '19 21:07 danielcompton

Is there similar consensus that names of boolean values should be suffixed with a question mark?

Let's ask around. I don't do it myself (mostly because I'm too used to Ruby where this is not support for variables, only for methods), but I've seen many people doing so.

bbatsov avatar Jul 30 '19 07:07 bbatsov

+1 for appending ? to boolean values as well as functions that return a boolean.

alexanderjamesking avatar Jul 30 '19 07:07 alexanderjamesking

Another :+1: for ? as a convention.

chrisglass avatar Jul 30 '19 07:07 chrisglass

I regularly use ?, even for keywords indicating a boolean value in a map.

manuel-uberti avatar Jul 30 '19 07:07 manuel-uberti

I usually do this in bindings (argument names, local bindings, etc) and var names that are intended as predicates, but not for configured values in EDN files or metadata. This seems to be consistent with how it's done in Clojure and ClojureScript. You have int?, string?, etc., but :private, :macro, etc. in metadata:

user=> (defmacro ^:private odd? [x])
#'user/odd?
user=> (meta #'odd?)
{:private true, :arglists ([x]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name odd?, :ns #object[clojure.lang.Namespace 0x5d1659ea "user"], :macro true}

Also note the boolean configuration options for the ClojureScript compiler have no question marks:

http://cljs.github.io/api/compiler-options/

So maybe:

  • settings/stating facts/dealing with serialized data: no question mark
  • asking questions (predicates): a question mark

borkdude avatar Jul 30 '19 07:07 borkdude

That's also what we do at Pitch

ioRekz avatar Jul 30 '19 08:07 ioRekz

I do it only occasionally, in cases where it is really important for that particular binding to stick out. I think that recommending that for all boolean variables would raise lots of confusion, since in clojure anything can be treated as logical true/false. Whether something is boolean or just a regular logical value is not that important in most cases. Another source of confusion would be that, since predicated are suffixed with ?, it would be visually less obvious what is a predicate function and what is a boolean local binding...

blueberry avatar Jul 30 '19 09:07 blueberry

Another consideration for the style guide:

  • IF you are using ? for a predicate THEN your function is expected to return a boolean.

There was a lot of debate when Rich introduced a question-marked predicate in 1.7-1.9 (I can't remember which release) that didn't return a boolean. Eventually he changed it.

borkdude avatar Jul 30 '19 09:07 borkdude

I always do this for fns, defs and keywords in maps for boolean values.

superstructor avatar Jul 30 '19 14:07 superstructor

I'm not that experienced at programming so I might be completely misunderstanding the question.

If you are suffixing a boolean value with a question mark instead of a function that returns a boolean then that seems wrong to me as a function that returns a boolean is a question and so it makes sense to suffix it with a question mark whereas a boolean value is not a question but can be an answer to a question.

SarmBoJim avatar Jul 31 '19 10:07 SarmBoJim

While I'm strongly in favor of ? on predicate functions -- and those should return only true or false -- I am against it on keywords for readability and because Clojure and ClojureScript seem to avoid ? on keywords even when they are simple Boolean flags.

I'm on the fence for local symbol bindings but lean toward not using ? on Boolean locals because I think it feels more of an arbitrary delineation between truthy locals and Boolean locals.

So my preference is ? on predicate functions only.

seancorfield avatar Jul 31 '19 18:07 seancorfield

I definitely tend towards "?" For functions, not values. I generally use that to indicate "return value should be used for it's truthiness" without strictly meaning "Boolean", since it seems like Boolean are second class citizens in Clojure (needed only for interop, since truthiness is conventionally indicated by nil in Clojure)

WorldsEndless avatar Aug 01 '19 11:08 WorldsEndless

[to qualify my comment: I do not have nearly as much experience with Clojure as the other commenters here so take this into context please & feel free to ignore]

I do like the elegance of the naming convention to use the ? suffix for predicate functions. It makes them easy for me to identify. They convey a useful implicit contract:

  • takes 1 argument
  • returns a boolean

(They might also work with 0 arguments and more than 1 argument on occasion but that's orthogonal additive functionality.)

Additional thought: mnemonically I read the ? as an indicator that work / thought might be done to "produce" the boolean.

I think it often causes more confusion than clarity to have similar but slightly different things seem the same.

tosh avatar Aug 01 '19 12:08 tosh

We suffix variables as well as keywords in maps with ? when they're intended to be used as boolean values at Metabase.

Personally I think it enhances readability. Let's say you have a function create-session! that can create a session for a user or some other sort of Session, e.g.

(defn create-session! [& {:keys [user-session?]}]
  (if user-session?
    #_(create user session...)
    #_(create non-user session...)))

It's pretty clear that user-session? is an option rather than some sort of existing session. Compare:

(defn create-session! [& {:keys [user-session]}]
  (if user-session
    #_(create user session...)
    #_(create non-user session...)))

It's not immediately clear whether user-session is a boolean option or some sort of existing session you can pass in. Of course, one could argue that user-session itself is a bad name, or that a docstring would fix this, but either way it seems to me like a ?-suffixed variable is always clearer, so there's no downside to adopting it as a convention.

camsaul avatar Aug 05 '19 23:08 camsaul

I do this on functions return boolean but not on boolean values 👀

liuchong avatar Apr 28 '20 03:04 liuchong

one could argue that user-session itself is a bad name, or that a docstring would fix this

Yes, I think it would be more appropriate to name it user-session-exists and get rid of the ?.

gphilipp avatar Mar 09 '22 18:03 gphilipp