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 <j...@abbott.me.uk> 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 <char...@charliemonroe.net 
> <mailto:char...@charliemonroe.net>> 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 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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 <j...@abbott.me.uk 
>> <mailto:j...@abbott.me.uk>> 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 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> On Sep 30, 2016, at 2:51 PM, Ted F.A. van Gaalen via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to