Changes between Version 29 and Version 30 of Records


Ignore:
Timestamp:
Jan 7, 2012 11:31:56 PM (2 years ago)
Author:
GregWeber
Comment:

move namespacing content to new page

Legend:

Unmodified
Added
Removed
Modified
  • Records

    v29 v30  
    3636 1. Overloading: polymorphic selection & update; see [wiki:Records/OverloadedRecordFields] 
    3737 2. Namespacing: simple name-spacing & type resolution; see [wiki:Records/NameSpacing] 
     38 3. '''Are there any other approaches?''' 
    3839 
    39 '''Are there any other approaches?''' 
    40  
    41 The discussion has many similarities with the original Type directed name resolution proposal: the question seems to be largely about nailing down a concrete implementation; see below and [http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution TDNR]. The original TDNR proposal had Overloading in mind, but Namespacing ends up having similarities. 
    4240 
    4341The benefit of Overloading over Namespacing is being able to write code that works against any Record with a given field. So I can have a function: 
     
    5553 
    5654 
     55=== Type directed name resolution === 
    5756 
    58 === Better name spacing & simple type resolution === 
    59  
    60 Note that the name-spacing and simple type resolution approach is an attempt to port the records solution in [http://code.google.com/p/frege/ Frege], a haskell-like language on the JVM. See 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-202.pdf Frege user manual] 
    61  
    62 In Haskell, you can look at an occurrence of any identifier `f` or `M.f` and decide where it is bound without thinking about types at all.  Broadly speaking it works like this: 
    63  * For qualified names, `M.f`, find an import that binds `M.f`. 
    64  * For unqualified names, `f`, find the innermost binding of `f`; or, if that takes you to top level, look for top level binding of `f` or an import that binds `f`. 
    65 If there is ambiguity (eg two imports both import something called `f`) then an error is reported.  And that's what happens for the `Record` and `RecordClash` example above. 
    66  
    67 So one solution for record field names is to specify more precisely which one you mean.  There are two schools of thought: 
    68  * '''Optionally use the type name'''.  So you could say `Record.a` or `RecordClash.a` rather than `a`, to specify which field selector you mean.  Apart from verbosity the difficulty here is that it's hard to know whether you are writing `<module-name>.f` or `<type-name>.f`.  That is, is `Record` the name of a type or of a module?  (Currently it legally could be both.) 
    69  
    70  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`. Programmers will avoid this by doing what they do now: structuring their programs to avoid this situation. We can try and give the greater assistance in this regard by providing simpler ways for them to alter the names of import types. 
    71  
    72  Verbosity is solved in Frege by using the TDNR concept. In `data Record = Record {a::String};r = Record "A"; r.a` The final `r.a` resolves to `Record.a r`. See the simple type resolution discussion below. 
    73  
    74  * '''Use the module name space mechanism'''; after all that's what it's for.  But putting each record definition in its own module is a bit heavyweight. So maybe we need local modules (just for name space control) and local import declarations.  Details are unclear. (This was proposed in 2008 in [http://www.haskell.org/pipermail/haskell-cafe/2008-August/046494.html this discussion] on the Haskell cafe mailing list and in #2551. - Yitz). 
    75  
    76  Rather than strictly re-use modules it may make more sense to have a name-spacing implementation construct that is shared between both records and modules - hopefully this would make implementation easier and unify behavior. In the Frege approach, each data declaration is its own namespace - if we were to go this far (instead of stopping purely at records) there may be much less need for local namespaces. Overall this seems to be more of an implementation detail that may have a side effect of making local modules easier to implement than a concrete design proposal relating to records. -- Greg Weber. 
    77  
    78  
    79 === Simple type resolution === 
    80  
    81  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 (you can't write code that works against multiple record types). Frege uses fairly normal type resolution, and it won't always be able to resolve the type (currently 1/3 or sparsely annotated code will need more type annotations, but we should be able to improve this). I will put down some more details here... 
    82  
    83 === Type directed name resolution === 
     57The discussion has many similarities with the original Type directed name resolution proposal: the question seems to be largely about nailing down a concrete implementation; see below and [http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution TDNR]. The original TDNR proposal had Overloading in mind, but Namespacing ends up having similarities. -- GregWeber 
    8458 
    8559All of the name-space mechanisms require some level of user-supplied disambiguation: if there are two fields `a` in scope, you must use a qualified name to disambiguate them.  What is tantalising about this is that the ''type'' of the argument immediately specifies which one you mean. There is really no ambiguity at all, so it is frustrating to have to type qualified names to redundantly specify that information.  Object-oriented languages take for granted this form of type-directed disambiguation.