-
Notifications
You must be signed in to change notification settings - Fork 0
Protocols
Clay current allows protocols (or concepts or type classes, if you prefer) to be defined in an ad-hoc way, using CallDefined?:
ForwardCoordinate?(T) = CallDefined?(dereference, T) and CallDefined?(inc, T);
While this works, it leaves the compiler with very little semantic information for error reporting or debugging—it can only report that the pattern match failed, not why. The CallDefined? syntax is also abstracted from actual expression syntax. First-class language support for protocols and function definition syntax for protocol-following types would allow for improvements in compiler error reporting and code readability, and would reduce boilerplate in common function definition cases.
There's plenty of prior art in designing the semantics of type constraints (ConceptC++, type classes in Haskell + the various GHC extensions, .NET generics, among others). The primary question in bringing them to Clay is syntax. We need a pattern matching form for constraining a pattern variable (such as "'X in Protocol") and forms for defining protocols (perhaps in both automatically-derived and formal forms), refinements of protocols, and formal instances of protocols.
A good spot-test is the sequence/iterator/coordinate family of protocols. Here's a theoretical definition of those protocols, using forall <pattern> in <ProtocolName>[<..ProtocolArgs>] { } as the syntactic form for protocol definitions, and <pattern> in <Protocol> as the pattern syntax for constrained pattern variables.
forall 'I in IteratorType['E] {
// required operations
next(i: 'I) : 'E;
hasNext?(i: 'I) : Bool;
// derived definitions
#IteratorTargetType('I) = 'E;
}
forall 'S in SequenceType['I in IteratorType] {
// required operations
iterator(x: 'S) : 'I;
// derived definitions
#SequenceIteratorType('S) = 'I;
#SequenceElementType('S) = IteratorTargetType('I);
}
forall 'C in CoordinateType['E] {
dereference(c: 'C) : 'E;
inc(ref c: 'C) : ;
dec(ref c: 'C) : ;
#CoordinateTargetType('C) = 'E;
}
forall ('S in SequenceType['I]) in CoordinateSequenceType['I in IteratorType['E], 'C in CoordinateType['E]] {
begin(s: 'S) : 'C;
end(s: 'S) : 'C;
#SequenceCoordinateType('S) = 'C;
}
Please add comments here.