Changes between Version 13 and Version 14 of Records/NameSpacing
- Timestamp:
- 01/08/12 10:21:02 (17 months ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Records/NameSpacing
v13 v14 1 See [wiki:Records] for the bigger picture. This is a proposal to solve the records name-spacing issue with simple name-spacing and simple type resolution. 1 See [wiki:Records] for the bigger picture. This is a proposal to solve the records name-spacing issue with simple name-spacing and simple type resolution. 2 2 3 3 This approach is an attempt to port the records solution in [http://code.google.com/p/frege/ Frege], a haskell-like language on the JVM. Please read Sections 3.2 (primary expressions) and 4.2.1 (Algebraic Data type Declaration - Constructors with labeled fields) of the [http://code.google.com/p/frege/downloads/detail?name=Language-411.pdf Frege user manual] 4 4 Many thanks to the Frege author, Ingo Wechsung for explaining his implementation and exploring this implementation territory for us. 5 5 6 The DDC language (again, very much like Haskell, but focused on better performance and predictability) puts forth a similar solution. See the [http://www.cse.unsw.edu.au/~benl/papers/thesis/lippmeier-impure-world.pdf thesis] section 2.7 - 2.7.4 pages 115 - 119 6 The DDC language (again, very much like Haskell, but focused on better and more predictable performance) puts forth a similar solution. See the [http://www.cse.unsw.edu.au/~benl/papers/thesis/lippmeier-impure-world.pdf thesis] section 2.7 - 2.7.4 pages 115 - 119 7 7 8 8 9 == Better name spacing == … … 26 27 data InconvenientName = X { f :: Int } 27 28 type IN = InconvenientName 28 -- IN.f is the same as InconvenientName.f 29 -- IN.f is the same as InconvenientName.f 29 30 }}} 30 31 … … 42 43 We have name-spaces, but the equivalent is already being accomplished by adding prefixes to record fields: `data Record = Record { recordA :: String }` 43 44 44 Verbosity is solved in Frege by using the TDNRsyntax concept. In `data Record = Record {a::String};r = Record "A"; r.a` The final `r.a` resolves to `Record.a r`.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`. 45 46 See below for how we resolve the type of this code. 46 47 … … 49 50 This proposal requires the current Haskell function composition dot operator to have spaces (at least on the left side). No spaces around the dot are reserved for name-spacing: this use and the current module namespace use. The dot operator should bind as tightly as possible. 50 51 52 51 53 == Simple type resolution == 52 54 55 Frege has a detailed explanation of the semantics of its record implementation, and the language is *very* similar to Haskell. After reading the Frege manual sections, one is still left wondering: how does Frege implement type resolution for its dot syntax. The answer is fairly simple: overloaded record fields are not allowed. So you can't write code that works against multiple record types. Please see the comparison with Overloading in [wiki Records], which includes a discussion of the relative merits. Note that the DDC thesis takes the same approach. 53 56 54 Frege has a detailed explanation of the semantics of its record implementation, and the language is *very* similar to Haskell. After reading the Frege manual sections, one is still left wondering: how does Frege implement type resolution for its TDNR syntax. The answer is fairly simple: overloaded record fields are not allowed. So you can't write code that works against multiple record types. Please see the comparison with Overloading in [wiki Records], which includes a discussion of the relative merits.Back to simple type resolution. From the Frege Author:57 Back to simple type resolution. From the Frege Author: 55 58 56 59 * Expressions of the form T.n are trivial, just look up n in the namespace T. … … 106 109 I estimate that in 2/3 of all cases one does not need to write `T.e x` in sparsely type annotated code, despite the fact that the frege type checker has a left to right bias and does not yet attempt to find the type of `x` in the code that "follows" the `x.e` construct (after let unrolling etc.) I think one could do better and guarantee that, if the type of `x` is inferrable at all, then so will be `x.e` (Still, it must be more than just a type variable.) 107 110 111 108 112 == Syntax for updates (in the Frege manual) == 109 113 … … 113 117 * the function that changes field x of a T by applying some function to it is `T.{x <-}` 114 118 119 The function update syntax is a new addition to Haskell that we do not need to immediately implement. 120 Any thoughts on the Frege field update syntax vs. the current Haskell syntax? 121 122 == Interaction with Typeclasses == 123 124 In the Frege system, the record's namespace is closed where it is defined. 125 However, making a record an instance of a class puts the class functions in the record name-space. 126 127 {{{ 128 module RExtension where 129 130 import original.M(R) -- access the R record defined in module original.M 131 132 class Rextension1 r where 133 f :: ..... 134 g :: ..... 135 136 instance Rextension1 R where 137 -- implementation for new functions 138 139 And now, in another module one could 140 141 import RExtension() -- equivalent to qualified import in Haskell 142 }}} 143 144 the new functions `f` and `g` are accessible (only) through R. 145 So we have a technique for lifting new functions into the Record namespace. 146 For the initial records implementaion we probably want to maintain `f` and `g` at both the top-level and through the name-space. 147 See below for a discussion of future directions. 148 115 149 == Compatibility with existing records == 116 150 117 Seems like it should be OK to use old records in the new system playing by the new rules, although those records likely already include some type of prefixing and would be verbose.151 Seems like it should be OK to use old records in the new system playing by the new rules, although those records likely already include some type of prefixing and would be quite verbose. 118 152 There is a chance for deeper though on this issue. 119 153 120 154 121 == Extending data name-spacing and TDNRsyntax ==155 == Extending data name-spacing and dot syntax == 122 156 123 157 This is mostly just something interesting to contemplate. 124 TDNR syntax does not have to be limited to records (although it probably should be for the initial implementation until this new record system is vetted). I think it is a bad idea to attempt to accomplish general function chaining through extending TDNR. However, we can extent the function name-spaced to a data type concept to any data type (as it is in Frege), and use TDNR syntax for that. This way the dot (without spaces) *always* means tapping into a namespace (and simple type resolution).125 158 126 Placing functions within a data name-space can make for nicer data-structure oriented code where the intent is clearer. It can help to achieve the data-oriented goal of OO without the entanglement of state. Is it possible to create "virtual" record field setters and getters that can be accessed through TDNR syntax and to control exactly what parts of the data namespace are accessible? 159 Dot syntax does not have to be limited to records (although it probably should be for the initial implementation until this new record system is vetted). I think it is a bad idea to attempt to attempt to extend the dot syntax to accomplish general function chaining through extending the dot syntax. However, it is consistent to extend the function name-spaced to a record data type concept to any data type (as it is in Frege), and use dot syntax for that. The dot (without spaces) *always* means tapping into a namespace (and simple type resolution). 160 161 Placing functions within a data name-space can make for nicer data-structure oriented code where the intent is clearer. It can help to achieve the data-oriented goal of OO (without the entanglement of state). With control over how the data namespace is exported (similar to controlling module namesapces), it is possible to create virtual record field setters and getters that can be accessed through dot syntax. 162 163 In this brave new world (see above where typeclass functions are also placed under the namespace of the data), there are few functions that *absolutlely must* be at the top level of a module. Although a library author might take attempt the approach of no top-level functions, obviously it will still be most convenient for users to define functions at the top level of modules rather than have to lift them into data structures. 164 165 == Partial application == 166 167 Fill this out by first looking at TDNR 168 `(.a) r == r.a` 169 170 == Potential Downside: mixing of 2 styles of code == 171 172 {{{ 173 data Record = Record { a::String } 174 b :: Record -> String 175 176 let r = Record "a" in b r.a 177 }}} 178 179 It bothers some that the code does not look like the previous `b a r` - chiefly that the record is now in the middle. Is it possible we can have an equivalent of the dot that changes the ordering? `b a.r` is theoretically possible, but probably extraordinarily confusing. Perhaps a new operator like: `b a <. r` 180 181 Partial application provides a potential solution: `b (.a) r`
