| 18 | | So you could say `Record.a` or `RecordClash.a` rather than `a`, to specify which field selector you mean. The difficulty here is that it's hard to know whether you are writing `<module-name>.f` or `<record-name>.f`. That is, is `Record` the name of a type or of a module? (Currently it legally could be both.) |
| 19 | | |
| 20 | | The module/record ambiguity is dealt with in Frege by preferring modules and requiring a module prefix for the record if there is ambiguity. So if your record named Record was inside a module named Record you would need `Record.Record.a`. I think we could improve upon this case to prefer a record rather than the name of the existing module, which should not need to be referenced. So just `Record.a`. |
| 21 | | |
| 22 | | However, we still have the case of conflicting imports between the names of modules and records. We have the choice of either requiring a module prefix or making this a compilation error. Generally, programmers will avoid this situation by doing what they do now: structuring their programs to avoid name collisions. We can try and give the greater assistance in this regard by providing simpler ways for them to alter the names of import types. |
| | 18 | So you could say `Record.a` or `RecordClash.a` rather than `a`, to specify which field selector you mean. This creates a potential ambiguity: did you mean `<module-name>.f` or `<record-name>.f`. `Record` could be the name of a type or of a module. |
| | 19 | |
| | 20 | There are 2 cases to consider: |
| | 21 | 1) inside module M naming a record M, and also importing both that module and record |
| | 22 | 2) importing 2 different modules, M1 and M2, where M2 defines a record named M1. |
| | 23 | |
| | 24 | The module/record ambiguity is dealt with in Frege by preferring modules and requiring a module prefix for the record if there is ambiguity. So for 1) you need M.M.field. For 2) you need M2.M1.field. |
| | 25 | |
| | 26 | We could instead prefer a record rather than a module - this would normally be the desired behavior, but then we must figure out how to still be able to access the module. This is particularly the case for modules not marked as qualified - generally all modules are under a verbose namespace and the Module.identifier syntax is only used if the module is first qualified. |
| | 27 | |
| | 28 | Generally, programmers will avoid this situation by doing what they do now: structuring their programs to avoid name collisions. We can try and give the greater assistance in this regard by providing simpler ways for them to alter the names of import types. |
| 43 | | We have name-spaces, but the equivalent is already being accomplished by adding prefixes to record fields: `data Record = Record { recordA :: String }` |
| 44 | | |
| 45 | | Verbosity is solved in Frege by using the dot syntax concept. In `data Record = Record {a::String};r = Record "A"; r.a` The final `r.a` resolves to `Record.a r`. |
| 46 | | See below for how we resolve the type of this code. |
| 47 | | |
| 48 | | === Details on the dot === |
| 49 | | |
| 50 | | This proposal requires the current Haskell function composition dot operator to have spaces on both sides. No spaces around the dot are reserved for name-spacing: this use and the current module namespace use. No space to the right would be partial application (see |
| 51 | | [http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution TDNR]. The dot operator should bind as tightly as possible. |
| 52 | | |
| 53 | | Given the dot's expanded use here, plus its common use in custom operators, it is possible to end up with dot-heavy code. |
| 54 | | |
| 55 | | {{{ |
| 56 | | quux (y . (foo>.< bar).baz (f . g)) moo |
| 57 | | }}} |
| 58 | | |
| 59 | | It's not that easy to distinguish from |
| 60 | | |
| 61 | | {{{ |
| 62 | | quux (y . (foo>.< bar) . baz (f . g)) moo |
| 63 | | }}} |
| 64 | | |
| 65 | | What then is the future of the dot if this proposal is accepted? I think the community need to chose among 2 alternatives: |
| 66 | | |
| 67 | | 1) discourage the use of dot in custom operators: `>.<` is bad, use a different character or none: `><` |
| 68 | | 2) discourage the use of dot for function composition - use a different operator for that task. Indeed, Frege users have the choice between `<~` or the proper unicode dot. |
| | 42 | We have name-spaces, but it is hard to see how this is better than the current practice of adding prefixes to record fields: `data Record = Record { recordA :: String }` |
| | 43 | |
| | 44 | Verbosity is solved in Frege and DDC by using the dot syntax concept. In `data Record = Record {a::String};r = Record "A"; r.a` The final `r.a` resolves to `Record.a r`. |
| | 45 | |
| | 46 | This is the TDNR syntax concept. See 'Simple Type Resolution' for how we resolve the type of this code. |
| | 47 | Also see 'Details on the dot' for a lengthy discussion of the dot. |
| 188 | | == Partial application == |
| 189 | | |
| 190 | | see [http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution TDNR] syntax discusion. |
| 191 | | `.a r == r.a` |
| 192 | | |
| 193 | | |
| 194 | | == Potential Downside: mixing of 2 styles of code == |
| | 168 | |
| | 169 | == Details on the dot == |
| | 170 | |
| | 171 | This proposal requires the current Haskell function composition dot operator to have spaces on both sides. No spaces around the dot are reserved for name-spacing: this use and the current module namespace use. No space to the right would be partial application (see |
| | 172 | [http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution TDNR]. The dot operator should bind as tightly as possible. |
| | 173 | |
| | 174 | === Partial application === |
| | 175 | |
| | 176 | see [http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution TDNR] syntax discusion for an explanation. |
| | 177 | {{{ |
| | 178 | (.a) r == r.a |
| | 179 | }}} |
| | 180 | |
| | 181 | .x (no space after the dot), for any identifier x, is a postfix operator that binds more tightly than function application, so that parentheses are not usually required. |
| | 182 | {{{ |
| | 183 | .a r == r.a |
| | 184 | }}} |
| | 185 | |
| | 186 | When there are multiple operators, they chain left to right |
| | 187 | {{{ |
| | 188 | (r.a.b.c) == (.c $ .b $ .a r) |
| | 189 | }}} |
| | 190 | |
| | 191 | See below for how partial application can allow for different code styles. |
| | 192 | |
| | 193 | Question: does this now hold? |
| | 194 | {{{ |
| | 195 | r.a == r.(Record.a) == r.Record.a |
| | 196 | }}} |
| | 197 | |
| | 198 | |
| | 199 | |
| | 200 | === Dealing with dot-heavy code === |
| | 201 | |
| | 202 | ==== Identifying the difference between a name-space dot and function composition ==== |
| | 203 | |
| | 204 | Given the dot's expanded use here, plus its common use in custom operators, it is possible to end up with dot-heavy code. |
| | 205 | |
| | 206 | {{{ |
| | 207 | quux (y . (foo>.< bar).baz (f . g)) moo |
| | 208 | }}} |
| | 209 | |
| | 210 | It's not that easy to distinguish from |
| | 211 | |
| | 212 | {{{ |
| | 213 | quux (y . (foo>.< bar) . baz (f . g)) moo |
| | 214 | }}} |
| | 215 | |
| | 216 | What then is the future of the dot if this proposal is accepted? The community needs to consider ways to reduce the dot: |
| | 217 | |
| | 218 | 1) discourage the use of dot in custom operators: `>.<` could be discouraged, use a different character or none: `><` |
| | 219 | In most cases the dot in custom operators has little to no inherent meaning. Instead it is just the character available for custom operators that takes up the least real-estate. This makes it the best choice for implementing a custom operator modeled after an existing Haskell operator: `.==` or `.<` is normably preferable to `@==` and `@<`. |
| | 220 | |
| | 221 | 2) discourage the use of dot for function composition - use a different operator for that task. Indeed, Frege users have the choice between `<~` or the proper unicode dot. |
| | 222 | |
| | 223 | Discouraging the use of the dot in custom operators makes the example code only slightly better. With the second we now have: |
| | 224 | |
| | 225 | {{ |
| | 226 | quux (y <~ (foo>.< bar).baz (f <~ g)) moo |
| | 227 | }}} |
| | 228 | |
| | 229 | Very easy to distinguish from |
| | 230 | |
| | 231 | {{{ |
| | 232 | quux (y <~ (foo>.< bar) <~ baz (f <~ g)) moo |
| | 233 | }}} |
| | 234 | |
| | 235 | If you are disgusted by `<~` than you can use the very pretty unicode dot. |
| | 236 | |
| | 237 | ==== Downside: mixing of 2 styles of code ==== |
| 220 | | Is there are more convenient syntax for this? `b <.a` |
| 221 | | Note that a move to a different operator for function composition (see brief discussion of the dot operator above) would make things much clearer: `b <~ .a`, where the unicode dot might be even nicer |
| 222 | | |
| 223 | | |
| 224 | | == Extending data name-spacing and dot syntax == |
| | 261 | Note that a move to a different operator for function composition (see discussion above) would make things much nicer: |
| | 262 | {{{ |
| | 263 | echo <~ delta <~ .charlie <~ .beta <~ .alpha |
| | 264 | }}} |
| | 265 | |
| | 266 | |
| | 267 | ===== Solution: Field selector to the left of the record ===== |
| | 268 | |
| | 269 | We could have an equivalent of the dot where the field is to the left of the record: `b a@r` |
| | 270 | Could this also be used in a partial syntax? |
| | 271 | |
| | 272 | {{{ |
| | 273 | echo . delta . charlie@ . beta@ . alpha@ |
| | 274 | }}} |
| | 275 | |
| | 276 | Can this be shortened to: |
| | 277 | |
| | 278 | {{{ |
| | 279 | echo . delta . charlie@beta@alpha@ |
| | 280 | }}} |
| | 281 | |
| | 282 | Or would this syntax alway need to be applied? |
| | 283 | |
| | 284 | {{{ |
| | 285 | echo . delta $ charlie@beta@alpha@r |
| | 286 | }}} |
| | 287 | |
| | 288 | |
| | 289 | |
| | 290 | |
| | 291 | == Extending data name-spacing == |