> On Nov 10, 2017, at 11:20 AM, Chris Lattner via swift-evolution 
> <[email protected]> wrote:
> 
> 
>> On Nov 10, 2017, at 10:57 AM, Alejandro Martinez via swift-evolution 
>> <[email protected]> wrote:
>> 
>> This seems a really interesting solution Chris.
>> Similar to what Joe mentions I think this would also be appreciated by
>> the community to make even nicer DSLs in Swift, which may or may not
>> be a good side effect of the proposal.
>> Also, I'm just wondering, how much complication adds this to the
>> compiler itself that would have to be maintained in the future?
> 
> This is a very localized and simple change to the compiler.  Assuming the 
> pitch process goes well, I will provide an implementation.

I don't think it's that localized. It's going to make call resolution massively 
more complicated. Through great pain and community anguish, we pushed ourselves 
to a model where argument labels are parts of the declaration name, not part of 
the call argument, and this would throw us straight back into the kinds of 
complications of dealing with overloaded name- and type-dependent behavior 
we're trying to get away from in the language.

Swift is a dynamic language too, and tuples have enough metadata in them that 
you could get almost everything you want with an infix operator. Mirror doesn't 
expose the reflection information particularly elegantly, but you can do 
something like this to decompose a Swift tuple into positional and keyword 
arguments to fit the Python model:

infix operator ∫ // a "snake". get it

protocol Pythonic {
  func call(positionalArgs: [Pythonic], kwArgs: [(String, Pythonic)]) -> 
Pythonic
}

func ∫(function: Pythonic, args: Any) -> Pythonic {
  var positionalArgs: [Pythonic] = []
  var kwArgs: [(String, Pythonic)] = []
  
  let argMirror = Mirror(reflecting: args)
  
  if argMirror.displayStyle == .tuple {
    // Tuple argument
    for child in argMirror.children {
      if let label = child.label, let first = label.first, first != "." {
        kwArgs.append((label, child.value as! Pythonic))
      } else {
        positionalArgs.append(child.value as! Pythonic)
      }
    }
  } else {
    // One argument
    positionalArgs = [args as! Pythonic]
  }
  
  return function.call(positionalArgs: positionalArgs, kwArgs: kwArgs)
}

x∫(0, "foo", bar: "bas")

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

Reply via email to