Is there any style convention of match
? For example: ;; 1.
(match exp
[pat1 body1]
[pat2 body2])
vs ;; 2.
(match exp
[pat1
body1]
[pat2
body2])
For nested match
;; 1.
(match exp
[pat1 (match exp
[pat body])]
[pat2 (match exp
[pat body])])
vs ;; 2.
(match exp
[pat1
(match exp
[pat1
body1]
[pat2
body2])
[pat2
(match exp
[pat1
body1]
[pat2
body2])])
Do you use the first or the second style? I currently use the first style.
In your first example, I write it like 1 if a clause has only one body form and the pattern and body form fit on one line, otherwise I write it like 2. In your second example, I write it like 2. I mostly do it that way because of something called the Rectangle Rule that I picked up from google’s java formatting conventions: https://github.com/google/google-java-format/wiki/The-Rectangle-Rule
@notjack I read this article you mentioned. But 1 break Rectangle Rule?
it doesn’t if each clause fits on one line. pat1
, body1
, pat2
, body2
, [pat1 body1]
, [pat2 body2]
each get their own rectangle that way
I use racket-mode
to format my code. It seems it is impossible to break the the Rectangle Rule, if using racket-mode
to format code.
another handy rule I like to follow is “prefer to break at the highest level of syntactic nesting”
so if you’ve got this: (long-function-name (longer-function-name (long-argument) (another-long-argument)))
I would prefer to indent it like this: (long-function-name
(longer-function-name (long-argument) (another-long-argument)))
and would avoid indenting it like this: (long-function-name (longer-function-name
(long-argument) (another-long-argument)))
hence why I prefer this: (match exp
[pat1
(match exp
[pat1 body1]
[pat2 body2])])
and not this: (match exp
[pat1 (match exp
[pat1 body1]
[pat2 body2])])
A more complicated example: PS: Just a example for nested match
, this code can be abstracted further. (define (recognize ps count)
(match ps
[(list) (match count
[(ZERO) #t]
[(SUCC c) #f]
)]
[(list #\) xs ...) (match count
[(ZERO) #f]
[(SUCC c) (recognize xs c)]
)]
[(list #\( xs ...) (recognize xs (SUCC count))]
))
vs (define (recognize ps count)
(match ps
[(list)
(match count
[(ZERO) #t]
[(SUCC c) #f]
)]
[(list #\) xs ...)
(match count
[(ZERO) #f]
[(SUCC c) (recognize xs c)]
)]
[(list #\( xs ...)
(recognize xs (SUCC count))]
))
The first code snippet seems more readable.
It might be nice, if racket-mode
can align the match
the clauses (define (recognize ps count)
(match ps
[(list) (match count
[(ZERO) #t]
[(SUCC c) #f]
)]
[(list #\) xs ...) (match count
[(ZERO) #f]
[(SUCC c) (recognize xs c)]
)]
[(list #\( xs ...) (recognize xs (SUCC count))]
))
I would actually just write your second snippet like this: (define (recognize ps count)
(match ps
[(list) (match count [(ZERO) #t] [(SUCC c) #f])]
[(list #\) xs ...) (match count [(ZERO) #f] [(SUCC c) (recognize xs c)])]
[(list #\( xs ...) (recognize xs (SUCC count))]))
because no newlines are needed to make the clauses fit in a single line (assuming you’re using the 102 columns limit in the racket style guide (yes, 102 columns, not 100, no I do not know what the point of the extra 2 columns is))
you might also be interested in match*
which lets you match on multiple values at once: (define (recognize ps count)
(match* (values ps count)
[((list) (ZERO)) #true]
[((list) (SUCC c)) #false]
[((list #\) xs ...) (ZERO)) #false]
[((list #\) xs ...) (SUCC c)) (recognize xs c)]
[((list #\( xs ...) _) (recognize xs (SUCC count))]))
It seems a good way. Thanks.