Changes between Version 13 and Version 14 of Records/NameSpacing


Ignore:
Timestamp:
Jan 8, 2012 6:21:02 PM (3 years ago)
Author:
GregWeber
Comment:

updates for mail list conversations

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.  
     1See [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. 
    22 
    33This 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] 
    44Many thanks to the Frege author, Ingo Wechsung for explaining his implementation and exploring this implementation territory for us. 
    55 
    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 
     6The 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 
    78 
    89== Better name spacing == 
     
    2627data InconvenientName = X { f :: Int } 
    2728type IN = InconvenientName 
    28 -- IN.f is the same as InconvenientName.f  
     29-- IN.f is the same as InconvenientName.f 
    2930}}} 
    3031 
     
    4243We have name-spaces, but the equivalent is already being accomplished by adding prefixes to record fields: `data Record = Record { recordA :: String }` 
    4344 
    44 Verbosity is solved in Frege by using the TDNR syntax concept. In `data Record = Record {a::String};r = Record "A"; r.a` The final `r.a` resolves to `Record.a r`. 
     45Verbosity 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`. 
    4546See below for how we resolve the type of this code. 
    4647 
     
    4950This 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. 
    5051 
     52 
    5153== Simple type resolution == 
    5254 
     55Frege 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. 
    5356 
    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: 
     57Back to simple type resolution. From the Frege Author: 
    5558 
    5659 * Expressions of the form T.n are trivial, just look up n in the namespace T. 
     
    106109I 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.) 
    107110 
     111 
    108112== Syntax for updates (in the Frege manual) == 
    109113 
     
    113117  * the function that changes field x of a T by applying some function to it is `T.{x <-}` 
    114118 
     119The function update syntax is a new addition to Haskell that we do not need to immediately implement. 
     120Any thoughts on the Frege field update syntax vs. the current Haskell syntax? 
     121 
     122== Interaction with Typeclasses == 
     123 
     124In the Frege system, the record's namespace is closed where it is defined. 
     125However, making a record an instance of a class puts the class functions in the record name-space. 
     126 
     127{{{ 
     128module RExtension where 
     129 
     130import original.M(R)    -- access the R record defined in module original.M 
     131 
     132class Rextension1 r where 
     133      f :: ..... 
     134      g :: ..... 
     135 
     136instance Rextension1 R where 
     137     -- implementation for new functions 
     138 
     139And now, in another module one could 
     140 
     141import RExtension()      -- equivalent to qualified import in Haskell 
     142}}} 
     143 
     144the new functions `f` and `g` are accessible (only) through R. 
     145So we have a technique for lifting new functions into the Record namespace. 
     146For the initial records implementaion we probably want to maintain `f` and `g` at both the top-level and through the name-space. 
     147See below for a discussion of future directions. 
     148 
    115149== Compatibility with existing records == 
    116150 
    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. 
     151Seems 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. 
    118152There is a chance for deeper though on this issue. 
    119153 
    120154 
    121 == Extending data name-spacing and TDNR syntax == 
     155== Extending data name-spacing and dot syntax == 
    122156 
    123157This 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). 
    125158 
    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? 
     159Dot 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 
     161Placing 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 
     163In 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 
     167Fill this out by first looking at TDNR 
     168`(.a) r == r.a` 
     169 
     170== Potential Downside: mixing of 2 styles of code == 
     171 
     172{{{ 
     173data Record = Record { a::String } 
     174b :: Record -> String 
     175 
     176let r = Record "a" in b r.a  
     177}}} 
     178 
     179It 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 
     181Partial application provides a potential solution: `b (.a) r`