In terms of 'if, I was looking through some of pg's code just now, and noticed that he does use the wavy form of indentation. Thus, if you're big on proof by authority, the correct form of indentation for 'if would be the wavy one...
However, in this case I agree with Adlai: pg had even planned on getting ppr to "properly indent long ifs". I presume that means to implement the wavy feature. It's also the convention for Anarki, according to the CONVENTIONS file.
So, here's what I'm thinking should be done for ifs:
1) If you only have three expressions, if-then-else, use:
(if a
b
c)
1) If you like the format, and the expressions are very short use:
(if a b
c d
...
e)
3) If you don't like that form, or the expressions are longer, use:
(if (a )
(b )
(c )
(d )
(e ))
I'm not sure whether to use one or two spaces between clauses. The anarki conventions file uses two spaces. Elsewhere I've seen only one space. So, which is it? Now or never ;)
(I'm writing a new version of ppr with proper indentation of forms, in case you wanted to know why I'm so interested in the indentation question)
I think two is better, because it a) clearly distinguishes it as indentation (rather than just an accidental #\space), and b) it's consistent with the indentation of macros & co.
Should it depend on whether they fit on one line or not? If they don't fit, should it still be like b., just with the second part spilling onto the next line?
Your first version is the one currently implemented by ppr.arc. If you would like, you can write the indentation function for your second version (it can even include the "; else")
Otherwise I think that the first version is generally clearer, and the second is rarely needed, as the value of the case statement can't usually be very long. Could you give me an example where you use your second version?
Sure; here's something from my tagged-unions.arc on Anarki (Arc 2). It's responsible for parsing the types specified for slots in the tagged union:
(each type-frag types
; Assemble the ('type name) pairs into two lists, so that we can iterate
; through them.
(case (type type-frag)
; If it's a symbol, then we're defining a new name; add a new set of
; values, and go.
sym
(do
(zap [cons type-frag _] names)
(zap [cons nil _] values))
; Otherwise, we're adding a value to an existing variant.
cons
; I changed my mind about the order (now it's (name pred?) instead of
; (pred? name)), so I'm reversing it here.
(zap [cons (rev type-frag) _] (car values))
; else
(err "Invalid member of tagged union declaration.")))
I should also add (just as another data point) that my multi-condition ifs look like that too, and single-condition ifs look like the following:
(def macexn (n expr)
" Macroexpand `expr' `n' times. NB: `expr' *is* evaluated!
See also [[macex1]] [[macex]] "
(if (and (number n) (> n 0))
(macexn (- n 1) (macex1 expr))
expr))
I'm not hugely wedded to any of my conventions, though, and I haven't coded in Arc for quite a while anyway; this isn't intended to get you to change anything or convert people to my style. As I said, it's just another data point.