Changes between Version 34 and Version 35 of Records/OverloadedRecordFields/Plan


Ignore:
Timestamp:
Aug 30, 2013 1:29:06 PM (18 months ago)
Author:
adamgundry
Comment:

scope issues

Legend:

Unmodified
Added
Removed
Modified
  • Records/OverloadedRecordFields/Plan

    v34 v35  
    275275== Design choices == 
    276276 
    277 == Unambiguous fields == 
     277=== Scope issues, or, why we miss dot === 
     278 
     279Consider the following example: 
     280 
     281{{{ 
     282f :: (Has r "g" Int) => r -> Int 
     283f x = g x + 1 
     284}}} 
     285 
     286Q1. What happens if `g` is not in scope? 
     287 
     288A. The code gives an error. This is where dot-notation (or another syntactic form marking a field name) is better: `f x = x.g + 1` can work even if `g` is not in scope. Observe that something similar happens with implicit parameters: `f y = y + ?x` works even if `x` is not in scope, and introduces a new constraint `(?x :: Int)`.  
     289 
     290Q2. What if we add `data T = MkT { g :: Char }`? 
     291 
     292A. The code compiles correctly, even though the datatype is "obviously" irrelevant because the field `g` it declares has the wrong type, so it cannot be selected. This would not be the case if we treated `g` as an unambiguous reference to the only field of that name in scope. 
     293 
     294Q3. What if we subsequently add another datatype with a field `g`? 
     295 
     296A. The code still compiles correctly. 
     297 
     298An advantage of distinguishing record projections syntactically (as in `x.g`) is that `g` is always treated as a record field, regardless of what is in scope. This allows better separation of concerns, as functions that manipulate records can be defined abstractly rather than referring to particular datatypes. We could consider using an operator less controversial than dot (for example, `(|:)` has been suggested), or a keyword such as '''select''': 
     299 
     300{{{ 
     301f x = x|:g + 1 
     302f x = select g x + 1 
     303}}} 
     304 
     305 
     306=== Introducing field names === 
     307 
     308As noted above, sometimes one might want to write code that uses record fields without any particular record types being in scope. One workaround is to define unused types with the appropriate field names. This is slightly odd! We might consider adding a new declaration form, say '''field''' `g`, which declares `g` as a record field that is always polymorphic, rather like the function declaration 
     309 
     310{{{ 
     311g :: r { g :: t } => r -> t 
     312g = field 
     313}}} 
     314 
     315but with the property that it will not clash with actual `g` fields. 
     316 
     317 
     318=== Unambiguous fields === 
    278319 
    279320What if `foo` occurs in an expression, and there is only one datatype `T` with a field `foo` in scope? There are three obvious choices: 
     
    321362 
    322363Since the selectors are hidden by clients (on import) rather than on export, fields can still be used for record update and mentioned in import and export lists, to control access to them (as discussed in the [wiki:Records/OverloadedRecordFields/Plan#Representationhiding representation hiding] section). 
    323  
    324  
    325 === Introducing field names === 
    326  
    327 An advantage of distinguishing record projections syntactically (as in `e.x`) is that `x` is always treated as a record field, regardless of what is in scope. This allows better separation of concerns, as functions that manipulate records can be defined abstractly rather than referring to particular datatypes. 
    328  
    329 One workaround is to define unused types with the appropriate field names. This is slightly odd, and we might consider adding a new declaration form, which declares `x` as a record field that is always polymorphic, rather like the function declaration 
    330  
    331 {{{ 
    332 x :: r { x :: t } => r -> t 
    333 x = field 
    334 }}} 
    335  
    336 but with the property that it will not clash with actual `x` fields. 
    337364 
    338365