> On Oct 10, 2016, at 1:13 PM, Jay Abbott <[email protected]> wrote:
> 
> I understand Charlie. A few points though:
> a) I'm talking about pure Swift, this is absolutely nothing to do with 
> Objective-C;

Sure, but in either case you will need to somehow solve locking of the 
structure holding the additional values.

> b) If you read back on the AO thread you'll see that initially I was thinking 
> "I want AO because it will give me stored properties in extensions" when 
> really I should have been thinking "I want stored properties in extensions". 
> So this discussion is no longer about AO at all, hence the new subject.

Agreed, though the actual backing of the values won't be a lot different from 
the AO - it can be called differently, but the fact that it is likely to be 
stored in a dictionary brings resemblence to AO - and what I've mentioned are a 
few downsides to how AO are implemented at this point.

> c) Protocol conformance in an extension cannot tell the compiler to add 
> members to classes defined in other precompiled modules, as it is not 
> compiling them. When you do have the code and you are compiling it yourself, 
> you actually don't *need* stored properties in extensions because you can 
> work around it (although it would be nice), so the case where you actually 
> need it is where you want to extend someone else's precompiled class.

This is why I mentioned that this "magic protocol" would be off limits to 
extensions. Perhaps the choice of a protocol to this was incorrect - better way 
would be to use an annotation like @allows_extension_properties or similar.

I bet you that in any case, there will be a lot of people on this list that 
will want explicit opt-in, or at least a way to opt-out.

> 
> On Mon, 10 Oct 2016 at 06:04 Charlie Monroe <[email protected] 
> <mailto:[email protected]>> wrote:
> No, I've also suggested how it would be implemented. It would, as I've 
> described, require support from the compiler and runtime - the protocol 
> conformance would tell the compiler to include an extra space in the instance 
> layout for [AnyHashable : Any], which would get to be used by the runtime to 
> store AO.
> 
> Note that the implementation noted below does not use any locks at all - 
> unlike ObjC AO, it's not thread-safe.
> 
> With AO, the main bottleneck always was that everything was stored in one 
> place - this way, each object would have its own AOs stored within itself. 
> This way, instead of a single spin (!) lock 
> (https://opensource.apple.com/source/objc4/objc4-680/runtime/objc-references.mm
>  
> <https://opensource.apple.com/source/objc4/objc4-680/runtime/objc-references.mm>),
>  you can use a lock pool - e.g. you have a dozen locks, depending on the hash 
> of the object itself, you decide which lock to use - this lowers the 
> contention a lot.
> 
> Try to run a few threads, read, write AO using the ObjC runtime - you'll see 
> how painfully slow it is - this is not something that should be in Swift.
> 
> 
>> On Oct 9, 2016, at 10:15 PM, Jay Abbott <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> Charlie,
>> 
>> What you suggest defines how you would use it from your code, not how it 
>> would be implemented in the language. If you look at my AO implementation it 
>> does what you say:
>> https://github.com/j-h-a/AssociatedObjects/blob/develop/AssociatedObjects/AssociatedObjects.swift
>>  
>> <https://github.com/j-h-a/AssociatedObjects/blob/develop/AssociatedObjects/AssociatedObjects.swift>
>> i.e. has a protocol called 'Associable' and you opt classes into it to get 
>> the behaviour. This works and is usable, but the implementation leaves a lot 
>> to be desired (it's not optimal and while the interface is clean the 
>> implementation is not). Anyway - I was trying to steer the conversation AWAY 
>> from AOs towards stored properties in extensions, since Robert Widmann 
>> helped me to understand that AO was just a *means*, whereas stored 
>> properties in extensions is the *end*.
>> 
>> In fact we don't need a solution to the problem of "how to define/use stored 
>> properties in extensions" because the existing syntax for extensions is 
>> perfectly fine. Currently you get an error if you try to define a stored 
>> property in an extension, so no new syntax is needed, we just remove that 
>> error and make it work.
>> 
>> Of course a runtime-check may be needed if there is doubt about whether a 
>> dynamically linked module supported this feature - so this might invalidate 
>> what I just said above, or it might still be possible if the runtime does 
>> the check automatically when an extension is linked and puts a different 
>> implementation in place for older modules.
>> 
>> I'm just airing some thoughts at the moment to see what people think and try 
>> to get some technical feedback on viability. So it's not all fully thought 
>> through :D
>> 
>> 
>> On Sun, 9 Oct 2016 at 20:54 Charlie Monroe <[email protected] 
>> <mailto:[email protected]>> wrote:
>> There is a 4th way.
>> 
>> Introduce an internal protocol Associatable, which would tell the compiler 
>> to add an additional (hidden) field to the object which would include the 
>> "dictionary" of key -> value associated values. (It would be off-limits to 
>> extensions, of course).
>> 
>> This way:
>> 
>> - it won't be a single dictionary containing all the associated values
>> - classes can opt-in to this
>> - the dictionary will be per-instance
>> 
>> This is a midway between the current implementation of ObjC associated 
>> objects and of what someone has suggested to have an extra space for each 
>> object for the AO...
>> 
>> 
>>> On Oct 9, 2016, at 9:47 PM, Jay Abbott via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> I have been thinking further on this and in addition to my previous two 
>>> thoughts about implementation, I have had another idea...
>>> 
>>> 3. If there is a bit spare in the object header somewhere (that is 
>>> currently always zero), this could be used to signify the presence of an 
>>> additional struct that immediately follows after the existing object data. 
>>> I *think* that this method would allow binary compatibility with older 
>>> modules. Instances that have this bit set would allow stored properties in 
>>> extensions. The struct at the end would have one member, a pointer to a 
>>> table of additional objects/values, stored properties defined in extensions 
>>> could be stored in here, using a hash derived from the 
>>> module/protocol/extension/property name (or something better if it exists).
>>> 
>>> The struct could be very simple as described above or more complex, with 
>>> additional features, for example a list of deinit hooks, dynamically added 
>>> methods, etc. The struct itself may also be dynamic in size/layout if such 
>>> complexity is warranted by size or extensibility concerns. Perhaps it 
>>> should start with some flags and its size (size would be fixed and only 
>>> increase with revisions so this would double as a 'version' number).
>>> 
>>> If viable - this would be a much better way to implement this feature than 
>>> my previous two ideas. It doesn't require global lookups or additional 
>>> levels of indirection beyond accessing the dynamic data/feature itself.
>>> 
>>> 
>>> On Mon, 3 Oct 2016 at 04:13 Jay Abbott <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> Are stored properties in extensions already being discussed elsewhere? Is 
>>> this one of those deferred-but-not-indexed-anywhere subjects?
>>> 
>>> I wonder how stored properties could potentially be implemented, I can only 
>>> think of two ways:
>>> 
>>> 1. An extra pointer per instance (with resulting ABI compatability 
>>> implications) to hold a collection of the stored items.
>>> 
>>> 2. A global lookup for any instance where stored properties have been set.
>>> 
>>> I'm not a language implementation expert, or familiar with the swift 
>>> implementation, so there may be other/better ways - I'd like to know if 
>>> there are?
>>> 
>>> If not, and option 2 was employed, a little foresight might enable the 
>>> mechanism to be overloaded in the future for other dynamic features too. A 
>>> bit flag (I'm hoping there's a spare bit in an existing flags field 
>>> somewhere?) could indicate whether any feature had caused the object to be 
>>> added to this lookup and deinit could check this bit and make sure the 
>>> object is removed, thus any stored properties are nilled. The lookup value 
>>> could be a struct with one member (extensionStoredProperties), and 
>>> additional members can be added in future for new features.
>>> 
>>> I get the impression from the associated objects discussion that perhaps 
>>> there are much better, more optimal, more ingenious, more unknown-by-me 
>>> ways of doing such things, so apologies if this whole idea is way-off the 
>>> mark :D
>>> 
>>> Jay
>>> 
>>> P.S. Note that stored properties in extensions could enable developers to 
>>> implement their own dynamic features in Swift.. so such desires could be 
>>> satisfied in the short term until they could be done properly in the 
>>> language.
>>> 
>>> On Sat, 1 Oct 2016 at 00:49 Chris Lattner via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> On Sep 30, 2016, at 2:51 PM, Ted F.A. van Gaalen via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> > Is it possible to have best of (these completely different) both worlds?
>>> 
>>> Yes, of course it is.  Your email spends a lot of words trying to form a 
>>> false dichotomy.  Swift can definitely have both awesome dynamic features 
>>> while still having performance, predictability and safety.
>>> 
>>> > Would it be possible in Swift to have facilities to generate objects
>>> > dynamically at runtime? and, if desirable, how can such be implemented?
>>> 
>>> Here’s an extant implementation that you can use today:
>>> https://github.com/Zewo/Reflection <https://github.com/Zewo/Reflection>
>>> 
>>> I’m sure it isn’t ideal, but it proves that it can be done.  When we have 
>>> bandwidth to reevaluate this area from first principles, I’m sure we can 
>>> make improvements on it.
>>> 
>>> I will grant you that Smalltalk is a beautiful language in its simplicity, 
>>> but for that simplicity it makes many tradeoffs that we’re not willing to 
>>> make.  We are willing to make the internal implementation of Swift complex 
>>> if that means that we get a beautiful model for programmers - one that 
>>> preserves the virtues of safety-by-default, predictability, performance, 
>>> and joy-to-develop-in.
>>> 
>>> The meme of “Swift can never (or will never) support dynamic features” is 
>>> tired, and also wildly inaccurate.
>>> 
>>> -Chris
>>> 
>>> _______________________________________________
>>> 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 
>>> <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