[Review] SE-0030 Property Behaviors


(Anton Zhilin) #1

I like the direction in which the proposal is moving, but I still have some
concerns about syntax.

0.
Thinking about it, behaviours don't really need to be full-fledged types.
Brent gave examples, for me the most convincing one was that property `var
x: lazy<Int>` doesn't really seem to be implementing protocol requirement
`var x: Int { get }`.

1.
I love the suggested attribute-like syntax `@lazy var x: Int = 42`.
Brackets `var [lazy] x: Int` is a precedent syntax, and we want to avoid
that if possible.
The position of @lazy also feels right, as well as motivation behind that.

2.
What's the point of `: Value {` part in behaviour declaration?
One of the purposes was disambiguating, which of the generic parameter we
are".
If we don't want generic notation, then I see no reason for that.
So we have `public var behaviour lazy<T> { ... }`

3.
Just `initialValue` in the body seems odd. I suggest `attribute
initialValue() -> Value`, alternatives are welcome.

4.
How will the `var` part be used?
Are we going to allow `let` behaviours? We can always create a `let`
behaviour by duplicating our initial behaviour and modifying as needed.
For example, `@lazy let x: Int` can be emulated with `@immutableLazy var x:
Int`. In this case, we can replace the name by something better.
So, isn't it duplicating functionality? If we decide not to have `let`
behaviours then we will just have to remove that `var` in declaration.
So we have `public behaviour lazy<T> { ... }` which is completely in line
with structs and whatsnot.

Suggestions for "future directions":

5.
We should be able to auto-derive types for variables with behaviours.
First of all, I don't see any reason why we can't: `@lazy var x = 42` is,
obviously, the same as `@lazy var x: Int = 42`
Then, all existing variables can have their types deduced. If we can write
`var x = 42` then why can't we write `@lazy var x = 42`?

6.
Member functions.
The ground for them is already prepared, actually.
I suggest the (obvious) syntax `x.@lazy.clear()` for calling functions of
behaviour and `x.@lazy.storage` for accessing variables of behaviour.

7.
Access control of member functions.
Why not define access control modifiers on members of behaviour to mean the
same as if they were applied to members of the enclosing type?
For example, `private var storage: Value?` would be accessible in the same
file as enclosing type as `x.@lazy.storage`.

Regarding time issues, are we going to get another week for review? I
support the proposal as a whole, but details are changing "on the fly".