[swift-evolution] [Pitch] Property reflection

Anders Ha hello at andersio.co
Fri May 27 17:37:13 CDT 2016


> On 28 May 2016, at 6:00 AM, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org> wrote:
> 
>>> 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- at 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.

In this case, I wonder if it would be less confusing if bound lenses are available only on reference types, or existential with a class bound.

> 
>>> 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
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list