chansey97
2020-12-2 21:41:09

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.


notjack
2020-12-2 21:45:05

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


chansey97
2020-12-2 21:57:49

@notjack I read this article you mentioned. But 1 break Rectangle Rule?


notjack
2020-12-2 21:59:03

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


chansey97
2020-12-2 22:01:15

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.


notjack
2020-12-2 22:04:14

another handy rule I like to follow is “prefer to break at the highest level of syntactic nesting”


notjack
2020-12-2 22:05:48

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)))


notjack
2020-12-2 22:07:16

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])])


chansey97
2020-12-2 22:07:49

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))] ))


notjack
2020-12-2 22:10:23

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))


notjack
2020-12-2 22:14:47

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))]))


chansey97
2020-12-2 22:20:05

It seems a good way. Thanks.