source: doc/proposals/specialized_casts.md @ 1b770e40

Last change on this file since 1b770e40 was 6dbeef7, checked in by Aaron Moss <a3moss@…>, 6 years ago

Minor fix to specialized casts proposal

  • Property mode set to 100644
File size: 4.0 KB
Line 
1## Specialized Casts ##
2
3There is some use in Cforall for cast operators with semantics other than the standard C cast. To make these alternate casts look like the familiar C cast, this proposal follows the example of the virtual proposal's virtual cast `(virtual Foo)x` and uses an added (pseudo-)keyword inside the cast parens.
4
5### C (Conversion) Cast ###
6The standard C cast performs _conversions_, transformations between types which may make a new object with a different in-memory representation. Cforall maintains these semantics in a backward-compatible way while accounting for name overloading by choosing the lowest-cost interpretation of the argument expression which is convertable to the target type, breaking ties by conversion cost.
7
8The C cast must be maintained for backward-compatibility, and developing a second cast operator with identical semantics seems an undesirable multiplication of language features, but `(convert Foo)` or `(to Foo)` would be reasonable options for a keyword. An alternate semantics for a Cforall-specific conversion cast would be to choose the cast interpretation with the lowest sum of conversion cost and interpretation cost, which aligns better with Cforall function call resolution algorithm.
9
10### Ascription Cast ###
11Using casts in Cforall for type _ascription_ ("select the interpretation of this type") works by the conversion-cost tiebreaker behaviour of the cast operator. However, the ascription interpretation of casts is prioritized less than the conversion interpretation of casts, sometimes resulting in some surprising results, as in the following example:
12
13        int f(int);      // f1
14        int f(double);   // f2
15        int g(int);      // g1
16        double g(long);  // g2
17
18        f((double)42);   // selects f2 by cast on argument
19        (double)g(42);   // does NOT select g2, argument conversion cost results in g1
20
21An ascription cast which reversed the priorities of the C cast would be useful for selecting expressions based on their return type; a reversal of the priorities of the standard C cast would work for this (that is, select the lowest-cost conversion, breaking ties based on argument cost). A plausible stricter semantics would be to select the cheapest interpretation with a zero-cost conversion to the target type, reporting a compiler error otherwise (this semantics would make ascription a solely compile-time phenomenon, rather than relying on possible runtime conversions). A resonable keyword would be `(as Foo)`, which is short, evocative, and echos "ascription"; `(return Foo)` would not introduce new keywords, and speaks to its use in return-type selection, as in the following corrected version of the example above:
22
23        (as double)g(42);  // selects g2, as expected (under either presented ascription semantics)
24
25### Coercion Cast ###
26Some of the explict conversions in C are defined to be a _coercions_ (reinterpret the bits of this value as another type). Use of coercions often relies on non-standard implementation details of the provided environment, and as such is discouraged, but is sometimes necessary. Since all explicit pointer casts in C are coercions, any lvalue `x` in C/Cforall can be coerced with the pattern `*(Foo*)&x`, but this is complex and doesn't extend to rvalues. A dedicated coercion cast would solve these issues; `(reinterpret Foo)` (from C++), `(transmute Foo)` (from Rust), or `(coerce Foo)` would be reasonable keywords.
27
28### Qualifier Cast ###
29A more restricted (and thus safer) form of coercion is modifiying the qualifiers of a type; C++ has `const_cast` for this purpose, and a similar feature would be useful for Cforall. With regard to syntax, `(requalify const Foo)`/`(requalify Foo)` to add/strip `const` would echo C++, but given that the vast majority of uses are stripping const-qualfiers, `(non const)` would be shorter, clearer, easily searchable, and not require the programmer to exactly match the argument type. In this syntax, coercion casts could be used to add qualifiers, or another cast type (say `(with const)`) could be introduced to add qualfiers.
30
31### Virtual Cast ###
32_see virtual.txt; semantics equivalent to C++ dynamic cast_
Note: See TracBrowser for help on using the repository browser.