On Sun, Dec 3, 2017 at 2:20 PM, Karl Wagner via swift-evolution < swift-evolution@swift.org> wrote:
> > I believe that adding explicit syntax would be counterproductive to your > goals, and would not make dynamic lookup syntax more clear. I assume that > you would also want the same thing for DynamicCallable too, and operator > overloads, subscripts, and every other operation you perform on these > values, since they all have the exact same behavior. > > If we required some syntax even as minimal as “foo.^bar” and "baz^(42)”, > that change would turn this (which uses runtime failing or IUO return > values like AnyObject): > > let np = Python.import("numpy") > let x = np.array([6, 7, 8]) > let y = np.arange(24).reshape(2, 3, 4) > let a = np.ones(3, dtype: np.int32) > let b = np.linspace(0, pi, 3) > let c = a+b > let d = np.exp(c) > print(d) > > into: > > let np = Python.import("numpy") > let b = np^.array^([6, 7, 8]) > let y = np^.arange^(24)^.reshape^(2, 3, 4) > > let a = np^.ones^(3, dtype: np^.int32) > let b = np^.linspace^(0, pi, 3) > let c = a+^b > let d = np^.exp^(c) > > This does not improve clarity of code, it merely serves to obfuscate > logic. It is immediately apparent from the APIs being used, the API style, > and the static types (in Xcode or through static declarations) that this is > all Python stuff. When you start mixing in use of native Swift types like > dictionaries (something we want to encourage because they are typed!) you > end up with an inconsistent mismash where people would just try adding > syntax or applying fixits continuously until the code builds. > > > That’s not Swift. You just wrote a bunch of Python. For example, Swift has > a native Int32.+ operator which fails on overflow - does your example also > do that? Anybody’s guess! Does your numpy array conform to Collection? I > guess not, because it’s an opaque Python value. > > That’s exactly the kind of stuff I, as a user of the language, really > don't want to see mixed together with real Swift. I appreciate the need to > use functionality from libraries written in Python, but I don’t appreciate > it being so invisible and pervasive throughout the language. If you have a > bunch of Python logic, I’d prefer you wrote as much of it as possible in > Python, with as few bridging points to Swift as you can get away with. I > remain convinced that this design encourages the opposite - because, as you > said earlier, it’s “too good”. > The use case that Chris is solving here is precisely how to enable the writing of this type of code in Swift. Put another way, how do I interface with libraries written in Python without writing my own code in Python? "That's exactly the kind of stuff I really don't want to see mixed together with real Swift" and "I'd prefer you wrote as much of it as possible in Python" is not an answer; it's rejecting the legitimacy of the use case in the first place. As for the point about Swift already including non-marked, > potentially-crashing operations (like the + operator, or Array > subscripting): nobody likes that behaviour! > I, for one, very much like that behavior. Swift has many non-marked, potentially-crashing operations because that is both performant and safe. There is a common misconception that crashing is unsafe, with corresponding misconceptions such as avoiding "!". This is simply incorrect. > Whenever I come to a new Swift codebase, I almost universally find that > people have written their own “safe” Array accessor which integrates > bounds-checking and returns an Optional. The issue has come up here many, > many times for inclusion in the standard library. I certainly would not use > it as justification for adding more of those kinds of unmarked, > potentially-unsafe operations. Also, enough Swift developers know about the > Array subscript behaviour that the square brackets almost become a marker, > like “!”, of a potentially-failing operation. The same is not true of the > dot operator, in general. > > I also don’t agree with the comparisons to Objective-C/AnyObject dispatch. > It’s true that it’s unsafe to an extent, but it’s also orders of magnitude > safer than this sort of dispatch. Clang is integrated in to the compiler, > and can at least perform some rudimentary checking of method > signatures/selectors. This sort of dispatch provides absolutely no > protections whatsoever — is “arange” really a function? Is it not really a > typo for “arrange”? That’s something I need to Google. With regular Swift I > can assume that if the compiler allows it, there is a function called > “arange” somewhere, and all I need to worry about is whether the erased > AnyObject is of the correct type to respond to that message. And as I said > earlier, AnyObject is incredibly rare in practice anyway. So no, I don’t > agree that we should just keep lowering the safeguards; it’s like > demolishing your house because of one draughty door. > > What I *could* support, would be some kind of optional syntax, possibly > with some kind of associated scope which allows you omit it. Something like: > > // Normally, optionals are required. > let result: PythonObject? = pythonObj.someProperty?.someFunction(1, 2, 3) > > // Within a special scope, you can omit them. The scope will bail at the > first lookup failure and return nil. > let result: PythonObject? = Python { > return pythonObj.someProperty.someFunction(1, 2, 3) > } > > Perhaps the “Python” object could conform to a protocol with an associated > type for the objects it can implicitly unwrap. There would be some > additional compiler work, for sure, but that’s secondary to a good language > model IMO (easy for me to say, I know). > > > > - Karl > > _______________________________________________ > 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