Typedef-Block
Difference (last change) (no other diffs, normal page display)
Deleted: 166,276d165
Typedef Block
A feature proposal for D -- EricAndertonA means for extending a scalar type in a struct-like way that can:
- maintain implicit casting to the underlying type
- allow for operator overloads on scalar types
- allow for static inheritance of methods when typedefs are 'inherited'
- transparently expand the role of scalar types throughout the language
Syntax
The typedef statment is extended to support an optional class-like syntax. Note that the secondary form only allows for scalar types, since both structs, and classes have their own semantics for extension (inheritance etc).
|
Any method signature is allowed, and any operator overload is possible. Constructor and Destructor syntaxes are allowed. The 'this' pesudo-member is also used throughout the typedef's methods, with the understanding that it is actually a pointer to the underlying type (scalar). Any members declared for the typedef must be static, as any non-static data would really make the type a struct not a scalar. The only valid, non-static member available is "this". The static member "init" is available to all typedefs and the static members "min" and "max" are available to non-array types.
Extending previously extended typedefs will force methods to be overloaded and overridden in a manner identical to class inheritance. Public, private and protected method types will be respected according to those rules.
The resulting type becomes a sort of static-class of methods that is only resolvable at compile time. The programmer must be aware that performing implicit or unsafe casts on such a typedef will result in changing the scalar's behavior to the behavior of the resulting type.
Motivation
The basic premise of extending typedef is to modify the behavior of scalars without having to re-implement a complete behavior type. If one wanted to add an attribute to an scalar type, or slightly modify the behavior of a scalar, all while still having the same behavior as the type it replaces, one would have to do no less than:
- create a class or struct
- completely emulate the behavior of the underlying type (arithmetic, casting and conversion)
- implement the slightly divergent or enhanced behaviors, new attributes, etc
Yet all this can be avoided if we can just change the parts we want to change. This is where the typedef block comes in.
Examples
By extending the notion of a typedef to include methods as well as just renaming the type, the language immediately becomes more flexible. Here are some examples.
|
Impact on D
The changes to the language needed to support an extended typedef may not be all that extensive. D already performs implicit casting and overload resolution for typedef and aliased types. Structs already enjoy the kind of compile-time class like method semantics that this would require, so that functionality already exists within the language. Also, the typedef statement has a syntax "hole" as there is no equivalent for the block-style declaration (using "{" and "}" ). This meshes perfectly with the overall context-free approach of D's design, and only serves to make it moreso.
Comments
A few comments on the first read-through:
- how would name lookup actually work? The proposal is not that clear to me exactly what would happen to figure out what function to call.
- opAssign? eek - that's a new operator for D and potentially very scary.
- Is the FriendlyReal? example useful? Can't one set the init property of a standard typedef?
Another variant
In my opinion typedef-blocks and structs are too similar to exists as different constructs. If we allow struct inheritance by means of just adding base struct members to the front of child struct, and allow struct inheritance from basic types it would solve the problem. Casting child struct to base struct can be allowed, but all struct methods must be treated as non-virtual, so we can keep compitability with C structs.Examples:
|