[swift-evolution] [Pitch] Property reflection

Matthew Johnson matthew at anandabits.com
Fri May 27 15:12:54 CDT 2016


> On May 27, 2016, at 2:57 PM, Brent Royal-Gordon <brent at architechies.com> wrote:
> 
>> I'm not sure how this alternative is related to access control.  Austin's proposal could enforce access control in the same way and he mentioned he was inclined to enforce it the same way you are describing.
>> 
>> The reason I say it is tricky is because enforcing access control in this way would prevent things people want to do with reflection (things that have received a lot of discussion recently).  Allowing a distinct visibility to be specified for reflection might be a way to strike a reasonable balance.
> 
> It's related to access control because it's specifically intended that you can pass your `properties` dictionary to other code to delegate your access. This works around the "but other code needs to see your private stuff" problem: it *can* see your private stuff, but only if you permit it.
> 
> I suppose we would want a `#properties` you could use in a protocol conformance which would mean "the properties visible at the conformance site":
> 
> 	protocol Serializable {
> 		var propertiesToSerialize: PropertyView<Self> { get set }
> 		init(forDeserialization: ())
> 	}
> 	extension Serializable {
> 		var propertiesToSerialize: PropertyView<Self> {
> 			get { return #properties }
> 			set { #properties = newValue }
> 		}
> 
> 		func serializedData() -> Data {
> 			return Serializer().serialize(self)
> 		}
> 		factory init(serializedData data: Data) {
> 			self = Serializer.deserialize(data, of: Self.self)
> 		}
> 	}

That’s an interesting approach.  That could also be a way to strike a reasonable balance.  Good to see different design possibilities explored here.  That’s what I was looking for.  

> 
>> Your suggested approach doesn't allow for access to property metadata.  Do you have any suggestions on how that would be exposed?  
> 
> 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.

> 
>> What about casting the lens to a typed lens?  Would you envision that being supported?
> 
> 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

> 	let abstractLens = lens as () throws(set) -> inout Any		// Upcasting an inout-returning function adds `throws(set)`

And I think this would be: `(inout Array<MyType>) -> inout Any` (with some additional syntax for throwing on the writeback which would make sense to me alongside the `inout`, but I haven’t seen any specific examples proposed).

> 
> 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

> 
> This is a slightly different form of existential opening, and `ReturnValue` doesn't currently exist on function types, but I hope these things would be possible.	
> 
>> I also think we would want a way to access a specific property by name if accessing the whole properties dictionary involved any non-trivial overhead (but maybe it wouldn't have to).
> 
> That's why I said "like a dictionary". :^) If there's a way to access individual keys without collecting them all ahead of time, or to generate lenses as needed, I'm all for it.

Right.  There has already been some talk of `Map` and `MutableMap` protocols.  `Map` would be useful here (as well as for supporting lazy dictionary operations among other things).

> 
> -- 
> Brent Royal-Gordon
> Architechies
> 



More information about the swift-evolution mailing list