Subscripts in Swift in fact have always looked to me like a way to make objects
"callable", where you use brackets instead of parentheses: the difference of
course is the fact that, when used point-free, the object will be considered an
instance and not a function.
In this sense we could theoretically make a KeyPath callable by adding
subscripts; consider the following code:
extension KeyPath {
subscript (get root: Root) -> Value {
return root[keyPath: self]
}
}
struct Person {
var firstName: String
var lastName: String
}
let x = Person.init(firstName: "Foo", lastName: "Bar")
let foo = (\Person.firstName)[get: x] /// "Foo"
This is valid Swift code (Swift 4.0 snapshot 2017-07-13). In theory a possible
evolution of this could be referencing the subscript function in a point-free
way like we can already do with regular functions:
let callable1 = (\Person.firstName)[get:] /// this won't compile
For the setter part, because the other half of a KeyPath is essentially a
function of type (Value, inout Root) -> (), we could theoretically considering
this kind of subscript function:
extension KeyPath {
subscript (set value: Value, on root: inout Root) -> () { /// this
won't compile
root[keyPath: self] = value
return ()
}
}
let callable2 = (\Person.firstName)[set:,on:] /// this won't compile
But we cannot write subscripts with inout parameters. I actually find the
subscript path a very interesting one to consider, but there's still a lot of
machinery that's missing.
I would prefer two standardized prefix operators - for extracting the "(Root)
-> Value" and the "(Value,inout Root) -> ()" parts of a KeyPath - to be added
to the standard library. This is exactly the case where custom operators make
sense: repeated operations that should be expressed with minimum code noise.
Elviro
> Il giorno 16 lug 2017, alle ore 18:34, Benjamin Herzog via swift-evolution
> <[email protected]> ha scritto:
>
> If it would be possible to make objects callable, wouldn't that also go
> in the same direction as subscripts currently? One could also implement
> it with the syntax for callable functions (in this case anonymous -
> without a name). Instead of this:
>
> subscript(index: Int) -> T
>
> we could also write
>
> func (_ index: Int) -> T
>
> On the call side it would change from this:
>
> list[3] to list(3)
>
> I know that it's not necessary and not even better readable, but it goes
> in the same direction in my opinion and is worth considering. What do
> you think?
>
> ______________________
>
> Benjamin Herzog
>
> On Wed, Jul 12, 2017, at 10:21 PM, Dave Abrahams via swift-evolution
> wrote:
>>
>> on Tue Jul 11 2017, Robert Bennett <rltbennett-AT-icloud.com> wrote:
>>
>>> Just realized that even inout functions don’t let you do
>>> member(object) = value.
>>
>> The other difference is that an inout function can't be used to get a
>> member from an immutable value, whereas a keypath/subscript/property
>> access can.
>>
>>
>> --
>> -Dave
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected]
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution