[Review] SE-0030 Property Behaviors


(Douglas Gregor) #1

Hello Swift community,

The review of SE-0030 "Property Behaviors" begins now and runs through February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-proposal.md>
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
Reply text

Other replies
<https://github.com/apple/swift-evolution#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

Doug Gregor

Review Manager


What happened to Property Behaviours SE-0030
(Douglas Gregor) #2

Through February 16, that is.

  - Doug

···

On Feb 10, 2016, at 2:00 PM, Douglas Gregor <dgregor@apple.com> wrote:

Hello Swift community,

The review of SE-0030 "Property Behaviors" begins now and runs through February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md


(Brent Royal-Gordon) #3

The review of SE-0030 "Property Behaviors" begins now and runs through February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md

I'm afraid that, although the address as written here is correct, the href attribute on the link is not. You'll need to copy and paste the address, not click on the link.

Given the frequent mistakes in review announcements (it's not just you, Doug, I've seen this happen during reviews managed by others too), perhaps someone should write a bot that monitors swift-evolution/master's schedule.md and generates these messages automatically. :^)

···

--
Brent Royal-Gordon
Architechies


(Brent Royal-Gordon) #4

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md

As for the proposal itself:

  • What is your evaluation of the proposal?

+1 with no changes suggested.

I do, however, have one caveat: this proposal is a good core for property behaviors, but alone, I don't think it carries its own weight. It will need at least a couple of the items in "Future Directions" section before it's really worth having. If we find we're not able to get those things proposed and accepted, we may want to reconsider whether we should add the feature at all.

Overall, though, I'm eagerly anticipating this feature.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Special behavior tied to properties is one of the largest sources of boilerplate in Swift, and allowing that boilerplate to be factored out is an extremely welcome step. Ever since the discussions about behaviors first started, I've been keeping an eye out for places I would use them if they were available, and I've spotted many such cases in my code.

  • Does this proposal fit well with the feel and direction of Swift?

Yes. Eventually, this proposal should allow us to rework many ad-hoc features of Swift properties into standard library features. This approach is very, very Swifty.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I've used metaprogramming in Ruby and Objective-C to do broadly similar factoring in a different way, by generating accessors at runtime based on pseudo-declarative code. The behaviors approach is less flexible, because it has to be extended for each capability we want to add, but it's also *far* easier to use correctly.

I also have experience with the Perl 6 approach (I haven't actually used the final Perl 6, but I was active in its design process, and actually wrote a proof-of-concept CMS for Pugs as a Summer of Code project). Perl 6 does this quite differently; essentially, it makes the variable an object of its own, separate from the value stored in it, and allows you to apply roles (traits/mixins) to the variable in order to customize its behavior. This is a very, very powerful approach, but it would most likely introduce more overhead than is appropriate for Swift, which aspires to be a systems language.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I participated quite heavily in the preliminary discussions and submitted detailed critiques at that time; it's probably safe to say that I have not suggested any changes because my suggestions have already been discussed and incorporated where appropriate. I've also been keeping an eye out in my Swift codebases for places where I would have used behaviors if they were available.

For this review specifically, I re-read the proposal from top to bottom.

···

--
Brent Royal-Gordon
Architechies


(Curt Clifton) #5

Original proposal: https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md

# What is your evaluation of the proposal?

I am strongly in favor of the proposal. While I eagerly await some of the work described in future directions—binding the name of the property, in particular—I think the proposal stands tall on its own.

# Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Property behaviors provide a well-founded mechanism to replace several existing special cases in the language. The new mechanism is orthogonal to existing language features, so it actually simplifies the language versus having special cases. As a general tool, it will help developers to eliminate substantial boilerplate in a principled way.

# Does this proposal fit well with the feel and direction of Swift?

Mostly certainly! Like Brent, I've been looking for places in my daily work that could benefit from property behaviors. These come up surprisingly often.

# If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I've used both KVC and dynamic method generation in Objective-C for achieving some of the aims satisfied by property behaviors. I expect that property behaviors will prove to be a more approachable and less error prone solution.

# How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I read all of the preceding discussions and participated in them lightly (2-3 emails sent). I closely read every public draft of the proposal.

Cheers,

Curt

···

-------------------------
Curt Clifton, PhD
Software Developer
The Omni Group
www.curtclifton.net


(Chris Lattner) #6

Proposal link:
https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
<https://github.com/apple/swift-evolution#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?

I’m +1 on the feature. I have some comments for discussion though, I’m sorry I didn’t get these to you before the formal proposal went out:

First, on the most obvious bikeshed, the surface level syntax proposed:

  var [lazy] foo = 1738
  foo.[lazy].clear()

Given the recent trend to use # for compiler synthesized / macroish / magic syntax, it is worth considering whether:

  var #lazy foo = 1738
  foo.#lazy.clear()

might make sense, or even:

   #lazy var foo = 1738

I think that something like this is a bit better aesthetically, since the [] delimiters are heavily array/collection/subscript-centric (which is a good thing). OTOH, this would be giving users access to the “#” namespace, which means that future conflicts would have to be resolved with backticks - e.g. if they wanted a “line” behavior, they’d have to use "var #`line` foo = 1738”. I guess the fact that we already have a solution to the imagined problem means that this isn’t a big concern in practice.

In any case, I think we should just pick a syntax, land the feature, and keep bikeshedding on it through the end of Swift 3 :-)

What are the semantics of behaviors applied to var/let decls with non-trivial patterns? For example:

  var [lazy] (foo, bar) = qux()

? While we could devise semantics for this in some cases, I think it is reasonable to only allow behaviors on single-identifier patterns, and reject the other cases as invalid. If you agree, please loop that into the proposal.

I understand the need to specifying whether the getter/setter and other random methods are mutating or not, but doesn’t this eliminate the difference between a var/let behavior? Couldn’t we just say that a behavior with a nonmutating getter & setter are valid on a “let”, and that any other mutating members are unavailable on a let? This seems like a theoretical win, though I’m not sure whether it would actually be a win in practice for any conceivable behaviors you’ve been thinking about.

I like the approach of having a behavior decl, but am not excited about the decl syntax itself:
behavior var [lazy] _: Value = initialValue {

I understand that this is intended to provide a template-like construct, but I have a few problems with this:

1) A number of the things here are actually totally invariant (e.g. the _, the colon) or only serve to provide a name (Value, initialValue) but cannot be expanded into general expressions, though they look like they are.

2) This is totally unprecedented in Swift. We have a very regular structure of “@attributes decl-modifiers introducer_keyword name” - we have no declarations that look like this. For example, while operator decls could follow this structure, they don’t.

3) If you agree that we don’t need to differentiate between var/let then “behavior var" is providing potentially misleading info.

IMO, the most regular decl structure would be:

@initial_value_required // or something like it.
property behavior lazy { // could be “subscript behavior” at some point in the future?
   var value: Self? = nil // Self is the property type? Seems weird if it is the enclosing type.
   ...
}

or perhaps:

@initial_value_required
property behavior lazy<PropertyType> { // specify the type of the property as a generic constraint?
   var value: PropertyType? = nil
   ...
}

though I agree that this would require us to take “behavior” as a keyword. Do we know whether or not this would be a problem in practice? If so, going with “behavior var” and “behavior let” is probably ok.

Of course, @initial_value_required is also pretty gross. The alternative is to follow the precedent of operator decls, and introduce random syntax in their body, such as:

property behavior lazy<PropertyType> {
   initializer initValue
   var value: PropertyType? = nil
   …
       value = initValue
   ...
}

  // Behaviors can declare storage that backs the property.
  private var value: Value?

What is the full range of access control allowed here? Is there any reason to allow anything other than “public” (which would mean that the entity is exposed at whatever the properties access control level is)? If so, why allow specifying internal? For sake of exposition in the proposal, it seems simplest to say:

var value: Value? // private by default

or something.

  // Behaviors can declare initialization logic for the storage.
  // (Stored properties can also be initialized in-line.)
  init() {
    value = nil
  }

If a behavior has an init() with no arguments, then are the semantics that it is *always* run? What if there are both an init() and an init(value : Value)?

// Inline initializers are also supported, so `var value: Value? = nil`
  // would work equivalently.

This example is using a stored property of type Optional<Value> which has a default value of nil, does that count or is this a syntactic requirement? To me, it seems most natural to follow the existing rules we have:

1) If you write any init, then you get what you write.
2) If there are no init’s, and any stored property in a behavior is non-default initializable, then it is an error.
3) If there are no init’s, and all stored properties in a behavior are default initializable, then you get init() implicitly.

Typographical comment:
    if let value = value {
      return value
    }

You have way too many “value”s floating around, for sake of clarity, how about:

    if let valuePresent = value {
      return valuePresent
    }

In "Resettable properties”, you have this:

  // Reset the property to its original initialized value.
  mutating func reset() {
    value = initialValue
  }

This raises the question of how “initialValue” works: Is it evaluated once when the property is bound and the resultant value is stored somewhere (evaluating any side effects exactly once) or is it an auto-closure-like concept? If it is autoclosure-like, what does it mean in terms of requiring “self." qualification & @noescape?

In the context of your @NSCopying-replacement example, I would want something like this:

class Foo {
  var [copying] myproperty : NSString

  init(a : NSString) {
     myproperty = a
  }
}

to work, where the behavior requires an initial value, but that value is provided by a flow-sensitive initialization point by DI . How does this happen?

"This imposes an initializer requirement on the behavior. Any property using the behavior must be declared with an initial value"

Ah, this gets to the @NSCopying replacement example. This might be too limiting, but so long as there is a path forward to generalize this, it seems like a fine starting point.

[[Coming back to this after reading to the end]] Ok, I see this is in the future directions section. I’m fine with punting this to a further revision of the proposal, but I think that it is worthwhile to provide a syntactic affordance to differentiate properties that “must have an initializer expression” and “must be initialized by an 'init(v: Value)’ member on the behavior before otherwise used”. @NSCopying replacement seems like the later case. I’m fine with pushing off the general case to a later proposal, but we should carve out space for it to fit in.

public behavior var [changeObserved] _: Value = initialValue {
...
   
    if oldValue != newValue {

This makes me vaguely uncomfortable, given that “changeObserved” has undeclared type requirements that are only diagnosed when the behavior is instantiated. I’d greatly prefer to see something like:

@initial_value_required
property behavior changeObserved<PropertyType : Equatable> { // constraint specified!

which would allow the behavior to be modularly type checked.

[[later…]] ah, I see that you’re doing something similar but different in the "Synchronized Property Access” example. I mostly care that we can express and modularly check this, the exact syntax isn’t as important.

In detailed design:
property-behavior-decl ::=
  attribute* decl-modifier*
  'behavior' 'var' '[' identifier ']' // behavior name
  (identifier | '_') // property name binding
If you go with this declaration syntax, I’d suggest requiring _ for the name, since the name isn’t otherwise used for anything. Ah, it looks like you say this later, maybe the grammar just needs to be updated?
A _ placeholder is required in the name position. (A future extension of behaviors may allow the property name to be bound as a string literal here.)

"Inside a behavior declaration, self is implicitly bound to the value that contains the property instantiated using this behavior. For a freestanding property at global or local scope, this will be the empty tuple (), and for a static or class property, this will be the metatype. Within the behavior declaration, the type of self is abstract and represented by the implicit generic type parameter Self."

This is somewhat strange to me. Would it be reasonable to say that self is bound iff the behavior has a classbound requirement on Self? Alternatively, perhaps you could somehow declare/name the declcontext type, and refer to it later by a name other than Self?

  mutating func update(x: Int) {
    [foo].x = x // Disambiguate reference to behavior storage
  }

It would be really nice to be able to keep “self” referring to the behavior, and require an explicit declaration for the enclosing declaration if a behavior requires one (e.g. in the case of atomic).

"Nested Types in Behaviors”

This sounds great in the fullness of time, but it seems subsettable out of the first implementation/proposal. Lacking this, it can be easily worked around with a private peer type.

    // Parameter gets the name 'bas' from the accessor requirement
    // by default, as with built-in accessors today.

Not really important for the v1 proposal, but it seems like a natural direction to allow this to be controlled by “API names” in the accessor. The default would be that there are no API names, but if a behavior specified one, e.g.:

    willSet(newValue newValue : Value)

then “newValue” would be the default name in the body of the accessor. If no “API name” were specified, then no name would be default injected.

Typographical comment w.r.t. the "// Reinvent computed properties” example, you refer to the behavior as both “foobar” and “computed” later, I think the later reference is supposed to be "var [foobar] bar: Int”? Feel free to find more diversity in your metasyntactic names here :-)

"Accessor requirements cannot take visibility modifiers; they are always as visible as the behavior itself."

Maybe I’m misinterpreting this, but I see accessors differently. I see them as “never being accessible to the code that declares a property using the behavior”. If you want this, you can define a method that wraps them or something. To a client of a behaviors, accessors are “implementation only”.

Can property requirements in protocols have behaviors on them?

Is the problem being addressed significant enough to warrant a change to Swift?

Yep.

Does this proposal fit well with the feel and direction of Swift?

Yep, moving generalizing special case hacks and moving them out of the compiler is a great direction.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I have not.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I’m spent a lot of time following the discussion and chatting with Joe about this periodically, starting when Dmitri pointed out this possible direction back in Dec 2014. :-)

-Chris

···

On Feb 10, 2016, at 2:00 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:


(Jonathan Tang) #7

Hello Swift community,

The review of SE-0030 "Property Behaviors" begins now and runs through
February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
<https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-proposal.md>

Reviews are an important part of the Swift evolution process. All reviews
should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager. When replying, please try to keep the proposal link at the
top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md

Reply text

Other replies

<https://github.com/apple/swift-evolution#what-goes-into-a-review-1>What
goes into a review?

The goal of the review process is to improve the proposal under review
through constructive criticism and, eventually, determine the direction of
Swift. When writing your review, here are some questions you might want to
answer in your review:

   - What is your evaluation of the proposal?

Would it be out-of-scope to propose extending this to functions? I can

think of several use-cases:

1.) Providing both static & singleton accessors, for the convenience of
users of your library. In a library I've been writing, I've found that all
my configuration calls take this form:

public static func useCoreData() -> Self { return
sharedInstance().useCoreData() }
public func useCoreData() { /* Code here; */ return self }

public static func useNotifications() -> Self { return
sharedInstance().useNotifications() }
public func useNotifications() { /* Code here; */ return self }

I'd love to be able to do (using the ... syntax for the proposed splat
operator being discussed in another thread):

public behavior func [StaticChainable] name(...ArgumentType) -> ResultType {
  public static func name(...args) -> Self { return
sharedInstance().name(...args) }
  public func name() { body; return self }
}

public func [StaticChainable] useCoreData() { /* Code here */ }
public func [StaticChainable] useNotifications() { /* Code here */ }

2.) Providing both "whole" and "parts" versions of Composite Pattern
methods. Very often, you might have a tree structure where each element
has the same type (or conforms to the same protocol). You want a method
with an optional first arg to specify which element you're operating on:

public func move(toElement: DOMElement, edge: EdgeType) { /* Code here */ }
public func move(childWithID id: String, toElement elem: DOMElement, edge:
EdgeType {
  children[id].move(toElement: elem, edge: edge)
}

public func hide() { /* Code here */ }
public func hide(childWithID id: String) { children[id].hide() }

public func show() { /* Code here */}
public func show(childWithID id: String) { children[id].show() }

vs.

public behavior func [Composite] name(...ArgumentType) -> ResultType where
Self: HasChildren {
  public func name(...args) { body }
  public func name(childWithID id: String, ...args) {
self.children[id].name(...args) }
}

public func [Composite] move(toElement: DOMElement, edge: EdgeType) { /*
Code here */ }
public func [Composite] show() { /* Code here */ }
public func [Composite] hide() { /* Code here */ }

3.) Or you have a number of convenience functions that differ only in what
helpers they invoke:

public func remove(elementAtIndex i: Index) { /* Code here */ }
public func remove(element: Generator.Element) { remove(elementAtIndex:
indexOf(element)) }
public func remove(firstMatchingPredicate pred: Generator.Element throws ->
Bool) {
   remove(elementAtIndex: indexOf(pred))
}

public func insertAfter(elementAtIndex i: Index, newElement:
Generator.Element) { /* Code here */ }
public func insertAfter(element: Generator.Element, newElement:
Generator.Element) {
   remove(elementAtIndex: indexOf(element))
}
public func insertAfter(firstMatchingPredicate pred: Generator.Element
throws -> Bool, newElement: Generator.Element) {
   remove(elementAtIndex: indexOf(pred))
}

public func insertBefore(elementAtIndex i: Index, newElement:
Generator.Element) { /* Code here */ }
public func insertBefore(element: Generator.Element, newElement:
Generator.Element) {
   remove(elementAtIndex: indexOf(element))
}
public func insertBefore(firstMatchingPredicate pred: Generator.Element
throws -> Bool, newElement: Generator.Element) {
   remove(elementAtIndex: indexOf(pred))
}

4.) Sometimes you need to define a combination of functions and related
properties, like in the Builder Pattern. (Note the usage of "return self"
here - that's why this is not done with straight settable properties, it's
so the user can chain set calls together and avoid repeating the object
name):

private var foo : String
public func setFoo(newValue: String) -> Self { foo = newValue; return self }

private var bar : String
public func setBar(newValue: String) -> Self { bar = newValue; return self }

private var baz : String
public func setBaz(newValue: String) -> Self { baz = newValue; return self }

(Also this is a good opportunity to use the "set once" behavior mentioned
in the proposal, but I won't repeat that code here.)

public behavior var [Builder] name: Type = initialValue {
  private var name: Type = initialValue
  public func set##name(newValue: Type) -> Self { name = newValue; return
self }
}

public var [Builder] foo: String
public var [Builder] bar: String
public var [Builder] baz: String

Notice that this is a "var" behavior rather than a "func" behavior...I'd
envision the keyword matching the type of entity you *decorate*, not the
type of entity generated. The declarations are public because the access
modifier of the declaration should set a *maximum* visibility, not a
minimum (i.e. you can always make individual instances of a behavior more
restrictive). ## is a token-pasting operation similar to the C
preprocessor; it lets you construct a new name out of identifiers. I'd
assume it would do automatic capitalization of the second argument to
preserve camelCasing.

5.) Sometimes you need a whole suite of classes, functions, and variables.
For example, think of event handlers:

public behavior class [Event] name {
  public class name##Event : Event {
    body

    func preventDefault() { ... }
  }

  public protocol name##Listener {
    public func on##name(event: name##Event)
  }

  private var listeners = [name##Listener]()
  public func add##name##Listener(listener: name##Listener) {
    listeners.append(listener)
  }
  public func remove##name##Listener(listener: name##Listener) {
    listeners.remove(atIndex: listeners.indexOf(listener))
  }

  func fire##name##Event(event: name##Event) {
    for listener in listeners {
      listener(event)
    }
  }
}

class [Event] Click {
  let windowCoordinates: Point
  let viewCoordinates: Point
}

class [Event] TouchDown {
  struct Touch {
    let coordinates: Point
    let force: Double
  }
  let touches: [Touch]
}

The way I'd envision this extension working is that the "behavior" keyword
could be followed by any top-level entity: let/var, func, class, struct,
enum. The behavior then forms a template for entities to be generated and
expanded in place. 'name' is bound to the name of the entity, 'body' to
the statement body from the grammar. Functions can define individual
arguments, types, and a result type, or can use whatever the outcome of the
splatting discussion is as "all remaining arguments, taken from the
instantiating func declaration." Classes can also bind the supertype and
associated types. I don't think it's necessary to be able to reach into
the body and parse it for individual statements; at least, none of the
use-cases I thought of require this.

All the scoping & storage concerns are as per the original proposal. Code
within the body is not allowed to access code inside the behavior (beyond -
possibly? - calling public member functions or properties that are defined
by the behavior). When generating names from behavior expansion, the
compiler checks for name conflicts with any other symbols. Code within the
behavior is not allowed to inspect or destructure the body beyond the
bindings already described, but may call other methods either within the
behavior or within the hosting class if the class conforms to a protocol
(as per the existing proposal). (Perhaps some form of limited
destructuring could be allowed as a generalization of accessor
requirements; allow binding names to functions with the 'func' keyword in
classes, binding to variables with 'let' in function bodies, etc. Haven't
really thought this through, may end up being too complicated.)

A couple features of the existing proposal can be removed under this
generalization. The syntax for calling a method of a property isn't
necessary; instead of x.[lazy].clear, define "func clear##name" inside the
behavior and call it as clearX(). (This also eliminates the need to have
debates over what that syntax should be. :-)) It also lifts the
restriction on 'let' parameters, as these are just another top-level entity
that could be expanded to a set of other entities. They wouldn't allow
accessors or get/set blocks, however; the purpose of this would not be to
allow computed 'let' properties, it would be to fold in additional
functionality into these declarations. One could imagine libraries that
allow clients to auto-delegate all method calls in a protocol to a
sub-object, for example:

public behavior let [DelegateCNContactPicker] name: Type = initialValue
      where Type: CNContactPickerDelegate, Self: CNContactPickerDelegate, {
  public func contactPickerDidCancel(...args) {
name.contactPickerDidCancel(...args) }
  public func contactPicker(...args) { name.contactPicker(...args)
  // Should it include overloads implicitly with ...args? Or should each
be overridden explicitly?
}

and then its use:

class MyViewController: CNContactPickerDelegate {
  private let [DelegateCNContactPicker] myObjectThatReallyHandlesIt =
MyContactPickerDelegate()
  // No forwarding methods needed, and no need to expose
myObjectThatReallyHandlesIt to the outside world.
}

I think this mechanism may also be able to subsume default methods on
protocols - instead of using an extension, you could use a behavior with a
protocol constraint. I haven't really thought through the implications of
this, though, in particular the possibility of protocols with storage. May
not be possible, in which case we wouldn't want to allow behaviors on
protocols.

   - Is the problem being addressed significant enough to warrant a
   change to Swift?

Yes. There are a number of use-cases here, and it generalizes several

special-case features that are currently baked into the compiler.

   - Does this proposal fit well with the feel and direction of Swift?

I think so, but I'll let people with a better sense of the feel and

direction of Swift make that decision.

   - If you have used other languages or libraries with a similar
   feature, how do you feel that this proposal compares to those?

It reminds me a lot of Lisp macros, and in particular the ability to

define many entities at once or intercept the definition of those entities
(used to good effect in CLOS). This is one of the best features of Lisp;
it lets you eliminate much of the boilerplate that shows up in
production-quality libraries for Java, C#, C++, etc.

Behaviors let you side-step many of the hygiene/gensym issues of Lisp
because they can't appear in unrestricted contexts the way Lisp macros
can. Even generalized to allow function & class bodies, the set of symbols
that may be visible inside the behavior body is limited to keywords &
argument lists in the language definition itself; you don't need to build a
whole symbol table to see which symbols are visible inside the behavior,
and you don't need to worry about inserting arbitrary blocks of code into
arbitrary insertion points. This limits the flexibility of behaviors a bit
(eg. you could never do something like loop or destructuring-bind as a
behavior), but it still seems like they cover a lot of the most annoying
boilerplate cases.

It's also somewhat similar to aspect-oriented programming, and to Python
decorators. Seems to be both more and less powerful than these - more
powerful in that you can define multiple get/set/accessors at once and
scope any code required by them, and less powerful because as it currently
stands you can't intercept functions.

   - How much effort did you put into your review? A glance, a quick
   reading, or an in-depth study?

Read through the proposal fully, skimmed some of the responses, wrote up a
lot of examples.

···

On Wed, Feb 10, 2016 at 2:00 PM, Douglas Gregor via swift-evolution < swift-evolution@swift.org> wrote:


(Michel Fortin) #8

What is your evaluation of the proposal?

I think property behaviors are a nice idea. But I feel the current proposal is trying to handle too many disparate use cases using an approach that doesn't work that well for all of them.

I already expressed my view of this in pre-review, and I'm a bit disappointed to see no mention of my suggestions in the "Alternatives considered" section. Basically I think this proposal should be broken in three or four separate smaller features that can each stand on their own:

1. the ability to add `func`, `var`, and `let` inside any property declaration to handle metadata and meta-operations. For instance:

  var count: Int {
    func reset() { count = 0 }
  }

  count::reset() // or some other syntax

  var root: NSObject {
    var lastModified: NSDate? = nil
    didSet { lastModified = NSDate() }
  }

  print(root::lastAccess)

  var lang: String {
    let xmlName = "xml:lang"
  }

  element.addAttribute(name: lang::xmlName, value: lang)

2. the ability to encapsulate those `func` and `var` inside a behaviour for reuse:

  behavior resettable<T>: T {
    func reset() { currentValue = initValue }
  }
  var [resettable] count: Int

  count::reset() // or some other syntax

  behavior changeMonitored<T>: T {
    var lastModified: NSDate? = nil
    didSet { lastModified = NSDate() }
  }
  var [changeMonitored] root: NSObject

  print(root::lastModified)

3. the ability for the behavior (extending point 2) to change the base storage type of the property:

  behavior synchronized<T>: Synchronized<T> {
    get { return currentValue.value }
    set { currentValue.value = newValue }
  }

  var [synchronized] count: Int

  count = 1

4. a way to define property observers such as `willSet` globally, with no need to attach a particular behavior to a variable:

  observer willSet<T>(newValue: T) {
    set {
      willSet(newValue)
      currentValue = newValue
    }
  }

  var count: Int {
    willSet {
      print("\(count) will become \(newValue)")
    }
  }

I don't have a fully formed proposal, but there's a bit more details in a relatively recent discussion here (I changed the syntax a bit since then):

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007194.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007238.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007295.html

Is the problem being addressed significant enough to warrant a change to Swift?

There are many disparate problems this proposal is trying to address.

Some of the problems illustrated in the proposal would benefit from it, but not all. In some cases, such as the `observed` behavior, it makes things worse because your observer functions have to be tied to a behavior attached to the variable.

Does this proposal fit well with the feel and direction of Swift?

Accessing functions inside behaviors such as `resettable` adds two layers of metadata/meta-operations to the property (one is the behavior name, the other is the `reset()` function). I would argue that including `resettable` before calling a `reset()` function is redundant. It is also against the principles of separation between the interface and the implementation since you might want to define `reset()` in your own way for some variables, which would entail the creation of a separate behavior with a different name, which would change the way you make your `reset()` call. To me, the way you can call behavior functions seems rather heavyweight and inflexible.

Swift currently lets you add `willSet` and `didSet` observers without having to opt-in through some special syntax. Requiring that a behavior be added, such as `observed` before being able to use these or other custom kinds of observers seems like a step in the wrong direction to me.

That's the two main points that I think don't work well in the current proposal when compared to the rest of Swift.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I haven't.

Though the syntax `property.[behavior].func()` reminds be a bit of how you select an axis when accessing nodes in XPath.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I followed and participated to the discussions pre-review. I have less time to follow it now, so I might have missed recent developments.

···

--
Michel Fortin
https://michelf.ca


(plx) #9

What is your evaluation of the proposal?

It’s “ok”. It is obviously scaled-back from earlier attempts, enough to be useful but not enough to be exciting.

The main shortcoming here is the complete lack of composability. I understand why behavior composition got cut, but I’m not convinced it was the right decision.

As far as I have followed it, it does seem that it’s only `synchronized`-style behaviors that are fundamentally-problematic under composition; that is, using the terminology in the proposal, linear behavior composition would work fine, and to my eyes most behaviors are “linear”.

If it’s actually the case that almost all behaviors would compose reasonably (being “linear”), what’s the actual harm in going back to the more-composable earlier proposals and simply accepting that although one *can* write `synchronized`-style behaviors, they’re going to be fragile and doing so will thus be ill-advised?

It feels like a lot of useful functionality has been given-up upon merely to avoid *potential* problems with a specific few, IMHO questionable, behaviors (like property-level `synchronized`).

Is the problem being addressed significant enough to warrant a change to Swift?

A good version of a feature like this will lead to huge robustness-of-implementation improvements.

Does this proposal fit well with the feel and direction of Swift?

The general idea very much so. The proposed behavior declaration syntax is odd, and only seems justifiable to me if a specific flavor of behavior composition winds up being the feature's future.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

A lot of thought towards earlier proposals, a skim of this one.


(Ricardo Parada) #10

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md

What is your evaluation of the proposal?
+1

Is the problem being addressed significant enough to warrant a change to Swift?
I think it has enough features to implement the typical patterns as discussed in the proposal and that seems like a good start.

Does this proposal fit well with the feel and direction of Swift?
Yes. It seems a powerful elegant addition that will allow boilerplate regarding properties to be moved out of the compiler and into libraries.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
I don't recall having seen this in other languages.

I think it opens up some interesting possibilities and could help solve some problems more elegantly than what I have seen solved through other means. For example managed properties and object/array faulting in Core Data and Enterprise Objects Frameworks for mapping objects to relational data bases. It would be interesting to see if property behaviors could be used to solve these problems.

I think it would help if property behaviors had the name binding to get a hold of the property name. That was mentioned as a future enhancement though. It will be nice to get that.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
I have been following the discussions in the mailing list and I have read the entire proposal. No in-depth study though.

···

On Feb 10, 2016, at 5:00 PM, Douglas Gregor <dgregor@apple.com> wrote:

Hello Swift community,

The review of SE-0030 "Property Behaviors" begins now and runs through February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
Reply text

Other replies
What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

Doug Gregor

Review Manager

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


(Patrick Gili) #11

Hello Swift community,

The review of SE-0030 "Property Behaviors" begins now and runs through February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-proposal.md>
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
Reply text

Other replies
<https://github.com/apple/swift-evolution#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?

I think this proposal not only has great merit, but it is well thought out. I followed the evolution of this proposal and thought Joe did a great job adapting the original concept to the community's concerns. I'm anxious to start using this feature and future enhancements based on this proposal.

Is the problem being addressed significant enough to warrant a change to Swift?

Yes.

Does this proposal fit well with the feel and direction of Swift?

Yes.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

The only languages I know of that has anything similar to this feature is Python and Drupal.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Given the length of the proposal, I really studied it and went back to review the threads it was based on.

···

On Feb 10, 2016, at 5:00 PM, Douglas Gregor <dgregor@apple.com> wrote:

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

Doug Gregor

Review Manager

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


(Joe Groff) #12

Hi everyone. In response to feedback, I've extended the review period for SE-0030 for another week. I've also decided to subset out member access from the initial proposal, as in accessing `x.[lazy].clear()` or other behavior-provided methods on a property. There's a lot of contention about the syntax, of course, but Michel Fortin and private reviewers have made good points that tying these "out-of-band" non-type members to properties is a feature that may not be best expressed as part of behaviors. Like many of the other topics that were factored out, the design space is deep enough that out-of-band member access deserves a design and review of its own. Thank you all for the feedback so far!

-Joe

···

On Feb 10, 2016, at 2:00 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of SE-0030 "Property Behaviors" begins now and runs through February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-proposal.md>
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
Reply text

Other replies
<https://github.com/apple/swift-evolution#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

Doug Gregor

Review Manager

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


(Drew Crawford) #13

I've been meaning to review this one.

What is your evaluation of the proposal?

This is an excellent proposal.

Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Actually, the "examples" within the proposal itself really only scratches the surface of the places I want to use this feature.

Swift's reflection system is pretty poor, supporting only read-only access. If I was writing a library to parse the options to `swiftc` for example, an application might want to declare a structure like

struct Options: String {
  let applicationExtension : Bool
        let assertConfig: Bool
        let embedBitcodeMarker: Bool
        let emitBitcode: Bool
       //etc
}

...and use this application-provided structure as part of the API itself. With clever use of Mirror, a library can reflect this structure, re-interpret the names under command-line-case-rules, and generate a parser that can read "-application-extension" "-assert-config" "embed-bitcode-marker" and so on.

However, while a library can understand this structure, it cannot set the values back on the structure defined by the application. Thus the application is doomed to work with a parse result object that has poor type information (such as a stringly-typed result). This basically negates the benefit of declaring a structure like this to begin with.

After this proposal, I can define a property behavior that relocates the variable storage to a stringly-typed underlying mechanism. As a result, I can construct a full-duplex bridge between "stringly-typed" access patterns and "statically-typed" access patterns, allowing me to alternate between one and the other as necessary. I can also get "writeable" reflection behavior.

I think the benefits of such a scheme (particularly as an opt-in mechanism, so as not to impact performance in general) is pretty endless. The API that I describe seems "obviously" the optimal API for practically any parse problem that terminates in a strongly typed structure (which is the case for most JSON, YAML, XML, CSV, CLI, and RPC-type application-layer problems), and under this proposal it becomes achievable.

One obvious extension I would like to see is "function behaviors" (a.k.a. decorators), but that is obviously a story for another proposal. Still, I would be really interested in studying in that direction in future proposals.

As others have mentioned, composeability is also interesting, but may not be entirely necessary for an initial pass at the feature. This seems like something that should be evaluated in the context of "so now we have two different libraries that each want their behavior on a property," which is a circumstance far removed from the present.

Does this proposal fit well with the feel and direction of Swift?

As explained above, the proposal can bridge an important problem; namely allowing dynamic behavior in a static type system. I think that this would allow clever library authors to design more Swift-like APIs.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I am familiar with function decorators in Python, which are a generalization of this scheme (they're composeable and they also work for functions). I miss decorators terribly in Swift. These are not quite as good, but they're a step.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I've tried to get to the meat of the proposal.

I'm deliberately avoiding the syntax bikeshed here–I'm much more interested in the behavior this proposal unlocks than the color of the paint. Paint the damn thing any color you like, but the underlying idea here is a really important step towards more dynamic kinds of runtime behaviors.

Drew


(Joe Groff) #14

If anyone wants to start playing with the feature, I now have some of the core functionality working in a branch:

https://github.com/apple/swift/pull/1297

I didn't want to waste time parsing a behavior declaration syntax while we're still painting the bikeshed, so behaviors are currently exposed as protocols with extension methods following a convention:

protocol delayedImmutable {
  // Type of the property.
  associatedtype Value
  // Storage required by the property.
  var storage: Value? { get set }
}
extension delayedImmutable {
  // Implementation of the property.
  var value: Value {
    // The property can only be read after it's been initialized.
    get {
      guard let theValue = storage else {
        fatalError("delayedImmutable property read before initialization")
      }
      return theValue
    }
    
    // The property can only be written once to initialize it.
    set {
      guard storage == nil else {
        fatalError("delayedImmutable property rewritten after initialization")
      }
      storage = newValue
    }
  }

  // Initialization logic for the property storage.
  static func initStorage() -> Value? {
    return nil
  }
}

Custom accessors and initializer expression bindings aren't handled yet, but there's enough there now to implement `delayed` initialization. Here's an example test case:

https://github.com/jckarter/swift/commit/9da36f8e1e45564a61da4cfc9ed5327bf57862df

-Joe


(TJ Usiyan) #15

- What is your evaluation of the proposal?
+1
- Is the problem being addressed significant enough to warrant a change to
Swift?Yes. It is 'only' a starting point but it does move some magic out of
the compiler and into the language and open up possibilities.
- Does this proposal fit well with the feel and direction of Swift?
Yes. Definitely
- If you have used other languages or libraries with a similar feature, how
do you feel that this proposal compares to those?I have not.
- How much effort did you put into your review? A glance, a quick reading,
or an in-depth study?I've been following along since the first proposal. I
lost quite a few details when things became more active but I have kept up
as best as I could.

···

On Wed, Feb 10, 2016 at 5:00 PM, Douglas Gregor via swift-evolution < swift-evolution@swift.org> wrote:

Hello Swift community,

The review of SE-0030 "Property Behaviors" begins now and runs through
February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
<https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-proposal.md>

Reviews are an important part of the Swift evolution process. All reviews
should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager. When replying, please try to keep the proposal link at the
top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md

Reply text

Other replies

<https://github.com/apple/swift-evolution#what-goes-into-a-review-1>What
goes into a review?

The goal of the review process is to improve the proposal under review
through constructive criticism and, eventually, determine the direction of
Swift. When writing your review, here are some questions you might want to
answer in your review:

   - What is your evaluation of the proposal?
   - Is the problem being addressed significant enough to warrant a
   change to Swift?
   - Does this proposal fit well with the feel and direction of Swift?
   - If you have used other languages or libraries with a similar
   feature, how do you feel that this proposal compares to those?
   - How much effort did you put into your review? A glance, a quick
   reading, or an in-depth study?

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

Doug Gregor

Review Manager

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


(Joe Groff) #16

Based on review feedback, I've revised the declaration syntax proposal for property behaviors to be more in line with our other declaration forms, reverting to the earlier pre-review "var behavior" proposal. I've updated the proposal in swift-evolution:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md

In discussion with the core team, we've also strongly come in favor of applying behaviors to properties using attribute syntax, e.g.:

@lazy var x = 111
@delayed var x: Int

They're definitely attribute-like, and we think it makes sense for behaviors to be the first of hopefully many kinds of user-defined behaviors. What do you all think of this direction?

-Joe

···

On Feb 10, 2016, at 2:00 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of SE-0030 "Property Behaviors" begins now and runs through February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-proposal.md>
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
Reply text

Other replies
<https://github.com/apple/swift-evolution#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

Doug Gregor

Review Manager

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


(Joe Groff) #17

I've merged my prototype implementation into the Swift 3 master branch. It's conditionally enabled behind a frontend flag—use `swiftc -Xfrontend -enable-experimental-property-behaviors` to enable the prototype implementation.

-Joe

···

On Feb 10, 2016, at 2:00 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of SE-0030 "Property Behaviors" begins now and runs through February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-proposal.md>
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
Reply text

Other replies
<https://github.com/apple/swift-evolution#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

Doug Gregor

Review Manager

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


(Tino) #18

I'm still very torn on this proposal, and I think a final evaluation should take into account the long-term goal of "hygienic macros":
Right now, I haven't seen anything concrete on this topic, as it is somewhat out of scope now — but there are soaring dreams for meta programming in Swift, and behaviors could be solved that way as well.

It is common practice to ask the question "would we add this feature now if we didn't already have it?" when it is about deprecating elements of the language; I fear that property behaviors might become to important to be removed once they are integrated, so I'm asking myself:
Would I add this feature if I could do something like

#Self.addProperty("age", type: Int, behavior: Lazy { return Date().year - self.birthday.year })

instead?
(this all is highly speculative, and so is the syntax — but I hope the intention is of that line is clear)

As the evolution process favors small steps, it is somewhat unfair to challenge a proposal this way, but imho sometimes it is important to step back and consider the "big picture" — which, btw, may as well lead to the conclusion that macros shouldn't be able to add behaviors, or that the feature deserves a special syntax anyways...

- Tino


#19

I hope you’ll forgive me for a not really constructive comment, but living in the country neighbouring the USA to the north, I’ll have hard time not typing the « u » in this new behaviour keyword. I do not want to start a war on which English is the proper one, after all if one do not like the wording of an API he can always create wrappers, but for main language keyword such thing is impossible in Swift.

At least the behaviour keyword is one that is not used that often in single file, so I’ll survive.
But I thought it was worth mentioning that not everyone use the same English dictionary.

Dany

···

Le 10 févr. 2016 à 17:04, Douglas Gregor via swift-evolution <swift-evolution@swift.org> a écrit :

On Feb 10, 2016, at 2:00 PM, Douglas Gregor <dgregor@apple.com <mailto:dgregor@apple.com>> wrote:

Hello Swift community,

The review of SE-0030 "Property Behaviors" begins now and runs through February, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md

Through February 16, that is.


(Chris Lattner) #20

FWIW, I agree with this. I see this as a step in the right direction, not the full answer. I also expect some iteration and refinement (in future proposals) based on usage experience. This is what we’ve seen for all other “big” features that have gone in in the past.

-Chris

···

On Feb 10, 2016, at 3:53 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md

I do, however, have one caveat: this proposal is a good core for property behaviors, but alone, I don't think it carries its own weight. It will need at least a couple of the items in "Future Directions" section before it's really worth having. If we find we're not able to get those things proposed and accepted, we may want to reconsider whether we should add the feature at all.