> On May 27, 2016, at 11:54 AM, Austin Zheng via swift-evolution 
> <[email protected]> wrote:
> 
> I think there is a consensus forming that we probably don't yet know enough 
> about Swift's future capabilities to nail down specific designs yet. (Not 
> that I want to stop people from talking about them if they wish.)
> 
> However, now that there is a conversation topic about reflection, I also 
> wanted to ask the following questions:
> 
> 1. What sorts of features are important, and what would you use them for?
> 
> For me, the list looks like the following:
> 
> - Describe the structure of a type. (We have that right now, with 
> introspection using "Mirror".)
> 
> - Find all the properties on a type. Get and set their values, and get 
> information about them (like their dynamic type).
> - Find all the methods on a type. Be able to get a reference to and invoke a 
> method on an instance of a type.
> - Find all the subscripts and initializers on a type?
> 
> - Get a list of all concrete types opting in to extended reflection.
> - Get a list of all concrete types visible to the caller that conform to some 
> protocol(s), possibly with additional requirements on associated types.
> - Get a list of all protocols.
> 
> - Create a reference to a type using a string, and perform certain actions 
> using that type. (It would be interesting if you could say "try parsing this 
> type into a concrete type that conforms to X, Y, and Z protocols", and if 
> successful you get a metatype to use or something you can pass to a generic 
> function.
> - Create a reference to a method or property using a string, and use it as 
> above.
> 
> - Reify methods and properties marked with the 'dynamic' keyword in such a 
> way that where they are dispatched to can be controlled at runtime. For 
> example, maybe a dynamic method of a class might use some default 
> implementation, or if some condition is met forward invocations of it to a 
> dynamic method on another class instead.
> 
> 2. What sorts of priorities should inform Swift's reflection capabilities?
> 
> For me, the option to perform both "statically typed" and runtime type 
> checked operations, when feasible, is a big one. I think something like 
> variadic generics could allow for typesafe reflection on methods and 
> functions at runtime - rather than having to call a performSelector: like 
> method, it would be possible to get a full-fledged value of function type and 
> use it just like any other method. This is something few languages have AFAIK.
> 
> The reflection machinery should cooperate with the rest of the language. If 
> there must be a way to, for example, access private members of an instance 
> through reflection, it should not be unconditional and should be carefully 
> considered such that there are certain invariants that are still honored. 
> Like Laurent said earlier, bad things can happen if you use reflection to 
> subvert access control.
> 
> I think reflection should be opt-in in most cases. Reflection opting-in 
> should be composable, inheritable, and retroactive, which covers the most 
> common cases in which reflection would be useful: working with Cocoa/Cocoa 
> Touch, for example.

One priority you don’t mention here that I think is worthwhile to consider is 
static reflection.  Any features that make sense both statically and 
dynamically should have the same API statically and dynamically wherever 
possible.  

> 
> Best,
> Austin
> 
> 
> 
>> On May 27, 2016, at 7:37 AM, plx via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>> I think this proposal should “simmer" until we know what property behaviors 
>> will look like (or find out they are never happening, etc.). 
>> 
>> The interaction with “property behaviors” seems likely to be quite subtle, 
>> even for something simple like `lazy`.
>> 
>> For sake of argument, let’s say that a `lazy` declaration like so:
>> 
>>   class SomeClass { 
>>     lazy var foo: Foo = Foo(bar: self.prepareBar())
>>   }
>> 
>> …gets implicitly-expanded into e.g. something like the below:
>> 
>>   class SomeClass {
>>  
>>     var foo: Foo {
>>       guard let foo = _foo else {
>>         _foo = Foo(bar: self.prepareBar())
>>         return _foo
>>       }
>>       return foo
>>     }
>> 
>>     private var _foo: Foo? = nil
>> 
>>   }
>> 
>> …which immediately exposes a few lazy-specific questions:
>> 
>> - should `foo` be exposed via reflection? (IMHO: yes)
>> - should `_foo` be exposed via reflection? (IMHO: probably not, but not 
>> certain)
>> - should `foo`’s lazy-ness be exposable? (IMHO: yes, but how exactly?)
>> 
>> …as well as a few more-general questions:
>> 
>> - should computed properties, in general, be exposed to reflection? (IMHO: 
>> probably not, but there are some exceptions…)
>> - if user-specified property behaviors get special exposure, how should that 
>> work?
>> - how should reflection work for enums/enums-with-payloads? 
>> 
>> Finally, I worry a lot less about the details of getter/setter pairs than I 
>> worry about being able to use reflection for construction/initialization.
>> 
>> I don’t have any actual proposal on that front, but it seems like it should 
>> be factored into any reflection design.
>> 
>>> On May 26, 2016, at 8:25 PM, Austin Zheng via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> Hi swift-evolution,
>>> 
>>> For those who are interested I'd like to present a pre-pre-proposal for 
>>> reflection upon a type's properties and solicit feedback. 
>>> 
>>> First of all, some caveats: this is only a very small piece of what 
>>> reflection in Swift might look like one day, and it's certainly not the 
>>> only possible design for such a feature. Reflection comes in many different 
>>> forms, and "no reflection" is also an option. Deciding what sort of 
>>> reflection capabilities Swift should support is a prerequisite to 
>>> stabilizing the runtime API, which I imagine has resilience consequences. 
>>> I'm not really interested in defending this specific proposal per se, as I 
>>> am looking for a jumping-off point to explore designs in this space.
>>> 
>>> Anyways, here is a gist outlining the public API to the feature: 
>>> 
>>> https://gist.github.com/austinzheng/699d47f50899b88645f56964c0b7109a 
>>> <https://gist.github.com/austinzheng/699d47f50899b88645f56964c0b7109a>
>>> 
>>> A couple of notes regarding the proposal:
>>> 
>>> The API names need improvement. Suggestions welcome.
>>> 
>>> It's opt-in: types have to conform to a special protocol for the compiler 
>>> to generate whatever hooks, metadata, and support code is necessary. Once a 
>>> type conforms, the interface to the reflection features naturally present 
>>> themselves as protocol methods. It would be great to allow an extension to 
>>> retroactively enable reflection on a type vended by another module, 
>>> although I have no idea how feasible that is.
>>> 
>>> It uses "views": there are four types of views, two of each in the 
>>> following categories: typed vs untyped, get-only versus get-set. A view is 
>>> a struct representing a property on an instance of a type (or maybe a 
>>> metatype, for type properties). It allows you to get information about that 
>>> property (like its name) and try getting and setting its values.
>>> 
>>> (You can get a get-only view to a property, and then try and upgrade it 
>>> later to a get-set view, if the underlying property is get-set. If you 
>>> don't care about setting, though, you can just work exclusively with 
>>> get-only views.)
>>> 
>>> It supports both typed and untyped access. You can ask for a property view 
>>> specifically for (e.g.) a `String` property, and if you get one you can be 
>>> assured that your getting and setting operations will be type safe. You can 
>>> also ask for an "untyped" property view that exposes the value as an Any, 
>>> and allows you to try (and possibly fail, with a thrown error) to set the 
>>> value.
>>> 
>>> The requirements part of it is composable. For example, you can imagine a 
>>> future "FullyReflectable" protocol that simply inherits from 
>>> "PropertyReflectable", "MethodReflectable", and other reflectable 
>>> protocols. Or maybe a library requires reflection access to types that it 
>>> needs to work with, and it can create its own protocols that inherit from 
>>> "PropertyReflectable" and naturally enforce reflection support on the 
>>> necessary types.
>>> 
>>> It looks a bit cumbersome, but there's room for refinement. Users won't 
>>> necessarily see all the types, though, and the interface is pretty 
>>> straightforward:
>>> 
>>> ```
>>> myPerson.typedReadWriteProperty<Int>("age")?.set(30)
>>> 
>>> try myPerson.allNamedProperties["age"]?.set(30)
>>> ```
>>> 
>>> I'm not yet sure how it should interact with access control (my inclination 
>>> is that it would only expose the properties you'd be able to directly 
>>> access), or property behaviors (I think get-set behavior is fundamental to 
>>> properties, although "behavior metadata" on the views might be useful).
>>> 
>>> I'd also have to figure out how it would operate with generic types or 
>>> existentials.
>>> 
>>> Anyways, thanks for reading all the way to the end, and any feedback, 
>>> criticism, or alternative proposals would be greatly appreciated.
>>> 
>>> Best,
>>> Austin
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to