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

Reply via email to