Support for pure setters

Currently Swift has computed properties that support get or get and set, but not set only. There are use cases where we would want set only.

For example, toggling a boolean which changes another stored property where it would be overkill to make a method for that. It's more intuitive to just assign a boolean. e.g. myObject.myBoolean = true

Another example, setting an object that is introspected in order to create a new object which is then stored on a different property. The property that is stored could be readonly/get, for example. A method for the setter (e.g. setSomething) would not be as intuitive as just a plain assignment (e.g. myObject.something = ..).

Another consideration is that a pure setter would support better information hiding. You may not want the parent object to expose the property. Example scenario: set a property on an object (via assignment), which creates/modifies a stored property based on the passed (set) value, and then pass the parent object to another part of the system which can than read the stored property but not the original set property — i.e. you may not want to expose the original set property to another part of the system.

Example:

var myProperty:MyClass {
    set {
        …
    }
}

One concern is that without ‘get’ there really is no property at all, and perhaps this is the reason that pure setter was never included. However, this does not invalidate the above.

As an alternative (to make it more semantically sensible) we could introduce a new keyword ‘set’, so:

set myProperty:MyClass {
    ...
}

Which would support simple assignment:

myObject.myProperty = myOtherObject

Finally, it’s important to know that this is still “computed", but only computed on the input, not on the output side.

David James

1 Like

.NET has them and I never felt that I needed them. For me, a property implies something that can be looked up.

What's the downside of using a method?

Félix

···

Le 7 janv. 2016 à 10:47:20, David James via swift-evolution <swift-evolution@swift.org> a écrit :

Currently Swift has computed properties that support get or get and set, but not set only. There are use cases where we would want set only.

For example, toggling a boolean which changes another stored property where it would be overkill to make a method for that. It's more intuitive to just assign a boolean. e.g. myObject.myBoolean = true

Another example, setting an object that is introspected in order to create a new object which is then stored on a different property. The property that is stored could be readonly/get, for example. A method for the setter (e.g. setSomething) would not be as intuitive as just a plain assignment (e.g. myObject.something = ..).

Another consideration is that a pure setter would support better information hiding. You may not want the parent object to expose the property. Example scenario: set a property on an object (via assignment), which creates/modifies a stored property based on the passed (set) value, and then pass the parent object to another part of the system which can than read the stored property but not the original set property — i.e. you may not want to expose the original set property to another part of the system.

Example:

var myProperty:MyClass {
    set {
        …
    }
}

One concern is that without ‘get’ there really is no property at all, and perhaps this is the reason that pure setter was never included. However, this does not invalidate the above.

As an alternative (to make it more semantically sensible) we could introduce a new keyword ‘set’, so:

set myProperty:MyClass {
    ...
}

Which would support simple assignment:

myObject.myProperty = myOtherObject

Finally, it’s important to know that this is still “computed", but only computed on the input, not on the output side.

David James

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

Perhaps “pure setters” is a misnomer. Probably more accurate would be to call it a “computed setter”?

To your point about properties being for lookup, understandable. That’s why I suggested introducing the “set” keyword instead of using var .. set.

The downside of using a method is it’s just not as convenient/elegant to use than simple assignment.

David

···

On Jan 7, 2016, at 6:16 PM, Félix Cloutier <felixcca@yahoo.ca> wrote:

.NET has them and I never felt that I needed them. For me, a property implies something that can be looked up.

What's the downside of using a method?

Félix

Le 7 janv. 2016 à 10:47:20, David James via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

Currently Swift has computed properties that support get or get and set, but not set only. There are use cases where we would want set only.

For example, toggling a boolean which changes another stored property where it would be overkill to make a method for that. It's more intuitive to just assign a boolean. e.g. myObject.myBoolean = true

Another example, setting an object that is introspected in order to create a new object which is then stored on a different property. The property that is stored could be readonly/get, for example. A method for the setter (e.g. setSomething) would not be as intuitive as just a plain assignment (e.g. myObject.something = ..).

Another consideration is that a pure setter would support better information hiding. You may not want the parent object to expose the property. Example scenario: set a property on an object (via assignment), which creates/modifies a stored property based on the passed (set) value, and then pass the parent object to another part of the system which can than read the stored property but not the original set property — i.e. you may not want to expose the original set property to another part of the system.

Example:

var myProperty:MyClass {
    set {
        …
    }
}

One concern is that without ‘get’ there really is no property at all, and perhaps this is the reason that pure setter was never included. However, this does not invalidate the above.

As an alternative (to make it more semantically sensible) we could introduce a new keyword ‘set’, so:

set myProperty:MyClass {
    ...
}

Which would support simple assignment:

myObject.myProperty = myOtherObject

Finally, it’s important to know that this is still “computed", but only computed on the input, not on the output side.

David James

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

David James

Set-only properties are problematic for Swift, because it relies on being able to do writeback in many more cases than Objective-C. A set-only property will be constrained in several surprising ways. For instance, it would be impossible to drill down to a component of a set-only value type property, because this:

var foo: Struct { get { ... } set { ... } }
foo.x = value

is really performing this behind the scenes:

var tmp = foo // invoke getter
tmp.x = value
foo = tmp // invoke setter

but we would have no getter in this case to initialize the temporary with. You also wouldn't be able to use the property as an 'inout' parameter or do many of the other things you expect to be able to do with a mutable property. A set-only property is so limited I don't think it really feels like a property at all anymore. These restrictions are far more obvious if you express the interface as a function rather than a property.

-Joe

···

On Jan 7, 2016, at 7:47 AM, David James via swift-evolution <swift-evolution@swift.org> wrote:

Currently Swift has computed properties that support get or get and set, but not set only. There are use cases where we would want set only.

For example, toggling a boolean which changes another stored property where it would be overkill to make a method for that. It's more intuitive to just assign a boolean. e.g. myObject.myBoolean = true

Another example, setting an object that is introspected in order to create a new object which is then stored on a different property. The property that is stored could be readonly/get, for example. A method for the setter (e.g. setSomething) would not be as intuitive as just a plain assignment (e.g. myObject.something = ..).

Another consideration is that a pure setter would support better information hiding. You may not want the parent object to expose the property. Example scenario: set a property on an object (via assignment), which creates/modifies a stored property based on the passed (set) value, and then pass the parent object to another part of the system which can than read the stored property but not the original set property — i.e. you may not want to expose the original set property to another part of the system.

Example:

var myProperty:MyClass {
    set {
        …
    }
}

One concern is that without ‘get’ there really is no property at all, and perhaps this is the reason that pure setter was never included. However, this does not invalidate the above.

As an alternative (to make it more semantically sensible) we could introduce a new keyword ‘set’, so:

set myProperty:MyClass {
    ...
}

Which would support simple assignment:

myObject.myProperty = myOtherObject

Finally, it’s important to know that this is still “computed", but only computed on the input, not on the output side.

David James

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

4 Likes

Sorry, there already is “set” keyword, but allow it to be used in place of “var”.

···

On Jan 7, 2016, at 6:31 PM, David James <davidbjames1@gmail.com> wrote:

Perhaps “pure setters” is a misnomer. Probably more accurate would be to call it a “computed setter”?

To your point about properties being for lookup, understandable. That’s why I suggested introducing the “set” keyword instead of using var .. set.

The downside of using a method is it’s just not as convenient/elegant to use than simple assignment.

David

On Jan 7, 2016, at 6:16 PM, Félix Cloutier <felixcca@yahoo.ca <mailto:felixcca@yahoo.ca>> wrote:

.NET has them and I never felt that I needed them. For me, a property implies something that can be looked up.

What's the downside of using a method?

Félix

Le 7 janv. 2016 à 10:47:20, David James via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

Currently Swift has computed properties that support get or get and set, but not set only. There are use cases where we would want set only.

For example, toggling a boolean which changes another stored property where it would be overkill to make a method for that. It's more intuitive to just assign a boolean. e.g. myObject.myBoolean = true

Another example, setting an object that is introspected in order to create a new object which is then stored on a different property. The property that is stored could be readonly/get, for example. A method for the setter (e.g. setSomething) would not be as intuitive as just a plain assignment (e.g. myObject.something = ..).

Another consideration is that a pure setter would support better information hiding. You may not want the parent object to expose the property. Example scenario: set a property on an object (via assignment), which creates/modifies a stored property based on the passed (set) value, and then pass the parent object to another part of the system which can than read the stored property but not the original set property — i.e. you may not want to expose the original set property to another part of the system.

Example:

var myProperty:MyClass {
    set {
        …
    }
}

One concern is that without ‘get’ there really is no property at all, and perhaps this is the reason that pure setter was never included. However, this does not invalidate the above.

As an alternative (to make it more semantically sensible) we could introduce a new keyword ‘set’, so:

set myProperty:MyClass {
    ...
}

Which would support simple assignment:

myObject.myProperty = myOtherObject

Finally, it’s important to know that this is still “computed", but only computed on the input, not on the output side.

David James

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

David James

David James

After considering this further, I think the answer is simpler and more in line with design goals.

Proposal:
• Support set-only real or computed properties limited by access level.
• To achieve this, add private(get) / internal(get) since we already support private/internal(set)
• Make get computed property optional (with set)

This would support patterns where client code can set data on file/module based structures, allowing that data to be read within the file/module structure. This supports information hiding where the client should only push data and allow modules to respond to that. Other parts of the code should not be reading this data and making assumptions. It should be hidden.

One example design pattern is the Builder pattern. The client could set various properties, and the builder would aggregate these and return a configured object.

This also provides a cleaner style of setting and more consistent style of setting, foo.prop = bar, rather than using function syntax, foo.setProp(bar), for this use case (where we want set-only), while using dot syntax for other use cases (where we want get and set).

Examples:

private(get) var foo:Foo

With computed setter,

private(get) var foo:Foo {
    get {
        return self.foo
    }
    set {
        self.foo = newValue
        self.bar = Bar(foo: self.foo) // e.g. Builder pattern
    }
}

or just make the computed getter optional,

private(get) var foo:Foo {
    set {
        self.foo = newValue
        self.bar = Bar(foo: self.foo)
    }
}

Is there a compelling argument not to support this? (aside from, "why bother, you can use a function setter")

David

···

On Jan 7, 2016, at 8:50 PM, Wallacy <wallacyf@gmail.com> wrote:

"The downside of using a method is it’s just not as convenient/elegant to use than simple assignment."

"pure setter" is also pretty confusing. I can set but not read the value again?

If you want a "simpler" setter, you can define a closure or unlabeled func.

  class iClass{
    let myProperty:(String)->() = { value in
        print("1: \(value)");
    }
    func myProperty(value: String)->() {
        print("2: \(value)");
    }
    func otherProperty(value: String)->() {
        print("3: \(value)");
    }
}

iClass().myProperty("a");
//iClass().myProperty(value: "b"); // How to call the function in this case?
iClass().otherProperty("c");

It's more clear than:

iClass().myProperty == "a";
iClass().otherProperty == "c";

FWIW:

func "myProperty(value: String)->()" seems to be hidden by closure "myProperty:(String)->()".

Em qui, 7 de jan de 2016 às 15:32, David James via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> escreveu:
Perhaps “pure setters” is a misnomer. Probably more accurate would be to call it a “computed setter”?

To your point about properties being for lookup, understandable. That’s why I suggested introducing the “set” keyword instead of using var .. set.

The downside of using a method is it’s just not as convenient/elegant to use than simple assignment.

David

On Jan 7, 2016, at 6:16 PM, Félix Cloutier <felixcca@yahoo.ca <mailto:felixcca@yahoo.ca>> wrote:

.NET has them and I never felt that I needed them. For me, a property implies something that can be looked up.

What's the downside of using a method?

Félix

Le 7 janv. 2016 à 10:47:20, David James via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

Currently Swift has computed properties that support get or get and set, but not set only. There are use cases where we would want set only.

For example, toggling a boolean which changes another stored property where it would be overkill to make a method for that. It's more intuitive to just assign a boolean. e.g. myObject.myBoolean = true

Another example, setting an object that is introspected in order to create a new object which is then stored on a different property. The property that is stored could be readonly/get, for example. A method for the setter (e.g. setSomething) would not be as intuitive as just a plain assignment (e.g. myObject.something = ..).

Another consideration is that a pure setter would support better information hiding. You may not want the parent object to expose the property. Example scenario: set a property on an object (via assignment), which creates/modifies a stored property based on the passed (set) value, and then pass the parent object to another part of the system which can than read the stored property but not the original set property — i.e. you may not want to expose the original set property to another part of the system.

Example:

var myProperty:MyClass {
    set {
        …
    }
}

One concern is that without ‘get’ there really is no property at all, and perhaps this is the reason that pure setter was never included. However, this does not invalidate the above.

As an alternative (to make it more semantically sensible) we could introduce a new keyword ‘set’, so:

set myProperty:MyClass {
    ...
}

Which would support simple assignment:

myObject.myProperty = myOtherObject

Finally, it’s important to know that this is still “computed", but only computed on the input, not on the output side.

David James

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

David James

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

David James

Is this true even if there is a getter that is private? e.g. private(get) (see my latest reply before this one)

···

On Jan 8, 2016, at 5:51 PM, Joe Groff <jgroff@apple.com> wrote:

Set-only properties are problematic for Swift, because it relies on being able to do writeback in many more cases than Objective-C. A set-only property will be constrained in several surprising ways. For instance, it would be impossible to drill down to a component of a set-only value type property, because this:

var foo: Struct { get { ... } set { ... } }
foo.x = value

is really performing this behind the scenes:

var tmp = foo // invoke getter
tmp.x = value
foo = tmp // invoke setter

but we would have no getter in this case to initialize the temporary with. You also wouldn't be able to use the property as an 'inout' parameter or do many of the other things you expect to be able to do with a mutable property. A set-only property is so limited I don't think it really feels like a property at all anymore. These restrictions are far more obvious if you express the interface as a function rather than a property.

-Joe

On Jan 7, 2016, at 7:47 AM, David James via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Currently Swift has computed properties that support get or get and set, but not set only. There are use cases where we would want set only.

For example, toggling a boolean which changes another stored property where it would be overkill to make a method for that. It's more intuitive to just assign a boolean. e.g. myObject.myBoolean = true

Another example, setting an object that is introspected in order to create a new object which is then stored on a different property. The property that is stored could be readonly/get, for example. A method for the setter (e.g. setSomething) would not be as intuitive as just a plain assignment (e.g. myObject.something = ..).

Another consideration is that a pure setter would support better information hiding. You may not want the parent object to expose the property. Example scenario: set a property on an object (via assignment), which creates/modifies a stored property based on the passed (set) value, and then pass the parent object to another part of the system which can than read the stored property but not the original set property — i.e. you may not want to expose the original set property to another part of the system.

Example:

var myProperty:MyClass {
    set {
        …
    }
}

One concern is that without ‘get’ there really is no property at all, and perhaps this is the reason that pure setter was never included. However, this does not invalidate the above.

As an alternative (to make it more semantically sensible) we could introduce a new keyword ‘set’, so:

set myProperty:MyClass {
    ...
}

Which would support simple assignment:

myObject.myProperty = myOtherObject

Finally, it’s important to know that this is still “computed", but only computed on the input, not on the output side.

David James

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

David James

Joe, to attempt to set foo.x doesn’t make sense. If foo cannot be gotten, a property of it will be inaccessible for getting or setting.

Set-only properties are always computed, and only used via assignment.

e.g. foo = value

···

Set-only properties are problematic for Swift, because it relies on being able to do writeback in many more cases than Objective-C. A set-only property will be constrained in several surprising ways. For instance, it would be impossible to drill down to a component of a set-only value type property, because this:

var foo: Struct { get { ... } set { ... } }
foo.x = value

is really performing this behind the scenes:

var tmp = foo // invoke getter
tmp.x = value
foo = tmp // invoke setter

but we would have no getter in this case to initialize the temporary with. You also wouldn't be able to use the property as an 'inout' parameter or do many of the other things you expect to be able to do with a mutable property. A set-only property is so limited I don't think it really feels like a property at all anymore. These restrictions are far more obvious if you express the interface as a function rather than a property.

-Joe

> On Jan 7, 2016, at 7:47 AM, David James via swift-evolution<swift-evolution at swift.org>wrote:
>
> Currently Swift has computed properties that support get or get and set, but not set only. There are use cases where we would want set only.
>
> For example, toggling a boolean which changes another stored property where it would be overkill to make a method for that. It's more intuitive to just assign a boolean. e.g. myObject.myBoolean = true
>
> Another example, setting an object that is introspected in order to create a new object which is then stored on a different property. The property that is stored could be readonly/get, for example. A method for the setter (e.g. setSomething) would not be as intuitive as just a plain assignment (e.g. myObject.something = ..).
>
> Another consideration is that a pure setter would support better information hiding. You may not want the parent object to expose the property. Example scenario: set a property on an object (via assignment), which creates/modifies a stored property based on the passed (set) value, and then pass the parent object to another part of the system which can than read the stored property but not the original set property — i.e. you may not want to expose the original set property to another part of the system.
>
> Example:
>
> var myProperty:MyClass {
> set {
> …
> }
> }
>
> One concern is that without ‘get’ there really is no property at all, and perhaps this is the reason that pure setter was never included. However, this does not invalidate the above.
>
> As an alternative (to make it more semantically sensible) we could introduce a new keyword ‘set’, so:
>
> set myProperty:MyClass {
> ...
> }
>
> Which would support simple assignment:
>
> myObject.myProperty = myOtherObject
>
> Finally, it’s important to know that this is still “computed", but only computed on the input, not on the output side.
>
> David James
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

Is this true even if there is a getter that is private? e.g. private(get) (see my latest reply before this one)

Yeah. If you can't see the getter, then the property is effectively set-only to you and has all the same problems.

-Joe

···

On Jan 8, 2016, at 9:23 AM, David James <davidbjames1@gmail.com> wrote:

On Jan 8, 2016, at 5:51 PM, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:

Set-only properties are problematic for Swift, because it relies on being able to do writeback in many more cases than Objective-C. A set-only property will be constrained in several surprising ways. For instance, it would be impossible to drill down to a component of a set-only value type property, because this:

var foo: Struct { get { ... } set { ... } }
foo.x = value

is really performing this behind the scenes:

var tmp = foo // invoke getter
tmp.x = value
foo = tmp // invoke setter

but we would have no getter in this case to initialize the temporary with. You also wouldn't be able to use the property as an 'inout' parameter or do many of the other things you expect to be able to do with a mutable property. A set-only property is so limited I don't think it really feels like a property at all anymore. These restrictions are far more obvious if you express the interface as a function rather than a property.

-Joe

On Jan 7, 2016, at 7:47 AM, David James via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Currently Swift has computed properties that support get or get and set, but not set only. There are use cases where we would want set only.

For example, toggling a boolean which changes another stored property where it would be overkill to make a method for that. It's more intuitive to just assign a boolean. e.g. myObject.myBoolean = true

Another example, setting an object that is introspected in order to create a new object which is then stored on a different property. The property that is stored could be readonly/get, for example. A method for the setter (e.g. setSomething) would not be as intuitive as just a plain assignment (e.g. myObject.something = ..).

Another consideration is that a pure setter would support better information hiding. You may not want the parent object to expose the property. Example scenario: set a property on an object (via assignment), which creates/modifies a stored property based on the passed (set) value, and then pass the parent object to another part of the system which can than read the stored property but not the original set property — i.e. you may not want to expose the original set property to another part of the system.

Example:

var myProperty:MyClass {
    set {
        …
    }
}

One concern is that without ‘get’ there really is no property at all, and perhaps this is the reason that pure setter was never included. However, this does not invalidate the above.

As an alternative (to make it more semantically sensible) we could introduce a new keyword ‘set’, so:

set myProperty:MyClass {
    ...
}

Which would support simple assignment:

myObject.myProperty = myOtherObject

Finally, it’s important to know that this is still “computed", but only computed on the input, not on the output side.

David James

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

David James

Let me ask you this. If the drawbacks in implementation did not exist, would this be an improvement worth adding?

My sense is yes, since it fills out functionality already half-way there (via private(set)).

···

On Jan 8, 2016, at 7:00 PM, Joe Groff <jgroff@apple.com> wrote:

On Jan 8, 2016, at 9:23 AM, David James <davidbjames1@gmail.com <mailto:davidbjames1@gmail.com>> wrote:

Is this true even if there is a getter that is private? e.g. private(get) (see my latest reply before this one)

Yeah. If you can't see the getter, then the property is effectively set-only to you and has all the same problems.

-Joe

On Jan 8, 2016, at 5:51 PM, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:

Set-only properties are problematic for Swift, because it relies on being able to do writeback in many more cases than Objective-C. A set-only property will be constrained in several surprising ways. For instance, it would be impossible to drill down to a component of a set-only value type property, because this:

var foo: Struct { get { ... } set { ... } }
foo.x = value

is really performing this behind the scenes:

var tmp = foo // invoke getter
tmp.x = value
foo = tmp // invoke setter

but we would have no getter in this case to initialize the temporary with. You also wouldn't be able to use the property as an 'inout' parameter or do many of the other things you expect to be able to do with a mutable property. A set-only property is so limited I don't think it really feels like a property at all anymore. These restrictions are far more obvious if you express the interface as a function rather than a property.

-Joe

On Jan 7, 2016, at 7:47 AM, David James via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Currently Swift has computed properties that support get or get and set, but not set only. There are use cases where we would want set only.

For example, toggling a boolean which changes another stored property where it would be overkill to make a method for that. It's more intuitive to just assign a boolean. e.g. myObject.myBoolean = true

Another example, setting an object that is introspected in order to create a new object which is then stored on a different property. The property that is stored could be readonly/get, for example. A method for the setter (e.g. setSomething) would not be as intuitive as just a plain assignment (e.g. myObject.something = ..).

Another consideration is that a pure setter would support better information hiding. You may not want the parent object to expose the property. Example scenario: set a property on an object (via assignment), which creates/modifies a stored property based on the passed (set) value, and then pass the parent object to another part of the system which can than read the stored property but not the original set property — i.e. you may not want to expose the original set property to another part of the system.

Example:

var myProperty:MyClass {
    set {
        …
    }
}

One concern is that without ‘get’ there really is no property at all, and perhaps this is the reason that pure setter was never included. However, this does not invalidate the above.

As an alternative (to make it more semantically sensible) we could introduce a new keyword ‘set’, so:

set myProperty:MyClass {
    ...
}

Which would support simple assignment:

myObject.myProperty = myOtherObject

Finally, it’s important to know that this is still “computed", but only computed on the input, not on the output side.

David James

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

David James

David James

I understand that. If that's all you're allowed to do with a set-only property, then this is just sugar over 'setFoo(value)', and I think the sugar implies you could do more with 'foo' than you really can. I don't think it's worth the complexity.

-Joe

···

On Feb 3, 2016, at 12:21 PM, Jessy Catterwaul <mr.jessy@gmail.com> wrote:

Joe, to attempt to set foo.x doesn’t make sense. If foo cannot be gotten, a property of it will be inaccessible for getting or setting.

Set-only properties are always computed, and only used via assignment.

e.g. foo = value

1 Like

Let me ask you this. If the drawbacks in implementation did not exist, would this be an improvement worth adding?

These are drawbacks in design, not implementation. Swift fundamentally assumes that something mutable can also be read. Making the model more complex to serve a very narrow use case is not worth it.

My sense is yes, since it fills out functionality already half-way there (via private(set)).

I see it the opposite way: private(set) gets you so close that there is even less reason to do something here.

-Chris

···

On Jan 8, 2016, at 10:45 AM, David James via swift-evolution <swift-evolution@swift.org> wrote:

I do not agree about the implication. A property can be gotten, set, or both, in at least C#, where I used a ton of set-only properties.

Here is a large list of properties that are set-only:

Some of them require more than a single value, for setting. Tuple assignment or named subscripts are the best way I currently know to handle that. Having them be functions that begin with “set” and take arguments feels archaic and not specific enough, to me.

func setStencilFrontReferenceValue(frontReferenceValue: UInt32,
   backReferenceValue: UInt32
)
setStencilFrontReferenceValue(0, backReferenceValue: 1)

versus

var stencilReferenceValues: (front: UInt32, back: UInt32) {set}
stencilReferenceValues = (front: 0, back: 1)

func setVertexSamplerState(sampler: MTLSamplerState?, atIndex index: Int)
setVertexSamplerState(someState, atIndex 0)

versus

subscript vertexSamplerState(index: Int): MTLSamplerState? {set}
vertexSamplerState[0] = someState

The former options, I feel are not Swift, but C masquerading as Swift.

···

Cc:swift-evolution@swift.org
Subject:[swift-evolution] Support for pure setters
Date:February 3, 2016 at 3:31:16 PM EST

> On Feb 3, 2016, at 12:21 PM, Jessy Catterwaul<mr.jessy@gmail.com>wrote:
>
> Joe, to attempt to set foo.x doesn’t make sense. If foo cannot be gotten, a property of it will be inaccessible for getting or setting.
>
> Set-only properties are always computed, and only used via assignment.
>
> e.g. foo = value
I understand that. If that's all you're allowed to do with a set-only property, then this is just sugar over 'setFoo(value)', and I think the sugar implies you could do more with 'foo' than you really can. I don't think it's worth the complexity.

-Joe

I would find a list of actual C# set-only properties more relevant. It wouldn't make sense for a lot of these "set-only properties" in there to offer only a setter if they were made into properties.

In general, I consider properties to be the observable state of an object. When I write something to a property, I expect to be able to get it back. When I pass something as a method parameter, I don't expect that I'll be able to get it back later.

Félix

···

Le 3 févr. 2016 à 16:02:41, Jessy Catterwaul via swift-evolution <swift-evolution@swift.org> a écrit :

I do not agree about the implication. A property can be gotten, set, or both, in at least C#, where I used a ton of set-only properties.

Here is a large list of properties that are set-only:
MTLRenderCommandEncoder | Apple Developer Documentation <MTLRenderCommandEncoder | Apple Developer Documentation;

Some of them require more than a single value, for setting. Tuple assignment or named subscripts are the best way I currently know to handle that. Having them be functions that begin with “set” and take arguments feels archaic and not specific enough, to me.

func setStencilFrontReferenceValue(frontReferenceValue: UInt32,
   backReferenceValue: UInt32
)
setStencilFrontReferenceValue(0, backReferenceValue: 1)

versus

var stencilReferenceValues: (front: UInt32, back: UInt32) {set}
stencilReferenceValues = (front: 0, back: 1)

func setVertexSamplerState(sampler: MTLSamplerState?, atIndex index: Int)
setVertexSamplerState(someState, atIndex 0)

versus

subscript vertexSamplerState(index: Int): MTLSamplerState? {set}
vertexSamplerState[0] = someState

The former options, I feel are not Swift, but C masquerading as Swift.

> Cc:swift-evolution@swift.org <mailto:evolution@swift.org>
> Subject:[swift-evolution] Support for pure setters
> Date:February 3, 2016 at 3:31:16 PM EST
>
>
>
> > On Feb 3, 2016, at 12:21 PM, Jessy Catterwaul<mr.jessy@gmail.com <mailto:mr.jessy@gmail.com>>wrote:
> >
> > Joe, to attempt to set foo.x doesn’t make sense. If foo cannot be gotten, a property of it will be inaccessible for getting or setting.
> >
> > Set-only properties are always computed, and only used via assignment.
> >
> > e.g. foo = value
> I understand that. If that's all you're allowed to do with a set-only property, then this is just sugar over 'setFoo(value)', and I think the sugar implies you could do more with 'foo' than you really can. I don't think it's worth the complexity.
>
> -Joe
>
>
>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Well, in C# it’s possible, sure, but it’s considered bad practice (see for example https://msdn.microsoft.com/en-us/library/ms182165.aspx\), and I wouldn’t want it for Swift. Being a property implies it’s “variable-like” at least to some extent.

~Sune

···

On 03 Feb 2016, at 22:02, Jessy Catterwaul via swift-evolution <swift-evolution@swift.org> wrote:

I do not agree about the implication. A property can be gotten, set, or both, in at least C#, where I used a ton of set-only properties.

C# still hasn’t gotten named subscripts or tuples. It is not the place to go to look for what Swift should be. It’s just the only place I’ve had access to set-only properties, and because much of what I was doing was feeding data to GPUs, set-only properties made a lot of sense, frequently.

The most important thing is to not consider setting “writing”, or getting “reading”. Properties and subscripts are specifically “get” and “set”, and don’t enforce reading or writing any state. The book even gets the terminology wrong, as “read-only” instead of “get-only": The Swift Programming Language: Redirect

I understand that there is a lot of history in thinking about getters and setters as having something to do with storage, but that we have the keywords “get” and “set”, and not “read” and “write”, is guidance for cleaner APIs.

···

On Feb 3, 2016, at 4:34 PM, Félix Cloutier <felixcca@yahoo.ca> wrote:

I would find a list of actual C# set-only properties more relevant. It wouldn't make sense for a lot of these "set-only properties" in there to offer only a setter if they were made into properties.

In general, I consider properties to be the observable state of an object. When I write something to a property, I expect to be able to get it back. When I pass something as a method parameter, I don't expect that I'll be able to get it back later.

Félix

Le 3 févr. 2016 à 16:02:41, Jessy Catterwaul via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

I do not agree about the implication. A property can be gotten, set, or both, in at least C#, where I used a ton of set-only properties.

Here is a large list of properties that are set-only:
MTLRenderCommandEncoder | Apple Developer Documentation <MTLRenderCommandEncoder | Apple Developer Documentation;

Some of them require more than a single value, for setting. Tuple assignment or named subscripts are the best way I currently know to handle that. Having them be functions that begin with “set” and take arguments feels archaic and not specific enough, to me.

func setStencilFrontReferenceValue(frontReferenceValue: UInt32,
   backReferenceValue: UInt32
)
setStencilFrontReferenceValue(0, backReferenceValue: 1)

versus

var stencilReferenceValues: (front: UInt32, back: UInt32) {set}
stencilReferenceValues = (front: 0, back: 1)

func setVertexSamplerState(sampler: MTLSamplerState?, atIndex index: Int)
setVertexSamplerState(someState, atIndex 0)

versus

subscript vertexSamplerState(index: Int): MTLSamplerState? {set}
vertexSamplerState[0] = someState

The former options, I feel are not Swift, but C masquerading as Swift.

> Cc:swift-evolution@swift.org <mailto:evolution@swift.org>
> Subject:[swift-evolution] Support for pure setters
> Date:February 3, 2016 at 3:31:16 PM EST
>
>
>
> > On Feb 3, 2016, at 12:21 PM, Jessy Catterwaul<mr.jessy@gmail.com <mailto:mr.jessy@gmail.com>>wrote:
> >
> > Joe, to attempt to set foo.x doesn’t make sense. If foo cannot be gotten, a property of it will be inaccessible for getting or setting.
> >
> > Set-only properties are always computed, and only used via assignment.
> >
> > e.g. foo = value
> I understand that. If that's all you're allowed to do with a set-only property, then this is just sugar over 'setFoo(value)', and I think the sugar implies you could do more with 'foo' than you really can. I don't think it's worth the complexity.
>
> -Joe
>
>
>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

The argument could go in either direction. Perhaps the right thing to do would be to change get and set to read and write. The guidance you're talking about was provided by the same people who disallowed set-only properties in the first place.

I don't know a lot about Metal specifically, but it seems that the class you pointed to encodes commands into a command buffer. I would think that it's a pretty good example of a place where methods need to stay methods. It's generally a violation of the principle of least surprise when something like:

foo.a = 4
foo.a = 5

isn't the same as just `foo.a = 5`.

Félix

···

Le 3 févr. 2016 à 16:49:02, Jessy Catterwaul <mr.jessy@gmail.com> a écrit :

C# still hasn’t gotten named subscripts or tuples. It is not the place to go to look for what Swift should be. It’s just the only place I’ve had access to set-only properties, and because much of what I was doing was feeding data to GPUs, set-only properties made a lot of sense, frequently.

The most important thing is to not consider setting “writing”, or getting “reading”. Properties and subscripts are specifically “get” and “set”, and don’t enforce reading or writing any state. The book even gets the terminology wrong, as “read-only” instead of “get-only": The Swift Programming Language: Redirect

I understand that there is a lot of history in thinking about getters and setters as having something to do with storage, but that we have the keywords “get” and “set”, and not “read” and “write”, is guidance for cleaner APIs.

On Feb 3, 2016, at 4:34 PM, Félix Cloutier <felixcca@yahoo.ca <mailto:felixcca@yahoo.ca>> wrote:

I would find a list of actual C# set-only properties more relevant. It wouldn't make sense for a lot of these "set-only properties" in there to offer only a setter if they were made into properties.

In general, I consider properties to be the observable state of an object. When I write something to a property, I expect to be able to get it back. When I pass something as a method parameter, I don't expect that I'll be able to get it back later.

Félix

Le 3 févr. 2016 à 16:02:41, Jessy Catterwaul via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

I do not agree about the implication. A property can be gotten, set, or both, in at least C#, where I used a ton of set-only properties.

Here is a large list of properties that are set-only:
MTLRenderCommandEncoder | Apple Developer Documentation <MTLRenderCommandEncoder | Apple Developer Documentation;

Some of them require more than a single value, for setting. Tuple assignment or named subscripts are the best way I currently know to handle that. Having them be functions that begin with “set” and take arguments feels archaic and not specific enough, to me.

func setStencilFrontReferenceValue(frontReferenceValue: UInt32,
   backReferenceValue: UInt32
)
setStencilFrontReferenceValue(0, backReferenceValue: 1)

versus

var stencilReferenceValues: (front: UInt32, back: UInt32) {set}
stencilReferenceValues = (front: 0, back: 1)

func setVertexSamplerState(sampler: MTLSamplerState?, atIndex index: Int)
setVertexSamplerState(someState, atIndex 0)

versus

subscript vertexSamplerState(index: Int): MTLSamplerState? {set}
vertexSamplerState[0] = someState

The former options, I feel are not Swift, but C masquerading as Swift.

> Cc:swift-evolution@swift.org <mailto:evolution@swift.org>
> Subject:[swift-evolution] Support for pure setters
> Date:February 3, 2016 at 3:31:16 PM EST
>
>
>
> > On Feb 3, 2016, at 12:21 PM, Jessy Catterwaul<mr.jessy@gmail.com <mailto:mr.jessy@gmail.com>>wrote:
> >
> > Joe, to attempt to set foo.x doesn’t make sense. If foo cannot be gotten, a property of it will be inaccessible for getting or setting.
> >
> > Set-only properties are always computed, and only used via assignment.
> >
> > e.g. foo = value
> I understand that. If that's all you're allowed to do with a set-only property, then this is just sugar over 'setFoo(value)', and I think the sugar implies you could do more with 'foo' than you really can. I don't think it's worth the complexity.
>
> -Joe
>
>
>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

My original post from yesterday, which describes the way that I am using set-only properties in Swift, still has not gotten through; attempting again:

I use set-only properties very, very often. I am interested to know how ubiquitous functions that begin with “set” are, in  frameworks. I’m currently under the impression that people usually don’t recognize that they could be using a setter, instead of a function, due to those frameworks, coming from a respected source, causing them to believe that the practice is reasonable.

/// Use this as the getter for set-only properties,
/// until Swift has real set-only properties.
///- Important: Causes a fatal error, logging the name of the property.
///- Parameter propertyName: Never use this; only use the default.
@noreturn public func setOnlyPropertyGetterError(propertyName: String = __FUNCTION__) {
   fatalError("\(propertyName) is set-only")
}

I remain unconvinced that any method that starts with "set" without a matching getter could be turned into a "good property setter". I'm not sure who you're trying to convince with this metric.

Maybe you should start by telling if you think that there can be a "bad setter". For instance, can I replace a `sendResponse(String)` method that sends a string over the network with a `response` set-only property?

IMO, a good setter behaves like it's setting a variable, because this is exactly what the assignment operator suggests. That is:
you should be able to replace a sequence of writes to a setter by a single write with the last value and still have essentially the same end result;
you should be able to reorder setter operations and still essentially get the same end result.
"Essentially the same end result" means that it's okay if the logging output is different or if you wasted cycles in the process.

Félix

···

Le 4 févr. 2016 à 10:25:14, Jessy Catterwaul <mr.jessy@gmail.com> a écrit :

My original post from yesterday, which describes the way that I am using set-only properties in Swift, still has not gotten through; attempting again:

I use set-only properties very, very often. I am interested to know how ubiquitous functions that begin with “set” are, in  frameworks. I’m currently under the impression that people usually don’t recognize that they could be using a setter, instead of a function, due to those frameworks, coming from a respected source, causing them to believe that the practice is reasonable.

/// Use this as the getter for set-only properties,
/// until Swift has real set-only properties.
///- Important: Causes a fatal error, logging the name of the property.
///- Parameter propertyName: Never use this; only use the default.
@noreturn public func setOnlyPropertyGetterError(propertyName: String = __FUNCTION__) {
   fatalError("\(propertyName) is set-only")
}

I remain unconvinced that any method that starts with "set" without a matching getter could be turned into a "good property setter". I'm not sure who you're trying to convince with this metric.

Are there counterexamples? I do not have a memory of coming across something that began with “set”, and not thinking that what come after should have been a property or a subscript.

Maybe you should start by telling if you think that there can be a "bad setter". For instance, can I replace a `sendResponse(String)` method that sends a string over the network with a `response` set-only property?

That’s “send response”, not “setResponse”. Without knowing more about that API, my inclination is to think it would correctly be titled

func send(response: String)

IMO, a good setter behaves like it's setting a variable, because this is exactly what the assignment operator suggests. That is:
you should be able to replace a sequence of writes to a setter by a single write with the last value and still have essentially the same end result;
you should be able to reorder setter operations and still essentially get the same end result.

"Essentially the same end result" means that it's okay if the logging output is different or if you wasted cycles in the process.

Sounds good to me. I believe all the places that I’ve used set-only properties matched these guidelines.