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 
> <swift-evolution@swift.org> 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
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

Reply via email to