| 4 | | == Bracketing Syntax == |
| 5 | | |
| 6 | | Due to the generality added to comprehensions by the paper, it now makes sense to allow bracketing of qualifiers. An example from the paper is: |
| 7 | | |
| 8 | | {{{ |
| 9 | | xs = [1,2] |
| 10 | | ys = [3,4] |
| 11 | | zs = [5,6] |
| 12 | | |
| 13 | | p1 = |
| 14 | | [ (x,y,z) |
| 15 | | | ( x <- xs |
| 16 | | | y <- ys ) |
| 17 | | , z <- zs ] |
| 18 | | |
| 19 | | p2 = |
| 20 | | [ (x,y,z) |
| 21 | | | x <- xs |
| 22 | | | ( y <- ys |
| 23 | | , z <- zs ) ] |
| 24 | | }}} |
| 25 | | |
| 26 | | This results in: |
| 27 | | |
| 28 | | {{{ |
| 29 | | p1 = [(1,3,5), (1,3,6), (2,4,5), (2,4,6)] |
| 30 | | p2 = [(1,3,5), (2,3,6)] |
| 31 | | }}} |
| 32 | | |
| 33 | | Unfortunately, there is a practical problem with using brackets in this way: doing so causes a reduce/reduce conflict in the grammar. Consider this expression: |
| 34 | | |
| 35 | | {{{ |
| 36 | | [foo | (i, e) <- ies] |
| 37 | | }}} |
| 38 | | |
| 39 | | When the parser reaches the bracket after "e" it is valid to either reduce "(i, e)" to a pair of qualifiers (i.e. i and e are treated as guard expressions), OR to reduce it to the tuple expression (i, e) which will be later converted to a pattern. There are a number of alternative ways we could solve this: |
| 40 | | |
| 41 | | * Disallow bracketing of qualifiers altogether! |
| 42 | | * This keeps the concrete syntax simple and should cover all common use cases |
| 43 | | * It does reduce the composability of the qualifier syntax rather drastically however |
| 44 | | * Keep bracketing in this manner but use type information to resolve the ambiguity |
| 45 | | * I will need to change the parser to consider qualifiers as expressions so that we can parse without any reduce/reduce conflicts |
| 46 | | * We can then always use type information to determine which reading is correct, because guards are always boolean, and so can be distinguished from tuples as required |
| 47 | | * Might have negative implications on the readability of some error messages :( |
| 48 | | * If the parser finds it hard to understand this syntax, you can argue that any human reader would too and hence we should look for something less ambiguous |
| 49 | | * Introduce new syntax to allow this idiom to be expressed unambiguously. Some examples of what we could use are below: |
| 50 | | |
| 51 | | {{{ |
| 52 | | -- 1) A new keyword |
| 53 | | [ foo | x <- e, |
| 54 | | nest { y <- ys, |
| 55 | | z <- zs }, |
| 56 | | x > y + 3 ] |
| 57 | | |
| 58 | | -- 2) Trying to suggest pulling things out of a sublist without having to mention binders |
| 59 | | [ foo | x <- e, |
| 60 | | <- [ .. | y <- ys, |
| 61 | | z <- zs ], |
| 62 | | x > y + 3 ] |
| 63 | | |
| 64 | | -- 3) New kind of brackets |
| 65 | | [ foo | x <- e, |
| 66 | | (| y <- ys, |
| 67 | | z <- zs |), |
| 68 | | x < y + 3 ] |
| 69 | | |
| 70 | | -- 4) Variation on 2), slightly more concise |
| 71 | | [ foo | x <- e, |
| 72 | | <- [ y <- ys, |
| 73 | | z <- zs ], |
| 74 | | x > y + 3 ] |
| 75 | | |
| 76 | | -- 5) Another variation on 2), moving the ".." into the pattern rather than the comprehension body |
| 77 | | [ foo | x <- e, |
| 78 | | .. <- [ y <- ys, |
| 79 | | z <- zs ], |
| 80 | | x > y + 3 ] |
| 81 | | }}} |
| | 82 | == Bracketing Syntax == |
| | 83 | |
| | 84 | Due to the generality added to comprehensions by the paper, it now makes sense to allow bracketing of qualifiers. An example from the paper is: |
| | 85 | |
| | 86 | {{{ |
| | 87 | xs = [1,2] |
| | 88 | ys = [3,4] |
| | 89 | zs = [5,6] |
| | 90 | |
| | 91 | p1 = |
| | 92 | [ (x,y,z) |
| | 93 | | ( x <- xs |
| | 94 | | y <- ys ) |
| | 95 | , z <- zs ] |
| | 96 | |
| | 97 | p2 = |
| | 98 | [ (x,y,z) |
| | 99 | | x <- xs |
| | 100 | | ( y <- ys |
| | 101 | , z <- zs ) ] |
| | 102 | }}} |
| | 103 | |
| | 104 | This results in: |
| | 105 | |
| | 106 | {{{ |
| | 107 | p1 = [(1,3,5), (1,3,6), (2,4,5), (2,4,6)] |
| | 108 | p2 = [(1,3,5), (2,3,6)] |
| | 109 | }}} |
| | 110 | |
| | 111 | Unfortunately, there is a practical problem with using brackets in this way: doing so causes a reduce/reduce conflict in the grammar. Consider this expression: |
| | 112 | |
| | 113 | {{{ |
| | 114 | [foo | (i, e) <- ies] |
| | 115 | }}} |
| | 116 | |
| | 117 | When the parser reaches the bracket after "e" it is valid to either reduce "(i, e)" to a pair of qualifiers (i.e. i and e are treated as guard expressions), OR to reduce it to the tuple expression (i, e) which will be later converted to a pattern. There are a number of alternative ways we could solve this: |
| | 118 | |
| | 119 | * Disallow bracketing of qualifiers altogether! |
| | 120 | * This keeps the concrete syntax simple and should cover all common use cases |
| | 121 | * It does reduce the composability of the qualifier syntax rather drastically however |
| | 122 | * Keep bracketing in this manner but use type information to resolve the ambiguity |
| | 123 | * I will need to change the parser to consider qualifiers as expressions so that we can parse without any reduce/reduce conflicts |
| | 124 | * We can then always use type information to determine which reading is correct, because guards are always boolean, and so can be distinguished from tuples as required |
| | 125 | * Might have negative implications on the readability of some error messages :( |
| | 126 | * If the parser finds it hard to understand this syntax, you can argue that any human reader would too and hence we should look for something less ambiguous |
| | 127 | * Introduce new syntax to allow this idiom to be expressed unambiguously. Some examples of what we could use are below: |
| | 128 | |
| | 129 | {{{ |
| | 130 | -- 1) A new keyword |
| | 131 | [ foo | x <- e, |
| | 132 | nest { y <- ys, |
| | 133 | z <- zs }, |
| | 134 | x > y + 3 ] |
| | 135 | |
| | 136 | -- 2) Trying to suggest pulling things out of a sublist |
| | 137 | -- without having to mention binders |
| | 138 | [ foo | x <- e, |
| | 139 | <- [ .. | y <- ys, |
| | 140 | z <- zs ], |
| | 141 | x > y + 3 ] |
| | 142 | |
| | 143 | -- 3) New kind of brackets |
| | 144 | [ foo | x <- e, |
| | 145 | (| y <- ys, |
| | 146 | z <- zs |), |
| | 147 | x < y + 3 ] |
| | 148 | |
| | 149 | -- 4) Variation on 2), slightly more concise |
| | 150 | [ foo | x <- e, |
| | 151 | <- [ y <- ys, |
| | 152 | z <- zs ], |
| | 153 | x > y + 3 ] |
| | 154 | |
| | 155 | -- 5) Another variation on 2), moving the ".." into |
| | 156 | -- the pattern rather than the comprehension body |
| | 157 | [ foo | x <- e, |
| | 158 | .. <- [ y <- ys, |
| | 159 | z <- zs ], |
| | 160 | x > y + 3 ] |
| | 161 | }}} |
| | 162 | |