>> I'm not sure how much metadata is necessary beyond name (in the key) and
>> type (discussed soon).
>
> In the future we may have user-defined attributes. It could be very useful
> to expose that.
This is true.
Actually, I'm wondering if property behaviors should be able to essentially
declare alternate PropertyViews and add their properties to them. For instance:
var behavior persistent<Value: PersistentValue>: Value where Self:
ManagedObject {
belongsto persistentProperties, static
persistentInstanceProperties
name: String
var value: Value
init() {
value = entity.propertiesByName[name].defaultValue
}
get { return value }
set { value = newValue }
}
protocol Managed {
static var persistentProperties: InstancePropertyView<Self> {
get }
var persistentProperties: PropertyView<Self> { get set }
...
}
class Person: Managed {
@persistent var name: String
@persistent var birthDate: Date
}
print(Person.persistentProperties.keys) // => "name",
"birthDate"
I think it's probably more likely that you want to access the subset of
properties with a particular attribute than that you want to look through all
the properties and check whether each one has or doesn't have that attribute.
(Incidentally, this is beginning to look a little like one of the
post-@memberwise proposals to have some sort of entity representing a group of
properties—only more flexible and with a broader set of use cases. Still, there
might be hope for a solution with a `@memberwise` behavior and a macro to look
at the resulting property view and generate an initializer from it.)
>> Yes. I would hope that you could downcast a concrete lens:
>>
>> let lens: () -> inout Int = &array.count
>> // Assuming this is a "get lens” syntax
>
> I think the syntax was actually a little bit different as the lens isn’t
> bound to the instance and a readonly lens wouldn’t return inout:
>
> let lens: (Array<MyType>) -> Int = &array.count
I envision there being both bound lenses (sorry, I forgot that `Array.count`
isn't mutating):
struct Person { var name: String }
var joe = Person(name: "Joe")
let lens: () -> inout String = &joe.name
And unbound ones:
let unboundLens: (inout Person) -> inout String = Person.name
`properties` on an instance would give you bound lenses; `properties` on a type
would give you unbound ones. (Or maybe the latter would be something like
`instanceProperties`, since type instances have properties too.)
On the other hand, the idea of bound lenses might not be coherent; the `inout`
parameter of an unbound lens helps make sure that mutation affects value-typed
instances, so bound lenses might not work. Perhaps `properties` on an instance
should be more akin to a `[String: Any]` dictionary, so that
`joe.properties["name"] = "Bob"` naturally calls `joe`'s `properties` setter.
The problem I see there is that the `openas` might open things too far: If the
property is declared to be of protocol type, `openas` would end up giving you
the concrete type of its current value instead.
>> And that you could later open the abstracted lens to get its concrete type:
>>
>> if let concreteLens = abstractLens openas Lens {
>> print(Lens.ReturnValue)
>> …
>> }
>
> What about casting like this:
>
> let typedLens = abstractLens as? (Array<MyType>) -> Int
If you're specifically expecting an `Int`, sure. But if you have no idea what
the type is and want to find out, I think you'd need to (somehow) open the Any
lens and see the concrete return type inside.
--
Brent Royal-Gordon
Architechies
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution