<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br><br>Sent from my iPad</div><div><br>On May 27, 2016, at 3:07 AM, L. Mihalkovic <<a href="mailto:laurent.mihalkovic@gmail.com">laurent.mihalkovic@gmail.com</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="content-type" content="text/html; charset=utf-8"><div><br></div><div><br>On May 27, 2016, at 4:20 AM, Matthew Johnson via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><br class=""><div><blockquote type="cite" class=""><div class="">On May 26, 2016, at 8:25 PM, Austin Zheng via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi swift-evolution,<div class=""><br class=""></div><div class="">For those who are interested I'd like to present a pre-pre-proposal for reflection upon a type's properties and solicit feedback. </div><div class=""><br class=""></div><div class="">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 <i class="">defending</i> this specific proposal per se, as I am looking for a jumping-off point to explore designs in this space.</div><div class=""><br class=""></div><div class="">Anyways, here is a gist outlining the public API to the feature: </div><div class=""><br class=""></div><div class=""><a href="https://gist.github.com/austinzheng/699d47f50899b88645f56964c0b7109a" class="">https://gist.github.com/austinzheng/699d47f50899b88645f56964c0b7109a</a><br class=""></div><div class=""><br class=""></div><div class="">A couple of notes regarding the proposal:</div><div class=""><br class=""></div><div class="">The API names need improvement. Suggestions welcome.</div></div></div></blockquote><div><br class=""></div><div>These names are a good place to start but I agree that it would be nice to improve them. I will give it some thought. One comment for now - you use both `get` / `set` and `read` / `write`. It’s probably better to pick one.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">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.</div></div></div></blockquote><div><br class=""></div><div>What do you think of using the `deriving` syntax for this (assuming we go in that direction for Equatable, Hashable, and other synthesized conformances).</div><br class=""></div></div></blockquote><div><br></div><div>I saw this syntax show up in the equatable/hashable context (could not convince myself of its value), are there other areas where it was put forward?</div></div></blockquote><div><br></div>Not yet, but when we have the ability to run code at compile time it is possible we could even have user-defined derivable protocols somehow. I'm sure we will have the ability to synthesize more than just these two eventually.<div><br><blockquote type="cite"><div><div><br></div><div><br></div><br><blockquote type="cite"><div><div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">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.</div></div></div></blockquote><div><br class=""></div><div>How did you arrive at `get` and `set` methods?</div><div><br class=""></div><div>I am wondering how this might relate to lenses. If we’re going to introduce those it feels like the property value should be introduced as a lens. I’m unsure of exactly what that would look like but I it is definitely worth thinking about.</div><div><br class=""></div>Another option if we don’t go with a lens is a simple property (`var value { get }` and `var value { get set }`). IIRC we are going to have throwing computed properties eventually so you could still throw from the setter.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">(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.)</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class="">```</div><div class="">myPerson.typedReadWriteProperty<Int>("age")?.set(30)</div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">try myPerson.allNamedProperties["age"]?.set(30)</div><div class="">```</div><div class=""><br class=""></div><div class="">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), </div></div></div></blockquote><div><br class=""></div><div>This one is tricky. I am generally be opposed to any way to get around access control. But people are going to implement things like serialization using this which may require access to private properties. I think we want to try to understand the consequences of different options and when in doubt decide in favor caution.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">or property behaviors (I think get-set behavior is fundamental to properties, although "behavior metadata" on the views might be useful).</div></div></div></blockquote><div><br class=""></div><div>Not just behavior metadata. Someday we might have user-defined attributes which we would also want to have available. It’s probably better to make available anything that could be useful and isn’t too costly to provide. It could all live behind a `metadata` property so we don’t clutter the interface of the views themselves.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">I'd also have to figure out how it would operate with generic types or existentials.</div><div class=""><br class=""></div><div class="">Anyways, thanks for reading all the way to the end, and any feedback, criticism, or alternative proposals would be greatly appreciated.</div><div class=""><br class=""></div><div class="">Best,</div><div class="">Austin</div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div></blockquote></div></body></html>