> On Sep 19, 2017, at 5:19 AM, David Zarzycki via swift-dev
> <swift-dev@swift.org> wrote:
>
>
>
>> On Sep 18, 2017, at 17:54, Ben Cohen via swift-dev <swift-dev@swift.org
>> <mailto:swift-dev@swift.org>> wrote:
>>
>>
>>
>>> On Sep 13, 2017, at 1:06 PM, David Zarzycki via swift-dev
>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>>>
>>>
>>>
>>>> On Sep 13, 2017, at 15:23, Matthew Johnson via swift-dev
>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>>>>
>>>>
>>>>
>>>> Sent from my iPhone
>>>>
>>>>> On Sep 13, 2017, at 11:56 AM, David Zarzycki via swift-dev
>>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>>>>>
>>>>>
>>>>>
>>>>>> On Sep 13, 2017, at 13:53, David Sweeris <daveswee...@mac.com
>>>>>> <mailto:daveswee...@mac.com>> wrote:
>>>>>>
>>>>>>
>>>>>>> On Sep 13, 2017, at 09:54, David Zarzycki via swift-dev
>>>>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>>>>>>>
>>>>>>> Hello,
>>>>>>>
>>>>>>> As a part of a research project that I’m working on, I’ve started
>>>>>>> bumping into the need for value-type bound protocols (as opposed to the
>>>>>>> existing class bound protocols). Is this something that would be worth
>>>>>>> proposing formally? Or should I just keep the patch I have on my
>>>>>>> research branch?
>>>>>>
>>>>>> I think it'd be worth a proposal, especially if can talk about why you
>>>>>> needed it.
>>>>>
>>>>> While I look forward to talking about my research, I’m not ready to do in
>>>>> the near future.
>>>>>
>>>>> That being said, value-type bound protocols seem independently useful and
>>>>> that is why I emailed the list.
>>>>>
>>>>> I think the use case for this is generic algorithms. Why? Because it can
>>>>> be hard to impossible to write *robust* generic code when you don’t know
>>>>> whether an abstract type copies by value or by reference during
>>>>> assignment/initialization. With class-bound protocols, you can guarantee
>>>>> reference semantics, but there is no analogous feature for ensuring value
>>>>> semantics. I have a small (~150 line) patch that fixes this.
>>>>
>>>> Value types and value semantics are not the same. Most people who have
>>>> asked for this capability actually want a constraint for value semantics,
>>>> not value types. Is that what you're asking for as well?
>>>
>>> The patch that I’m ready to put forth is only a value-type bound. In other
>>> words only structs and enums would be able to conform to a value-type bound
>>> protocol. Enforcing value semantics is arguably a separable language goal.
>>>
>>
>> But knowing something is a value type isn’t particularly useful, given it
>> doesn’t guarantee value semantics. It could even do more harm than good, by
>> being confusable with enforcing value semantics.
>>
>> Can you go into the use cases you have where you would use the knowledge
>> that a type is a value type?
>
>
> Hi Ben,
>
> As a part of a much larger goal, I’m experimenting with enforced value
> *semantics* and I found that value-type bound protocols are a wholly
> separable and independently useful prerequisite. Here is a contrived but
> representative example:
>
> protocol ValueThingy : !class { // From the patch sent to the list
> mutating func increment()
> }
>
> func incrementByCopy<T : ValueThingy>(_ arg : T) -> T {
> var copy = arg
> copy.increment()
> return copy
> }
>
> Without value-type bound protocols, generic code cannot ensure that required
> copies are actually happening. This is independently useful and good.
As others have noted, this doesn't by itself guarantee anything. Value
semantics is a property of an operation, not of a type. You can use an Int as a
reference:
var counters: [Double]
extension Int: ValueThingy {
mutating func increment() {
counters[self] += 1.0
}
}
which, despite "using value types everywhere", violates the contract you're
looking for without warning. On the other hand, a class can also serve as a
value:
protocol Incrementable {
var incremented: Self { get }
}
extension ValueThingy where Self: Incrementable {
mutating func increment() {
self = self.incremented
}
}
class IndirectInt: ValueThingy, Incrementable {
var value: Int
init(value: Int) { self.value = value }
var incremented: Int { return IndirectInt(value: value + 1) }
}
The more fundamental thing I think we're looking for in this space is a "pure"
restriction for functions and methods, meaning they only access
non-shared-mutable data. Any annotation at the type level is not going to give
strong enough guarantees to build sound abstractions on top of.
-Joe
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev