I kinda feel my idea went into the wrong direction.
By introducing these implicit protocols (formatted with Source Code Pro font) I
didn’t meant them to force a type to have only reference or value semantics.
+-------+
| Any |
+---+---+
|
+-------------+-------------+
| |
+------+-------+ +-----+----+
| AnyReference | | AnyValue |
+------+-------+ +-----+----+
| |
+--------+---------+ ....................................
| AnyObject (ObjC) | : Optionally Swift could also have :
+------------------+ : | :
: +-------+--------+ :
: | | :
: +----+----+ +-----+-----+ :
: | AnyEnum | | AnyStruct | :
: +----+----+ +-----+-----+ :
....................................
Array<UIView> is a great example that `AnyValue` should not restrict your type
to contain only value types.
The main idea behind these implicit protocols was the ability to create
protocols which only can be applied to a specific type (class, struct or enum,
maybe tuples one day) or to distinguish between types.
Here are some simple examples:
protocol MagicValueType: AnyValue {}
extension MagicValueType {
func expectoPatronum() { /* do some amazing magic */ }
func getMeAView() -> UIView { return UIView() }
// AnyValue should not forbid value types to work with reference types
}
class A {}
struct B {}
extension A: MagicValueType {} // this should NOT work and produce an error,
because MagicValueType is restricted to value types only
extension B: MagicValueType {} // wow we extended our type with an value type
protocol (this is new to the language)
Same rules goes to the `AnyReference`.
We already can do something like this:
protocol SomeReferenceProtocol: class {} // restricted to classes only
extension SomeReferenceProtocol {
func foo() -> B { return B() } // we can work with value or reference
types as we pleased
}
extension A: SomeReferenceProtocol {} // works as expected
extension B: SomeReferenceProtocol {} // this already produces an error which
is the way it should work
I’d be great if we change the `class` keyword to `AnyReference` (not @objc
protocol AnyObject {} as explained before).
protocol SomeReferenceProtocol: AnyReference {}
Any value type except buildin types (Tuples can’t be extended at the moment
anyways) should implicitly conform to AnyValue and any Swift classes should
implicitly conform to AnyReference. All ObjC classes should conform to
AnyObject.
If these protocols would exist we could use them to overload correctly (an
abstract example I used in my post two weeks ago):
func mutate<T: AnyValue>(value: T, scope: @noescape (value: inout T) -> Void)
-> T {
var mutableValue = value
scope(value: &mutableValue)
return mutableValue
}
func mutate<T: AnyReference>(value: T, scope: @noescape (value: T) -> Void) ->
T {
scope(value: value)
return value
}
The first `mutate` function will be called if you pass any class to it,
including ObjC classes. And finally the second `mutate` function is only called
when there is a value type (struct, enum).
I don’t want to restrict the semantics of a type with implicit protocol, but
just to constrain protocols if there is a need and correctly detect reference
vs. value types.
We could go even further and allow mixing of implicit protocols:
protocol Cocktail: AnyReference, AnyValue {}
this would be equivalent to:
protocol Cocktail: Any {}
or just:
protocol Cocktail {}
Complex restriction might also be possible for whatever desire:
protocol Burger: AnyObject, AnyStruct {}
extension UIView: Burger{} and extension B: Burger {} should work.
I home my English was enough to clarify my idea.
--
Adrian Zubarev
Sent with Airmail
Am 4. Mai 2016 bei 20:46:40, Matthew Johnson via swift-evolution
([email protected]) schrieb:
> On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
> <[email protected]> wrote:
>
>
> on Wed May 04 2016, Adrian Zubarev <[email protected]> wrote:
>
>> Not sure what to think about the enum cases inside a protocol (if AnyEnum
>> would
>> even exist), it could be a nice addition to the language, but this is an own
>> proposal I guess.
>>
>> We should start by adding AnyValue protocol to which all value types
>> conforms.
>
> Having a way to constrain conformance to things with value semantics is
> something I've long wanted. *However*, the approach described is too
> simplistic. It's possible to build classes whose instances have value
> semantics (just make them immutable) and it's possible to build structs
> whose instances have reference semantics (just put the struct's storage
> in a mutable class instance that it holds as a property, and don't do
> copy-on-write).
>
> In order for something like AnyValue to have meaning, we need to impose
> greater order. After thinking through many approaches over the years, I
> have arrived at the (admittedly rather drastic) opinion that the
> language should effectively outlaw the creation of structs and enums
> that don't have value semantics. (I have no problem with the idea that
> immutable classes that want to act as values should be wrapped in a
> struct). The language could then do lots of things much more
> intelligently, such as correctly generating implementations of equality.
That is a drastic solution indeed! How would this impact things like
Array<UIView>? While Array itself has value semantics, the aggregate obviously
does not as it contains references which usually be mutated underneath us.
Similar considerations apply to simpler wrapper structs such as Weak.
My expectation is a generic aggregate such as Array would have to conditionally
conform to AnyValue only when Element also conforms to AnyValue.
I’m also wondering how such a rule would be implemented while still allowing
for CoW structs that *do* implement value semantics, but do so while using
references internally.
If the compiler can be sophisticated enough to verify value semantics
statically maybe it would be better to have that mechanism be triggered by
conformance to AnyValue rather than for all structs and enums. Types that
conform to AnyValue would receive the benefits of the compiler knowing they
have value semantics, while other uses of structs and enums would remain valid.
Best practice would be to conform structs and enums to AnyValue whenever
possible.
Another possible advantage of this approach would be allowing immutable
reference types to conform to AnyValue and receive the associated benefits such
as the generated implementation of equality, etc.
-Matthew
>
>
> --
> Dave
>
> _______________________________________________
> 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
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution