Changes between Version 13 and Version 14 of Records/NameSpacing


Ignore:
Timestamp:
Jan 8, 2012 6:21:02 PM (4 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`