[swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

Xiaodi Wu xiaodi.wu at gmail.com
Sun Dec 3 16:38:56 CST 2017


On Sun, Dec 3, 2017 at 2:20 PM, Karl Wagner via swift-evolution <
swift-evolution at 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171203/55a2045d/attachment.html>


More information about the swift-evolution mailing list