[swift-evolution] [Review] SE-0030 Property Behaviors

Joe Groff jgroff at apple.com
Fri Feb 19 12:50:44 CST 2016


> On Feb 19, 2016, at 8:17 AM, Maximilian Hünenberger <m.huenenberger at me.com> wrote:
> 
> First a general question: Are these behaviors also allowed on normal variables in function bodies (regarding the current proposal)?
> 
> ----------
> 
> The "initialValue" should be exposed as closure/function since it can introduce side effects:
> 
>         var [resettable] y = functionWithSideEffects()
> 
> According to your proposal: "If the behavior includes an initial value requirement declaration, then the identifier initialValue is bound as a get-only computed property that evaluates the initial value expression for the property"
> 
> So if I understand it right if I reset "y" "functionWithSideEffects" gets executed.

Perhaps. It would be reasonable to consider initialValue a special accessor.

> 
> ------------
> 
> Can you explain what is the difference between "Self" and "Value" in the following example?:
> 
> protocol Fungible {
>         typealias Fungus
>         func funge() -> Fungus
> }
> 
> var behavior runcible<Value where Self: Fungible, Self.Fungus == Value>: Value {
>         get {
>                 return self.funge()
>         }
> }
> 
> Isn't "Self" the same as "Value"? So it can be rewritten to:
> 
> var behavior runcible<Value: Fungible, Value.Fungus == Value>: Value {
>         get {
>                 return self.funge()
>         }
> }

`Self` is the type that contains the property. `Value` is the type of the property itself. If you have:

class Foo {
  var [behavior] x: Bar
}

then behavior's implementation will see Self == Foo and Value == Bar.

> 
> ----------
> 
> You've wrote that behaviors shouldn't be types/type-like e.g. "var x: lazy<Int>".
> Can you mention some disadvantages?
> 
A few:

- If the property formally has type `lazy<Int>`, then that impacts overload resolution and method lookup under the property. Even if we introduced implicit conversions, there would inevitably be differences in behavior from a pure `Int` property. It also wouldn't be ABI-resilient to change a property's implementation to be lazy, or to use a different behavior, or to not use a behavior at all.

- Types aren't quite zero-cost abstractions in Swift today. Unspecialized code would generate type metadata records for every lazy<T> it instantiated at runtime.

- A purely type-encapsulated property delegate design like Kotlin's requires the property delegate instance to carry any information about the declaration it may need for later inside the instance itself; for instance, for a lazy property, the closure that evaluates the initial value would have to be stored in-line inside every instance of every property. The 

> I can't see huge ones. However I don't see any advantages.
> 
> Is there any advantage regarding a type-like behavior?

A type-like behavior could provide an arguably simpler user model, possibly with less impact on the language as a whole.

> 
> ---------
> 
> I just remembered recursive value types...
> We can even eliminate another keyword: "indirect"
> 
> implementation:
> 
> var behavior indirect<Value>: Value {
>         class Ref<T> {
>                 var value: T
>                 init(_ value: T) { self.value = value }
>         }
> 
>         var reference: Ref<Value> = Ref(initialValue())
>         get { return reference.value }
>         set { reference.value = newValue }
> }
> 

Yeah, indirect would be another good use for property behaviors.

-Joe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160219/f20d09ac/attachment.html>


More information about the swift-evolution mailing list