Changes in / [7a43045:471613c]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/autogen.md

    r7a43045 r471613c  
    1 # Review of Auto-generation
     1# Review of Autogeneration
    22There have been known issues with auto-generated routines for a long time. Although no one has time to leap onto the problem right now, we figure people should start thinking about that. And the first part of that is to get all the grievances with the current system.
    33
     
    66
    77## C Compatibility
    8 Old C code should continue to work without any (or minimal). Furthermore, C-style code should usually work when mixed with CFA features. This includes behaviour not implemented as operators in CFA (such as field access and designators) as well as those that do.
     8Old C code should continue to work without any (or mimimal). Furthermore, C-style code should usually work when mixed with CFA features. This includes behaviour not implemented as operators in CFA (such as field access and designators) as well as those that do.
    99
    10 Note, that some CFA feature can disable C Compatibility, for instance visibility modifiers on fields might disable by-field initialization (PAB explain). However, orthogonal features, such as polymorphism, should not.
     10Note, that some CFA feature can disable C Compatibility, for instance visibility modifiers on fields might disable by-field initialization. However, orthogonal features, such as polymorphism, should not.
    1111
    1212## Life-Time Functions
    13 We want to get the life-time functions (destructor, copy assignment and copy construction) without having to write them when they are obvious as does C++.
     13We want to get the life-time functions (destructor, copy assignment and copy construction) without having to write them when they are obvious.
    1414
    1515This actually has a lot of overlap with C Compatibility, in that these are also things you can do with them in C. So these functions should act like the primitive operations in C in those cases.
    1616
    1717## Custom Implementations
    18 We should be able to write custom implementations of the operators. These can be used to replace one of the generated functions. It also can add a new operator for the type.
     18We should be able to write custom implementations of the operators. These can be used to replace one of the generated functions. It also or to add a new operator for the type.
    1919
    2020## Purposeful Missing Functions
    21 For the C-Compatibility's functions and life-time functions, sometimes we do not need, and in fact do not want, some of those functions. These should be possible to remove and any attempt to use them should be rejected at compilation.
     21For the C-Compatibility's functions and life-time functions, sometimes we do not need, and in fact do not want, some of those functions. These should be possible to remove and any attempt to use them should be rejected on compilation.
    2222
    2323# Problems
     
    2828
    2929### Value Call Semantics
    30 This is actually more general issue than autogenerated functions, but the copy constructor and copy assignment operators still take their source argument by value. They have to be copied in C-style to implement the copy operator. When it is fixed, then autogeneration will have to be updated as well.
     30This is actually more general issue than autogenerated functions, but the the copy constructor and copy assignment operators still take their source argument by value. They have to be copied in C-style to implement the copy operator. When it is fixed, then autogeneration will have to be updated as well.
    3131
    3232Current Forms:
     
    3939
    4040### Unused Assertions Still Added to the Assertion List
    41 All assertions on the type declaration are used in all autogenerated functions even if they are never used. For example:
     41All assertions on the type decklaration are used in all autogenerated functions even if they are never used. For example:
    4242
    4343The declaration of:
     
    5757        void ?{}(Cell(T)&, T);
    5858
    59 If these assertions were reduced to the minimal required assertions the result would instead look something like the:
     59If these assertions were reduced to the minimial required assertions the result would instead look something like the:
    6060        forall(T* | { void ?{}(T&); })
    6161        void ?{}(Cell(T)&);
     
    7171This leads to exponential thunk generation for `Cell(Cell(int))` (or a matrix represented `vector(vector(vector(int)))`).
    7272
    73 ### Autogened Functions cannot use Available Functions
     73### Autogened Functions cannot use Avaible Functions
    7474If you supply an implementation for one of the autogenerated functions, it will not be used while generating other functions.
    7575
    76 Consider a case with a custom copy constructor but don't define an assignment operator. The current (problematic) behaviour reimplements the assignment operator member-wise. The ideal solution would be to create a new implementation of the operator that applies the appropriate destructor, then the custom copy constructor. Although this implementation may be slower, it will have correct behaviour if the other operators are implemented properly.
     76Consider a case with a custom copy constructor but don't define an assignment operator. The current (problematic) behaviour reimplements the assignment operator member-wise. The ideal solution would be to create a new implementation of the operator that applies the approprate destructor, then the custom copy constructor. Although this implementation may be slower, it will have correct behaviour if the other operators are implemented properly.
    7777
    78 An alternate behaviour would simply to remove the assignment operator entirely unless the users explicit provides one. This is more similar to C++'s "The Rule of Three" (or "The Rule of Five" with move operations), where all three of the lifetime functions must be redefined if any of them are. The advantage of the new assignment operator (mentioned in the "ideal solution") is that it avoids a similar rule of three, needing only destruction and copy construction for proper lifetime behaviour.
     78An alternate behaviour would simply to remove the assignment operator entirely unless the users explicity provides one. This is more similar to C++'s "The Rule of Three" (or "The Rule of Five" with move operations), where all three of the lifetime functions must be redefined if any of them are. The advantage of the new assignment operator (mentioned in the "ideal solution") is that it avoids a similar rule of three, needing only destruction and copy construction for proper lifetime behaivour.
    7979
    8080## Problems With Removed Functions
    8181
    8282### Failed Autogeneration Leaves Behind Declaration
    83 All autogenerated functions are checked by attempting to resolve them. If there is an error, than the autogenerated function is removed. But that only removes the definition, so it can still be considered as a candidate for resolution. The following code will compile but fail during linking.
     83All autogenerated functions are a checked by attempting to resolve it. If there is an error than the autogenerated function is removed. But that only removes the definition, so it can still be considered as a candidate for resolution. The following code will compile but fail during linking.
    8484
    8585        forall(T *) struct Cell { T x; };
     
    8989
    9090### Overriding a Function can Lead to Problems
    91 Implementing your own version of a function should always override the autogenerated function. This does not happen, especially if the declared function does not use the exact same assertions as the autogenerated function (provided via the type declaration itself).
     91Implementing your oven version of a function should always override the autogenerated function. This does not happen, especially if the declared function does not use the exact same assertions as the autogenerated function (provided via the type declaration itself).
    9292
    9393(This issue is filled as Trac Ticket 186.)
     
    107107        vector v = {capacity: 128};
    108108
    109 The designator syntax (included in the example) being different from C is also a problem for compatibility, but does not change their use in pure Cforall.
     109The designator syntax (including in the example) being different from C is also a problem for compatability, but does not change their use in pure Cforall.
    110110
    111111### Non-Intuitive Reference Initializer
     
    126126                (this.x){ x };
    127127                // A correct way to implement this operation.
    128         //      ?{}(*(int*)&this.x, x); // remove const
     128        //      ?{}(*(int*)&this.x, x);
    129129        }
    130130
     
    14214210%:  anything else
    143143
    144 (This was not counting copy assignment, although it could be considered an optimization of destroy and then copy (re)construct.)
     144(This was not counting copy assignment, although it could be considered an optimization of destory and then copy (re)construct.)
    145145
    146146### Incorrect Field Detection
     
    150150
    151151### No-op Constructor
    152 This may be solved, in some cases, but there is no clear interface to specify that a construction should not be run. It would be nice, like in C, to leave stack allocated variable uninitialized, this is mostly a performance issue but can allow you do declare a variable before the information to construct it is read.
     152This may be solved, in some cases, but there is not a clear interface for not running constructors. It would be nice to, like in C, to leave stack allocated variable uninitialized, this is mostly a preformance issue but can allow you do declare a variable before the information to construct it is read.
    153153
    154154However, if a constructor is run, then all of its components should be initialized by default.
     
    163163Currently, the C escape for constructors only work at the top constructor. This suggestion moves the escape from the initialization context to the constructor call/initializer. (As an aside, ideally there would be no need for a C escape because Cforall would never overstep, but until then, we should try to have good escapes.)
    164164
    165 There are two ways to escape an constructor, so that Cforall always resolves it as a C initializer and not a Cforall constructor call. These are syntactically tied to the initialization context, not the initializer, and semantically apply to the top initializer.
     165There are two ways to escape an constructor, so that Cforall always resolves it as a C initializer and not a Cforall constructor call. These are syntaxically tied to the initialization context, not the initializer, and semanitically apply to the top initializer.
    166166
    167 The syntax change could just move the `@` from the declaration to the initializer. Escaped initializers are written `@{ ... }`. This doesn't change the syntax for compound literals (`(TYPE)@{ ... }`), but it does change variable declarations (`DECL @= { ... };` becomes `DECL = @{ ... };`). Each escape means exactly that initializer must not be a constructor call.
     167The syntax change could just move the `@` from the declaration to the initializer. Escaped initializers are written `@{ ... }`. This doesn't change the syntax for compound literals (`(TYPE)@{ ... }`), but it does change variable declarations (`DECL @= { ... };` becomes `DECL = @{ ... };`). Each escape means exactly that initizlizer must not be a constructor call.
    168168
    169169## Initializer/Constructor
    170 A different way to stop Cforall constructors from conflicting C initializers they could just use a different syntax. This could try to be a small change to the initializer syntax, the minimum change to separate the two, or a more drastic change, that might enable new features (ex. `ctor_name{ ... }`, allowing for named constructors).
     170A different way to stop Cforall construcors from conflicting C initializers they could just use a different syntax. This could try to be a small change to the initalizer syntax, the minimum change to separate the two, or a more drastic change, that might enable new features (ex. `ctor_name{ ... }`, allowing for named constructors).
    171171
    172 This fixes the backwards compatibility issue, and removes the need for escapes, but does result in a larger syntax change for new calls. Separating initializers from constructors might also help with autogeneration and unexpected conflicts between autogen and manually defined functions.
     172This fixes the backwards compatablity issue, and removes the need for escapes, but does result in a larger syntax change for new calls. Separating initializers from constructors might also help with autogeneration and unexpected conflicts between autogen and manually defined functions.
    173173
    174174## Autogeneration Attributes
     
    181181+   Destroying an instance of the type is a no-op, no clean-up required.
    182182+   Copying the type replicates the bit pattern in the new memory location.
    183 +   Moving the type is equivalent to copying the type.
     183+   Moving the type is equivilent to copying the type.
    184184
    185 This means that the type carries size and alignment, and from that you can implement the copy constructor, copy assignment and destructor using just memory operations. That means this is equivalent to `is_value` in terms of operations but the implementations of those functions can be different, and less data has to be passed around.
     185The `is_pod` assertion says that a type is a plain old data type. This means that the type carries size and alignment, and from that you can implement the copy constructor, copy assignment and destructor using just memory operations. That means this is equivlent to `is_value` in terms of operations but the implementations of those functions can be different, and less data has to be passed around.
    186186
    187187One requirement that is not used is that all zeros a valid bit pattern for that type (or that and given bit pattern is valid). It could be added, and then you can also construct instances of the type by zero filling the storage. It is a `is_object` interface and considering the trend to from object to value, right now it seems it should at most be a secondary trait/assertion (ex. `is_pod0`).
    188188
    189 However, in both of these cases there is actually no new functionality added. These are existing operations. The advantage is it allows for more optimizations to be used. The function pointers do not need to be passed into polymorphic functions and some operations can be bundled together. Whether these optimizations save significant about of time or memory has to be investigated.
     189However, in both of these cases there is actually no new functionality added. These are existing operations. The advantage is it allows for more optimizations to be used. The function pointers do not need to be passed into polymorphic functions and some operations can be bundled together. Wheither these optimizations save significant about of time or memory has to be investigated.
Note: See TracChangeset for help on using the changeset viewer.