[swift-evolution] [Proposal] Property behaviors

Jacob Bandes-Storch jtbandes at gmail.com
Mon Jan 18 18:29:46 CST 2016

Here are some of my thoughts from reading through the current version (
https://gist.github.com/jckarter/50b838e7f036fe85eaa3). Apologies if this
duplicates what anyone else has said; the thread is kind of unmanageable :)

  // Behaviors can declare that properties using the behavior require
>   // a `deferred initializer` expression. When deferred, the
>   // initializer expression is assumed to be evaluated after
>   // initialization of the containing value, which allows it to refer
>   // to `self`. If declared, `initializer` is bound in accessors and
>   // methods of the behavior.
>   deferred initializer: Value

This seems like an important feature, but the syntax is strange to me. It
looks like it would be declaring storage inside the behavior, but it's
really specifying the type of something used in the containing object's
property declaration.

I can think of a couple alternatives:

1. Rather than passing an initial value in the containing object like "var
[lazy] prop = someInitialValue", pass it explicitly as a parameter to the
    like "var [ lazy({ return someInitialValue }) ] prop: Type"

    I think it might be generally useful for behaviors' initializers to
take arguments; it'd handle more than just this case. For example, you
could have a behavior called synchronized(maxConcurrentRequests: Int) which
would allow arguments passed to affect the behavior's...behavior.

2. Make the "deferred"-ness a modifier/attribute on the behavior
declaration, like "public @deferred var behavior lazy<Value>: Value { ...
}", which would make the implicit initialValue inaccessible from the
behavior's init(). The same with @eager.

x.lazy.clear() // Invokes `lazy`'s `clear` method

As I think others have mentioned, this is ambiguous if x itself has a
property called "lazy". I'd be reasonably satisfied with any of the
proposed solutions to this.

  base var value: Int

I don't think I like the fact that this needs to be explicitly declared. Do
all behaviors have to use the same identifier for them to be composable?
Could you use "super" to mean this, instead of explicitly declaring a base

Accessor requirements can be made optional by specifying a default
> implementation:
>   mutating accessor willSet(newValue: Value) {
>     // do nothing by default
>   }

Up until this point, I was thinking of accessor declarations like protocol
requirements, in that they have no implementation ("accessor foo()" like
"func foo()"). I think the lack of implementation is what makes it clear
that these are requirements, not things the behavior is implementing.

So perhaps you could use the "optional" specifier to indicate that they
aren't required, rather than allowing an implementation block in the
behavior. "optional accessor foo()" would allow the behavior's
implementation to use "foo?()".

var [foo] x: Int {

    bar(myArg) { print(myArg) } // `arg` explicitly bound to `myArg`


Why not require a type annotation for parameters here? I recognize this
matches the current syntax of set(newValue), but it would be more flexible
if this were more like a function declaration.

To preserve the shorthand for get-only computed properties, if the accessor
> declaration consists of code like a function body, that code is used as the
> implementation of a single accessor named "get".

This seems a bit vestigial. Maybe it could be allowed only when a computed
property is declared without using any behaviors.

A few more questions:

- Can a behavior's own properties/storage use other behaviors? Can a
behavior be recursive?

- What of deinitializers for behaviors? Would it be possible, for example,
to make an observable behavior whose willSet/didSet run during init and
deinit (which Swift's current property observers can't do)?

- Are accessor implementations allowed to access the "current" property
value? Currently, inside "var foo { didSet { … } }" you can access the
current value by referencing "foo".

Overall this looks great. I'm looking forward to it. :-)

Jacob Bandes-Storch
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160118/2867f735/attachment.html>

More information about the swift-evolution mailing list