Open
Description
Most languages have either:
- language-level support for properties
- C#:
string MyProperty { get; set; }
- JavaScript:
get myProperty()
- JavaScript:
set myProperty(value)
- C#:
- or conventions on how to name property-like methods.
- Java:
String getMyProperty()
- Java:
void setMyProperty(String value)
- Rust:
my_property(&self) -> String
- Rust:
set_my_property(&mut self, value: String) -> ()
- Java:
If properties are not encoded natively in WIT, we'll probably end up with everybody choosing their own convention (based on their own language). Which is bound to end up looking foreign to the other languages.
Or we can prescribe a convention for tooling to convert from&to, but at that point we might as well just encode it into Wit itself.
My suggestion:
interface abc {
resource blob {
content-type1: string { get } // Read-only property
content-type2: string { set } // Write-only property
content-type3: string { get, set } // Read/write property
content-type4: string // TODO: Without annotation defaults to { get } ? Or { get, set } ?
content-type5: string { // Customized signatures
get -> result<string, my-get-error>,
set -> result<_, my-set-error>,
}
content-type6: string { // Infallible getter, fallible setter
get, // If no custom signature is provided, the getter/setter is assumed to be infallible.
set -> result<_, my-set-error>,
}
/// General doc-comment applicable to both the getter & setter.
content-type7: string {
/// Documentation specific to the getter.
get,
/// Documentation specific to the setter.
set,
}
}
// Is equivalent to:
resource blob
%[get]blob.content-type1: func(self: borrow<blob>) -> string
%[set]blob.content-type2: func(self: borrow<blob>, value: string)
%[get]blob.content-type3: func(self: borrow<blob>) -> string
%[set]blob.content-type3: func(self: borrow<blob>, value: string)
// %[???]blob.content-type4
%[get]blob.content-type5: func(self: borrow<blob>) -> result<string, my-get-error>
%[set]blob.content-type5: func(self: borrow<blob>, value: string) -> result<_, my-set-error>
%[get]blob.content-type6: func(self: borrow<blob>) -> string
%[set]blob.content-type6: func(self: borrow<blob>, value: string) -> result<_, my-set-error>
}
Or more Javascript-esque:
interface abc {
resource blob {
// Together these two declarations represent one logical property.
content-type: get func() -> string
content-type: set func(value: string)
}
}
Either way, in both variants getters and setters:
- are never async
- always borrow their
self
argument, regardless of the outcome of Allow consuming methodsย #226 - must satisfy one of these signatures:
%[get]T.property-name: func(self: borrow<T>) -> T
%[get]T.property-name: func(self: borrow<T>) -> result<T, error-type>
%[set]T.property-name: func(self: borrow<T>, value: T)
%[set]T.property-name: func(self: borrow<T>, value: T) -> result<_, error-type>