> On Dec 27, 2015, at 2:47 PM, John McCall <[email protected]> wrote:
> 
>> On Dec 27, 2015, at 10:37 AM, Joe Groff via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>>> Getters and setters can be written using dotted syntax within the 
>>> back-ticks:
>>> 
>>> let specificTitle = button.`currentTitle.get` // has type () -> String?
>>> let otherTitle = UIButton.`currentTitle.get`  // has type (UIButton) -> () 
>>> -> String?
>>> let setTintColor = button.`tintColor.set`     // has type (UIColor!) -> ()
>>> The same syntax works with subscript getters and setters as well, using the 
>>> full name of the subscript:
>>> 
>>> extension Matrix {
>>>   subscript (row row: Int) -> [Double] {
>>>     get { ... }
>>>     set { ... }
>>>   }
>>> }
>>> 
>>> let getRow = someMatrix.`subscript(row:).get` // has type (Int) -> () -> 
>>> [Double]
>>> let setRow = someMatrix.`subscript(row:).set` // has type (Int) -> 
>>> ([Double]) -> ()
>> At least as far as pure Swift is concerned, for unapplied access, like 
>> `UIButton.currentTitle`, I think it would be more consistent with the way 
>> method references works for that to give you the getter (or lens) without 
>> decoration. instance.instanceMethod has type Args -> Ret, and 
>> Type.instanceMethod has type Self -> Args -> Ret; by analogy, since 
>> instance.instanceProperty has type Ret or inout Ret, it's reasonable to 
>> expect Type.instanceProperty to have type Self -> [inout] Ret. Forming a 
>> getter or setter partially applied to an instance feels unmotivated to me—{ 
>> button.currentTitle } or { button.currentTitle = $0 } already work, and are 
>> arguably clearer than this syntax.
>> 
>> I acknowledge that this leaves forming selectors from setters out to dry, 
>> but I feel like that's something that could be incorporated into a "lens" 
>> design along with typed selectors. As a rough sketch, we could say that the 
>> representation of @convention(selector) T -> inout U is a pair of 
>> getter/setter selectors, and provide API on Selector to grab the individual 
>> selectors from that, maybe Selector(getterFor: 
>> UIView.currentTitle)/(setterFor: UIView.currentTitle). I don't think get/set 
>> is a good interface for working with Swift properties, so I don't like the 
>> idea of building in language support to codify it beyond what's needed for 
>> ObjC interaction.
> 
> I know this might be too early, but: what syntax are we thinking of for 
> lenses?  We might want to design this with future consistency in mind.

Vaguely, I think it could look something like this. You could define a lens 
function by having it return `inout`. Calling the function produces an lvalue 
whose access nests within the accesses of its input `inout` parameters, if any, 
allowing for things like:

var localVar = 1
let localRef: () -> inout Int = { &localVar }

func second(inout array: [Int]) -> inout Int {
  return &array[1]
}

// Maybe you can define an inout function with accessors too
func fahrenheit(inout celsius: Double) -> inout Double {
  get {
    return celsius * 9/5 + 32
  }
  set {
    celsius = (newValue - 32) * 5/9
  }
}

and you could access the unapplied lens for an instance property using 
`Type.property` syntax, analogous to how `Type.method` works. I feel like if we 
did that, then it would obviate the need for explicit `property.get` or 
`property.set` for most native Swift uses, though maybe not ObjC interop uses.

-Joe
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to